Subversion Repositories HelenOS

Compare Revisions

No changes between revisions

Ignore whitespace Rev 1834 → Rev 1967

/tags/0.2.0.3/kernel/arch/xen32/src/xen32.c
0,0 → 1,209
/*
* 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 xen32
* @{
*/
/** @file
*/
 
#include <arch.h>
#include <main/main.h>
 
#include <arch/types.h>
#include <typedefs.h>
#include <align.h>
 
#include <arch/pm.h>
 
#include <arch/drivers/xconsole.h>
#include <arch/mm/page.h>
 
#include <arch/context.h>
 
#include <config.h>
 
#include <arch/interrupt.h>
#include <arch/asm.h>
#include <genarch/acpi/acpi.h>
 
#include <arch/bios/bios.h>
 
#include <arch/boot/boot.h>
#include <arch/mm/memory_init.h>
#include <interrupt.h>
#include <arch/debugger.h>
#include <proc/thread.h>
#include <syscall/syscall.h>
#include <console/console.h>
 
start_info_t start_info;
memzone_t meminfo;
 
extern void xen_callback(void);
extern void xen_failsafe_callback(void);
 
void arch_pre_main(void)
{
xen_vm_assist(VMASST_CMD_ENABLE, VMASST_TYPE_WRITABLE_PAGETABLES);
pte_t pte;
memsetb((uintptr_t) &pte, sizeof(pte), 0);
pte.present = 1;
pte.writeable = 1;
pte.frame_address = ADDR2PFN((uintptr_t) start_info.shared_info);
xen_update_va_mapping(&shared_info, pte, UVMF_INVLPG);
pte.present = 1;
pte.writeable = 1;
pte.frame_address = start_info.console_mfn;
xen_update_va_mapping(&console_page, pte, UVMF_INVLPG);
xen_set_callbacks(XEN_CS, xen_callback, XEN_CS, xen_failsafe_callback);
/* Create identity mapping */
meminfo.start = ADDR2PFN(ALIGN_UP(KA2PA(start_info.ptl0), PAGE_SIZE)) + start_info.pt_frames;
meminfo.size = start_info.frames - meminfo.start;
meminfo.reserved = 0;
uintptr_t pa;
index_t last_ptl0 = 0;
for (pa = PFN2ADDR(meminfo.start); pa < PFN2ADDR(meminfo.start + meminfo.size); pa += FRAME_SIZE) {
uintptr_t va = PA2KA(pa);
if ((PTL0_INDEX(va) != last_ptl0) && (GET_PTL1_FLAGS(start_info.ptl0, PTL0_INDEX(va)) & PAGE_NOT_PRESENT)) {
/* New page directory entry needed */
uintptr_t tpa = PFN2ADDR(meminfo.start + meminfo.reserved);
uintptr_t tva = PA2KA(tpa);
memsetb(tva, PAGE_SIZE, 0);
pte_t *tptl3 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(start_info.ptl0, PTL0_INDEX(tva)));
SET_FRAME_FLAGS(tptl3, PTL3_INDEX(tva), PAGE_PRESENT);
SET_PTL1_ADDRESS(start_info.ptl0, PTL0_INDEX(va), tpa);
last_ptl0 = PTL0_INDEX(va);
meminfo.reserved++;
}
pte_t *ptl3 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(start_info.ptl0, PTL0_INDEX(va)));
SET_FRAME_ADDRESS(ptl3, PTL3_INDEX(va), pa);
SET_FRAME_FLAGS(ptl3, PTL3_INDEX(va), PAGE_PRESENT | PAGE_WRITE);
}
/* Put initial stack safely in the mapped area */
stack_safe = PA2KA(PFN2ADDR(meminfo.start + meminfo.reserved));
}
 
void arch_pre_mm_init(void)
{
pm_init();
 
if (config.cpu_active == 1) {
// bios_init();
exc_register(VECTOR_SYSCALL, "syscall", (iroutine) syscall);
#ifdef CONFIG_SMP
exc_register(VECTOR_TLB_SHOOTDOWN_IPI, "tlb_shootdown",
(iroutine) tlb_shootdown_ipi);
#endif /* CONFIG_SMP */
}
}
 
void arch_post_mm_init(void)
{
if (config.cpu_active == 1) {
/* video */
xen_console_init();
/* Enable debugger */
debugger_init();
/* Merge all memory zones to 1 big zone */
zone_merge_all();
}
}
 
void arch_pre_smp_init(void)
{
if (config.cpu_active == 1) {
memory_print_map();
#ifdef CONFIG_SMP
acpi_init();
#endif /* CONFIG_SMP */
}
}
 
void arch_post_smp_init(void)
{
}
 
void calibrate_delay_loop(void)
{
// i8254_calibrate_delay_loop();
if (config.cpu_active == 1) {
/*
* This has to be done only on UP.
* On SMP, i8254 is not used for time keeping and its interrupt pin remains masked.
*/
// i8254_normal_operation();
}
}
 
/** Set thread-local-storage pointer
*
* TLS pointer is set in GS register. That means, the GS contains
* selector, and the descriptor->base is the correct address.
*/
unative_t sys_tls_set(unative_t addr)
{
THREAD->arch.tls = addr;
set_tls_desc(addr);
 
return 0;
}
 
/** Acquire console back for kernel
*
*/
void arch_grab_console(void)
{
}
 
/** Return console to userspace
*
*/
void arch_release_console(void)
{
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/xen32/src/boot/boot.S
0,0 → 1,84
#
# Copyright (C) 2001-2004 Jakub Jermar
# Copyright (C) 2005-2006 Martin Decky
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# - The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
#include <arch/boot/boot.h>
#include <arch/mm/page.h>
#include <arch/pm.h>
 
.section __xen_guest
.ascii "GUEST_OS=HelenOS,"
.ascii "XEN_VER=xen-3.0,"
.ascii "HYPERCALL_PAGE=0x0000,"
.ascii "LOADER=generic,"
.ascii "FEATURES=writable_page_tables"
.byte 0
 
.text
 
.code32
.align 4
.global kernel_image_start
kernel_image_start:
# copy start_info (esi initialized by Xen)
movl $start_info, %edi
movl $START_INFO_SIZE >> 2, %ecx
cld
rep movsb
# switch to temporal kernel stack
movl $kernel_stack, %esp
call arch_pre_main
call main_bsp # never returns
 
cli
hlt
 
kernel_stack_bottom:
.space TEMP_STACK_SIZE
kernel_stack:
 
.section K_TEXT_START, "aw", @progbits
.global hypercall_page
.org 0
hypercall_page:
.space PAGE_SIZE
 
.global shared_info
.org 0x1000
shared_info:
.space PAGE_SIZE
 
.global console_page
.org 0x2000
console_page:
.space PAGE_SIZE
/tags/0.2.0.3/kernel/arch/xen32/src/drivers/xconsole.c
0,0 → 1,86
/*
* Copyright (C) 2006 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup xen32
* @{
*/
/**
* @file
* @brief Xen32 console driver.
*/
 
#include <arch/drivers/xconsole.h>
#include <putchar.h>
#include <console/chardev.h>
#include <console/console.h>
#include <arch/hypercall.h>
 
#define MASK_INDEX(index, ring) ((index) & (sizeof(ring) - 1))
 
static bool asynchronous = false;
static void xen_putchar(chardev_t *d, const char ch);
 
chardev_t xen_console;
static chardev_operations_t xen_ops = {
.write = xen_putchar
};
 
void xen_console_init(void)
{
chardev_initialize("xen_out", &xen_console, &xen_ops);
stdout = &xen_console;
if (!(start_info.flags & SIF_INITDOMAIN))
asynchronous = true;
}
 
void xen_putchar(chardev_t *d, const char ch)
{
if (asynchronous) {
uint32_t cons = console_page.out_cons;
uint32_t prod = console_page.out_prod;
memory_barrier();
if ((prod - cons) > sizeof(console_page.out))
return;
if (ch == '\n')
console_page.out[MASK_INDEX(prod++, console_page.out)] = '\r';
console_page.out[MASK_INDEX(prod++, console_page.out)] = ch;
write_barrier();
console_page.out_prod = prod;
xen_notify_remote(start_info.console_evtchn);
} else
xen_console_io(CONSOLE_IO_WRITE, 1, &ch);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/xen32/src/asm.S
0,0 → 1,124
#
# Copyright (C) 2001-2004 Jakub Jermar
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# - The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
## very low and hardware-level functions
 
# Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int has no error word
# and 1 means interrupt with error word
#define ERROR_WORD_INTERRUPT_LIST 0x00027D00
 
.text
 
.global xen_callback
.global xen_failsafe_callback
.global enable_l_apic_in_msr
.global memcpy
.global memcpy_from_uspace
.global memcpy_from_uspace_failover_address
.global memcpy_to_uspace
.global memcpy_to_uspace_failover_address
 
 
xen_callback:
iret
 
xen_failsafe_callback:
iret
 
 
#define MEMCPY_DST 4
#define MEMCPY_SRC 8
#define MEMCPY_SIZE 12
 
/** Copy memory to/from userspace.
*
* This is almost conventional memcpy().
* The difference is that there is a failover part
* to where control is returned from a page fault
* if the page fault occurs during copy_from_uspace()
* or copy_to_uspace().
*
* @param MEMCPY_DST(%esp) Destination address.
* @param MEMCPY_SRC(%esp) Source address.
* @param MEMCPY_SIZE(%esp) Size.
*
* @return MEMCPY_SRC(%esp) on success and 0 on failure.
*/
memcpy:
memcpy_from_uspace:
memcpy_to_uspace:
movl %edi, %edx /* save %edi */
movl %esi, %eax /* save %esi */
movl MEMCPY_SIZE(%esp), %ecx
shrl $2, %ecx /* size / 4 */
movl MEMCPY_DST(%esp), %edi
movl MEMCPY_SRC(%esp), %esi
rep movsl /* copy as much as possible word by word */
 
movl MEMCPY_SIZE(%esp), %ecx
andl $3, %ecx /* size % 4 */
jz 0f
rep movsb /* copy the rest byte by byte */
 
0:
movl %edx, %edi
movl %eax, %esi
movl MEMCPY_SRC(%esp), %eax /* MEMCPY_SRC(%esp), success */
ret
/*
* We got here from as_page_fault() after the memory operations
* above had caused a page fault.
*/
memcpy_from_uspace_failover_address:
memcpy_to_uspace_failover_address:
movl %edx, %edi
movl %eax, %esi
xorl %eax, %eax /* return 0, failure */
ret
 
 
## Enable local APIC
#
# Enable local APIC in MSR.
#
enable_l_apic_in_msr:
push %eax
 
movl $0x1b, %ecx
rdmsr
orl $(1<<11),%eax
orl $(0xfee00000),%eax
wrmsr
 
pop %eax
ret
/tags/0.2.0.3/kernel/arch/xen32/src/pm.c
0,0 → 1,214
/*
* 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 xen32
* @{
*/
/** @file
*/
 
#include <arch/pm.h>
#include <config.h>
#include <arch/types.h>
#include <typedefs.h>
#include <arch/interrupt.h>
#include <arch/asm.h>
#include <arch/context.h>
#include <panic.h>
#include <arch/mm/page.h>
#include <mm/slab.h>
#include <memstr.h>
#include <arch/boot/boot.h>
#include <interrupt.h>
 
/*
* Early xen32 configuration functions and data structures.
*/
 
/*
* We have no use for segmentation so we set up flat mode. In this
* mode, we use, for each privilege level, two segments spanning the
* whole memory. One is for code and one is for data.
*
* One is for GS register which holds pointer to the TLS thread
* structure in it's base.
*/
descriptor_t gdt[GDT_ITEMS] = {
/* NULL descriptor */
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
/* KTEXT descriptor */
{ 0xffff, 0, 0, AR_PRESENT | AR_CODE | DPL_KERNEL, 0xf, 0, 0, 1, 1, 0 },
/* KDATA descriptor */
{ 0xffff, 0, 0, AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_KERNEL, 0xf, 0, 0, 1, 1, 0 },
/* UTEXT descriptor */
{ 0xffff, 0, 0, AR_PRESENT | AR_CODE | DPL_USER, 0xf, 0, 0, 1, 1, 0 },
/* UDATA descriptor */
{ 0xffff, 0, 0, AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_USER, 0xf, 0, 0, 1, 1, 0 },
/* TSS descriptor - set up will be completed later */
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
/* TLS descriptor */
{ 0xffff, 0, 0, AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_USER, 0xf, 0, 0, 1, 1, 0 },
};
 
static trap_info_t traps[IDT_ITEMS + 1];
 
static tss_t tss;
 
tss_t *tss_p = NULL;
 
/* gdtr is changed by kmp before next CPU is initialized */
ptr_16_32_t bootstrap_gdtr = { .limit = sizeof(gdt), .base = KA2PA((uintptr_t) gdt) };
ptr_16_32_t gdtr = { .limit = sizeof(gdt), .base = (uintptr_t) gdt };
 
void gdt_setbase(descriptor_t *d, uintptr_t base)
{
d->base_0_15 = base & 0xffff;
d->base_16_23 = ((base) >> 16) & 0xff;
d->base_24_31 = ((base) >> 24) & 0xff;
}
 
void gdt_setlimit(descriptor_t *d, uint32_t limit)
{
d->limit_0_15 = limit & 0xffff;
d->limit_16_19 = (limit >> 16) & 0xf;
}
 
void tss_initialize(tss_t *t)
{
memsetb((uintptr_t) t, sizeof(struct tss), 0);
}
 
static void trap(void)
{
}
 
void traps_init(void)
{
index_t i;
for (i = 0; i < IDT_ITEMS; i++) {
traps[i].vector = i;
if (i == VECTOR_SYSCALL)
traps[i].flags = 3;
else
traps[i].flags = 0;
traps[i].cs = XEN_CS;
traps[i].address = trap;
exc_register(i, "undef", (iroutine) null_interrupt);
}
traps[IDT_ITEMS].vector = 0;
traps[IDT_ITEMS].flags = 0;
traps[IDT_ITEMS].cs = 0;
traps[IDT_ITEMS].address = NULL;
exc_register(13, "gp_fault", (iroutine) gp_fault);
exc_register( 7, "nm_fault", (iroutine) nm_fault);
exc_register(12, "ss_fault", (iroutine) ss_fault);
exc_register(19, "simd_fp", (iroutine) simd_fp_exception);
}
 
 
/* Clean IOPL(12,13) and NT(14) flags in EFLAGS register */
static void clean_IOPL_NT_flags(void)
{
// __asm__ volatile (
// "pushfl\n"
// "pop %%eax\n"
// "and $0xffff8fff, %%eax\n"
// "push %%eax\n"
// "popfl\n"
// : : : "eax"
// );
}
 
/* Clean AM(18) flag in CR0 register */
static void clean_AM_flag(void)
{
// __asm__ volatile (
// "mov %%cr0, %%eax\n"
// "and $0xfffbffff, %%eax\n"
// "mov %%eax, %%cr0\n"
// : : : "eax"
// );
}
 
void pm_init(void)
{
descriptor_t *gdt_p = (descriptor_t *) gdtr.base;
 
// gdtr_load(&gdtr);
if (config.cpu_active == 1) {
traps_init();
xen_set_trap_table(traps);
/*
* NOTE: bootstrap CPU has statically allocated TSS, because
* the heap hasn't been initialized so far.
*/
tss_p = &tss;
} else {
tss_p = (tss_t *) malloc(sizeof(tss_t), FRAME_ATOMIC);
if (!tss_p)
panic("could not allocate TSS\n");
}
 
// tss_initialize(tss_p);
gdt_p[TSS_DES].access = AR_PRESENT | AR_TSS | DPL_KERNEL;
gdt_p[TSS_DES].special = 1;
gdt_p[TSS_DES].granularity = 0;
gdt_setbase(&gdt_p[TSS_DES], (uintptr_t) tss_p);
gdt_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE - 1);
 
/*
* As of this moment, the current CPU has its own GDT pointing
* to its own TSS. We just need to load the TR register.
*/
// tr_load(selector(TSS_DES));
clean_IOPL_NT_flags(); /* Disable I/O on nonprivileged levels and clear NT flag. */
clean_AM_flag(); /* Disable alignment check */
}
 
void set_tls_desc(uintptr_t tls)
{
ptr_16_32_t cpugdtr;
descriptor_t *gdt_p;
 
gdtr_store(&cpugdtr);
gdt_p = (descriptor_t *) cpugdtr.base;
gdt_setbase(&gdt_p[TLS_DES], tls);
/* Reload gdt register to update GS in CPU */
gdtr_load(&cpugdtr);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/xen32/src/userspace.c
0,0 → 1,85
/*
* 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 xen32
* @{
*/
/** @file
*/
 
#include <userspace.h>
#include <arch/pm.h>
#include <arch/types.h>
#include <arch.h>
#include <proc/uarg.h>
#include <mm/as.h>
 
 
/** Enter userspace
*
* Change CPU protection level to 3, enter userspace.
*
*/
void userspace(uspace_arg_t *kernel_uarg)
{
uint32_t ipl = interrupts_disable();
 
asm volatile (
/*
* Clear nested task flag.
*/
"pushfl\n"
"pop %%eax\n"
"and $0xffffbfff, %%eax\n"
"push %%eax\n"
"popfl\n"
 
/* Set up GS register (TLS) */
"movl %6, %%gs\n"
 
"pushl %0\n"
"pushl %1\n"
"pushl %2\n"
"pushl %3\n"
"pushl %4\n"
"movl %5, %%eax\n"
"iret\n"
:
: "i" (selector(UDATA_DES) | PL_USER), "r" (kernel_uarg->uspace_stack+THREAD_STACK_SIZE),
"r" (ipl), "i" (selector(UTEXT_DES) | PL_USER), "r" (kernel_uarg->uspace_entry),
"r" (kernel_uarg->uspace_uarg),
"r" (selector(TLS_DES))
: "eax");
/* Unreachable */
for(;;)
;
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/xen32/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 xen32proc
* @{
*/
/** @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)
{
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/xen32/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 xen32proc
* @{
*/
/** @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);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/xen32/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 xen32proc
* @{
*/
/** @file
*/
 
#include <proc/thread.h>
 
/** Perform xen32 specific thread initialization.
*
* @param t Thread to be initialized.
*/
void thread_create_arch(thread_t *t)
{
t->arch.tls = 0;
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/xen32/src/mm/memory_init.c
0,0 → 1,53
/*
* Copyright (C) 2005 Josef Cejka
* 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 xen32mm
* @{
*/
/** @file
*/
 
#include <arch/mm/memory_init.h>
#include <arch/mm/page.h>
#include <arch/boot/boot.h>
#include <print.h>
#include <mm/frame.h>
 
size_t get_memory_size(void)
{
return start_info.frames * PAGE_SIZE;
}
 
void memory_print_map(void)
{
printf("Xen memory: %p size: %d (reserved %d)\n", PFN2ADDR(meminfo.start), PFN2ADDR(meminfo.size - meminfo.reserved), PFN2ADDR(meminfo.reserved));
}
 
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/xen32/src/mm/frame.c
0,0 → 1,49
/*
* 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 xen32mm
* @{
*/
/** @file
* @ingroup xen32mm
*/
 
#include <mm/frame.h>
#include <config.h>
 
void frame_arch_init(void)
{
if (config.cpu_active == 1) {
/* The only memory zone */
zone_create(meminfo.start, meminfo.size, meminfo.start + meminfo.reserved, 0);
frame_mark_unavailable(meminfo.start, meminfo.reserved);
}
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/xen32/src/mm/tlb.c
0,0 → 1,75
/*
* 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 xen32mm
* @{
*/
/** @file
* @ingroup xen32mm
*/
 
#include <mm/tlb.h>
#include <arch/mm/asid.h>
#include <arch/asm.h>
#include <arch/types.h>
#include <arch/hypercall.h>
 
/** Invalidate all entries in TLB. */
void tlb_invalidate_all(void)
{
mmuext_op_t mmu_ext;
mmu_ext.cmd = MMUEXT_TLB_FLUSH_LOCAL;
xen_mmuext_op(&mmu_ext, 1, NULL, DOMID_SELF);
}
 
/** Invalidate all entries in TLB that belong to specified address space.
*
* @param asid This parameter is ignored as the architecture doesn't support it.
*/
void tlb_invalidate_asid(asid_t asid)
{
tlb_invalidate_all();
}
 
/** Invalidate TLB entries for specified page range belonging to specified address space.
*
* @param asid This parameter is ignored as the architecture doesn't support it.
* @param page Address of the first page whose entry is to be invalidated.
* @param cnt Number of entries to invalidate.
*/
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt)
{
int i;
 
for (i = 0; i < cnt; i++)
invlpg(page + i * PAGE_SIZE);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/xen32/src/mm/page.c
0,0 → 1,86
/*
* 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 xen32mm
* @{
*/
/** @file
*/
 
#include <arch/mm/page.h>
#include <genarch/mm/page_pt.h>
#include <arch/mm/frame.h>
#include <mm/frame.h>
#include <mm/page.h>
#include <mm/as.h>
#include <arch/types.h>
#include <align.h>
#include <config.h>
#include <func.h>
#include <arch/interrupt.h>
#include <arch/asm.h>
#include <debug.h>
#include <memstr.h>
#include <print.h>
#include <interrupt.h>
 
void page_arch_init(void)
{
if (config.cpu_active == 1) {
page_mapping_operations = &pt_mapping_operations;
AS_KERNEL->page_table = (pte_t *) KA2PA(start_info.ptl0);
} else
SET_PTL0_ADDRESS_ARCH(AS_KERNEL->page_table);
}
 
void page_fault(int n, istate_t *istate)
{
uintptr_t page;
pf_access_t access;
page = read_cr2();
if (istate->error_word & PFERR_CODE_RSVD)
panic("Reserved bit set in page directory.\n");
if (istate->error_word & PFERR_CODE_RW)
access = PF_ACCESS_WRITE;
else
access = PF_ACCESS_READ;
if (as_page_fault(page, access, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate, "Page fault: %#x", page);
PRINT_INFO_ERRCODE(istate);
printf("page fault address: %#x\n", page);
panic("page fault\n");
}
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/xen32/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 xen32mm
* @{
*/
/** @file
* @ingroup xen32mm
*/
 
#include <arch/mm/as.h>
#include <genarch/mm/as_pt.h>
 
/** Architecture dependent address space init. */
void as_arch_init(void)
{
as_operations = &as_pt_operations;
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/xen32/src/smp/smp.c
0,0 → 1,175
/*
* Copyright (C) 2005 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup xen32
* @{
*/
/** @file
*/
 
#include <smp/smp.h>
#include <arch/smp/smp.h>
#include <arch/smp/mps.h>
#include <arch/smp/ap.h>
#include <arch/boot/boot.h>
#include <genarch/acpi/acpi.h>
#include <genarch/acpi/madt.h>
#include <config.h>
#include <synch/waitq.h>
#include <synch/synch.h>
#include <arch/pm.h>
#include <func.h>
#include <panic.h>
#include <debug.h>
#include <arch/asm.h>
#include <mm/frame.h>
#include <mm/page.h>
#include <mm/slab.h>
#include <mm/as.h>
#include <print.h>
#include <memstr.h>
 
#ifdef CONFIG_SMP
 
static struct smp_config_operations *ops = NULL;
 
void smp_init(void)
{
uintptr_t l_apic_address, io_apic_address;
 
if (acpi_madt) {
acpi_madt_parse();
ops = &madt_config_operations;
}
if (config.cpu_count == 1) {
mps_init();
ops = &mps_config_operations;
}
 
l_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, FRAME_ATOMIC | FRAME_KA);
if (!l_apic_address)
panic("cannot allocate address for l_apic\n");
 
io_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, FRAME_ATOMIC | FRAME_KA);
if (!io_apic_address)
panic("cannot allocate address for io_apic\n");
 
if (config.cpu_count > 1) {
page_mapping_insert(AS_KERNEL, l_apic_address, (uintptr_t) l_apic,
PAGE_NOT_CACHEABLE);
page_mapping_insert(AS_KERNEL, io_apic_address, (uintptr_t) io_apic,
PAGE_NOT_CACHEABLE);
l_apic = (uint32_t *) l_apic_address;
io_apic = (uint32_t *) io_apic_address;
}
}
 
/*
* Kernel thread for bringing up application processors. It becomes clear
* that we need an arrangement like this (AP's being initialized by a kernel
* thread), for a thread has its dedicated stack. (The stack used during the
* BSP initialization (prior the very first call to scheduler()) will be used
* as an initialization stack for each AP.)
*/
void kmp(void *arg)
{
int i;
ASSERT(ops != NULL);
 
waitq_initialize(&ap_completion_wq);
 
/*
* We need to access data in frame 0.
* We boldly make use of kernel address space mapping.
*/
 
/*
* Save 0xa to address 0xf of the CMOS RAM.
* BIOS will not do the POST after the INIT signal.
*/
outb(0x70,0xf);
outb(0x71,0xa);
 
// pic_disable_irqs(0xffff);
apic_init();
 
for (i = 0; i < ops->cpu_count(); i++) {
struct descriptor *gdt_new;
/*
* Skip processors marked unusable.
*/
if (!ops->cpu_enabled(i))
continue;
 
/*
* The bootstrap processor is already up.
*/
if (ops->cpu_bootstrap(i))
continue;
 
if (ops->cpu_apic_id(i) == l_apic_id()) {
printf("%s: bad processor entry #%d, will not send IPI to myself\n", __FUNCTION__, i);
continue;
}
/*
* Prepare new GDT for CPU in question.
*/
if (!(gdt_new = (struct descriptor *) malloc(GDT_ITEMS*sizeof(struct descriptor), FRAME_ATOMIC)))
panic("couldn't allocate memory for GDT\n");
 
memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(struct descriptor));
memsetb((uintptr_t)(&gdt_new[TSS_DES]), sizeof(struct descriptor), 0);
gdtr.base = (uintptr_t) gdt_new;
 
if (l_apic_send_init_ipi(ops->cpu_apic_id(i))) {
/*
* There may be just one AP being initialized at
* the time. After it comes completely up, it is
* supposed to wake us up.
*/
if (waitq_sleep_timeout(&ap_completion_wq, 1000000, SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT)
printf("%s: waiting for cpu%d (APIC ID = %d) timed out\n", __FUNCTION__, config.cpu_active > i ? config.cpu_active : i, ops->cpu_apic_id(i));
} else
printf("INIT IPI for l_apic%d failed\n", ops->cpu_apic_id(i));
}
}
 
int smp_irq_to_pin(int irq)
{
ASSERT(ops != NULL);
return ops->irq_to_pin(irq);
}
 
#endif /* CONFIG_SMP */
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/xen32/src/smp/mps.c
0,0 → 1,434
/*
* Copyright (C) 2001-2005 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup xen32
* @{
*/
/** @file
*/
 
#ifdef CONFIG_SMP
 
#include <config.h>
#include <print.h>
#include <debug.h>
#include <arch/smp/mps.h>
#include <arch/smp/apic.h>
#include <arch/smp/smp.h>
#include <func.h>
#include <arch/types.h>
#include <typedefs.h>
#include <cpu.h>
#include <arch/asm.h>
#include <arch/bios/bios.h>
#include <mm/frame.h>
 
/*
* MultiProcessor Specification detection code.
*/
 
#define FS_SIGNATURE 0x5f504d5f
#define CT_SIGNATURE 0x504d4350
 
int mps_fs_check(uint8_t *base);
int mps_ct_check(void);
 
int configure_via_ct(void);
int configure_via_default(uint8_t n);
 
int ct_processor_entry(struct __processor_entry *pr);
void ct_bus_entry(struct __bus_entry *bus);
void ct_io_apic_entry(struct __io_apic_entry *ioa);
void ct_io_intr_entry(struct __io_intr_entry *iointr);
void ct_l_intr_entry(struct __l_intr_entry *lintr);
 
void ct_extended_entries(void);
 
static struct mps_fs *fs;
static struct mps_ct *ct;
 
struct __processor_entry *processor_entries = NULL;
struct __bus_entry *bus_entries = NULL;
struct __io_apic_entry *io_apic_entries = NULL;
struct __io_intr_entry *io_intr_entries = NULL;
struct __l_intr_entry *l_intr_entries = NULL;
 
int processor_entry_cnt = 0;
int bus_entry_cnt = 0;
int io_apic_entry_cnt = 0;
int io_intr_entry_cnt = 0;
int l_intr_entry_cnt = 0;
 
waitq_t ap_completion_wq;
 
/*
* Implementation of IA-32 SMP configuration interface.
*/
static count_t get_cpu_count(void);
static bool is_cpu_enabled(index_t i);
static bool is_bsp(index_t i);
static uint8_t get_cpu_apic_id(index_t i);
static int mps_irq_to_pin(int irq);
 
struct smp_config_operations mps_config_operations = {
.cpu_count = get_cpu_count,
.cpu_enabled = is_cpu_enabled,
.cpu_bootstrap = is_bsp,
.cpu_apic_id = get_cpu_apic_id,
.irq_to_pin = mps_irq_to_pin
};
 
count_t get_cpu_count(void)
{
return processor_entry_cnt;
}
 
bool is_cpu_enabled(index_t i)
{
ASSERT(i < processor_entry_cnt);
return processor_entries[i].cpu_flags & 0x1;
}
 
bool is_bsp(index_t i)
{
ASSERT(i < processor_entry_cnt);
return processor_entries[i].cpu_flags & 0x2;
}
 
uint8_t get_cpu_apic_id(index_t i)
{
ASSERT(i < processor_entry_cnt);
return processor_entries[i].l_apic_id;
}
 
 
/*
* Used to check the integrity of the MP Floating Structure.
*/
int mps_fs_check(uint8_t *base)
{
int i;
uint8_t sum;
for (i = 0, sum = 0; i < 16; i++)
sum += base[i];
return !sum;
}
 
/*
* Used to check the integrity of the MP Configuration Table.
*/
int mps_ct_check(void)
{
uint8_t *base = (uint8_t *) ct;
uint8_t *ext = base + ct->base_table_length;
uint8_t sum;
int i;
/* count the checksum for the base table */
for (i=0,sum=0; i < ct->base_table_length; i++)
sum += base[i];
if (sum)
return 0;
/* count the checksum for the extended table */
for (i=0,sum=0; i < ct->ext_table_length; i++)
sum += ext[i];
return sum == ct->ext_table_checksum;
}
 
void mps_init(void)
{
uint8_t *addr[2] = { NULL, (uint8_t *) PA2KA(0xf0000) };
int i, j, length[2] = { 1024, 64*1024 };
 
/*
* Find MP Floating Pointer Structure
* 1a. search first 1K of EBDA
* 1b. if EBDA is undefined, search last 1K of base memory
* 2. search 64K starting at 0xf0000
*/
 
addr[0] = (uint8_t *) PA2KA(ebda ? ebda : 639 * 1024);
for (i = 0; i < 2; i++) {
for (j = 0; j < length[i]; j += 16) {
if (*((uint32_t *) &addr[i][j]) == FS_SIGNATURE && mps_fs_check(&addr[i][j])) {
fs = (struct mps_fs *) &addr[i][j];
goto fs_found;
}
}
}
 
return;
fs_found:
printf("%p: MPS Floating Pointer Structure\n", fs);
 
if (fs->config_type == 0 && fs->configuration_table) {
if (fs->mpfib2 >> 7) {
printf("%s: PIC mode not supported\n", __FUNCTION__);
return;
}
 
ct = (struct mps_ct *)PA2KA((uintptr_t)fs->configuration_table);
config.cpu_count = configure_via_ct();
}
else
config.cpu_count = configure_via_default(fs->config_type);
 
return;
}
 
int configure_via_ct(void)
{
uint8_t *cur;
int i, cnt;
if (ct->signature != CT_SIGNATURE) {
printf("%s: bad ct->signature\n", __FUNCTION__);
return 1;
}
if (!mps_ct_check()) {
printf("%s: bad ct checksum\n", __FUNCTION__);
return 1;
}
if (ct->oem_table) {
printf("%s: ct->oem_table not supported\n", __FUNCTION__);
return 1;
}
l_apic = (uint32_t *)(uintptr_t)ct->l_apic;
 
cnt = 0;
cur = &ct->base_table[0];
for (i=0; i < ct->entry_count; i++) {
switch (*cur) {
/* Processor entry */
case 0:
processor_entries = processor_entries ? processor_entries : (struct __processor_entry *) cur;
processor_entry_cnt++;
cnt += ct_processor_entry((struct __processor_entry *) cur);
cur += 20;
break;
 
/* Bus entry */
case 1:
bus_entries = bus_entries ? bus_entries : (struct __bus_entry *) cur;
bus_entry_cnt++;
ct_bus_entry((struct __bus_entry *) cur);
cur += 8;
break;
/* I/O Apic */
case 2:
io_apic_entries = io_apic_entries ? io_apic_entries : (struct __io_apic_entry *) cur;
io_apic_entry_cnt++;
ct_io_apic_entry((struct __io_apic_entry *) cur);
cur += 8;
break;
/* I/O Interrupt Assignment */
case 3:
io_intr_entries = io_intr_entries ? io_intr_entries : (struct __io_intr_entry *) cur;
io_intr_entry_cnt++;
ct_io_intr_entry((struct __io_intr_entry *) cur);
cur += 8;
break;
 
/* Local Interrupt Assignment */
case 4:
l_intr_entries = l_intr_entries ? l_intr_entries : (struct __l_intr_entry *) cur;
l_intr_entry_cnt++;
ct_l_intr_entry((struct __l_intr_entry *) cur);
cur += 8;
break;
 
default:
/*
* Something is wrong. Fallback to UP mode.
*/
printf("%s: ct badness\n", __FUNCTION__);
return 1;
}
}
/*
* Process extended entries.
*/
ct_extended_entries();
return cnt;
}
 
int configure_via_default(uint8_t n)
{
/*
* Not yet implemented.
*/
printf("%s: not supported\n", __FUNCTION__);
return 1;
}
 
 
int ct_processor_entry(struct __processor_entry *pr)
{
/*
* Ignore processors which are not marked enabled.
*/
if ((pr->cpu_flags & (1<<0)) == 0)
return 0;
apic_id_mask |= (1<<pr->l_apic_id);
return 1;
}
 
void ct_bus_entry(struct __bus_entry *bus)
{
#ifdef MPSCT_VERBOSE
char buf[7];
memcpy((void *) buf, (void *) bus->bus_type, 6);
buf[6] = 0;
printf("bus%d: %s\n", bus->bus_id, buf);
#endif
}
 
void ct_io_apic_entry(struct __io_apic_entry *ioa)
{
static int io_apic_count = 0;
 
/* this ioapic is marked unusable */
if ((ioa->io_apic_flags & 1) == 0)
return;
if (io_apic_count++ > 0) {
/*
* Multiple IO APIC's are currently not supported.
*/
return;
}
io_apic = (uint32_t *)(uintptr_t)ioa->io_apic;
}
 
//#define MPSCT_VERBOSE
void ct_io_intr_entry(struct __io_intr_entry *iointr)
{
#ifdef MPSCT_VERBOSE
switch (iointr->intr_type) {
case 0: printf("INT"); break;
case 1: printf("NMI"); break;
case 2: printf("SMI"); break;
case 3: printf("ExtINT"); break;
}
putchar(',');
switch (iointr->poel&3) {
case 0: printf("bus-like"); break;
case 1: printf("active high"); break;
case 2: printf("reserved"); break;
case 3: printf("active low"); break;
}
putchar(',');
switch ((iointr->poel>>2)&3) {
case 0: printf("bus-like"); break;
case 1: printf("edge-triggered"); break;
case 2: printf("reserved"); break;
case 3: printf("level-triggered"); break;
}
putchar(',');
printf("bus%d,irq%d", iointr->src_bus_id, iointr->src_bus_irq);
putchar(',');
printf("io_apic%d,pin%d", iointr->dst_io_apic_id, iointr->dst_io_apic_pin);
putchar('\n');
#endif
}
 
void ct_l_intr_entry(struct __l_intr_entry *lintr)
{
#ifdef MPSCT_VERBOSE
switch (lintr->intr_type) {
case 0: printf("INT"); break;
case 1: printf("NMI"); break;
case 2: printf("SMI"); break;
case 3: printf("ExtINT"); break;
}
putchar(',');
switch (lintr->poel&3) {
case 0: printf("bus-like"); break;
case 1: printf("active high"); break;
case 2: printf("reserved"); break;
case 3: printf("active low"); break;
}
putchar(',');
switch ((lintr->poel>>2)&3) {
case 0: printf("bus-like"); break;
case 1: printf("edge-triggered"); break;
case 2: printf("reserved"); break;
case 3: printf("level-triggered"); break;
}
putchar(',');
printf("bus%d,irq%d", lintr->src_bus_id, lintr->src_bus_irq);
putchar(',');
printf("l_apic%d,pin%d", lintr->dst_l_apic_id, lintr->dst_l_apic_pin);
putchar('\n');
#endif
}
 
void ct_extended_entries(void)
{
uint8_t *ext = (uint8_t *) ct + ct->base_table_length;
uint8_t *cur;
 
for (cur = ext; cur < ext + ct->ext_table_length; cur += cur[CT_EXT_ENTRY_LEN]) {
switch (cur[CT_EXT_ENTRY_TYPE]) {
default:
printf("%p: skipping MP Configuration Table extended entry type %d\n", cur, cur[CT_EXT_ENTRY_TYPE]);
break;
}
}
}
 
int mps_irq_to_pin(int irq)
{
int i;
for(i=0;i<io_intr_entry_cnt;i++) {
if (io_intr_entries[i].src_bus_irq == irq && io_intr_entries[i].intr_type == 0)
return io_intr_entries[i].dst_io_apic_pin;
}
return -1;
}
 
#endif /* CONFIG_SMP */
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/xen32/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 xen32
* @{
*/
/** @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 */
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/xen32/src/smp/apic.c
0,0 → 1,580
/*
* Copyright (C) 2001-2004 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup xen32
* @{
*/
/** @file
*/
 
#include <arch/types.h>
#include <arch/smp/apic.h>
#include <arch/smp/ap.h>
#include <arch/smp/mps.h>
#include <arch/boot/boot.h>
#include <mm/page.h>
#include <time/delay.h>
#include <interrupt.h>
#include <arch/interrupt.h>
#include <print.h>
#include <arch/asm.h>
#include <arch.h>
 
#ifdef CONFIG_SMP
 
/*
* Advanced Programmable Interrupt Controller for SMP systems.
* Tested on:
* Bochs 2.0.2 - Bochs 2.2.6 with 2-8 CPUs
* Simics 2.0.28 - Simics 2.2.19 2-15 CPUs
* VMware Workstation 5.5 with 2 CPUs
* QEMU 0.8.0 with 2-15 CPUs
* ASUS P/I-P65UP5 + ASUS C-P55T2D REV. 1.41 with 2x 200Mhz Pentium CPUs
* ASUS PCH-DL with 2x 3000Mhz Pentium 4 Xeon (HT) CPUs
* MSI K7D Master-L with 2x 2100MHz Athlon MP CPUs
*/
 
/*
* These variables either stay configured as initilalized, or are changed by
* the MP configuration code.
*
* Pay special attention to the volatile keyword. Without it, gcc -O2 would
* optimize the code too much and accesses to l_apic and io_apic, that must
* always be 32-bit, would use byte oriented instructions.
*/
volatile uint32_t *l_apic = (uint32_t *) 0xfee00000;
volatile uint32_t *io_apic = (uint32_t *) 0xfec00000;
 
uint32_t apic_id_mask = 0;
 
static int apic_poll_errors(void);
 
#ifdef LAPIC_VERBOSE
static char *delmod_str[] = {
"Fixed",
"Lowest Priority",
"SMI",
"Reserved",
"NMI",
"INIT",
"STARTUP",
"ExtInt"
};
 
static char *destmod_str[] = {
"Physical",
"Logical"
};
 
static char *trigmod_str[] = {
"Edge",
"Level"
};
 
static char *mask_str[] = {
"Unmasked",
"Masked"
};
 
static char *delivs_str[] = {
"Idle",
"Send Pending"
};
 
static char *tm_mode_str[] = {
"One-shot",
"Periodic"
};
 
static char *intpol_str[] = {
"Polarity High",
"Polarity Low"
};
#endif /* LAPIC_VERBOSE */
 
 
static void apic_spurious(int n, istate_t *istate);
static void l_apic_timer_interrupt(int n, istate_t *istate);
 
/** Initialize APIC on BSP. */
void apic_init(void)
{
io_apic_id_t idreg;
int i;
 
exc_register(VECTOR_APIC_SPUR, "apic_spurious", (iroutine) apic_spurious);
 
enable_irqs_function = io_apic_enable_irqs;
disable_irqs_function = io_apic_disable_irqs;
eoi_function = l_apic_eoi;
/*
* Configure interrupt routing.
* IRQ 0 remains masked as the time signal is generated by l_apic's themselves.
* Other interrupts will be forwarded to the lowest priority CPU.
*/
io_apic_disable_irqs(0xffff);
exc_register(VECTOR_CLK, "l_apic_timer", (iroutine) l_apic_timer_interrupt);
for (i = 0; i < IRQ_COUNT; i++) {
int pin;
if ((pin = smp_irq_to_pin(i)) != -1) {
io_apic_change_ioredtbl(pin, DEST_ALL, IVT_IRQBASE+i, LOPRI);
}
}
/*
* Ensure that io_apic has unique ID.
*/
idreg.value = io_apic_read(IOAPICID);
if ((1<<idreg.apic_id) & apic_id_mask) { /* see if IO APIC ID is used already */
for (i = 0; i < APIC_ID_COUNT; i++) {
if (!((1<<i) & apic_id_mask)) {
idreg.apic_id = i;
io_apic_write(IOAPICID, idreg.value);
break;
}
}
}
 
/*
* Configure the BSP's lapic.
*/
l_apic_init();
 
l_apic_debug();
}
 
/** APIC spurious interrupt handler.
*
* @param n Interrupt vector.
* @param istate Interrupted state.
*/
void apic_spurious(int n, istate_t *istate)
{
#ifdef CONFIG_DEBUG
printf("cpu%d: APIC spurious interrupt\n", CPU->id);
#endif
}
 
/** Poll for APIC errors.
*
* Examine Error Status Register and report all errors found.
*
* @return 0 on error, 1 on success.
*/
int apic_poll_errors(void)
{
esr_t esr;
esr.value = l_apic[ESR];
if (esr.send_checksum_error)
printf("Send Checksum Error\n");
if (esr.receive_checksum_error)
printf("Receive Checksum Error\n");
if (esr.send_accept_error)
printf("Send Accept Error\n");
if (esr.receive_accept_error)
printf("Receive Accept Error\n");
if (esr.send_illegal_vector)
printf("Send Illegal Vector\n");
if (esr.received_illegal_vector)
printf("Received Illegal Vector\n");
if (esr.illegal_register_address)
printf("Illegal Register Address\n");
 
return !esr.err_bitmap;
}
 
/** Send all CPUs excluding CPU IPI vector.
*
* @param vector Interrupt vector to be sent.
*
* @return 0 on failure, 1 on success.
*/
int l_apic_broadcast_custom_ipi(uint8_t vector)
{
icr_t icr;
 
icr.lo = l_apic[ICRlo];
icr.delmod = DELMOD_FIXED;
icr.destmod = DESTMOD_LOGIC;
icr.level = LEVEL_ASSERT;
icr.shorthand = SHORTHAND_ALL_EXCL;
icr.trigger_mode = TRIGMOD_LEVEL;
icr.vector = vector;
 
l_apic[ICRlo] = icr.lo;
 
icr.lo = l_apic[ICRlo];
if (icr.delivs == DELIVS_PENDING) {
#ifdef CONFIG_DEBUG
printf("IPI is pending.\n");
#endif
}
 
return apic_poll_errors();
}
 
/** Universal Start-up Algorithm for bringing up the AP processors.
*
* @param apicid APIC ID of the processor to be brought up.
*
* @return 0 on failure, 1 on success.
*/
int l_apic_send_init_ipi(uint8_t apicid)
{
icr_t icr;
int i;
 
/*
* Read the ICR register in and zero all non-reserved fields.
*/
icr.lo = l_apic[ICRlo];
icr.hi = l_apic[ICRhi];
icr.delmod = DELMOD_INIT;
icr.destmod = DESTMOD_PHYS;
icr.level = LEVEL_ASSERT;
icr.trigger_mode = TRIGMOD_LEVEL;
icr.shorthand = SHORTHAND_NONE;
icr.vector = 0;
icr.dest = apicid;
l_apic[ICRhi] = icr.hi;
l_apic[ICRlo] = icr.lo;
 
/*
* According to MP Specification, 20us should be enough to
* deliver the IPI.
*/
delay(20);
 
if (!apic_poll_errors())
return 0;
 
icr.lo = l_apic[ICRlo];
if (icr.delivs == DELIVS_PENDING) {
#ifdef CONFIG_DEBUG
printf("IPI is pending.\n");
#endif
}
 
icr.delmod = DELMOD_INIT;
icr.destmod = DESTMOD_PHYS;
icr.level = LEVEL_DEASSERT;
icr.shorthand = SHORTHAND_NONE;
icr.trigger_mode = TRIGMOD_LEVEL;
icr.vector = 0;
l_apic[ICRlo] = icr.lo;
 
/*
* Wait 10ms as MP Specification specifies.
*/
delay(10000);
 
if (!is_82489DX_apic(l_apic[LAVR])) {
/*
* If this is not 82489DX-based l_apic we must send two STARTUP IPI's.
*/
for (i = 0; i<2; i++) {
icr.lo = l_apic[ICRlo];
icr.delmod = DELMOD_STARTUP;
icr.destmod = DESTMOD_PHYS;
icr.level = LEVEL_ASSERT;
icr.shorthand = SHORTHAND_NONE;
icr.trigger_mode = TRIGMOD_LEVEL;
l_apic[ICRlo] = icr.lo;
delay(200);
}
}
return apic_poll_errors();
}
 
/** Initialize Local APIC. */
void l_apic_init(void)
{
lvt_error_t error;
lvt_lint_t lint;
tpr_t tpr;
svr_t svr;
icr_t icr;
tdcr_t tdcr;
lvt_tm_t tm;
ldr_t ldr;
dfr_t dfr;
uint32_t t1, t2;
 
/* Initialize LVT Error register. */
error.value = l_apic[LVT_Err];
error.masked = true;
l_apic[LVT_Err] = error.value;
 
/* Initialize LVT LINT0 register. */
lint.value = l_apic[LVT_LINT0];
lint.masked = true;
l_apic[LVT_LINT0] = lint.value;
 
/* Initialize LVT LINT1 register. */
lint.value = l_apic[LVT_LINT1];
lint.masked = true;
l_apic[LVT_LINT1] = lint.value;
 
/* Task Priority Register initialization. */
tpr.value = l_apic[TPR];
tpr.pri_sc = 0;
tpr.pri = 0;
l_apic[TPR] = tpr.value;
/* Spurious-Interrupt Vector Register initialization. */
svr.value = l_apic[SVR];
svr.vector = VECTOR_APIC_SPUR;
svr.lapic_enabled = true;
svr.focus_checking = true;
l_apic[SVR] = svr.value;
 
if (CPU->arch.family >= 6)
enable_l_apic_in_msr();
/* Interrupt Command Register initialization. */
icr.lo = l_apic[ICRlo];
icr.delmod = DELMOD_INIT;
icr.destmod = DESTMOD_PHYS;
icr.level = LEVEL_DEASSERT;
icr.shorthand = SHORTHAND_ALL_INCL;
icr.trigger_mode = TRIGMOD_LEVEL;
l_apic[ICRlo] = icr.lo;
/* Timer Divide Configuration Register initialization. */
tdcr.value = l_apic[TDCR];
tdcr.div_value = DIVIDE_1;
l_apic[TDCR] = tdcr.value;
 
/* Program local timer. */
tm.value = l_apic[LVT_Tm];
tm.vector = VECTOR_CLK;
tm.mode = TIMER_PERIODIC;
tm.masked = false;
l_apic[LVT_Tm] = tm.value;
 
/*
* Measure and configure the timer to generate timer
* interrupt with period 1s/HZ seconds.
*/
t1 = l_apic[CCRT];
l_apic[ICRT] = 0xffffffff;
 
while (l_apic[CCRT] == t1)
;
t1 = l_apic[CCRT];
delay(1000000/HZ);
t2 = l_apic[CCRT];
l_apic[ICRT] = t1-t2;
/* Program Logical Destination Register. */
ldr.value = l_apic[LDR];
if (CPU->id < sizeof(CPU->id)*8) /* size in bits */
ldr.id = (1<<CPU->id);
l_apic[LDR] = ldr.value;
/* Program Destination Format Register for Flat mode. */
dfr.value = l_apic[DFR];
dfr.model = MODEL_FLAT;
l_apic[DFR] = dfr.value;
}
 
/** Local APIC End of Interrupt. */
void l_apic_eoi(void)
{
l_apic[EOI] = 0;
}
 
/** Dump content of Local APIC registers. */
void l_apic_debug(void)
{
#ifdef LAPIC_VERBOSE
lvt_tm_t tm;
lvt_lint_t lint;
lvt_error_t error;
printf("LVT on cpu%d, LAPIC ID: %d\n", CPU->id, l_apic_id());
 
tm.value = l_apic[LVT_Tm];
printf("LVT Tm: vector=%hhd, %s, %s, %s\n", tm.vector, delivs_str[tm.delivs], mask_str[tm.masked], tm_mode_str[tm.mode]);
lint.value = l_apic[LVT_LINT0];
printf("LVT LINT0: vector=%hhd, %s, %s, %s, irr=%d, %s, %s\n", tm.vector, delmod_str[lint.delmod], delivs_str[lint.delivs], intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode], mask_str[lint.masked]);
lint.value = l_apic[LVT_LINT1];
printf("LVT LINT1: vector=%hhd, %s, %s, %s, irr=%d, %s, %s\n", tm.vector, delmod_str[lint.delmod], delivs_str[lint.delivs], intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode], mask_str[lint.masked]);
error.value = l_apic[LVT_Err];
printf("LVT Err: vector=%hhd, %s, %s\n", error.vector, delivs_str[error.delivs], mask_str[error.masked]);
#endif
}
 
/** Local APIC Timer Interrupt.
*
* @param n Interrupt vector number.
* @param istate Interrupted state.
*/
void l_apic_timer_interrupt(int n, istate_t *istate)
{
l_apic_eoi();
clock();
}
 
/** Get Local APIC ID.
*
* @return Local APIC ID.
*/
uint8_t l_apic_id(void)
{
l_apic_id_t idreg;
idreg.value = l_apic[L_APIC_ID];
return idreg.apic_id;
}
 
/** Read from IO APIC register.
*
* @param address IO APIC register address.
*
* @return Content of the addressed IO APIC register.
*/
uint32_t io_apic_read(uint8_t address)
{
io_regsel_t regsel;
regsel.value = io_apic[IOREGSEL];
regsel.reg_addr = address;
io_apic[IOREGSEL] = regsel.value;
return io_apic[IOWIN];
}
 
/** Write to IO APIC register.
*
* @param address IO APIC register address.
* @param x Content to be written to the addressed IO APIC register.
*/
void io_apic_write(uint8_t address, uint32_t x)
{
io_regsel_t regsel;
regsel.value = io_apic[IOREGSEL];
regsel.reg_addr = address;
io_apic[IOREGSEL] = regsel.value;
io_apic[IOWIN] = x;
}
 
/** Change some attributes of one item in I/O Redirection Table.
*
* @param pin IO APIC pin number.
* @param dest Interrupt destination address.
* @param v Interrupt vector to trigger.
* @param flags Flags.
*/
void io_apic_change_ioredtbl(int pin, int dest, uint8_t v, int flags)
{
io_redirection_reg_t reg;
int dlvr = DELMOD_FIXED;
if (flags & LOPRI)
dlvr = DELMOD_LOWPRI;
 
reg.lo = io_apic_read(IOREDTBL + pin*2);
reg.hi = io_apic_read(IOREDTBL + pin*2 + 1);
reg.dest = dest;
reg.destmod = DESTMOD_LOGIC;
reg.trigger_mode = TRIGMOD_EDGE;
reg.intpol = POLARITY_HIGH;
reg.delmod = dlvr;
reg.intvec = v;
 
io_apic_write(IOREDTBL + pin*2, reg.lo);
io_apic_write(IOREDTBL + pin*2 + 1, reg.hi);
}
 
/** Mask IRQs in IO APIC.
*
* @param irqmask Bitmask of IRQs to be masked (0 = do not mask, 1 = mask).
*/
void io_apic_disable_irqs(uint16_t irqmask)
{
io_redirection_reg_t reg;
int i, pin;
for (i=0;i<16;i++) {
if (irqmask & (1<<i)) {
/*
* Mask the signal input in IO APIC if there is a
* mapping for the respective IRQ number.
*/
pin = smp_irq_to_pin(i);
if (pin != -1) {
reg.lo = io_apic_read(IOREDTBL + pin*2);
reg.masked = true;
io_apic_write(IOREDTBL + pin*2, reg.lo);
}
}
}
}
 
/** Unmask IRQs in IO APIC.
*
* @param irqmask Bitmask of IRQs to be unmasked (0 = do not unmask, 1 = unmask).
*/
void io_apic_enable_irqs(uint16_t irqmask)
{
int i, pin;
io_redirection_reg_t reg;
for (i=0;i<16;i++) {
if (irqmask & (1<<i)) {
/*
* Unmask the signal input in IO APIC if there is a
* mapping for the respective IRQ number.
*/
pin = smp_irq_to_pin(i);
if (pin != -1) {
reg.lo = io_apic_read(IOREDTBL + pin*2);
reg.masked = false;
io_apic_write(IOREDTBL + pin*2, reg.lo);
}
}
}
}
 
#endif /* CONFIG_SMP */
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/xen32/src/interrupt.c
0,0 → 1,209
/*
* 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 xen32interrupt
* @{
*/
/** @file
*/
 
#include <arch/interrupt.h>
#include <syscall/syscall.h>
#include <print.h>
#include <debug.h>
#include <panic.h>
#include <func.h>
#include <cpu.h>
#include <arch/asm.h>
#include <mm/tlb.h>
#include <mm/as.h>
#include <arch.h>
#include <symtab.h>
#include <proc/thread.h>
#include <proc/task.h>
#include <synch/spinlock.h>
#include <arch/ddi/ddi.h>
#include <ipc/sysipc.h>
#include <interrupt.h>
 
/*
* Interrupt and exception dispatching.
*/
 
void (* disable_irqs_function)(uint16_t irqmask) = NULL;
void (* enable_irqs_function)(uint16_t irqmask) = NULL;
void (* eoi_function)(void) = NULL;
 
void PRINT_INFO_ERRCODE(istate_t *istate)
{
char *symbol = get_symtab_entry(istate->eip);
 
if (!symbol)
symbol = "";
 
if (CPU)
printf("----------------EXCEPTION OCCURED (cpu%d)----------------\n", CPU->id);
else
printf("----------------EXCEPTION OCCURED----------------\n");
printf("%%eip: %#x (%s)\n",istate->eip,symbol);
printf("ERROR_WORD=%#x\n", istate->error_word);
printf("%%cs=%#x,flags=%#x\n", istate->cs, istate->eflags);
printf("%%eax=%#x, %%ecx=%#x, %%edx=%#x, %%esp=%#x\n", istate->eax,istate->ecx,istate->edx,&istate->stack[0]);
#ifdef CONFIG_DEBUG_ALLREGS
printf("%%esi=%#x, %%edi=%#x, %%ebp=%#x, %%ebx=%#x\n", istate->esi,istate->edi,istate->ebp,istate->ebx);
#endif
printf("stack: %#x, %#x, %#x, %#x\n", istate->stack[0], istate->stack[1], istate->stack[2], istate->stack[3]);
printf(" %#x, %#x, %#x, %#x\n", istate->stack[4], istate->stack[5], istate->stack[6], istate->stack[7]);
}
 
void null_interrupt(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "unserviced interrupt: %d", n);
 
PRINT_INFO_ERRCODE(istate);
panic("unserviced interrupt: %d\n", n);
}
 
/** General Protection Fault. */
void gp_fault(int n, istate_t *istate)
{
if (TASK) {
count_t ver;
spinlock_lock(&TASK->lock);
ver = TASK->arch.iomapver;
spinlock_unlock(&TASK->lock);
if (CPU->arch.iomapver_copy != ver) {
/*
* This fault can be caused by an early access
* to I/O port because of an out-dated
* I/O Permission bitmap installed on CPU.
* Install the fresh copy and restart
* the instruction.
*/
io_perm_bitmap_install();
return;
}
fault_if_from_uspace(istate, "general protection fault");
}
 
PRINT_INFO_ERRCODE(istate);
panic("general protection fault\n");
}
 
void ss_fault(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "stack fault");
 
PRINT_INFO_ERRCODE(istate);
panic("stack fault\n");
}
 
void simd_fp_exception(int n, istate_t *istate)
{
uint32_t mxcsr;
asm
(
"stmxcsr %0;\n"
:"=m"(mxcsr)
);
fault_if_from_uspace(istate, "SIMD FP exception(19), MXCSR: %#zx",
(unative_t)mxcsr);
 
PRINT_INFO_ERRCODE(istate);
printf("MXCSR: %#zx\n",(unative_t)(mxcsr));
panic("SIMD FP exception(19)\n");
}
 
void nm_fault(int n, istate_t *istate)
{
#ifdef CONFIG_FPU_LAZY
scheduler_fpu_lazy_request();
#else
fault_if_from_uspace(istate, "fpu fault");
panic("fpu fault");
#endif
}
 
void syscall(int n, istate_t *istate)
{
panic("Obsolete syscall handler.");
}
 
void tlb_shootdown_ipi(int n, istate_t *istate)
{
trap_virtual_eoi();
tlb_shootdown_ipi_recv();
}
 
void trap_virtual_enable_irqs(uint16_t irqmask)
{
if (enable_irqs_function)
enable_irqs_function(irqmask);
else
panic("no enable_irqs_function\n");
}
 
void trap_virtual_disable_irqs(uint16_t irqmask)
{
if (disable_irqs_function)
disable_irqs_function(irqmask);
else
panic("no disable_irqs_function\n");
}
 
void trap_virtual_eoi(void)
{
if (eoi_function)
eoi_function();
else
panic("no eoi_function\n");
 
}
 
static void ipc_int(int n, istate_t *istate)
{
ipc_irq_send_notif(n-IVT_IRQBASE);
trap_virtual_eoi();
}
 
 
/* Reregister irq to be IPC-ready */
void irq_ipc_bind_arch(unative_t irq)
{
if (irq == IRQ_CLK)
return;
exc_register(IVT_IRQBASE+irq, "ipc_int", ipc_int);
trap_virtual_enable_irqs(1 << irq);
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/xen32/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
/tags/0.2.0.3/kernel/arch/xen32/src/context.s
0,0 → 1,0
link ../../ia32/src/context.s
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/xen32/src/debug
0,0 → 1,0
link ../../ia32/src/debug
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/xen32/src/cpu
0,0 → 1,0
link ../../ia32/src/cpu
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/xen32/src/bios
0,0 → 1,0
link ../../ia32/src/bios
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/xen32/src/delay.s
0,0 → 1,0
link ../../ia32/src/delay.s
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/xen32/src/ddi
0,0 → 1,0
link ../../ia32/src/ddi
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/xen32/src/debugger.c
0,0 → 1,0
link ../../ia32/src/debugger.c
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/xen32/src/atomic.S
0,0 → 1,0
link ../../ia32/src/atomic.S
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/xen32/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 xen32
* @{
*/
/** @file
*/
 
#ifndef __XCONSOLE_H__
#define __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
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/xen32/include/boot/boot.h
0,0 → 1,132
/*
* Copyright (C) 2006 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup xen32
* @{
*/
/** @file
*/
 
#ifndef __xen32_BOOT_H__
#define __xen32_BOOT_H__
 
#define GUEST_CMDLINE 1024
#define VIRT_CPUS 32
#define START_INFO_SIZE 1104
 
#define BOOT_OFFSET 0x0000
#define TEMP_STACK_SIZE 0x1000
 
#define XEN_VIRT_START 0xFC000000
#define XEN_CS 0xe019
 
#ifndef __ASM__
 
#define mp_map ((pfn_t *) XEN_VIRT_START)
 
#define SIF_PRIVILEGED (1 << 0) /**< Privileged domain */
#define SIF_INITDOMAIN (1 << 1) /**< Iinitial control domain */
 
#include <arch/types.h>
 
typedef uint32_t evtchn_t;
 
typedef struct {
uint32_t version;
uint32_t pad0;
uint64_t tsc_timestamp; /**< TSC at last update of time vals */
uint64_t system_time; /**< Time, in nanosecs, since boot */
uint32_t tsc_to_system_mul;
int8_t tsc_shift;
int8_t pad1[3];
} vcpu_time_info_t;
 
typedef struct {
uint32_t cr2;
uint32_t pad[5];
} arch_vcpu_info_t;
 
typedef struct arch_shared_info {
pfn_t max_pfn; /**< max pfn that appears in table */
uint32_t pfn_to_mfn_frame_list_list;
uint32_t nmi_reason;
} arch_shared_info_t;
 
typedef struct {
uint8_t evtchn_upcall_pending;
ipl_t evtchn_upcall_mask;
evtchn_t evtchn_pending_sel;
arch_vcpu_info_t arch;
vcpu_time_info_t time;
} vcpu_info_t;
 
typedef struct {
vcpu_info_t vcpu_info[VIRT_CPUS];
evtchn_t evtchn_pending[32];
evtchn_t evtchn_mask[32];
uint32_t wc_version; /**< Version counter */
uint32_t wc_sec; /**< Secs 00:00:00 UTC, Jan 1, 1970 */
uint32_t wc_nsec; /**< Nsecs 00:00:00 UTC, Jan 1, 1970 */
arch_shared_info_t arch;
} shared_info_t;
 
typedef struct {
int8_t magic[32]; /**< "xen-<version>-<platform>" */
uint32_t frames; /**< Available frames */
shared_info_t *shared_info; /**< Shared info structure (machine address) */
uint32_t flags; /**< SIF_xxx flags */
pfn_t store_mfn; /**< Shared page (machine page) */
evtchn_t store_evtchn; /**< Event channel for store communication */
pfn_t console_mfn; /**< Console page (machine page) */
evtchn_t console_evtchn; /**< Event channel for console messages */
pte_t *ptl0; /**< Boot PTL0 (kernel address) */
uint32_t pt_frames; /**< Number of bootstrap page table frames */
pfn_t *pm_map; /**< Physical->machine frame map (kernel address) */
void *mod_start; /**< Modules start (kernel address) */
uint32_t mod_len; /**< Modules size (bytes) */
int8_t cmd_line[GUEST_CMDLINE];
} start_info_t;
 
typedef struct {
pfn_t start;
pfn_t size;
pfn_t reserved;
} memzone_t;
 
extern start_info_t start_info;
extern shared_info_t shared_info;
extern memzone_t meminfo;
 
#endif
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/xen32/include/asm.h
0,0 → 1,280
/*
* Copyright (C) 2001-2004 Jakub Jermar
* Copyright (C) 2005 Sergey Bondari
* 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 xen32
* @{
*/
/** @file
*/
 
#ifndef __xen32_ASM_H__
#define __xen32_ASM_H__
 
#include <arch/pm.h>
#include <arch/types.h>
#include <arch/barrier.h>
#include <config.h>
 
extern void enable_l_apic_in_msr(void);
 
 
extern void asm_delay_loop(uint32_t t);
extern void asm_fake_loop(uint32_t t);
 
 
/** Halt CPU
*
* Halt the current CPU until interrupt event.
*/
#define cpu_halt() ((void) 0)
#define cpu_sleep() ((void) 0)
 
#define GEN_READ_REG(reg) static inline unative_t read_ ##reg (void) \
{ \
unative_t res; \
__asm__ volatile ("movl %%" #reg ", %0" : "=r" (res) ); \
return res; \
}
 
#define GEN_WRITE_REG(reg) static inline void write_ ##reg (unative_t regn) \
{ \
__asm__ volatile ("movl %0, %%" #reg : : "r" (regn)); \
}
 
GEN_READ_REG(cr0);
GEN_READ_REG(cr2);
 
GEN_READ_REG(dr0);
GEN_READ_REG(dr1);
GEN_READ_REG(dr2);
GEN_READ_REG(dr3);
GEN_READ_REG(dr6);
GEN_READ_REG(dr7);
 
GEN_WRITE_REG(dr0);
GEN_WRITE_REG(dr1);
GEN_WRITE_REG(dr2);
GEN_WRITE_REG(dr3);
GEN_WRITE_REG(dr6);
GEN_WRITE_REG(dr7);
 
/** Byte to port
*
* Output byte to port
*
* @param port Port to write to
* @param val Value to write
*/
static inline void outb(uint16_t port, uint8_t val) { __asm__ volatile ("outb %b0, %w1\n" : : "a" (val), "d" (port) ); }
 
/** Word to port
*
* Output word to port
*
* @param port Port to write to
* @param val Value to write
*/
static inline void outw(uint16_t port, uint16_t val) { __asm__ volatile ("outw %w0, %w1\n" : : "a" (val), "d" (port) ); }
 
/** Double word to port
*
* Output double word to port
*
* @param port Port to write to
* @param val Value to write
*/
static inline void outl(uint16_t port, uint32_t val) { __asm__ volatile ("outl %l0, %w1\n" : : "a" (val), "d" (port) ); }
 
/** Byte from port
*
* Get byte from port
*
* @param port Port to read from
* @return Value read
*/
static inline uint8_t inb(uint16_t port) { uint8_t val; __asm__ volatile ("inb %w1, %b0 \n" : "=a" (val) : "d" (port) ); return val; }
 
/** Word from port
*
* Get word from port
*
* @param port Port to read from
* @return Value read
*/
static inline uint16_t inw(uint16_t port) { uint16_t val; __asm__ volatile ("inw %w1, %w0 \n" : "=a" (val) : "d" (port) ); return val; }
 
/** Double word from port
*
* Get double word from port
*
* @param port Port to read from
* @return Value read
*/
static inline uint32_t inl(uint16_t port) { uint32_t val; __asm__ volatile ("inl %w1, %l0 \n" : "=a" (val) : "d" (port) ); return val; }
 
/** Enable interrupts.
*
* Enable interrupts and return previous
* value of EFLAGS.
*
* @return Old interrupt priority level.
*/
static inline ipl_t interrupts_enable(void)
{
// FIXME SMP
ipl_t v = shared_info.vcpu_info[0].evtchn_upcall_mask;
write_barrier();
shared_info.vcpu_info[0].evtchn_upcall_mask = 0;
write_barrier();
if (shared_info.vcpu_info[0].evtchn_upcall_pending)
force_evtchn_callback();
return v;
}
 
/** Disable interrupts.
*
* Disable interrupts and return previous
* value of EFLAGS.
*
* @return Old interrupt priority level.
*/
static inline ipl_t interrupts_disable(void)
{
// FIXME SMP
ipl_t v = shared_info.vcpu_info[0].evtchn_upcall_mask;
shared_info.vcpu_info[0].evtchn_upcall_mask = 1;
write_barrier();
return v;
}
 
/** Restore interrupt priority level.
*
* Restore EFLAGS.
*
* @param ipl Saved interrupt priority level.
*/
static inline void interrupts_restore(ipl_t ipl)
{
if (ipl == 0)
interrupts_enable();
else
interrupts_disable();
}
 
/** Return interrupt priority level.
*
* @return EFLAFS.
*/
static inline ipl_t interrupts_read(void)
{
// FIXME SMP
return shared_info.vcpu_info[0].evtchn_upcall_mask;
}
 
/** Return base address of current stack
*
* Return the base address of the current stack.
* The stack is assumed to be STACK_SIZE bytes long.
* The stack must start on page boundary.
*/
static inline uintptr_t get_stack_base(void)
{
uintptr_t v;
__asm__ volatile ("andl %%esp, %0\n" : "=r" (v) : "0" (~(STACK_SIZE-1)));
return v;
}
 
static inline uint64_t rdtsc(void)
{
uint64_t v;
__asm__ volatile("rdtsc\n" : "=A" (v));
return v;
}
 
/** Return current IP address */
static inline uintptr_t * get_ip()
{
uintptr_t *ip;
 
__asm__ volatile (
"mov %%eip, %0"
: "=r" (ip)
);
return ip;
}
 
/** Invalidate TLB Entry.
*
* @param addr Address on a page whose TLB entry is to be invalidated.
*/
static inline void invlpg(uintptr_t addr)
{
__asm__ volatile ("invlpg %0\n" :: "m" (*(unative_t *)addr));
}
 
/** Load GDTR register from memory.
*
* @param gdtr_reg Address of memory from where to load GDTR.
*/
static inline void gdtr_load(ptr_16_32_t *gdtr_reg)
{
__asm__ volatile ("lgdtl %0\n" : : "m" (*gdtr_reg));
}
 
/** Store GDTR register to memory.
*
* @param gdtr_reg Address of memory to where to load GDTR.
*/
static inline void gdtr_store(ptr_16_32_t *gdtr_reg)
{
__asm__ volatile ("sgdtl %0\n" : : "m" (*gdtr_reg));
}
 
/** Load TR from descriptor table.
*
* @param sel Selector specifying descriptor of TSS segment.
*/
static inline void tr_load(uint16_t sel)
{
__asm__ volatile ("ltr %0" : : "r" (sel));
}
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/xen32/include/hypercall.h
0,0 → 1,254
/*
* 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 __xen32_HYPERCALL_H__
#define __xen32_HYPERCALL_H__
 
#include <arch/types.h>
#include <macros.h>
 
 
typedef uint16_t domid_t;
 
 
typedef struct {
uint8_t vector; /**< Exception vector */
uint8_t flags; /**< 0-3: privilege level; 4: clear event enable */
uint16_t cs; /**< Code selector */
void *address; /**< Code offset */
} trap_info_t;
 
 
typedef struct {
evtchn_t port;
} evtchn_send_t;
 
typedef struct {
uint32_t cmd;
union {
evtchn_send_t send;
};
} evtchn_op_t;
 
 
#define XEN_SET_TRAP_TABLE 0
#define XEN_MMU_UPDATE 1
#define XEN_SET_CALLBACKS 4
#define XEN_UPDATE_VA_MAPPING 14
#define XEN_EVENT_CHANNEL_OP 16
#define XEN_VERSION 17
#define XEN_CONSOLE_IO 18
#define XEN_VM_ASSIST 21
#define XEN_MMUEXT_OP 26
 
 
/*
* Commands for XEN_CONSOLE_IO
*/
#define CONSOLE_IO_WRITE 0
#define CONSOLE_IO_READ 1
 
 
#define MMUEXT_PIN_L1_TABLE 0
#define MMUEXT_PIN_L2_TABLE 1
#define MMUEXT_PIN_L3_TABLE 2
#define MMUEXT_PIN_L4_TABLE 3
#define MMUEXT_UNPIN_TABLE 4
#define MMUEXT_NEW_BASEPTR 5
#define MMUEXT_TLB_FLUSH_LOCAL 6
#define MMUEXT_INVLPG_LOCAL 7
#define MMUEXT_TLB_FLUSH_MULTI 8
#define MMUEXT_INVLPG_MULTI 9
#define MMUEXT_TLB_FLUSH_ALL 10
#define MMUEXT_INVLPG_ALL 11
#define MMUEXT_FLUSH_CACHE 12
#define MMUEXT_SET_LDT 13
#define MMUEXT_NEW_USER_BASEPTR 15
 
 
#define EVTCHNOP_SEND 4
 
 
#define UVMF_NONE 0 /**< No flushing at all */
#define UVMF_TLB_FLUSH 1 /**< Flush entire TLB(s) */
#define UVMF_INVLPG 2 /**< Flush only one entry */
#define UVMF_FLUSHTYPE_MASK 3
#define UVMF_MULTI 0 /**< Flush subset of TLBs */
#define UVMF_LOCAL 0 /**< Flush local TLB */
#define UVMF_ALL (1 << 2) /**< Flush all TLBs */
 
 
/*
* Commands to XEN_VM_ASSIST
*/
#define VMASST_CMD_ENABLE 0
#define VMASST_CMD_DISABLE 1
#define VMASST_TYPE_4GB_SEGMENTS 0
#define VMASST_TYPE_4GB_SEGMENTS_NOTIFY 1
#define VMASST_TYPE_WRITABLE_PAGETABLES 2
 
 
#define DOMID_SELF (0x7FF0U)
#define DOMID_IO (0x7FF1U)
 
 
#define force_evtchn_callback() ((void) xen_version(0, 0))
 
#define hypercall0(id) \
({ \
unative_t ret; \
asm volatile ( \
"call hypercall_page + (" STRING(id) " * 32)\n" \
: "=a" (ret) \
: \
: "memory" \
); \
ret; \
})
 
#define hypercall1(id, p1) \
({ \
unative_t ret, __ign1; \
asm volatile ( \
"call hypercall_page + (" STRING(id) " * 32)\n" \
: "=a" (ret), \
"=b" (__ign1) \
: "1" (p1) \
: "memory" \
); \
ret; \
})
 
#define hypercall2(id, p1, p2) \
({ \
unative_t ret, __ign1, __ign2; \
asm volatile ( \
"call hypercall_page + (" STRING(id) " * 32)\n" \
: "=a" (ret), \
"=b" (__ign1), \
"=c" (__ign2) \
: "1" (p1), \
"2" (p2) \
: "memory" \
); \
ret; \
})
 
#define hypercall3(id, p1, p2, p3) \
({ \
unative_t ret, __ign1, __ign2, __ign3; \
asm volatile ( \
"call hypercall_page + (" STRING(id) " * 32)\n" \
: "=a" (ret), \
"=b" (__ign1), \
"=c" (__ign2), \
"=d" (__ign3) \
: "1" (p1), \
"2" (p2), \
"3" (p3) \
: "memory" \
); \
ret; \
})
 
#define hypercall4(id, p1, p2, p3, p4) \
({ \
unative_t ret, __ign1, __ign2, __ign3, __ign4; \
asm volatile ( \
"call hypercall_page + (" STRING(id) " * 32)\n" \
: "=a" (ret), \
"=b" (__ign1), \
"=c" (__ign2), \
"=d" (__ign3), \
"=S" (__ign4) \
: "1" (p1), \
"2" (p2), \
"3" (p3), \
"4" (p4) \
: "memory" \
); \
ret; \
})
 
#define hypercall5(id, p1, p2, p3, p4, p5) \
({ \
unative_t ret, __ign1, __ign2, __ign3, __ign4, __ign5; \
asm volatile ( \
"call hypercall_page + (" STRING(id) " * 32)\n" \
: "=a" (ret), \
"=b" (__ign1), \
"=c" (__ign2), \
"=d" (__ign3), \
"=S" (__ign4), \
"=D" (__ign5) \
: "1" (p1), \
"2" (p2), \
"3" (p3), \
"4" (p4), \
"5" (p5) \
: "memory" \
); \
ret; \
})
 
 
static inline int xen_console_io(const unsigned int cmd, const unsigned int count, const char *str)
{
return hypercall3(XEN_CONSOLE_IO, cmd, count, str);
}
 
static inline int xen_vm_assist(const unsigned int cmd, const unsigned int type)
{
return hypercall2(XEN_VM_ASSIST, cmd, type);
}
 
static inline int xen_set_callbacks(const unsigned int event_selector, const void *event_address, const unsigned int failsafe_selector, void *failsafe_address)
{
return hypercall4(XEN_SET_CALLBACKS, event_selector, event_address, failsafe_selector, failsafe_address);
}
 
static inline int xen_set_trap_table(const trap_info_t *table)
{
return hypercall1(XEN_SET_TRAP_TABLE, table);
}
 
static inline int xen_version(const unsigned int cmd, const void *arg)
{
return hypercall2(XEN_VERSION, cmd, arg);
}
 
static inline int xen_notify_remote(evtchn_t channel)
{
evtchn_op_t op;
op.cmd = EVTCHNOP_SEND;
op.send.port = channel;
return hypercall1(XEN_EVENT_CHANNEL_OP, &op);
}
 
#endif
/tags/0.2.0.3/kernel/arch/xen32/include/types.h
0,0 → 1,63
/*
* Copyright (C) 2001-2004 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup xen32
* @{
*/
/** @file
*/
 
#ifndef __TYPES_H__
#define __TYPES_H__
 
#define NULL 0
 
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed long int32_t;
typedef signed long long int64_t;
 
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned long uint32_t;
typedef unsigned long long uint64_t;
 
typedef uint32_t uintptr_t;
typedef uint32_t pfn_t;
 
typedef uint8_t ipl_t;
 
typedef uint32_t unative_t;
typedef int32_t native_t;
 
typedef struct page_specifier pte_t;
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/xen32/include/pm.h
0,0 → 1,160
/*
* 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 xen32
* @{
*/
/** @file
*/
 
#ifndef __PM_H__
#define __PM_H__
 
#define IDT_ITEMS 64
#define GDT_ITEMS 7
 
#define NULL_DES 0
#define KTEXT_DES 1
#define KDATA_DES 2
#define UTEXT_DES 3
#define UDATA_DES 4
#define TSS_DES 5
#define TLS_DES 6 /* Pointer to Thread-Local-Storage data */
 
#define selector(des) ((des) << 3)
 
#define PL_KERNEL 1
#define PL_USER 3
 
#define AR_PRESENT (1<<7)
#define AR_DATA (2<<3)
#define AR_CODE (3<<3)
#define AR_WRITABLE (1<<1)
#define AR_INTERRUPT (0xe)
#define AR_TSS (0x9)
 
#define DPL_KERNEL (PL_KERNEL<<5)
#define DPL_USER (PL_USER<<5)
 
#define TSS_BASIC_SIZE 104
#define TSS_IOMAP_SIZE (16*1024+1) /* 16K for bitmap + 1 terminating byte for convenience */
 
#define IO_PORTS (64*1024)
 
#ifndef __ASM__
 
#include <arch/types.h>
#include <typedefs.h>
#include <arch/context.h>
 
struct ptr_16_32 {
uint16_t limit;
uint32_t base;
} __attribute__ ((packed));
typedef struct ptr_16_32 ptr_16_32_t;
 
struct descriptor {
unsigned limit_0_15: 16;
unsigned base_0_15: 16;
unsigned base_16_23: 8;
unsigned access: 8;
unsigned limit_16_19: 4;
unsigned available: 1;
unsigned unused: 1;
unsigned special: 1;
unsigned granularity : 1;
unsigned base_24_31: 8;
} __attribute__ ((packed));
typedef struct descriptor descriptor_t;
 
struct tss {
uint16_t link;
unsigned : 16;
uint32_t esp0;
uint16_t ss0;
unsigned : 16;
uint32_t esp1;
uint16_t ss1;
unsigned : 16;
uint32_t esp2;
uint16_t ss2;
unsigned : 16;
uint32_t cr3;
uint32_t eip;
uint32_t eflags;
uint32_t eax;
uint32_t ecx;
uint32_t edx;
uint32_t ebx;
uint32_t esp;
uint32_t ebp;
uint32_t esi;
uint32_t edi;
uint16_t es;
unsigned : 16;
uint16_t cs;
unsigned : 16;
uint16_t ss;
unsigned : 16;
uint16_t ds;
unsigned : 16;
uint16_t fs;
unsigned : 16;
uint16_t gs;
unsigned : 16;
uint16_t ldtr;
unsigned : 16;
unsigned : 16;
uint16_t iomap_base;
uint8_t iomap[TSS_IOMAP_SIZE];
} __attribute__ ((packed));
typedef struct tss tss_t;
 
extern ptr_16_32_t gdtr;
extern ptr_16_32_t bootstrap_gdtr;
extern ptr_16_32_t protected_ap_gdtr;
extern struct tss *tss_p;
 
extern descriptor_t gdt[];
 
extern void pm_init(void);
 
extern void gdt_setbase(descriptor_t *d, uintptr_t base);
extern void gdt_setlimit(descriptor_t *d, uint32_t limit);
 
extern void traps_init(void);
 
extern void tss_initialize(tss_t *t);
extern void set_tls_desc(uintptr_t tls);
 
#endif /* __ASM__ */
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/xen32/include/mm/frame.h
0,0 → 1,59
/*
* 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 xen32mm
* @{
*/
/** @file
*/
 
#ifndef __xen32_FRAME_H__
#define __xen32_FRAME_H__
 
#define FRAME_WIDTH 12 /* 4K */
#define FRAME_SIZE (1 << FRAME_WIDTH)
 
 
#ifdef KERNEL
#ifndef __ASM__
 
#include <arch/types.h>
#include <arch/boot/boot.h>
 
#define PA2MA(x) ((start_info.pm_map[((uintptr_t) (x)) >> 12] << 12) + (((uintptr_t) (x)) & 0xfff))
#define MA2PA(x) ((mp_map[((uintptr_t) (x)) >> 12] << 12) + (((uintptr_t) (x)) & 0xfff))
 
extern void frame_arch_init(void);
 
#endif /* __ASM__ */
#endif /* KERNEL */
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/xen32/include/mm/page.h
0,0 → 1,221
/*
* 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 xen32mm
* @{
*/
/** @file
*/
 
#ifndef __xen32_PAGE_H__
#define __xen32_PAGE_H__
 
#include <arch/mm/frame.h>
 
#define PAGE_WIDTH FRAME_WIDTH
#define PAGE_SIZE FRAME_SIZE
 
#ifdef KERNEL
 
#ifndef __ASM__
# define KA2PA(x) (((uintptr_t) (x)) - 0x80000000)
# define PA2KA(x) (((uintptr_t) (x)) + 0x80000000)
#else
# define KA2PA(x) ((x) - 0x80000000)
# define PA2KA(x) ((x) + 0x80000000)
#endif
 
/*
* Implementation of generic 4-level page table interface.
* IA-32 has 2-level page tables, so PTL1 and PTL2 are left out.
*/
#define PTL0_ENTRIES_ARCH 1024
#define PTL1_ENTRIES_ARCH 0
#define PTL2_ENTRIES_ARCH 0
#define PTL3_ENTRIES_ARCH 1024
 
#define PTL0_INDEX_ARCH(vaddr) (((vaddr) >> 22) & 0x3ff)
#define PTL1_INDEX_ARCH(vaddr) 0
#define PTL2_INDEX_ARCH(vaddr) 0
#define PTL3_INDEX_ARCH(vaddr) (((vaddr) >> 12) & 0x3ff)
 
#define GET_PTL1_ADDRESS_ARCH(ptl0, i) ((pte_t *) MA2PA((((pte_t *) (ptl0))[(i)].frame_address) << 12))
#define GET_PTL2_ADDRESS_ARCH(ptl1, i) (ptl1)
#define GET_PTL3_ADDRESS_ARCH(ptl2, i) (ptl2)
#define GET_FRAME_ADDRESS_ARCH(ptl3, i) ((uintptr_t) MA2PA((((pte_t *) (ptl3))[(i)].frame_address) << 12))
 
#define SET_PTL0_ADDRESS_ARCH(ptl0) { \
mmuext_op_t mmu_ext; \
\
mmu_ext.cmd = MMUEXT_NEW_BASEPTR; \
mmu_ext.mfn = ADDR2PFN(PA2MA(ptl0)); \
xen_mmuext_op(&mmu_ext, 1, NULL, DOMID_SELF); \
}
 
#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) { \
mmu_update_t update; \
\
update.ptr = PA2MA(KA2PA(&((pte_t *) (ptl0))[(i)])); \
update.val = PA2MA(a) | 0x0003; \
xen_mmu_update(&update, 1, NULL, DOMID_SELF); \
}
#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) (((pte_t *) (ptl3))[(i)].frame_address = PA2MA(a) >> 12)
 
#define GET_PTL1_FLAGS_ARCH(ptl0, i) get_pt_flags((pte_t *) (ptl0), (index_t)(i))
#define GET_PTL2_FLAGS_ARCH(ptl1, i) PAGE_PRESENT
#define GET_PTL3_FLAGS_ARCH(ptl2, i) PAGE_PRESENT
#define GET_FRAME_FLAGS_ARCH(ptl3, i) get_pt_flags((pte_t *) (ptl3), (index_t)(i))
 
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) set_pt_flags((pte_t *) (ptl0), (index_t)(i), (x))
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x)
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) set_pt_flags((pte_t *) (ptl3), (index_t)(i), (x))
 
#define PTE_VALID_ARCH(p) (*((uint32_t *) (p)) != 0)
#define PTE_PRESENT_ARCH(p) ((p)->present != 0)
#define PTE_GET_FRAME_ARCH(p) ((p)->frame_address << FRAME_WIDTH)
#define PTE_WRITABLE_ARCH(p) ((p)->writeable != 0)
#define PTE_EXECUTABLE_ARCH(p) 1
 
#ifndef __ASM__
 
#include <mm/page.h>
#include <arch/types.h>
#include <arch/mm/frame.h>
#include <typedefs.h>
#include <arch/hypercall.h>
 
/* Page fault error codes. */
 
/** When bit on this position is 0, the page fault was caused by a not-present page. */
#define PFERR_CODE_P (1 << 0)
 
/** When bit on this position is 1, the page fault was caused by a write. */
#define PFERR_CODE_RW (1 << 1)
 
/** When bit on this position is 1, the page fault was caused in user mode. */
#define PFERR_CODE_US (1 << 2)
 
/** When bit on this position is 1, a reserved bit was set in page directory. */
#define PFERR_CODE_RSVD (1 << 3)
 
/** Page Table Entry. */
struct page_specifier {
unsigned present : 1;
unsigned writeable : 1;
unsigned uaccessible : 1;
unsigned page_write_through : 1;
unsigned page_cache_disable : 1;
unsigned accessed : 1;
unsigned dirty : 1;
unsigned pat : 1;
unsigned global : 1;
unsigned soft_valid : 1; /**< Valid content even if the present bit is not set. */
unsigned avl : 2;
unsigned frame_address : 20;
} __attribute__ ((packed));
 
typedef struct {
uint64_t ptr; /**< Machine address of PTE */
union { /**< New contents of PTE */
uint64_t val;
pte_t pte;
};
} mmu_update_t;
 
typedef struct {
unsigned int cmd;
union {
unsigned long mfn;
unsigned long linear_addr;
};
union {
unsigned int nr_ents;
void *vcpumask;
};
} mmuext_op_t;
 
static inline int xen_update_va_mapping(const void *va, const pte_t pte, const unsigned int flags)
{
return hypercall4(XEN_UPDATE_VA_MAPPING, va, pte, 0, flags);
}
 
static inline int xen_mmu_update(const mmu_update_t *req, const unsigned int count, unsigned int *success_count, domid_t domid)
{
return hypercall4(XEN_MMU_UPDATE, req, count, success_count, domid);
}
 
static inline int xen_mmuext_op(const mmuext_op_t *op, const unsigned int count, unsigned int *success_count, domid_t domid)
{
return hypercall4(XEN_MMUEXT_OP, op, count, success_count, domid);
}
 
static inline int get_pt_flags(pte_t *pt, index_t i)
{
pte_t *p = &pt[i];
return (
(!p->page_cache_disable)<<PAGE_CACHEABLE_SHIFT |
(!p->present)<<PAGE_PRESENT_SHIFT |
p->uaccessible<<PAGE_USER_SHIFT |
1<<PAGE_READ_SHIFT |
p->writeable<<PAGE_WRITE_SHIFT |
1<<PAGE_EXEC_SHIFT |
p->global<<PAGE_GLOBAL_SHIFT
);
}
 
static inline void set_pt_flags(pte_t *pt, index_t i, int flags)
{
pte_t *p = &pt[i];
p->page_cache_disable = !(flags & PAGE_CACHEABLE);
p->present = !(flags & PAGE_NOT_PRESENT);
p->uaccessible = (flags & PAGE_USER) != 0;
p->writeable = (flags & PAGE_WRITE) != 0;
p->global = (flags & PAGE_GLOBAL) != 0;
/*
* Ensure that there is at least one bit set even if the present bit is cleared.
*/
p->soft_valid = true;
}
 
extern void page_arch_init(void);
extern void page_fault(int n, istate_t *istate);
 
#endif /* __ASM__ */
 
#endif /* KERNEL */
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/xen32/include/mm/memory_init.h
0,0 → 1,48
/*
* Copyright (C) 2005 Josef Cejka
* 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 xen32mm
* @{
*/
/** @file
* @ingroup xen32mm
*/
 
#ifndef __xen32_MEMORY_INIT_H__
#define __xen32_MEMORY_INIT_H__
 
#include <typedefs.h>
 
size_t get_memory_size(void);
 
void memory_print_map(void);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/xen32/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 xen32mm
* @{
*/
/** @file
* @ingroup xen32mm
*/
 
/*
* xen32 has no hardware support for address space identifiers.
* This file is provided to do nop-implementation of mm/asid.h
* interface.
*/
 
#ifndef __xen32_ASID_H__
#define __xen32_ASID_H__
 
typedef int asid_t;
 
#define ASID_MAX_ARCH 3
 
#define asid_get() (ASID_START+1)
#define asid_put(asid)
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/xen32/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 xen32mm
* @{
*/
/** @file
*/
 
#ifndef __xen32_TLB_H__
#define __xen32_TLB_H__
 
#define tlb_arch_init()
#define tlb_print()
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/xen32/include/mm/as.h
0,0 → 1,54
/*
* 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 xen32mm
* @{
*/
/** @file
*/
 
#ifndef __xen32_AS_H__
#define __xen32_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))
 
#define as_install_arch(as)
 
extern void as_arch_init(void);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/xen32/include/interrupt.h
0,0 → 1,0
link ../../ia32/include/interrupt.h
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/xen32/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
/tags/0.2.0.3/kernel/arch/xen32/include/byteorder.h
0,0 → 1,0
link ../../ia32/include/byteorder.h
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/xen32/include/cpuid.h
0,0 → 1,0
link ../../ia32/include/cpuid.h
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/xen32/include/elf.h
0,0 → 1,0
link ../../ia32/include/elf.h
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/xen32/include/bios
0,0 → 1,0
link ../../ia32/include/bios
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/xen32/include/memstr.h
0,0 → 1,0
link ../../ia32/include/memstr.h
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/xen32/include/arg.h
0,0 → 1,0
link ../../ia32/include/arg.h
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/xen32/include/smp
0,0 → 1,0
link ../../ia32/include/smp
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/xen32/include/ddi
0,0 → 1,0
link ../../ia32/include/ddi
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/xen32/include/atomic.h
0,0 → 1,0
link ../../ia32/include/atomic.h
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/xen32/include/arch.h
0,0 → 1,0
link ../../ia32/include/arch.h
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/xen32/include/proc
0,0 → 1,0
link ../../ia32/include/proc
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/xen32/include/faddr.h
0,0 → 1,0
link ../../ia32/include/faddr.h
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/xen32/include/debugger.h
0,0 → 1,0
link ../../ia32/include/debugger.h
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/xen32/include/context.h
0,0 → 1,0
link ../../ia32/include/context.h
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/xen32/include/debug.h
0,0 → 1,0
link ../../ia32/include/debug.h
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/xen32/include/barrier.h
0,0 → 1,0
link ../../ia32/include/barrier.h
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/xen32/include/cpu.h
0,0 → 1,0
link ../../ia32/include/cpu.h
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/xen32/Makefile.inc
0,0 → 1,122
#
# Copyright (C) 2006 Martin Decky
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# - The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
## Toolchain configuration
#
 
BFD_NAME = elf32-i386
BFD_ARCH = i386
BFD = elf32-i386
TARGET = i686-pc-linux-gnu
TOOLCHAIN_DIR = /usr/local/i686/bin
 
DEFS += -DMACHINE=$(MACHINE) -D__32_BITS__
 
## Accepted CPUs
#
 
ifeq ($(MACHINE),athlon-xp)
CFLAGS += -march=athlon-xp -mmmx -msse -m3dnow
DEFS += -DCONFIG_FENCES_P3
CONFIG_SMP = n
CONFIG_HT = n
endif
ifeq ($(MACHINE),athlon-mp)
CFLAGS += -march=athlon-mp -mmmx -msse -m3dnow
DEFS += -DCONFIG_FENCES_P3
CONFIG_HT = n
endif
ifeq ($(MACHINE),pentium3)
CFLAGS += -march=pentium3 -mmmx -msse
DEFS += -DCONFIG_FENCES_P3
CONFIG_HT = n
endif
ifeq ($(MACHINE),prescott)
CFLAGS += -march=pentium4 -mfpmath=sse -mmmx -msse -msse2 -msse3
DEFS += -DCONFIG_FENCES_P4
endif
ifeq ($(MACHINE),pentium4)
CFLAGS += -march=pentium4 -mfpmath=sse -mmmx -msse -msse2
DEFS += -DCONFIG_FENCES_P4
endif
 
## Own configuration directives
#
 
CONFIG_ACPI = y
 
## Compile with hierarchical page tables support.
#
 
CONFIG_PAGE_PT = y
DEFS += -DCONFIG_PAGE_PT
 
## Accepted configuration directives
#
 
ifeq ($(CONFIG_SMP),y)
DEFS += -DCONFIG_SMP
endif
ifeq ($(CONFIG_HT),y)
DEFS += -DCONFIG_HT
endif
 
## Compile with support for software integer division.
#
 
CONFIG_SOFTINT = y
 
ARCH_SOURCES = \
arch/$(ARCH)/src/context.s \
arch/$(ARCH)/src/debug/panic.s \
arch/$(ARCH)/src/delay.s \
arch/$(ARCH)/src/asm.S \
arch/$(ARCH)/src/proc/scheduler.c \
arch/$(ARCH)/src/proc/task.c \
arch/$(ARCH)/src/proc/thread.c \
arch/$(ARCH)/src/bios/bios.c \
arch/$(ARCH)/src/smp/apic.c \
arch/$(ARCH)/src/smp/mps.c \
arch/$(ARCH)/src/smp/smp.c \
arch/$(ARCH)/src/atomic.S \
arch/$(ARCH)/src/smp/ipi.c \
arch/$(ARCH)/src/xen32.c \
arch/$(ARCH)/src/interrupt.c \
arch/$(ARCH)/src/pm.c \
arch/$(ARCH)/src/userspace.c \
arch/$(ARCH)/src/cpu/cpu.c \
arch/$(ARCH)/src/mm/as.c \
arch/$(ARCH)/src/mm/frame.c \
arch/$(ARCH)/src/mm/memory_init.c \
arch/$(ARCH)/src/mm/page.c \
arch/$(ARCH)/src/mm/tlb.c \
arch/$(ARCH)/src/ddi/ddi.c \
arch/$(ARCH)/src/drivers/xconsole.c \
arch/$(ARCH)/src/boot/boot.S \
arch/$(ARCH)/src/fpu_context.c \
arch/$(ARCH)/src/debugger.c
/tags/0.2.0.3/kernel/arch/xen32/_link.ld.in
0,0 → 1,41
/** Xen32 linker script
*/
 
#define __ASM__
#include <arch/boot/boot.h>
#include <arch/mm/page.h>
 
ENTRY(kernel_image_start)
 
SECTIONS {
__xen_guest : {
*(__xen_guest);
}
.image PA2KA(BOOT_OFFSET): {
ktext_start = .;
*(K_TEXT_START);
*(.text);
ktext_end = .;
kdata_start = .;
*(.data); /* initialized data */
*(.rodata*); /* string literals */
*(COMMON); /* global variables */
hardcoded_load_address = .;
LONG(PA2KA(0));
hardcoded_ktext_size = .;
LONG(ktext_end - ktext_start);
hardcoded_kdata_size = .;
LONG(kdata_end - kdata_start);
symbol_table = .;
*(symtab.*); /* Symbol table, must be LAST symbol! */
*(.bss); /* uninitialized static variables */
kdata_end = .;
}
 
/DISCARD/ : {
*(.note.GNU-stack);
*(.comment);
}
}
/tags/0.2.0.3/kernel/arch/amd64/src/mm/page.c
0,0 → 1,220
/*
* 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 amd64mm
* @{
*/
/** @file
*/
 
#include <arch/mm/page.h>
#include <genarch/mm/page_pt.h>
#include <arch/mm/frame.h>
#include <mm/page.h>
#include <mm/frame.h>
#include <mm/as.h>
#include <arch/interrupt.h>
#include <arch/asm.h>
#include <config.h>
#include <memstr.h>
#include <interrupt.h>
#include <print.h>
#include <panic.h>
#include <align.h>
 
/* Definitions for identity page mapper */
pte_t helper_ptl1[512] __attribute__((aligned (PAGE_SIZE)));
pte_t helper_ptl2[512] __attribute__((aligned (PAGE_SIZE)));
pte_t helper_ptl3[512] __attribute__((aligned (PAGE_SIZE)));
extern pte_t ptl_0; /* From boot.S */
 
#define PTL1_PRESENT(ptl0, page) (!(GET_PTL1_FLAGS_ARCH(ptl0, PTL0_INDEX_ARCH(page)) & PAGE_NOT_PRESENT))
#define PTL2_PRESENT(ptl1, page) (!(GET_PTL2_FLAGS_ARCH(ptl1, PTL1_INDEX_ARCH(page)) & PAGE_NOT_PRESENT))
#define PTL3_PRESENT(ptl2, page) (!(GET_PTL3_FLAGS_ARCH(ptl2, PTL2_INDEX_ARCH(page)) & PAGE_NOT_PRESENT))
 
#define PTL1_ADDR(ptl0, page) ((pte_t *)PA2KA(GET_PTL1_ADDRESS_ARCH(ptl0, PTL0_INDEX_ARCH(page))))
#define PTL2_ADDR(ptl1, page) ((pte_t *)PA2KA(GET_PTL2_ADDRESS_ARCH(ptl1, PTL1_INDEX_ARCH(page))))
#define PTL3_ADDR(ptl2, page) ((pte_t *)PA2KA(GET_PTL3_ADDRESS_ARCH(ptl2, PTL2_INDEX_ARCH(page))))
 
#define SETUP_PTL1(ptl0, page, tgt) { \
SET_PTL1_ADDRESS_ARCH(ptl0, PTL0_INDEX_ARCH(page), (uintptr_t)KA2PA(tgt)); \
SET_PTL1_FLAGS_ARCH(ptl0, PTL0_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \
}
#define SETUP_PTL2(ptl1, page, tgt) { \
SET_PTL2_ADDRESS_ARCH(ptl1, PTL1_INDEX_ARCH(page), (uintptr_t)KA2PA(tgt)); \
SET_PTL2_FLAGS_ARCH(ptl1, PTL1_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \
}
#define SETUP_PTL3(ptl2, page, tgt) { \
SET_PTL3_ADDRESS_ARCH(ptl2, PTL2_INDEX_ARCH(page), (uintptr_t)KA2PA(tgt)); \
SET_PTL3_FLAGS_ARCH(ptl2, PTL2_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \
}
#define SETUP_FRAME(ptl3, page, tgt) { \
SET_FRAME_ADDRESS_ARCH(ptl3, PTL3_INDEX_ARCH(page), (uintptr_t)KA2PA(tgt)); \
SET_FRAME_FLAGS_ARCH(ptl3, PTL3_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \
}
 
 
void page_arch_init(void)
{
uintptr_t cur;
int i;
int identity_flags = PAGE_CACHEABLE | PAGE_EXEC | PAGE_GLOBAL;
 
if (config.cpu_active == 1) {
page_mapping_operations = &pt_mapping_operations;
/*
* PA2KA(identity) mapping for all frames.
*/
for (cur = 0; cur < last_frame; cur += FRAME_SIZE) {
/* Standard identity mapping */
page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, identity_flags);
}
/* Upper kernel mapping
* - from zero to top of kernel (include bottom addresses
* because some are needed for init )
*/
for (cur = PA2KA_CODE(0); cur < config.base + config.kernel_size; cur += FRAME_SIZE)
page_mapping_insert(AS_KERNEL, cur, KA2PA(cur), identity_flags);
for (cur = config.stack_base; cur < config.stack_base + config.stack_size; cur += FRAME_SIZE)
page_mapping_insert(AS_KERNEL, cur, KA2PA(cur), identity_flags);
for (i = 0; i < init.cnt; i++) {
for (cur = init.tasks[i].addr; cur < init.tasks[i].addr + init.tasks[i].size; cur += FRAME_SIZE)
page_mapping_insert(AS_KERNEL, PA2KA_CODE(KA2PA(cur)), KA2PA(cur), identity_flags);
}
 
exc_register(14, "page_fault", (iroutine)page_fault);
write_cr3((uintptr_t) AS_KERNEL->page_table);
}
else {
write_cr3((uintptr_t) AS_KERNEL->page_table);
}
}
 
 
/** Identity page mapper
*
* We need to map whole physical memory identically before the page subsystem
* is initializaed. This thing clears page table and fills in the specific
* items.
*/
void ident_page_fault(int n, istate_t *istate)
{
uintptr_t page;
static uintptr_t oldpage = 0;
pte_t *aptl_1, *aptl_2, *aptl_3;
 
page = read_cr2();
if (oldpage) {
/* Unmap old address */
aptl_1 = PTL1_ADDR(&ptl_0, oldpage);
aptl_2 = PTL2_ADDR(aptl_1, oldpage);
aptl_3 = PTL3_ADDR(aptl_2, oldpage);
 
SET_FRAME_FLAGS_ARCH(aptl_3, PTL3_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT);
if (KA2PA(aptl_3) == KA2PA(helper_ptl3))
SET_PTL3_FLAGS_ARCH(aptl_2, PTL2_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT);
if (KA2PA(aptl_2) == KA2PA(helper_ptl2))
SET_PTL2_FLAGS_ARCH(aptl_1, PTL1_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT);
if (KA2PA(aptl_1) == KA2PA(helper_ptl1))
SET_PTL1_FLAGS_ARCH(&ptl_0, PTL0_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT);
}
if (PTL1_PRESENT(&ptl_0, page))
aptl_1 = PTL1_ADDR(&ptl_0, page);
else {
SETUP_PTL1(&ptl_0, page, helper_ptl1);
aptl_1 = helper_ptl1;
}
if (PTL2_PRESENT(aptl_1, page))
aptl_2 = PTL2_ADDR(aptl_1, page);
else {
SETUP_PTL2(aptl_1, page, helper_ptl2);
aptl_2 = helper_ptl2;
}
 
if (PTL3_PRESENT(aptl_2, page))
aptl_3 = PTL3_ADDR(aptl_2, page);
else {
SETUP_PTL3(aptl_2, page, helper_ptl3);
aptl_3 = helper_ptl3;
}
SETUP_FRAME(aptl_3, page, page);
 
oldpage = page;
}
 
 
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 table entry.\n");
if (istate->error_word & PFERR_CODE_RW)
access = PF_ACCESS_WRITE;
else if (istate->error_word & PFERR_CODE_ID)
access = PF_ACCESS_EXEC;
else
access = PF_ACCESS_READ;
if (as_page_fault(page, access, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate, "Page fault: %#x", page);
 
print_info_errcode(n, istate);
printf("Page fault address: %llx\n", page);
panic("page fault\n");
}
}
 
 
uintptr_t hw_map(uintptr_t physaddr, size_t size)
{
if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH))
panic("Unable to map physical memory %p (%d bytes)", physaddr, size)
uintptr_t virtaddr = PA2KA(last_frame);
pfn_t i;
for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++)
page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE);
last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE);
return virtaddr;
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/src/mm/memory_init.c
0,0 → 1,81
/*
* Copyright (C) 2005 Josef Cejka
* 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 amd64mm
* @{
*/
/** @file
*/
 
#include <arch/boot/memmap.h>
#include <arch/mm/memory_init.h>
#include <arch/mm/page.h>
#include <print.h>
 
uint8_t e820counter = 0xff;
struct e820memmap_ e820table[MEMMAP_E820_MAX_RECORDS];
uint32_t e801memorysize;
 
size_t get_memory_size(void)
{
return e801memorysize*1024;
}
 
void memory_print_map(void)
{
uint8_t i;
for (i=0;i<e820counter;i++) {
printf("E820 base: %#llx size: %#llx type: ", e820table[i].base_address, e820table[i].size);
switch (e820table[i].type) {
case MEMMAP_MEMORY_AVAILABLE:
printf("available memory\n");
break;
case MEMMAP_MEMORY_RESERVED:
printf("reserved memory\n");
break;
case MEMMAP_MEMORY_ACPI:
printf("ACPI table\n");
break;
case MEMMAP_MEMORY_NVS:
printf("NVS\n");
break;
case MEMMAP_MEMORY_UNUSABLE:
printf("unusable memory\n");
break;
default:
printf("undefined memory type\n");
}
}
 
}
 
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/src/mm/as.c
0,0 → 1,0
link ../../../ia32/src/mm/as.c
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/amd64/src/mm/tlb.c
0,0 → 1,0
link ../../../ia32/src/mm/tlb.c
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/amd64/src/mm/frame.c
0,0 → 1,0
link ../../../ia32/src/mm/frame.c
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/amd64/src/cpu/cpu.c
0,0 → 1,168
/*
* 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 amd64
* @{
*/
/** @file
*/
 
#include <arch/cpu.h>
#include <arch/cpuid.h>
#include <arch/pm.h>
 
#include <arch.h>
#include <arch/types.h>
#include <print.h>
#include <typedefs.h>
#include <fpu_context.h>
 
/*
* Identification of CPUs.
* Contains only non-MP-Specification specific SMP code.
*/
#define AMD_CPUID_EBX 0x68747541
#define AMD_CPUID_ECX 0x444d4163
#define AMD_CPUID_EDX 0x69746e65
 
#define INTEL_CPUID_EBX 0x756e6547
#define INTEL_CPUID_ECX 0x6c65746e
#define INTEL_CPUID_EDX 0x49656e69
 
 
enum vendor {
VendorUnknown=0,
VendorAMD,
VendorIntel
};
 
static char *vendor_str[] = {
"Unknown Vendor",
"AuthenticAMD",
"GenuineIntel"
};
 
 
/** Setup flags on processor so that we can use the FPU
*
* cr0.osfxsr = 1 -> we do support fxstor/fxrestor
* cr0.em = 0 -> we do not emulate coprocessor
* cr0.mp = 1 -> we do want lazy context switch
*/
void cpu_setup_fpu(void)
{
__asm__ volatile (
"movq %%cr0, %%rax;"
"btsq $1, %%rax;" /* cr0.mp */
"btrq $2, %%rax;" /* cr0.em */
"movq %%rax, %%cr0;"
 
"movq %%cr4, %%rax;"
"bts $9, %%rax;" /* cr4.osfxsr */
"movq %%rax, %%cr4;"
:
:
:"%rax"
);
}
 
/** Set the TS flag to 1.
*
* If a thread accesses coprocessor, exception is run, which
* does a lazy fpu context switch.
*
*/
void fpu_disable(void)
{
__asm__ volatile (
"mov %%cr0,%%rax;"
"bts $3,%%rax;"
"mov %%rax,%%cr0;"
:
:
:"%rax"
);
}
 
void fpu_enable(void)
{
__asm__ volatile (
"mov %%cr0,%%rax;"
"btr $3,%%rax;"
"mov %%rax,%%cr0;"
:
:
:"%rax"
);
}
 
void cpu_arch_init(void)
{
CPU->arch.tss = tss_p;
CPU->arch.tss->iomap_base = &CPU->arch.tss->iomap[0] - ((uint8_t *) CPU->arch.tss);
CPU->fpu_owner = NULL;
}
 
void cpu_identify(void)
{
cpu_info_t info;
 
CPU->arch.vendor = VendorUnknown;
if (has_cpuid()) {
cpuid(0, &info);
 
/*
* Check for AMD processor.
*/
if (info.cpuid_ebx==AMD_CPUID_EBX && info.cpuid_ecx==AMD_CPUID_ECX && info.cpuid_edx==AMD_CPUID_EDX) {
CPU->arch.vendor = VendorAMD;
}
 
/*
* Check for Intel processor.
*/
if (info.cpuid_ebx==INTEL_CPUID_EBX && info.cpuid_ecx==INTEL_CPUID_ECX && info.cpuid_edx==INTEL_CPUID_EDX) {
CPU->arch.vendor = VendorIntel;
}
cpuid(1, &info);
CPU->arch.family = (info.cpuid_eax>>8)&0xf;
CPU->arch.model = (info.cpuid_eax>>4)&0xf;
CPU->arch.stepping = (info.cpuid_eax>>0)&0xf;
}
}
 
void cpu_print_report(cpu_t* m)
{
printf("cpu%d: (%s family=%d model=%d stepping=%d) %dMHz\n",
m->id, vendor_str[m->arch.vendor], m->arch.family, m->arch.model, m->arch.stepping,
m->frequency_mhz);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/amd64/src/syscall.c
0,0 → 1,72
/*
* Copyright (C) 2006 Ondrej Palkovsky
* 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 amd64
* @{
*/
/** @file
*/
 
#include <syscall/syscall.h>
#include <arch/syscall.h>
#include <panic.h>
#include <arch/cpu.h>
#include <arch/pm.h>
#include <arch/asm.h>
 
#include <print.h>
#include <arch/cpu.h>
 
extern void syscall_entry(void);
 
/** Enable & setup support for SYSCALL/SYSRET */
void syscall_setup_cpu(void)
{
/* Enable SYSCALL/SYSRET */
set_efer_flag(AMD_SCE_FLAG);
 
/* Setup syscall entry address */
/* This is _mess_ - the 64-bit CS is argument+16,
* the SS is argument+8. The order is:
* +0(KDATA_DES), +8(UDATA_DES), +16(UTEXT_DES)
*/
write_msr(AMD_MSR_STAR,
((uint64_t)(gdtselector(KDATA_DES) | PL_USER)<<48) \
| ((uint64_t)(gdtselector(KTEXT_DES) | PL_KERNEL)<<32));
write_msr(AMD_MSR_LSTAR, (uint64_t)syscall_entry);
/* Mask RFLAGS on syscall
* - disable interrupts, until we exchange the stack register
* (mask the IE bit)
*/
write_msr(AMD_MSR_SFMASK, 0x200);
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/src/amd64.c
0,0 → 1,213
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 amd64
* @{
*/
/** @file
*/
 
#include <arch.h>
 
#include <arch/types.h>
 
#include <config.h>
 
#include <proc/thread.h>
#include <arch/drivers/ega.h>
#include <arch/drivers/vesa.h>
#include <genarch/i8042/i8042.h>
#include <arch/drivers/i8254.h>
#include <arch/drivers/i8259.h>
 
#include <arch/bios/bios.h>
#include <arch/mm/memory_init.h>
#include <arch/cpu.h>
#include <print.h>
#include <arch/cpuid.h>
#include <genarch/acpi/acpi.h>
#include <panic.h>
#include <interrupt.h>
#include <arch/syscall.h>
#include <arch/debugger.h>
#include <syscall/syscall.h>
#include <console/console.h>
 
 
/** Disable I/O on non-privileged levels
*
* Clean IOPL(12,13) and NT(14) flags in EFLAGS register
*/
static void clean_IOPL_NT_flags(void)
{
asm
(
"pushfq;"
"pop %%rax;"
"and $~(0x7000),%%rax;"
"pushq %%rax;"
"popfq;"
:
:
:"%rax"
);
}
 
/** Disable alignment check
*
* Clean AM(18) flag in CR0 register
*/
static void clean_AM_flag(void)
{
asm
(
"mov %%cr0,%%rax;"
"and $~(0x40000),%%rax;"
"mov %%rax,%%cr0;"
:
:
:"%rax"
);
}
 
void arch_pre_mm_init(void)
{
struct cpu_info cpuid_s;
 
cpuid(AMD_CPUID_EXTENDED,&cpuid_s);
if (! (cpuid_s.cpuid_edx & (1<<AMD_EXT_NOEXECUTE)))
panic("Processor does not support No-execute pages.\n");
 
cpuid(INTEL_CPUID_STANDARD,&cpuid_s);
if (! (cpuid_s.cpuid_edx & (1<<INTEL_FXSAVE)))
panic("Processor does not support FXSAVE/FXRESTORE.\n");
if (! (cpuid_s.cpuid_edx & (1<<INTEL_SSE2)))
panic("Processor does not support SSE2 instructions.\n");
 
/* Enable No-execute pages */
set_efer_flag(AMD_NXE_FLAG);
/* Enable FPU */
cpu_setup_fpu();
 
/* Initialize segmentation */
pm_init();
 
/* Disable I/O on nonprivileged levels
* clear the NT(nested-thread) flag
*/
clean_IOPL_NT_flags();
/* Disable alignment check */
clean_AM_flag();
 
if (config.cpu_active == 1) {
bios_init();
i8259_init(); /* PIC */
i8254_init(); /* hard clock */
 
#ifdef CONFIG_SMP
exc_register(VECTOR_TLB_SHOOTDOWN_IPI, "tlb_shootdown",
tlb_shootdown_ipi);
#endif /* CONFIG_SMP */
}
}
 
void arch_post_mm_init(void)
{
if (config.cpu_active == 1) {
#ifdef CONFIG_FB
if (vesa_present())
vesa_init();
else
#endif
ega_init(); /* video */
/* Enable debugger */
debugger_init();
/* Merge all memory zones to 1 big zone */
zone_merge_all();
}
/* Setup fast SYSCALL/SYSRET */
syscall_setup_cpu();
}
 
void arch_pre_smp_init(void)
{
if (config.cpu_active == 1) {
memory_print_map();
#ifdef CONFIG_SMP
acpi_init();
#endif /* CONFIG_SMP */
}
}
 
void arch_post_smp_init(void)
{
i8042_init(); /* keyboard controller */
}
 
void calibrate_delay_loop(void)
{
i8254_calibrate_delay_loop();
i8254_normal_operation();
}
 
/** Set thread-local-storage pointer
*
* TLS pointer is set in FS register. Unfortunately the 64-bit
* part can be set only in CPL0 mode.
*
* The specs say, that on %fs:0 there is stored contents of %fs register,
* we need not to go to CPL0 to read it.
*/
unative_t sys_tls_set(unative_t addr)
{
THREAD->arch.tls = addr;
write_msr(AMD_MSR_FS, addr);
return 0;
}
 
/** Acquire console back for kernel
*
*/
void arch_grab_console(void)
{
i8042_grab();
}
/** Return console to userspace
*
*/
void arch_release_console(void)
{
i8042_release();
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/src/pm.c
0,0 → 1,245
/*
* Copyright (C) 2001-2004 Jakub Jermar
* Copyright (C) 2005-2006 Ondrej Palkovsky
* 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 amd64
* @{
*/
/** @file
*/
 
#include <arch/pm.h>
#include <arch/mm/page.h>
#include <arch/types.h>
#include <arch/interrupt.h>
#include <arch/asm.h>
#include <interrupt.h>
#include <mm/as.h>
 
#include <config.h>
 
#include <memstr.h>
#include <mm/slab.h>
#include <debug.h>
 
/*
* There is no segmentation in long mode 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.
*/
 
descriptor_t gdt[GDT_ITEMS] = {
/* NULL descriptor */
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
/* KTEXT descriptor */
{ .limit_0_15 = 0xffff,
.base_0_15 = 0,
.base_16_23 = 0,
.access = AR_PRESENT | AR_CODE | DPL_KERNEL | AR_READABLE ,
.limit_16_19 = 0xf,
.available = 0,
.longmode = 1,
.special = 0,
.granularity = 1,
.base_24_31 = 0 },
/* KDATA descriptor */
{ .limit_0_15 = 0xffff,
.base_0_15 = 0,
.base_16_23 = 0,
.access = AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_KERNEL,
.limit_16_19 = 0xf,
.available = 0,
.longmode = 0,
.special = 0,
.granularity = 1,
.base_24_31 = 0 },
/* UDATA descriptor */
{ .limit_0_15 = 0xffff,
.base_0_15 = 0,
.base_16_23 = 0,
.access = AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_USER,
.limit_16_19 = 0xf,
.available = 0,
.longmode = 0,
.special = 1,
.granularity = 1,
.base_24_31 = 0 },
/* UTEXT descriptor */
{ .limit_0_15 = 0xffff,
.base_0_15 = 0,
.base_16_23 = 0,
.access = AR_PRESENT | AR_CODE | DPL_USER,
.limit_16_19 = 0xf,
.available = 0,
.longmode = 1,
.special = 0,
.granularity = 1,
.base_24_31 = 0 },
/* KTEXT 32-bit protected, for protected mode before long mode */
{ .limit_0_15 = 0xffff,
.base_0_15 = 0,
.base_16_23 = 0,
.access = AR_PRESENT | AR_CODE | DPL_KERNEL | AR_READABLE,
.limit_16_19 = 0xf,
.available = 0,
.longmode = 0,
.special = 1,
.granularity = 1,
.base_24_31 = 0 },
/* TSS descriptor - set up will be completed later,
* on AMD64 it is 64-bit - 2 items in table */
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
/* VESA Init descriptor */
#ifdef CONFIG_FB
{ 0xffff, 0, VESA_INIT_SEGMENT>>12, AR_PRESENT | AR_CODE | DPL_KERNEL, 0xf, 0, 0, 0, 0, 0 }
#endif
};
 
idescriptor_t idt[IDT_ITEMS];
 
ptr_16_64_t gdtr = {.limit = sizeof(gdt), .base= (uint64_t) gdt };
ptr_16_64_t idtr = {.limit = sizeof(idt), .base= (uint64_t) idt };
 
static tss_t tss;
tss_t *tss_p = NULL;
 
void gdt_tss_setbase(descriptor_t *d, uintptr_t base)
{
tss_descriptor_t *td = (tss_descriptor_t *) d;
 
td->base_0_15 = base & 0xffff;
td->base_16_23 = ((base) >> 16) & 0xff;
td->base_24_31 = ((base) >> 24) & 0xff;
td->base_32_63 = ((base) >> 32);
}
 
void gdt_tss_setlimit(descriptor_t *d, uint32_t limit)
{
struct tss_descriptor *td = (tss_descriptor_t *) d;
 
td->limit_0_15 = limit & 0xffff;
td->limit_16_19 = (limit >> 16) & 0xf;
}
 
void idt_setoffset(idescriptor_t *d, uintptr_t offset)
{
/*
* Offset is a linear address.
*/
d->offset_0_15 = offset & 0xffff;
d->offset_16_31 = offset >> 16 & 0xffff;
d->offset_32_63 = offset >> 32;
}
 
void tss_initialize(tss_t *t)
{
memsetb((uintptr_t) t, sizeof(tss_t), 0);
}
 
/*
* This function takes care of proper setup of IDT and IDTR.
*/
void idt_init(void)
{
idescriptor_t *d;
int i;
 
for (i = 0; i < IDT_ITEMS; i++) {
d = &idt[i];
 
d->unused = 0;
d->selector = gdtselector(KTEXT_DES);
 
d->present = 1;
d->type = AR_INTERRUPT; /* masking interrupt */
 
idt_setoffset(d, ((uintptr_t) interrupt_handlers) + i*interrupt_handler_size);
exc_register(i, "undef", (iroutine)null_interrupt);
}
 
exc_register( 7, "nm_fault", nm_fault);
exc_register(12, "ss_fault", ss_fault);
exc_register(13, "gp_fault", gp_fault);
exc_register(14, "ident_mapper", ident_page_fault);
}
 
/** Initialize segmentation - code/data/idt tables
*
*/
void pm_init(void)
{
descriptor_t *gdt_p = (struct descriptor *) gdtr.base;
tss_descriptor_t *tss_desc;
 
/*
* Each CPU has its private GDT and TSS.
* All CPUs share one IDT.
*/
 
if (config.cpu_active == 1) {
idt_init();
/*
* NOTE: bootstrap CPU has statically allocated TSS, because
* the heap hasn't been initialized so far.
*/
tss_p = &tss;
}
else {
/* We are going to use malloc, which may return
* non boot-mapped pointer, initialize the CR3 register
* ahead of page_init */
write_cr3((uintptr_t) AS_KERNEL->page_table);
 
tss_p = (struct tss *) malloc(sizeof(tss_t), FRAME_ATOMIC);
if (!tss_p)
panic("could not allocate TSS\n");
}
 
tss_initialize(tss_p);
 
tss_desc = (tss_descriptor_t *) (&gdt_p[TSS_DES]);
tss_desc->present = 1;
tss_desc->type = AR_TSS;
tss_desc->dpl = PL_KERNEL;
gdt_tss_setbase(&gdt_p[TSS_DES], (uintptr_t) tss_p);
gdt_tss_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE - 1);
 
gdtr_load(&gdtr);
idtr_load(&idtr);
/*
* 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(gdtselector(TSS_DES));
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/src/ddi/ddi.c
0,0 → 1,167
/*
* 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 amd64ddi
* @{
*/
/** @file
*/
 
#include <ddi/ddi.h>
#include <arch/ddi/ddi.h>
#include <proc/task.h>
#include <arch/types.h>
#include <typedefs.h>
#include <adt/bitmap.h>
#include <mm/slab.h>
#include <arch/pm.h>
#include <errno.h>
#include <arch/cpu.h>
#include <arch.h>
#include <align.h>
 
/** Enable I/O space range for task.
*
* Interrupts are disabled and task is locked.
*
* @param task Task.
* @param ioaddr Startign I/O space address.
* @param size Size of the enabled I/O range.
*
* @return 0 on success or an error code from errno.h.
*/
int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
{
count_t bits;
 
bits = ioaddr + size;
if (bits > IO_PORTS)
return ENOENT;
 
if (task->arch.iomap.bits < bits) {
bitmap_t oldiomap;
uint8_t *newmap;
/*
* The I/O permission bitmap is too small and needs to be grown.
*/
newmap = (uint8_t *) malloc(BITS2BYTES(bits), FRAME_ATOMIC);
if (!newmap)
return ENOMEM;
bitmap_initialize(&oldiomap, task->arch.iomap.map, task->arch.iomap.bits);
bitmap_initialize(&task->arch.iomap, newmap, bits);
 
/*
* Mark the new range inaccessible.
*/
bitmap_set_range(&task->arch.iomap, oldiomap.bits, bits - oldiomap.bits);
 
/*
* In case there really existed smaller iomap,
* copy its contents and deallocate it.
*/
if (oldiomap.bits) {
bitmap_copy(&task->arch.iomap, &oldiomap, oldiomap.bits);
free(oldiomap.map);
}
}
 
/*
* Enable the range and we are done.
*/
bitmap_clear_range(&task->arch.iomap, (index_t) ioaddr, (count_t) size);
 
/*
* Increment I/O Permission bitmap generation counter.
*/
task->arch.iomapver++;
 
return 0;
}
 
/** Install I/O Permission bitmap.
*
* Current task's I/O permission bitmap, if any, is installed
* in the current CPU's TSS.
*
* Interrupts must be disabled prior this call.
*/
void io_perm_bitmap_install(void)
{
count_t bits;
ptr_16_64_t cpugdtr;
descriptor_t *gdt_p;
tss_descriptor_t *tss_desc;
count_t ver;
 
/* First, copy the I/O Permission Bitmap. */
spinlock_lock(&TASK->lock);
ver = TASK->arch.iomapver;
if ((bits = TASK->arch.iomap.bits)) {
bitmap_t iomap;
ASSERT(TASK->arch.iomap.map);
bitmap_initialize(&iomap, CPU->arch.tss->iomap, TSS_IOMAP_SIZE * 8);
bitmap_copy(&iomap, &TASK->arch.iomap, TASK->arch.iomap.bits);
/*
* It is safe to set the trailing eight bits because of the extra
* convenience byte in TSS_IOMAP_SIZE.
*/
bitmap_set_range(&iomap, ALIGN_UP(TASK->arch.iomap.bits, 8), 8);
}
spinlock_unlock(&TASK->lock);
 
/*
* Second, adjust TSS segment limit.
* Take the extra ending byte will all bits set into account.
*/
gdtr_store(&cpugdtr);
gdt_p = (descriptor_t *) cpugdtr.base;
gdt_tss_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE + BITS2BYTES(bits));
gdtr_load(&cpugdtr);
/*
* Before we load new TSS limit, the current TSS descriptor
* type must be changed to describe inactive TSS.
*/
tss_desc = (tss_descriptor_t *) &gdt_p[TSS_DES];
tss_desc->type = AR_TSS;
tr_load(gdtselector(TSS_DES));
/*
* Update the generation count so that faults caused by
* early accesses can be serviced.
*/
CPU->arch.iomapver_copy = ver;
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/src/proc/scheduler.c
0,0 → 1,85
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 amd64proc
* @{
*/
/** @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/asm.h>
#include <arch/debugger.h>
#include <print.h>
#include <arch/pm.h>
#include <arch/ddi/ddi.h>
 
/** Perform amd64 specific tasks needed before the new task is run.
*
* Interrupts are disabled.
*/
void before_task_runs_arch(void)
{
io_perm_bitmap_install();
}
 
/** Perform amd64 specific tasks needed before the new thread is scheduled. */
void before_thread_runs_arch(void)
{
CPU->arch.tss->rsp0 = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE-SP_DELTA];
 
/* Syscall support - write address of thread stack pointer to
* hidden part of gs */
swapgs();
write_msr(AMD_MSR_GS, (uint64_t)&THREAD->kstack);
swapgs();
 
/* TLS support - set FS to thread local storage */
write_msr(AMD_MSR_FS, 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)
{
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/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 amd64proc
* @{
*/
/** @file
*/
 
#include <proc/task.h>
#include <mm/slab.h>
#include <arch/types.h>
 
/** Perform amd64 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 amd64 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);
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/src/proc/thread.c
0,0 → 1,48
/*
* 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 amd64proc
* @{
*/
/** @file
*/
 
#include <proc/thread.h>
 
/** Perform amd64 specific thread initialization.
*
* @param t Thread to be initialized.
*/
void thread_create_arch(thread_t *t)
{
t->arch.tls = 0;
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/src/debugger.c
0,0 → 1,387
/*
* Copyright (C) 2006 Ondrej Palkovsky
* 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 amd64debug
* @{
*/
/** @file
*/
 
#include <arch/debugger.h>
#include <console/kconsole.h>
#include <console/cmd.h>
#include <symtab.h>
#include <print.h>
#include <panic.h>
#include <interrupt.h>
#include <arch/asm.h>
#include <arch/cpu.h>
#include <debug.h>
#include <func.h>
#include <smp/ipi.h>
 
typedef struct {
uintptr_t address; /**< Breakpoint address */
int flags; /**< Flags regarding breakpoint */
int counter; /**< How many times the exception occured */
} bpinfo_t;
 
static bpinfo_t breakpoints[BKPOINTS_MAX];
SPINLOCK_INITIALIZE(bkpoint_lock);
 
static int cmd_print_breakpoints(cmd_arg_t *argv);
static cmd_info_t bkpts_info = {
.name = "bkpts",
.description = "Print breakpoint table.",
.func = cmd_print_breakpoints,
.argc = 0,
};
 
#ifndef CONFIG_DEBUG_AS_WATCHPOINT
 
static int cmd_del_breakpoint(cmd_arg_t *argv);
static cmd_arg_t del_argv = {
.type = ARG_TYPE_INT
};
static cmd_info_t delbkpt_info = {
.name = "delbkpt",
.description = "delbkpt <number> - Delete breakpoint.",
.func = cmd_del_breakpoint,
.argc = 1,
.argv = &del_argv
};
 
static int cmd_add_breakpoint(cmd_arg_t *argv);
static cmd_arg_t add_argv = {
.type = ARG_TYPE_INT
};
static cmd_info_t addbkpt_info = {
.name = "addbkpt",
.description = "addbkpt <&symbol> - new breakpoint.",
.func = cmd_add_breakpoint,
.argc = 1,
.argv = &add_argv
};
 
static cmd_arg_t addw_argv = {
.type = ARG_TYPE_INT
};
static cmd_info_t addwatchp_info = {
.name = "addwatchp",
.description = "addbwatchp <&symbol> - new write watchpoint.",
.func = cmd_add_breakpoint,
.argc = 1,
.argv = &addw_argv
};
 
#endif
 
/** Print table of active breakpoints */
int cmd_print_breakpoints(cmd_arg_t *argv)
{
int i;
char *symbol;
 
printf("Breakpoint table.\n");
for (i=0; i < BKPOINTS_MAX; i++)
if (breakpoints[i].address) {
symbol = get_symtab_entry(breakpoints[i].address);
printf("%d. %p in %s\n",i,
breakpoints[i].address, symbol);
printf(" Count(%d) ", breakpoints[i].counter);
printf("\n");
}
return 1;
}
 
/* Setup DR register according to table */
static void setup_dr(int curidx)
{
unative_t dr7;
bpinfo_t *cur = &breakpoints[curidx];
int flags = breakpoints[curidx].flags;
 
/* Disable breakpoint in DR7 */
dr7 = read_dr7();
dr7 &= ~(0x2 << (curidx*2));
 
if (cur->address) { /* Setup DR register */
/* Set breakpoint to debug registers */
switch (curidx) {
case 0:
write_dr0(cur->address);
break;
case 1:
write_dr1(cur->address);
break;
case 2:
write_dr2(cur->address);
break;
case 3:
write_dr3(cur->address);
break;
}
/* Set type to requested breakpoint & length*/
dr7 &= ~ (0x3 << (16 + 4*curidx));
dr7 &= ~ (0x3 << (18 + 4*curidx));
if ((flags & BKPOINT_INSTR)) {
;
} else {
if (sizeof(int) == 4)
dr7 |= ((unative_t) 0x3) << (18 + 4*curidx);
else /* 8 */
dr7 |= ((unative_t) 0x2) << (18 + 4*curidx);
if ((flags & BKPOINT_WRITE))
dr7 |= ((unative_t) 0x1) << (16 + 4*curidx);
else if ((flags & BKPOINT_READ_WRITE))
dr7 |= ((unative_t) 0x3) << (16 + 4*curidx);
}
 
/* Enable global breakpoint */
dr7 |= 0x2 << (curidx*2);
 
write_dr7(dr7);
}
}
/** Enable hardware breakpoint
*
*
* @param where Address of HW breakpoint
* @param flags Type of breakpoint (EXECUTE, WRITE)
* @return Debug slot on success, -1 - no available HW breakpoint
*/
int breakpoint_add(void * where, int flags, int curidx)
{
ipl_t ipl;
int i;
bpinfo_t *cur;
 
ASSERT( flags & (BKPOINT_INSTR | BKPOINT_WRITE | BKPOINT_READ_WRITE));
 
ipl = interrupts_disable();
spinlock_lock(&bkpoint_lock);
if (curidx == -1) {
/* Find free space in slots */
for (i=0; i<BKPOINTS_MAX; i++)
if (!breakpoints[i].address) {
curidx = i;
break;
}
if (curidx == -1) {
/* Too many breakpoints */
spinlock_unlock(&bkpoint_lock);
interrupts_restore(ipl);
return -1;
}
}
cur = &breakpoints[curidx];
 
cur->address = (uintptr_t) where;
cur->flags = flags;
cur->counter = 0;
 
setup_dr(curidx);
 
spinlock_unlock(&bkpoint_lock);
interrupts_restore(ipl);
 
/* Send IPI */
#ifdef CONFIG_SMP
// ipi_broadcast(VECTOR_DEBUG_IPI);
#endif
 
return curidx;
}
 
#ifdef amd64
# define getip(x) ((x)->rip)
#else
# define getip(x) ((x)->eip)
#endif
 
static void handle_exception(int slot, istate_t *istate)
{
ASSERT(breakpoints[slot].address);
 
/* Handle zero checker */
if (! (breakpoints[slot].flags & BKPOINT_INSTR)) {
if ((breakpoints[slot].flags & BKPOINT_CHECK_ZERO)) {
if (*((unative_t *) breakpoints[slot].address) != 0)
return;
printf("**** Found ZERO on address %p ****\n",
slot, breakpoints[slot].address);
} else {
printf("Data watchpoint - new data: %p\n",
*((unative_t *) breakpoints[slot].address));
}
}
printf("Reached breakpoint %d:%p(%s)\n", slot, getip(istate),
get_symtab_entry(getip(istate)));
printf("***Type 'exit' to exit kconsole.\n");
atomic_set(&haltstate,1);
kconsole("debug");
atomic_set(&haltstate,0);
}
 
void breakpoint_del(int slot)
{
bpinfo_t *cur;
ipl_t ipl;
 
ipl = interrupts_disable();
spinlock_lock(&bkpoint_lock);
 
cur = &breakpoints[slot];
if (!cur->address) {
spinlock_unlock(&bkpoint_lock);
interrupts_restore(ipl);
return;
}
 
cur->address = NULL;
 
setup_dr(slot);
 
spinlock_unlock(&bkpoint_lock);
interrupts_restore(ipl);
#ifdef CONFIG_SMP
// ipi_broadcast(VECTOR_DEBUG_IPI);
#endif
}
 
#ifndef CONFIG_DEBUG_AS_WATCHPOINT
 
/** Remove breakpoint from table */
int cmd_del_breakpoint(cmd_arg_t *argv)
{
if (argv->intval < 0 || argv->intval > BKPOINTS_MAX) {
printf("Invalid breakpoint number.\n");
return 0;
}
breakpoint_del(argv->intval);
return 1;
}
 
/** Add new breakpoint to table */
static int cmd_add_breakpoint(cmd_arg_t *argv)
{
int flags;
int id;
 
if (argv == &add_argv) {
flags = BKPOINT_INSTR;
} else { /* addwatchp */
flags = BKPOINT_WRITE;
}
printf("Adding breakpoint on address: %p\n", argv->intval);
id = breakpoint_add((void *)argv->intval, flags, -1);
if (id < 0)
printf("Add breakpoint failed.\n");
else
printf("Added breakpoint %d.\n", id);
return 1;
}
#endif
 
static void debug_exception(int n, istate_t *istate)
{
unative_t dr6;
int i;
/* Set RF to restart the instruction */
#ifdef amd64
istate->rflags |= RFLAGS_RF;
#else
istate->eflags |= EFLAGS_RF;
#endif
 
dr6 = read_dr6();
for (i=0; i < BKPOINTS_MAX; i++) {
if (dr6 & (1 << i)) {
dr6 &= ~ (1 << i);
write_dr6(dr6);
handle_exception(i, istate);
}
}
}
 
#ifdef CONFIG_SMP
static void debug_ipi(int n, istate_t *istate)
{
int i;
 
spinlock_lock(&bkpoint_lock);
for (i=0; i < BKPOINTS_MAX; i++)
setup_dr(i);
spinlock_unlock(&bkpoint_lock);
}
#endif
 
/** Initialize debugger */
void debugger_init()
{
int i;
 
for (i=0; i<BKPOINTS_MAX; i++)
breakpoints[i].address = NULL;
cmd_initialize(&bkpts_info);
if (!cmd_register(&bkpts_info))
panic("could not register command %s\n", bkpts_info.name);
 
#ifndef CONFIG_DEBUG_AS_WATCHPOINT
cmd_initialize(&delbkpt_info);
if (!cmd_register(&delbkpt_info))
panic("could not register command %s\n", delbkpt_info.name);
 
cmd_initialize(&addbkpt_info);
if (!cmd_register(&addbkpt_info))
panic("could not register command %s\n", addbkpt_info.name);
 
cmd_initialize(&addwatchp_info);
if (!cmd_register(&addwatchp_info))
panic("could not register command %s\n", addwatchp_info.name);
#endif
exc_register(VECTOR_DEBUG, "debugger",
debug_exception);
#ifdef CONFIG_SMP
exc_register(VECTOR_DEBUG_IPI, "debugger_smp",
debug_ipi);
#endif
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/src/interrupt.c
0,0 → 1,187
/*
* 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 amd64interrupt
* @{
*/
/** @file
*/
 
#include <arch/interrupt.h>
#include <print.h>
#include <debug.h>
#include <panic.h>
#include <arch/drivers/i8259.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 <arch/asm.h>
#include <proc/scheduler.h>
#include <proc/thread.h>
#include <proc/task.h>
#include <synch/spinlock.h>
#include <arch/ddi/ddi.h>
#include <interrupt.h>
#include <ipc/irq.h>
 
void print_info_errcode(int n, istate_t *istate)
{
char *symbol;
/* uint64_t *x = &istate->stack[0]; */
 
if (!(symbol=get_symtab_entry(istate->rip)))
symbol = "";
 
printf("-----EXCEPTION(%d) OCCURED----- ( %s )\n",n, __FUNCTION__);
printf("%%rip: %#llx (%s)\n",istate->rip, symbol);
printf("ERROR_WORD=%#llx\n", istate->error_word);
printf("%%rcs=%#llx, flags=%#llx, %%cr0=%#llx\n", istate->cs, istate->rflags, read_cr0());
printf("%%rax=%#llx, %%rcx=%#llx, %%rdx=%#llx\n", istate->rax, istate->rcx, istate->rdx);
printf("%%rsi=%#llx, %%rdi=%#llx, %%r8 =%#llx\n", istate->rsi, istate->rdi, istate->r8);
printf("%%r9 =%#llx, %%r10 =%#llx, %%r11=%#llx\n", istate->r9, istate->r10, istate->r11);
#ifdef CONFIG_DEBUG_ALLREGS
printf("%%r12=%#llx, %%r13=%#llx, %%r14=%#llx\n", istate->r12, istate->r13, istate->r14);
printf("%%r15=%#llx, %%rbx=%#llx, %%rbp=%#llx\n", istate->r15, istate->rbx, &istate->rbp);
#endif
printf("%%rsp=%#llx\n", &istate->stack[0]);
}
 
/*
* 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 null_interrupt(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "unserviced interrupt: %d", n);
print_info_errcode(n, istate);
panic("unserviced interrupt\n");
}
 
/** General Protection Fault. */
void gp_fault(int n, istate_t *istate)
{
if (TASK) {
count_t ver;
 
spinlock_lock(&TASK->lock);
ver = TASK->arch.iomapver;
spinlock_unlock(&TASK->lock);
 
if (CPU->arch.iomapver_copy != ver) {
/*
* This fault can be caused by an early access
* to I/O port because of an out-dated
* I/O Permission bitmap installed on CPU.
* Install the fresh copy and restart
* the instruction.
*/
io_perm_bitmap_install();
return;
}
fault_if_from_uspace(istate, "general protection fault");
}
 
print_info_errcode(n, istate);
panic("general protection fault\n");
}
 
void ss_fault(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "stack fault");
print_info_errcode(n, istate);
panic("stack fault\n");
}
 
void nm_fault(int n, istate_t *istate)
{
#ifdef CONFIG_FPU_LAZY
scheduler_fpu_lazy_request();
#else
fault_if_from_uspace(istate, "fpu fault");
panic("fpu fault");
#endif
}
 
void tlb_shootdown_ipi(int n, istate_t *istate)
{
trap_virtual_eoi();
tlb_shootdown_ipi_recv();
}
 
void trap_virtual_enable_irqs(uint16_t irqmask)
{
if (enable_irqs_function)
enable_irqs_function(irqmask);
else
panic("no enable_irqs_function\n");
}
 
void trap_virtual_disable_irqs(uint16_t irqmask)
{
if (disable_irqs_function)
disable_irqs_function(irqmask);
else
panic("no disable_irqs_function\n");
}
 
void trap_virtual_eoi(void)
{
if (eoi_function)
eoi_function();
else
panic("no eoi_function\n");
 
}
 
static void ipc_int(int n, istate_t *istate)
{
ipc_irq_send_notif(n-IVT_IRQBASE);
trap_virtual_eoi();
}
 
 
/* Reregister irq to be IPC-ready */
void irq_ipc_bind_arch(unative_t irq)
{
if (irq == IRQ_CLK)
return;
exc_register(IVT_IRQBASE+irq, "ipc_int", ipc_int);
trap_virtual_enable_irqs(1 << irq);
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/src/fpu_context.c
0,0 → 1,68
/*
* Copyright (C) 2005 Jakub Vana
* 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 amd64
* @{
*/
/** @file
*
*/
 
#include <fpu_context.h>
#include <arch.h>
#include <cpu.h>
 
/** Save FPU (mmx, sse) context using fxsave instruction */
void fpu_context_save(fpu_context_t *fctx)
{
__asm__ volatile (
"fxsave %0"
: "=m"(*fctx)
);
}
 
/** Restore FPU (mmx,sse) context using fxrstor instruction */
void fpu_context_restore(fpu_context_t *fctx)
{
__asm__ volatile (
"fxrstor %0"
: "=m"(*fctx)
);
}
 
void fpu_init()
{
/* TODO: Zero all SSE, MMX etc. registers */
__asm__ volatile (
"fninit;"
);
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/src/userspace.c
0,0 → 1,82
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 amd64
* @{
*/
/** @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)
{
ipl_t ipl;
ipl = interrupts_disable();
 
/* Clear CF,PF,AF,ZF,SF,DF,OF */
ipl &= ~(0xcd4);
 
__asm__ volatile (""
"pushq %0\n"
"pushq %1\n"
"pushq %2\n"
"pushq %3\n"
"pushq %4\n"
"movq %5, %%rax\n"
"iretq\n"
: :
"i" (gdtselector(UDATA_DES) | PL_USER),
"r" (kernel_uarg->uspace_stack+THREAD_STACK_SIZE),
"r" (ipl),
"i" (gdtselector(UTEXT_DES) | PL_USER),
"r" (kernel_uarg->uspace_entry),
"r" (kernel_uarg->uspace_uarg)
: "rax"
);
/* Unreachable */
for(;;)
;
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/src/boot/boot.S
0,0 → 1,515
#
# Copyright (C) 2005 Ondrej Palkovsky
# Copyright (C) 2006 Martin Decky
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# - The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
#include <arch/boot/boot.h>
#include <arch/boot/memmap.h>
#include <arch/mm/page.h>
#include <arch/mm/ptl.h>
#include <arch/pm.h>
#include <arch/cpu.h>
#include <arch/cpuid.h>
 
#define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE)
.section K_TEXT_START, "ax"
 
.code32
.align 4
.global multiboot_image_start
multiboot_header:
.long MULTIBOOT_HEADER_MAGIC
.long MULTIBOOT_HEADER_FLAGS
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) # checksum
.long multiboot_header
.long unmapped_ktext_start
.long 0
.long 0
.long multiboot_image_start
 
multiboot_image_start:
movl $START_STACK, %esp # initialize stack pointer
lgdt bootstrap_gdtr # initialize Global Descriptor Table register
 
movw $gdtselector(KDATA_DES), %cx
movw %cx, %es
movw %cx, %ds # kernel data + stack
movw %cx, %ss
# Simics seems to remove hidden part of GS on entering user mode
# when _visible_ part of GS does not point to user-mode segment
movw $gdtselector(UDATA_DES), %cx
movw %cx, %fs
movw %cx, %gs
jmpl $gdtselector(KTEXT32_DES), $multiboot_meeting_point
multiboot_meeting_point:
movl %eax, grub_eax # save parameters from GRUB
movl %ebx, grub_ebx
#ifdef CONFIG_FB
mov $vesa_init, %esi;
mov $VESA_INIT_SEGMENT << 4, %edi
mov $e_vesa_init - vesa_init, %ecx
cld
rep movsb
 
mov $VESA_INIT_SEGMENT << 4, %edi
jmpl *%edi
vesa_meeting_point:
mov %esi, KA2PA(vesa_ph_addr)
mov %di, KA2PA(vesa_height)
shr $16, %edi
mov %di, KA2PA(vesa_width)
mov %bx, KA2PA(vesa_scanline)
shr $16, %ebx
mov %bx, KA2PA(vesa_bpp)
#endif
 
# Protected 32-bit. We want to reuse the code-seg descriptor,
# the Default operand size must not be 1 when entering long mode
movl $0x80000000, %eax
cpuid
cmp $0x80000000, %eax # any function > 80000000h?
jbe long_mode_unsupported
movl $(AMD_CPUID_EXTENDED), %eax # Extended function code 80000001
cpuid
bt $29, %edx # Test if long mode is supported.
jc long_mode_supported
 
long_mode_unsupported:
cli
hlt
long_mode_supported:
# Enable 64-bit page transaltion entries - CR4.PAE = 1.
# Paging is not enabled until after long mode is enabled
movl %cr4, %eax
btsl $5, %eax
movl %eax, %cr4
 
# Set up paging tables
leal ptl_0, %eax
movl %eax, %cr3
# Enable long mode
movl $EFER_MSR_NUM, %ecx # EFER MSR number
rdmsr # Read EFER
btsl $AMD_LME_FLAG, %eax # Set LME=1
wrmsr # Write EFER
# Enable paging to activate long mode (set CR0.PG=1)
movl %cr0, %eax
btsl $31, %eax
movl %eax, %cr0
# At this point we are in compatibility mode
jmpl $gdtselector(KTEXT_DES), $start64
 
.code64
start64:
movq $(PA2KA(START_STACK)), %rsp
movl grub_eax, %eax
movl grub_ebx, %ebx
cmpl $MULTIBOOT_LOADER_MAGIC, %eax # compare GRUB signature
je valid_boot
xorl %ecx, %ecx # no memory size or map available
movl %ecx, e801memorysize
movl %ecx, e820counter
jmp invalid_boot
valid_boot:
movl (%ebx), %eax # ebx = physical address of struct multiboot_info
bt $0, %eax # mbi->flags[0] (mem_lower, mem_upper valid)
jc mem_valid
xorl %ecx, %ecx
jmp mem_invalid
mem_valid:
movl 4(%ebx), %ecx # mbi->mem_lower
addl 8(%ebx), %ecx # mbi->mem_upper
mem_invalid:
movl %ecx, e801memorysize
bt $3, %eax # mbi->flags[3] (mods_count, mods_addr valid)
jc mods_valid
xorq %rcx, %rcx
movq %rcx, init
jmp mods_end
mods_valid:
xorq %rcx, %rcx
movl 20(%ebx), %ecx # mbi->mods_count
movq %rcx, init
cmpl $0, %ecx
je mods_end
movl 24(%ebx), %esi # mbi->mods_addr
movq $init, %rdi
mods_loop:
xorq %rdx, %rdx
movl 0(%esi), %edx # mods->mod_start
movq $0xffff800000000000, %r10
addq %r10, %rdx
movq %rdx, 8(%rdi)
xorq %rdx, %rdx
movl 4(%esi), %edx
subl 0(%esi), %edx # mods->mod_end - mods->mod_start
movq %rdx, 16(%rdi)
addl $16, %esi
addq $16, %rdi
loop mods_loop
mods_end:
bt $6, %eax # mbi->flags[6] (mmap_length, mmap_addr valid)
jc mmap_valid
xorl %edx, %edx
jmp mmap_invalid
mmap_valid:
movl 44(%ebx), %ecx # mbi->mmap_length
movl 48(%ebx), %esi # mbi->mmap_addr
movq $e820table, %rdi
xorl %edx, %edx
mmap_loop:
cmpl $0, %ecx
jle mmap_end
movl 4(%esi), %eax # mmap->base_addr_low
movl %eax, (%rdi)
movl 8(%esi), %eax # mmap->base_addr_high
movl %eax, 4(%rdi)
movl 12(%esi), %eax # mmap->length_low
movl %eax, 8(%rdi)
movl 16(%esi), %eax # mmap->length_high
movl %eax, 12(%rdi)
movl 20(%esi), %eax # mmap->type
movl %eax, 16(%rdi)
movl (%esi), %eax # mmap->size
addl $0x4, %eax
addl %eax, %esi
subl %eax, %ecx
addq $MEMMAP_E820_RECORD_SIZE, %rdi
incl %edx
jmp mmap_loop
mmap_end:
mmap_invalid:
movl %edx, e820counter
invalid_boot:
#ifdef CONFIG_SMP
# copy AP bootstrap routines below 1 MB
movq $BOOT_OFFSET, %rsi
movq $AP_BOOT_OFFSET, %rdi
movq $_hardcoded_unmapped_size, %rcx
cld
rep movsb
#endif
call main_bsp # never returns
cli
hlt
 
#ifdef CONFIG_FB
.code32
vesa_init:
jmp $gdtselector(VESA_INIT_DES), $vesa_init_real - vesa_init
.code16
vesa_init_real:
mov %cr0, %eax
and $~1, %eax
mov %eax, %cr0
jmp $VESA_INIT_SEGMENT, $vesa_init_real2 - vesa_init
vesa_init_real2:
mov $VESA_INIT_SEGMENT, %bx
mov %bx, %es
mov %bx, %fs
mov %bx, %gs
mov %bx, %ds
mov %bx, %ss
movl $0x0000fffc, %esp
movl $0x0000fffc, %ebp
#define VESA_INFO_SIZE 1024
 
#define VESA_MODE_LIST_PTR_OFFSET 14
#define VESA_MODE_WIDTH_OFFSET 18
#define VESA_MODE_HEIGHT_OFFSET 20
#define VESA_MODE_BPP_OFFSET 25
#define VESA_MODE_SCANLINE_OFFSET 16
#define VESA_MODE_PHADDR_OFFSET 40
 
#define VESA_END_OF_MODES 0xffff
 
#define VESA_OK 0x4f
 
#define VESA_GET_INFO 0x4f00
#define VESA_GET_MODE_INFO 0x4f01
#define VESA_SET_MODE 0x4f02
 
#define CONFIG_VESA_BPP_a 255
 
#if CONFIG_VESA_BPP == 24
#undef CONFIG_VESA_BPP_a
#define CONFIG_VESA_BPP_a 32
#endif
mov $VESA_GET_INFO, %ax
mov $e_vesa_init - vesa_init, %di
push %di
int $0x10
pop %di
cmp $VESA_OK, %al
jnz 0f
mov 2 + VESA_MODE_LIST_PTR_OFFSET(%di), %si
mov %si, %gs
mov VESA_MODE_LIST_PTR_OFFSET(%di), %si
add $VESA_INFO_SIZE, %di
1:# Try next mode
mov %gs:(%si), %cx
cmp $VESA_END_OF_MODES, %cx
jz 0f
inc %si
inc %si
push %cx
push %di
push %si
mov $VESA_GET_MODE_INFO, %ax
int $0x10
pop %si
pop %di
pop %cx
cmp $VESA_OK, %al
jnz 0f
mov $CONFIG_VESA_WIDTH, %ax
cmp VESA_MODE_WIDTH_OFFSET(%di), %ax
jnz 1b
mov $CONFIG_VESA_HEIGHT, %ax
cmp VESA_MODE_HEIGHT_OFFSET(%di), %ax
jnz 1b
mov $CONFIG_VESA_BPP, %al
cmp VESA_MODE_BPP_OFFSET(%di), %al
jz 2f
mov $CONFIG_VESA_BPP_a, %al
cmp VESA_MODE_BPP_OFFSET(%di), %al
jnz 1b
2:
mov %cx, %bx
or $0xc000, %bx
push %di
mov $VESA_SET_MODE, %ax
int $0x10
pop %di
cmp $VESA_OK, %al
jnz 0f
mov VESA_MODE_PHADDR_OFFSET(%di), %esi
mov VESA_MODE_WIDTH_OFFSET(%di), %ax
shl $16, %eax
mov VESA_MODE_HEIGHT_OFFSET(%di), %ax
mov VESA_MODE_BPP_OFFSET(%di), %bl
xor %bh, %bh
shl $16, %ebx
mov VESA_MODE_SCANLINE_OFFSET(%di), %bx
mov %eax, %edi
8:
mov %cr0, %eax
or $1, %eax
mov %eax, %cr0
jmp 9f
9:
ljmpl $gdtselector(KTEXT32_DES), $(vesa_init_protect - vesa_init + VESA_INIT_SEGMENT << 4)
0:# No prefered mode found
mov $0x111, %cx
push %di
push %cx
mov $VESA_GET_MODE_INFO, %ax
int $0x10
pop %cx
pop %di
cmp $VESA_OK, %al
jnz 1f
jz 2b # Force relative jump
 
1:
mov $0x0003, %ax
int $0x10
mov $0xffffffff, %edi # EGA text mode used, because of problems with VESA
xor %ax, %ax
jz 8b # Force relative jump
.code32
vesa_init_protect:
movw $gdtselector(KDATA_DES), %cx
movw %cx, %es
movw %cx, %ds # kernel data + stack
movw %cx, %ss
# Simics seems to remove hidden part of GS on entering user mode
# when _visible_ part of GS does not point to user-mode segment
movw $gdtselector(UDATA_DES), %cx
movw %cx, %fs
movw %cx, %gs
jmpl $gdtselector(KTEXT32_DES), $vesa_meeting_point
.align 4
e_vesa_init:
#endif
.section K_DATA_START, "aw", @progbits
.align 4096
 
# Identical mapping of first 64MB and the same of -2GB -> 0
.global ptl_2
ptl_2:
.quad 0x0 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad 0x200000 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad 0x400000 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad 0x600000 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad 0x800000 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad 0xa00000 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad 0xc00000 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad 0xe00000 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad 0x1000000 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad 0x1200000 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad 0x1400000 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad 0x1600000 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad 0x1800000 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad 0x1a00000 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad 0x1c00000 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad 0x1e00000 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad 0x2000000 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad 0x2200000 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad 0x2400000 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad 0x2600000 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad 0x2800000 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad 0x2a00000 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad 0x2c00000 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad 0x2e00000 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad 0x3000000 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad 0x3200000 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad 0x3400000 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad 0x3600000 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad 0x3800000 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad 0x3a00000 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad 0x3c00000 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad 0x3e00000 | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.align 4096
.global ptl_1
ptl_1:
.quad ptl_2 + (PTL_WRITABLE | PTL_PRESENT)
.fill 509,8,0
.quad ptl_2 + (PTL_WRITABLE | PTL_PRESENT)
.fill 1,8,0
.align 4096
.global ptl_0
ptl_0:
.quad ptl_1 + (PTL_WRITABLE | PTL_PRESENT)
.fill 255,8,0
.quad ptl_1 + (PTL_WRITABLE | PTL_PRESENT)
.fill 254,8,0
.quad ptl_1 + (PTL_WRITABLE | PTL_PRESENT)
 
.global bootstrap_gdtr
bootstrap_gdtr:
.word gdtselector(GDT_ITEMS)
.long KA2PA(gdt)
 
grub_eax:
.long 0
 
grub_ebx:
.long 0
/tags/0.2.0.3/kernel/arch/amd64/src/asm_utils.S
0,0 → 1,303
#
# Copyright (C) 2005 Ondrej Palkovsky
# 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.
#
 
#define IREGISTER_SPACE 120
 
#define IOFFSET_RAX 0x0
#define IOFFSET_RBX 0x8
#define IOFFSET_RCX 0x10
#define IOFFSET_RDX 0x18
#define IOFFSET_RSI 0x20
#define IOFFSET_RDI 0x28
#define IOFFSET_R8 0x30
#define IOFFSET_R9 0x38
#define IOFFSET_R10 0x40
#define IOFFSET_R11 0x48
#define IOFFSET_R12 0x50
#define IOFFSET_R13 0x58
#define IOFFSET_R14 0x60
#define IOFFSET_R15 0x68
#define IOFFSET_RBP 0x70
 
# 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
 
#include <arch/pm.h>
#include <arch/mm/page.h>
.text
.global interrupt_handlers
.global syscall_entry
.global panic_printf
 
panic_printf:
movq $halt, (%rsp)
jmp printf
 
.global cpuid
.global has_cpuid
.global rdtsc
.global read_efer_flag
.global set_efer_flag
.global memcpy
.global memcpy_from_uspace
.global memcpy_to_uspace
.global memcpy_from_uspace_failover_address
.global memcpy_to_uspace_failover_address
 
#define MEMCPY_DST %rdi
#define MEMCPY_SRC %rsi
#define MEMCPY_SIZE %rdx
 
/**
* Copy memory from/to 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 Destination address.
* @param MEMCPY_SRC Source address.
* @param MEMCPY_SIZE Number of bytes to copy.
*
* @retrun MEMCPY_SRC on success, 0 on failure.
*/
memcpy:
memcpy_from_uspace:
memcpy_to_uspace:
movq MEMCPY_SRC, %rax
 
movq MEMCPY_SIZE, %rcx
shrq $3, %rcx /* size / 8 */
rep movsq /* copy as much as possible word by word */
 
movq MEMCPY_SIZE, %rcx
andq $7, %rcx /* size % 8 */
jz 0f
rep movsb /* copy the rest byte by byte */
0:
ret /* return MEMCPY_SRC, success */
 
memcpy_from_uspace_failover_address:
memcpy_to_uspace_failover_address:
xorq %rax, %rax /* return 0, failure */
ret
 
## Determine CPUID support
#
# Return 0 in EAX if CPUID is not support, 1 if supported.
#
has_cpuid:
pushfq # store flags
popq %rax # read flags
movq %rax,%rdx # copy flags
btcl $21,%edx # swap the ID bit
pushq %rdx
popfq # propagate the change into flags
pushfq
popq %rdx # read flags
andl $(1<<21),%eax # interested only in ID bit
andl $(1<<21),%edx
xorl %edx,%eax # 0 if not supported, 1 if supported
ret
 
cpuid:
movq %rbx, %r10 # we have to preserve rbx across function calls
 
movl %edi,%eax # load the command into %eax
 
cpuid
movl %eax,0(%rsi)
movl %ebx,4(%rsi)
movl %ecx,8(%rsi)
movl %edx,12(%rsi)
 
movq %r10, %rbx
ret
 
rdtsc:
xorq %rax,%rax
rdtsc
ret
 
set_efer_flag:
movq $0xc0000080, %rcx
rdmsr
btsl %edi, %eax
wrmsr
ret
read_efer_flag:
movq $0xc0000080, %rcx
rdmsr
ret
 
# Push all general purpose registers on stack except %rbp, %rsp
.macro save_all_gpr
movq %rax, IOFFSET_RAX(%rsp)
movq %rcx, IOFFSET_RCX(%rsp)
movq %rdx, IOFFSET_RDX(%rsp)
movq %rsi, IOFFSET_RSI(%rsp)
movq %rdi, IOFFSET_RDI(%rsp)
movq %r8, IOFFSET_R8(%rsp)
movq %r9, IOFFSET_R9(%rsp)
movq %r10, IOFFSET_R10(%rsp)
movq %r11, IOFFSET_R11(%rsp)
#ifdef CONFIG_DEBUG_ALLREGS
movq %rbx, IOFFSET_RBX(%rsp)
movq %rbp, IOFFSET_RBP(%rsp)
movq %r12, IOFFSET_R12(%rsp)
movq %r13, IOFFSET_R13(%rsp)
movq %r14, IOFFSET_R14(%rsp)
movq %r15, IOFFSET_R15(%rsp)
#endif
.endm
 
.macro restore_all_gpr
movq IOFFSET_RAX(%rsp), %rax
movq IOFFSET_RCX(%rsp), %rcx
movq IOFFSET_RDX(%rsp), %rdx
movq IOFFSET_RSI(%rsp), %rsi
movq IOFFSET_RDI(%rsp), %rdi
movq IOFFSET_R8(%rsp), %r8
movq IOFFSET_R9(%rsp), %r9
movq IOFFSET_R10(%rsp), %r10
movq IOFFSET_R11(%rsp), %r11
#ifdef CONFIG_DEBUG_ALLREGS
movq IOFFSET_RBX(%rsp), %rbx
movq IOFFSET_RBP(%rsp), %rbp
movq IOFFSET_R12(%rsp), %r12
movq IOFFSET_R13(%rsp), %r13
movq IOFFSET_R14(%rsp), %r14
movq IOFFSET_R15(%rsp), %r15
#endif
.endm
 
#ifdef CONFIG_DEBUG_ALLREGS
# define INTERRUPT_ALIGN 256
#else
# define INTERRUPT_ALIGN 128
#endif
## Declare interrupt handlers
#
# Declare interrupt handlers for n interrupt
# vectors starting at vector i.
#
# The handlers call exc_dispatch().
#
.macro handler i n
 
/*
* Choose between version with error code and version without error code.
* Both versions have to be of the same size. amd64 assembly is, however,
* a little bit tricky. For instance, subq $0x80, %rsp and subq $0x78, %rsp
* can result in two instructions with different op-code lengths.
* Therefore we align the interrupt handlers.
*/
 
.iflt \i-32
.if (1 << \i) & ERROR_WORD_INTERRUPT_LIST
/*
* Version with error word.
*/
subq $IREGISTER_SPACE, %rsp
.else
/*
* Version without error word,
*/
subq $(IREGISTER_SPACE+8), %rsp
.endif
.else
/*
* Version without error word,
*/
subq $(IREGISTER_SPACE+8), %rsp
.endif
 
save_all_gpr
 
movq $(\i), %rdi # %rdi - first parameter
movq %rsp, %rsi # %rsi - pointer to istate
call exc_dispatch # exc_dispatch(i, istate)
restore_all_gpr
# $8 = Skip error word
addq $(IREGISTER_SPACE+8), %rsp
iretq
 
.align INTERRUPT_ALIGN
.if (\n-\i)-1
handler "(\i+1)",\n
.endif
.endm
 
.align INTERRUPT_ALIGN
interrupt_handlers:
h_start:
handler 0 IDT_ITEMS
h_end:
 
syscall_entry:
# Switch to hidden gs
swapgs
# %gs:0 now points to pointer to stack page
mov %gs:0, %r10 # We have a ptr to stack page in r10
addq $PAGE_SIZE-16, %r10 # We need some space to store old %sp
movq %rsp, 0(%r10) # Save old stack pointer to stack
movq %r10, %rsp # Change to new stack
pushq %rcx # Return address
pushq %r11 # Save flags
 
# Switch back to remain consistent
swapgs
 
sti
movq %r9, %rcx # Exchange last parameter as a third
call syscall_handler
cli # We will be touching stack pointer
popq %r11
popq %rcx
movq 0(%rsp), %rsp
sysretq
.data
.global interrupt_handler_size
 
interrupt_handler_size: .quad (h_end-h_start)/IDT_ITEMS
/tags/0.2.0.3/kernel/arch/amd64/src/smp/ap.S
0,0 → 1,115
#
# Copyright (C) 2001-2004 Jakub Jermar
# Copyright (C) 2005-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.
#
 
#
# Init code for application processors.
#
 
#include <arch/boot/boot.h>
#include <arch/boot/memmap.h>
#include <arch/mm/page.h>
#include <arch/pm.h>
#include <arch/cpu.h>
#include <arch/cpuid.h>
 
.section K_TEXT_START, "ax"
 
#ifdef CONFIG_SMP
 
.global unmapped_ap_boot
 
# This piece of code is real-mode and is meant to be alligned at 4K boundary.
# The requirement for such an alignment comes from MP Specification's STARTUP IPI
# requirements.
 
.align 4096
unmapped_ap_boot:
.code16
cli
xorw %ax, %ax
movw %ax, %ds
 
lgdtl ap_gdtr # initialize Global Descriptor Table register
movl %cr0, %eax
orl $1, %eax
movl %eax, %cr0 # switch to protected mode
jmpl $gdtselector(KTEXT32_DES), $jump_to_kernel - BOOT_OFFSET + AP_BOOT_OFFSET
jump_to_kernel:
.code32
movw $gdtselector(KDATA_DES), %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
movw $gdtselector(UDATA_DES), %ax
movw %ax, %gs
# Enable 64-bit page transaltion entries - CR4.PAE = 1.
# Paging is not enabled until after long mode is enabled
movl %cr4, %eax
btsl $5, %eax
movl %eax, %cr4
 
leal ptl_0, %eax
movl %eax, %cr3
# Enable long mode
movl $EFER_MSR_NUM, %ecx # EFER MSR number
rdmsr # Read EFER
btsl $AMD_LME_FLAG, %eax # Set LME=1
wrmsr # Write EFER
# Enable paging to activate long mode (set CR0.PG=1)
movl %cr0, %eax
btsl $31, %eax
movl %eax, %cr0
# At this point we are in compatibility mode
jmpl $gdtselector(KTEXT_DES), $start64 - BOOT_OFFSET + AP_BOOT_OFFSET
 
.code64
start64:
movq (ctx), %rsp
call main_ap - AP_BOOT_OFFSET + BOOT_OFFSET # never returns
 
#endif /* CONFIG_SMP */
 
.section K_DATA_START, "aw", @progbits
 
#ifdef CONFIG_SMP
 
.global unmapped_ap_gdtr
 
unmapped_ap_gdtr:
.word 0
.long 0
 
#endif /* CONFIG_SMP */
/tags/0.2.0.3/kernel/arch/amd64/src/smp/mps.c
0,0 → 1,0
link ../../../ia32/src/smp/mps.c
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/amd64/src/smp/smp.c
0,0 → 1,0
link ../../../ia32/src/smp/smp.c
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/amd64/src/smp/ipi.c
0,0 → 1,0
link ../../../ia32/src/smp/ipi.c
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/amd64/src/smp/apic.c
0,0 → 1,0
link ../../../ia32/src/smp/apic.c
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/amd64/src/bios
0,0 → 1,0
link ../../ia32/src/bios
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/amd64/src/drivers
0,0 → 1,0
link ../../ia32/src/drivers
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/amd64/src/context.S
0,0 → 1,78
#
# 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.
#
 
.text
 
.global context_save_arch
.global context_restore_arch
 
#include <arch/context_offset.h>
 
## Save current CPU context
#
# Save CPU context to context_t variable
# pointed by the 1st argument. Returns 1 in EAX.
#
context_save_arch:
movq (%rsp), %rdx # the caller's return %eip
# In %edi is passed 1st argument
movq %rdx, OFFSET_PC(%rdi)
movq %rsp, OFFSET_SP(%rdi)
movq %rbx, OFFSET_RBX(%rdi)
movq %rbp, OFFSET_RBP(%rdi)
movq %r12, OFFSET_R12(%rdi)
movq %r13, OFFSET_R13(%rdi)
movq %r14, OFFSET_R14(%rdi)
movq %r15, OFFSET_R15(%rdi)
xorq %rax,%rax # context_save returns 1
incq %rax
ret
 
 
## Restore current CPU context
#
# Restore CPU context from context_t variable
# pointed by the 1st argument. Returns 0 in EAX.
#
context_restore_arch:
movq OFFSET_R15(%rdi), %r15
movq OFFSET_R14(%rdi), %r14
movq OFFSET_R13(%rdi), %r13
movq OFFSET_R12(%rdi), %r12
movq OFFSET_RBP(%rdi), %rbp
movq OFFSET_RBX(%rdi), %rbx
movq OFFSET_SP(%rdi), %rsp # ctx->sp -> %rsp
movq OFFSET_PC(%rdi), %rdx
movq %rdx,(%rsp)
 
xorq %rax,%rax # context_restore returns 0
ret
/tags/0.2.0.3/kernel/arch/amd64/src/delay.S
0,0 → 1,46
#
# 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.
#
 
#
# Micro second delay loop functions.
#
 
.text
 
.global asm_delay_loop
.global asm_fake_loop
 
asm_delay_loop:
0: dec %rdi
jnz 0b
ret
 
asm_fake_loop:
0: dec %rdi
jz 0b
ret
/tags/0.2.0.3/kernel/arch/amd64/include/pm.h
0,0 → 1,199
/*
* 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 amd64
* @{
*/
/** @file
*/
 
#ifndef __amd64_PM_H__
#define __amd64_PM_H__
 
#ifndef __ASM__
# include <arch/types.h>
# include <typedefs.h>
# include <arch/context.h>
#endif
 
#define IDT_ITEMS 64
#define GDT_ITEMS 8
 
 
#define NULL_DES 0
/* Warning: Do not reorder next items, unless you look into syscall.c!!! */
#define KTEXT_DES 1
#define KDATA_DES 2
#define UDATA_DES 3
#define UTEXT_DES 4
#define KTEXT32_DES 5
/* EndOfWarning */
#define TSS_DES 6
 
 
 
#ifdef CONFIG_FB
 
#define VESA_INIT_DES 8
#define VESA_INIT_SEGMENT 0x8000
#undef GDT_ITEMS
#define GDT_ITEMS 9
 
#endif /*CONFIG_FB*/
 
 
 
#define gdtselector(des) ((des) << 3)
#define idtselector(des) ((des) << 4)
 
#define PL_KERNEL 0
#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_READABLE (1<<1)
#define AR_TSS (0x9)
#define AR_INTERRUPT (0xe)
#define AR_TRAP (0xf)
 
#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__
 
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 longmode: 1;
unsigned special: 1;
unsigned granularity : 1;
unsigned base_24_31: 8;
} __attribute__ ((packed));
typedef struct descriptor descriptor_t;
 
struct tss_descriptor {
unsigned limit_0_15: 16;
unsigned base_0_15: 16;
unsigned base_16_23: 8;
unsigned type: 4;
unsigned : 1;
unsigned dpl : 2;
unsigned present : 1;
unsigned limit_16_19: 4;
unsigned available: 1;
unsigned : 2;
unsigned granularity : 1;
unsigned base_24_31: 8;
unsigned base_32_63 : 32;
unsigned : 32;
} __attribute__ ((packed));
typedef struct tss_descriptor tss_descriptor_t;
 
struct idescriptor {
unsigned offset_0_15: 16;
unsigned selector: 16;
unsigned ist:3;
unsigned unused: 5;
unsigned type: 5;
unsigned dpl: 2;
unsigned present : 1;
unsigned offset_16_31: 16;
unsigned offset_32_63: 32;
unsigned : 32;
} __attribute__ ((packed));
typedef struct idescriptor idescriptor_t;
 
struct ptr_16_64 {
uint16_t limit;
uint64_t base;
} __attribute__ ((packed));
typedef struct ptr_16_64 ptr_16_64_t;
 
struct ptr_16_32 {
uint16_t limit;
uint32_t base;
} __attribute__ ((packed));
typedef struct ptr_16_32 ptr_16_32_t;
 
struct tss {
uint32_t reserve1;
uint64_t rsp0;
uint64_t rsp1;
uint64_t rsp2;
uint64_t reserve2;
uint64_t ist1;
uint64_t ist2;
uint64_t ist3;
uint64_t ist4;
uint64_t ist5;
uint64_t ist6;
uint64_t ist7;
uint64_t reserve3;
uint16_t reserve4;
uint16_t iomap_base;
uint8_t iomap[TSS_IOMAP_SIZE];
} __attribute__ ((packed));
typedef struct tss tss_t;
 
extern tss_t *tss_p;
 
extern descriptor_t gdt[];
extern idescriptor_t idt[];
 
extern ptr_16_64_t gdtr;
extern ptr_16_32_t bootstrap_gdtr;
extern ptr_16_32_t protected_ap_gdtr;
 
extern void pm_init(void);
 
extern void gdt_tss_setbase(descriptor_t *d, uintptr_t base);
extern void gdt_tss_setlimit(descriptor_t *d, uint32_t limit);
 
extern void idt_init(void);
extern void idt_setoffset(idescriptor_t *d, uintptr_t offset);
 
extern void tss_initialize(tss_t *t);
 
#endif /* __ASM__ */
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/include/boot/boot.h
0,0 → 1,50
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 amd64
* @{
*/
/** @file
*/
 
#ifndef __amd64_BOOT_H__
#define __amd64_BOOT_H__
 
#define BOOT_OFFSET 0x108000
#define AP_BOOT_OFFSET 0x8000
#define BOOT_STACK_SIZE 0x400
 
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
#define MULTIBOOT_HEADER_FLAGS 0x00010003
 
#define MULTIBOOT_LOADER_MAGIC 0x2BADB002
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/amd64/include/boot/memmap.h
0,0 → 1,0
link ../../../ia32/include/boot/memmap.h
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/amd64/include/interrupt.h
0,0 → 1,133
/*
* 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 amd64interrupt
* @{
*/
/** @file
*/
 
#ifndef __ia32_INTERRUPT_H__
#define __ia32_INTERRUPT_H__
 
#include <arch/types.h>
#include <arch/pm.h>
 
#define IVT_ITEMS IDT_ITEMS
 
#define EXC_COUNT 32
#define IRQ_COUNT 16
 
#define IVT_EXCBASE 0
#define IVT_IRQBASE (IVT_EXCBASE+EXC_COUNT)
#define IVT_FREEBASE (IVT_IRQBASE+IRQ_COUNT)
 
#define IRQ_CLK 0
#define IRQ_KBD 1
#define IRQ_PIC1 2
#define IRQ_PIC_SPUR 7
 
/* this one must have four least significant bits set to ones */
#define VECTOR_APIC_SPUR (IVT_ITEMS-1)
 
#if (((VECTOR_APIC_SPUR + 1)%16) || VECTOR_APIC_SPUR >= IVT_ITEMS)
#error Wrong definition of VECTOR_APIC_SPUR
#endif
 
#define VECTOR_DEBUG 1
#define VECTOR_PIC_SPUR (IVT_IRQBASE+IRQ_PIC_SPUR)
#define VECTOR_CLK (IVT_IRQBASE+IRQ_CLK)
#define VECTOR_KBD (IVT_IRQBASE+IRQ_KBD)
 
#define VECTOR_TLB_SHOOTDOWN_IPI (IVT_FREEBASE+0)
#define VECTOR_WAKEUP_IPI (IVT_FREEBASE+1)
#define VECTOR_DEBUG_IPI (IVT_FREEBASE+2)
 
/** This is passed to interrupt handlers */
struct istate {
uint64_t rax;
uint64_t rbx;
uint64_t rcx;
uint64_t rdx;
uint64_t rsi;
uint64_t rdi;
uint64_t r8;
uint64_t r9;
uint64_t r10;
uint64_t r11;
uint64_t r12;
uint64_t r13;
uint64_t r14;
uint64_t r15;
uint64_t rbp;
uint64_t error_word;
uint64_t rip;
uint64_t cs;
uint64_t rflags;
uint64_t stack[]; /* Additional data on stack */
};
 
/** Return true if exception happened while in userspace */
static inline int istate_from_uspace(istate_t *istate)
{
return !(istate->rip & 0x8000000000000000);
}
 
static inline void istate_set_retaddr(istate_t *istate, uintptr_t retaddr)
{
istate->rip = retaddr;
}
static inline unative_t istate_get_pc(istate_t *istate)
{
return istate->rip;
}
 
extern void (* disable_irqs_function)(uint16_t irqmask);
extern void (* enable_irqs_function)(uint16_t irqmask);
extern void (* eoi_function)(void);
 
extern void print_info_errcode(int n, istate_t *istate);
extern void null_interrupt(int n, istate_t *istate);
extern void gp_fault(int n, istate_t *istate);
extern void nm_fault(int n, istate_t *istate);
extern void ss_fault(int n, istate_t *istate);
extern void page_fault(int n, istate_t *istate);
extern void syscall(int n, istate_t *istate);
extern void tlb_shootdown_ipi(int n, istate_t *istate);
 
extern void trap_virtual_enable_irqs(uint16_t irqmask);
extern void trap_virtual_disable_irqs(uint16_t irqmask);
extern void trap_virtual_eoi(void);
/* AMD64 - specific page handler */
extern void ident_page_fault(int n, istate_t *istate);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/include/byteorder.h
0,0 → 1,46
/*
* 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 amd64
* @{
*/
/** @file
*/
 
#ifndef __amd64_BYTEORDER_H__
#define __amd64_BYTEORDER_H__
 
/* AMD64 is little-endian */
#define unative_t_le2host(n) (n)
#define uint64_t_le2host(n) (n)
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/include/cpuid.h
0,0 → 1,67
/*
* Copyright (C) 2001-2004 Ondrej Palkovsky
* 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 amd64
* @{
*/
/** @file
*/
 
#ifndef __amd64_CPUID_H__
#define __amd64_CPUID_H__
 
#define AMD_CPUID_EXTENDED 0x80000001
#define AMD_EXT_NOEXECUTE 20
 
#define INTEL_CPUID_STANDARD 0x1
#define INTEL_SSE2 26
#define INTEL_FXSAVE 24
 
#ifndef __ASM__
 
#include <arch/types.h>
 
struct cpu_info {
uint32_t cpuid_eax;
uint32_t cpuid_ebx;
uint32_t cpuid_ecx;
uint32_t cpuid_edx;
} __attribute__ ((packed));
 
extern int has_cpuid(void);
 
extern void cpuid(uint32_t cmd, cpu_info_t *info);
 
 
extern uint64_t rdtsc(void);
 
#endif /* __ASM__ */
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/amd64/include/types.h
0,0 → 1,64
/*
* 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 amd64
* @{
*/
/** @file
*/
 
#ifndef __amd64_TYPES_H__
#define __amd64_TYPES_H__
 
#define NULL 0
 
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef signed long long int64_t;
 
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
 
typedef uint64_t uintptr_t;
typedef uint64_t pfn_t;
 
/* Flags of processor (return value of interrupts_disable()) */
typedef uint64_t ipl_t;
 
typedef uint64_t unative_t;
typedef int64_t native_t;
 
typedef struct page_specifier pte_t;
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/amd64/include/memstr.h
0,0 → 1,146
/*
* Copyright (C) 2005 Sergey Bondari
* 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 amd64
* @{
*/
/** @file
*/
 
#ifndef __amd64_MEMSTR_H__
#define __amd64_MEMSTR_H__
 
/** Copy memory
*
* Copy a given number of bytes (3rd argument)
* from the memory location defined by 2nd argument
* to the memory location defined by 1st argument.
* The memory areas cannot overlap.
*
* @param dst Destination
* @param src Source
* @param cnt Number of bytes
* @return Destination
*/
static inline void * memcpy(void * dst, const void * src, size_t cnt)
{
unative_t d0, d1, d2;
 
__asm__ __volatile__(
"rep movsq\n\t"
"movq %4, %%rcx\n\t"
"andq $7, %%rcx\n\t"
"jz 1f\n\t"
"rep movsb\n\t"
"1:\n"
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
: "0" ((unative_t)(cnt / 8)), "g" ((unative_t)cnt), "1" ((unative_t) dst), "2" ((unative_t) src)
: "memory");
 
return dst;
}
 
 
/** Compare memory regions for equality
*
* Compare a given number of bytes (3rd argument)
* at memory locations defined by 1st and 2nd argument
* for equality. If bytes are equal function returns 0.
*
* @param src Region 1
* @param dst Region 2
* @param cnt Number of bytes
* @return Zero if bytes are equal, non-zero otherwise
*/
static inline int memcmp(const void * src, const void * dst, size_t cnt)
{
unative_t d0, d1, d2;
unative_t ret;
__asm__ (
"repe cmpsb\n\t"
"je 1f\n\t"
"movq %3, %0\n\t"
"addq $1, %0\n\t"
"1:\n"
: "=a" (ret), "=%S" (d0), "=&D" (d1), "=&c" (d2)
: "0" (0), "1" (src), "2" (dst), "3" ((unative_t)cnt)
);
return ret;
}
 
/** Fill memory with words
* Fill a given number of words (2nd argument)
* at memory defined by 1st argument with the
* word value defined by 3rd argument.
*
* @param dst Destination
* @param cnt Number of words
* @param x Value to fill
*/
static inline void memsetw(uintptr_t dst, size_t cnt, uint16_t x)
{
unative_t d0, d1;
__asm__ __volatile__ (
"rep stosw\n\t"
: "=&D" (d0), "=&c" (d1), "=a" (x)
: "0" (dst), "1" ((unative_t)cnt), "2" (x)
: "memory"
);
 
}
 
/** Fill memory with bytes
* Fill a given number of bytes (2nd argument)
* at memory defined by 1st argument with the
* word value defined by 3rd argument.
*
* @param dst Destination
* @param cnt Number of bytes
* @param x Value to fill
*/
static inline void memsetb(uintptr_t dst, size_t cnt, uint8_t x)
{
unative_t d0, d1;
__asm__ __volatile__ (
"rep stosb\n\t"
: "=&D" (d0), "=&c" (d1), "=a" (x)
: "0" (dst), "1" ((unative_t)cnt), "2" (x)
: "memory"
);
 
}
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/include/atomic.h
0,0 → 1,130
/*
* 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 amd64
* @{
*/
/** @file
*/
 
#ifndef __amd64_ATOMIC_H__
#define __amd64_ATOMIC_H__
 
#include <arch/types.h>
#include <arch/barrier.h>
#include <preemption.h>
#include <typedefs.h>
 
static inline void atomic_inc(atomic_t *val) {
#ifdef CONFIG_SMP
__asm__ volatile ("lock incq %0\n" : "=m" (val->count));
#else
__asm__ volatile ("incq %0\n" : "=m" (val->count));
#endif /* CONFIG_SMP */
}
 
static inline void atomic_dec(atomic_t *val) {
#ifdef CONFIG_SMP
__asm__ volatile ("lock decq %0\n" : "=m" (val->count));
#else
__asm__ volatile ("decq %0\n" : "=m" (val->count));
#endif /* CONFIG_SMP */
}
 
static inline long atomic_postinc(atomic_t *val)
{
long r = 1;
 
__asm__ volatile (
"lock xaddq %1, %0\n"
: "=m" (val->count), "+r" (r)
);
 
return r;
}
 
static inline long atomic_postdec(atomic_t *val)
{
long r = -1;
__asm__ volatile (
"lock xaddq %1, %0\n"
: "=m" (val->count), "+r" (r)
);
return r;
}
 
#define atomic_preinc(val) (atomic_postinc(val)+1)
#define atomic_predec(val) (atomic_postdec(val)-1)
 
static inline uint64_t test_and_set(atomic_t *val) {
uint64_t v;
__asm__ volatile (
"movq $1, %0\n"
"xchgq %0, %1\n"
: "=r" (v),"=m" (val->count)
);
return v;
}
 
 
/** amd64 specific fast spinlock */
static inline void atomic_lock_arch(atomic_t *val)
{
uint64_t tmp;
 
preemption_disable();
__asm__ volatile (
"0:;"
#ifdef CONFIG_HT
"pause;"
#endif
"mov %0, %1;"
"testq %1, %1;"
"jnz 0b;" /* Lightweight looping on locked spinlock */
"incq %1;" /* now use the atomic operation */
"xchgq %0, %1;"
"testq %1, %1;"
"jnz 0b;"
: "=m"(val->count),"=r"(tmp)
);
/*
* Prevent critical section code from bleeding out this way up.
*/
CS_ENTER_BARRIER();
}
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/include/proc/thread.h
0,0 → 1,48
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 amd64proc
* @{
*/
/** @file
*/
 
#ifndef __amd64_THREAD_H__
#define __amd64_THREAD_H__
 
#include <arch/types.h>
 
typedef struct {
unative_t tls;
} thread_arch_t;
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/include/proc/task.h
0,0 → 1,51
/*
* 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 amd64proc
* @{
*/
/** @file
*/
 
#ifndef __amd64_TASK_H__
#define __amd64_TASK_H__
 
#include <typedefs.h>
#include <arch/types.h>
#include <adt/bitmap.h>
 
typedef struct {
count_t iomapver; /**< I/O Permission bitmap Generation counter. */
bitmap_t iomap; /**< I/O Permission bitmap. */
} task_arch_t;
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/include/asm.h
0,0 → 1,285
/*
* 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 amd64
* @{
*/
/** @file
*/
 
#ifndef __amd64_ASM_H__
#define __amd64_ASM_H__
 
#include <arch/pm.h>
#include <arch/types.h>
#include <config.h>
 
extern void asm_delay_loop(uint32_t t);
extern void asm_fake_loop(uint32_t t);
 
/** 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 ("andq %%rsp, %0\n" : "=r" (v) : "0" (~((uint64_t)STACK_SIZE-1)));
return v;
}
 
static inline void cpu_sleep(void) { __asm__ volatile ("hlt\n"); };
static inline void cpu_halt(void) { __asm__ volatile ("hlt\n"); };
 
 
/** 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; }
 
/** 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) ); }
 
/** Swap Hidden part of GS register with visible one */
static inline void swapgs(void) { __asm__ volatile("swapgs"); }
 
/** Enable interrupts.
*
* Enable interrupts and return previous
* value of EFLAGS.
*
* @return Old interrupt priority level.
*/
static inline ipl_t interrupts_enable(void) {
ipl_t v;
__asm__ volatile (
"pushfq\n"
"popq %0\n"
"sti\n"
: "=r" (v)
);
return v;
}
 
/** Disable interrupts.
*
* Disable interrupts and return previous
* value of EFLAGS.
*
* @return Old interrupt priority level.
*/
static inline ipl_t interrupts_disable(void) {
ipl_t v;
__asm__ volatile (
"pushfq\n"
"popq %0\n"
"cli\n"
: "=r" (v)
);
return v;
}
 
/** Restore interrupt priority level.
*
* Restore EFLAGS.
*
* @param ipl Saved interrupt priority level.
*/
static inline void interrupts_restore(ipl_t ipl) {
__asm__ volatile (
"pushq %0\n"
"popfq\n"
: : "r" (ipl)
);
}
 
/** Return interrupt priority level.
*
* Return EFLAFS.
*
* @return Current interrupt priority level.
*/
static inline ipl_t interrupts_read(void) {
ipl_t v;
__asm__ volatile (
"pushfq\n"
"popq %0\n"
: "=r" (v)
);
return v;
}
 
/** Write to MSR */
static inline void write_msr(uint32_t msr, uint64_t value)
{
__asm__ volatile (
"wrmsr;" : : "c" (msr),
"a" ((uint32_t)(value)),
"d" ((uint32_t)(value >> 32))
);
}
 
static inline unative_t read_msr(uint32_t msr)
{
uint32_t ax, dx;
 
__asm__ volatile (
"rdmsr;" : "=a"(ax), "=d"(dx) : "c" (msr)
);
return ((uint64_t)dx << 32) | ax;
}
 
 
/** Enable local APIC
*
* Enable local APIC in MSR.
*/
static inline void enable_l_apic_in_msr()
{
__asm__ volatile (
"movl $0x1b, %%ecx\n"
"rdmsr\n"
"orl $(1<<11),%%eax\n"
"orl $(0xfee00000),%%eax\n"
"wrmsr\n"
:
:
:"%eax","%ecx","%edx"
);
}
 
static inline uintptr_t * get_ip()
{
uintptr_t *ip;
 
__asm__ volatile (
"mov %%rip, %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(struct ptr_16_64 *gdtr_reg)
{
__asm__ volatile ("lgdtq %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(struct ptr_16_64 *gdtr_reg)
{
__asm__ volatile ("sgdtq %0\n" : : "m" (*gdtr_reg));
}
 
/** Load IDTR register from memory.
*
* @param idtr_reg Address of memory from where to load IDTR.
*/
static inline void idtr_load(struct ptr_16_64 *idtr_reg)
{
__asm__ volatile ("lidtq %0\n" : : "m" (*idtr_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));
}
 
#define GEN_READ_REG(reg) static inline unative_t read_ ##reg (void) \
{ \
unative_t res; \
__asm__ volatile ("movq %%" #reg ", %0" : "=r" (res) ); \
return res; \
}
 
#define GEN_WRITE_REG(reg) static inline void write_ ##reg (unative_t regn) \
{ \
__asm__ volatile ("movq %0, %%" #reg : : "r" (regn)); \
}
 
GEN_READ_REG(cr0);
GEN_READ_REG(cr2);
GEN_READ_REG(cr3);
GEN_WRITE_REG(cr3);
 
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);
 
 
extern size_t interrupt_handler_size;
extern void interrupt_handlers(void);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/include/faddr.h
0,0 → 1,45
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 amd64
* @{
*/
/** @file
*/
 
#ifndef __amd64_FADDR_H__
#define __amd64_FADDR_H__
 
#include <arch/types.h>
 
#define FADDR(fptr) ((uintptr_t) (fptr))
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/amd64/include/mm/frame.h
0,0 → 1,55
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 amd64mm
* @{
*/
/** @file
*/
 
#ifndef __amd64_FRAME_H__
#define __amd64_FRAME_H__
 
#ifndef __ASM__
#include <arch/types.h>
#endif /* __ASM__ */
 
#define FRAME_WIDTH 12 /* 4K */
#define FRAME_SIZE (1<<FRAME_WIDTH)
 
 
#ifndef __ASM__
extern uintptr_t last_frame;
extern void frame_arch_init(void);
#endif /* __ASM__ */
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/include/mm/page.h
0,0 → 1,201
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 amd64mm
* @{
*/
/** @file
*/
 
/** Paging on AMD64
*
* The space is divided in positive numbers - userspace and
* negative numbers - kernel space. The 'negative' space starting
* with 0xffff800000000000 and ending with 0xffffffff80000000
* (-2GB) is identically mapped physical memory. The area
* (0xffffffff80000000 ... 0xffffffffffffffff is again identically
* mapped first 2GB.
*
* ATTENTION - PA2KA(KA2PA(x)) != x if 'x' is in kernel
*/
 
#ifndef __amd64_PAGE_H__
#define __amd64_PAGE_H__
 
#include <arch/mm/frame.h>
 
#define PAGE_WIDTH FRAME_WIDTH
#define PAGE_SIZE FRAME_SIZE
 
#ifdef KERNEL
 
#ifndef __ASM__
# include <mm/page.h>
# include <arch/types.h>
#endif
 
#ifndef __ASM__
static inline uintptr_t ka2pa(uintptr_t x)
{
if (x > 0xffffffff80000000)
return x - 0xffffffff80000000;
else
return x - 0xffff800000000000;
}
# define KA2PA(x) ka2pa((uintptr_t)x)
# define PA2KA_CODE(x) (((uintptr_t) (x)) + 0xffffffff80000000)
# define PA2KA(x) (((uintptr_t) (x)) + 0xffff800000000000)
#else
# define KA2PA(x) ((x) - 0xffffffff80000000)
# define PA2KA(x) ((x) + 0xffffffff80000000)
#endif
 
#define PTL0_ENTRIES_ARCH 512
#define PTL1_ENTRIES_ARCH 512
#define PTL2_ENTRIES_ARCH 512
#define PTL3_ENTRIES_ARCH 512
 
#define PTL0_INDEX_ARCH(vaddr) (((vaddr)>>39)&0x1ff)
#define PTL1_INDEX_ARCH(vaddr) (((vaddr)>>30)&0x1ff)
#define PTL2_INDEX_ARCH(vaddr) (((vaddr)>>21)&0x1ff)
#define PTL3_INDEX_ARCH(vaddr) (((vaddr)>>12)&0x1ff)
 
#define GET_PTL1_ADDRESS_ARCH(ptl0, i) ((pte_t *) ((((uint64_t) ((pte_t *)(ptl0))[(i)].addr_12_31)<<12) | (((uint64_t) ((pte_t *)(ptl0))[(i)].addr_32_51)<<32 )))
#define GET_PTL2_ADDRESS_ARCH(ptl1, i) ((pte_t *) ((((uint64_t) ((pte_t *)(ptl1))[(i)].addr_12_31)<<12) | (((uint64_t) ((pte_t *)(ptl1))[(i)].addr_32_51)<<32 )))
#define GET_PTL3_ADDRESS_ARCH(ptl2, i) ((pte_t *) ((((uint64_t) ((pte_t *)(ptl2))[(i)].addr_12_31)<<12) | (((uint64_t) ((pte_t *)(ptl2))[(i)].addr_32_51)<<32 )))
#define GET_FRAME_ADDRESS_ARCH(ptl3, i) ((uintptr_t *) ((((uint64_t) ((pte_t *)(ptl3))[(i)].addr_12_31)<<12) | (((uint64_t) ((pte_t *)(ptl3))[(i)].addr_32_51)<<32 )))
 
#define SET_PTL0_ADDRESS_ARCH(ptl0) (write_cr3((uintptr_t) (ptl0)))
#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) set_pt_addr((pte_t *)(ptl0), (index_t)(i), a)
#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a) set_pt_addr((pte_t *)(ptl1), (index_t)(i), a)
#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a) set_pt_addr((pte_t *)(ptl2), (index_t)(i), a)
#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) set_pt_addr((pte_t *)(ptl3), (index_t)(i), a)
 
#define GET_PTL1_FLAGS_ARCH(ptl0, i) get_pt_flags((pte_t *)(ptl0), (index_t)(i))
#define GET_PTL2_FLAGS_ARCH(ptl1, i) get_pt_flags((pte_t *)(ptl1), (index_t)(i))
#define GET_PTL3_FLAGS_ARCH(ptl2, i) get_pt_flags((pte_t *)(ptl2), (index_t)(i))
#define GET_FRAME_FLAGS_ARCH(ptl3, i) get_pt_flags((pte_t *)(ptl3), (index_t)(i))
 
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) set_pt_flags((pte_t *)(ptl0), (index_t)(i), (x))
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x) set_pt_flags((pte_t *)(ptl1), (index_t)(i), (x))
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x) set_pt_flags((pte_t *)(ptl2), (index_t)(i), (x))
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) set_pt_flags((pte_t *)(ptl3), (index_t)(i), (x))
 
#define PTE_VALID_ARCH(p) (*((uint64_t *) (p)) != 0)
#define PTE_PRESENT_ARCH(p) ((p)->present != 0)
#define PTE_GET_FRAME_ARCH(p) ((((uintptr_t)(p)->addr_12_31)<<12) | ((uintptr_t)(p)->addr_32_51<<32))
#define PTE_WRITABLE_ARCH(p) ((p)->writeable != 0)
#define PTE_EXECUTABLE_ARCH(p) ((p)->no_execute == 0)
 
#ifndef __ASM__
 
/* 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)
 
/** When bit on this position os 1, the page fault was caused during instruction fecth. */
#define PFERR_CODE_ID (1<<4)
 
/** Page Table Entry. */
struct page_specifier {
unsigned present : 1;
unsigned writeable : 1;
unsigned uaccessible : 1;
unsigned page_write_through : 1;
unsigned page_cache_disable : 1;
unsigned accessed : 1;
unsigned dirty : 1;
unsigned unused: 1;
unsigned global : 1;
unsigned soft_valid : 1; /**< Valid content even if present bit is cleared. */
unsigned avl : 2;
unsigned addr_12_31 : 30;
unsigned addr_32_51 : 21;
unsigned no_execute : 1;
} __attribute__ ((packed));
 
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 |
(!p->no_execute)<<PAGE_EXEC_SHIFT |
p->global<<PAGE_GLOBAL_SHIFT
);
}
 
static inline void set_pt_addr(pte_t *pt, index_t i, uintptr_t a)
{
pte_t *p = &pt[i];
 
p->addr_12_31 = (a >> 12) & 0xfffff;
p->addr_32_51 = a >> 32;
}
 
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->no_execute = (flags & PAGE_EXEC) == 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 = 1;
}
 
extern void page_arch_init(void);
 
#endif /* __ASM__ */
 
#endif /* KERNEL */
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/amd64/include/mm/ptl.h
0,0 → 1,53
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 amd64mm
* @{
*/
/** @file
*/
 
 
#ifndef __amd64_PTL_H_
#define __amd64_PTL_H_
 
#define PTL_NO_EXEC (1<<63)
#define PTL_ACCESSED (1<<5)
#define PTL_CACHE_DISABLE (1<<4)
#define PTL_CACHE_THROUGH (1<<3)
#define PTL_USER (1<<2)
#define PTL_WRITABLE (1<<1)
#define PTL_PRESENT 1
#define PTL_2MB_PAGE (1<<7)
 
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/include/mm/tlb.h
0,0 → 1,45
/*
* 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 amd64mm
* @{
*/
/** @file
*/
 
#ifndef __amd64_TLB_H__
#define __amd64_TLB_H__
 
#define tlb_arch_init()
#define tlb_print()
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/include/mm/as.h
0,0 → 1,55
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 amd64mm
* @{
*/
/** @file
*/
 
#ifndef __amd64_AS_H__
#define __amd64_AS_H__
 
#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH 0
 
#define KERNEL_ADDRESS_SPACE_START_ARCH (unsigned long) 0xffff800000000000
#define KERNEL_ADDRESS_SPACE_END_ARCH (unsigned long) 0xffffffffffffffff
#define USER_ADDRESS_SPACE_START_ARCH (unsigned long) 0x0000000000000000
#define USER_ADDRESS_SPACE_END_ARCH (unsigned long) 0x00007fffffffffff
 
#define USTACK_ADDRESS_ARCH (USER_ADDRESS_SPACE_END_ARCH-(PAGE_SIZE-1))
 
#define as_install_arch(as)
 
extern void as_arch_init(void);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/include/mm/asid.h
0,0 → 1,0
link ../../../ia32/include/mm/asid.h
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/amd64/include/mm/memory_init.h
0,0 → 1,0
link ../../../ia32/include/mm/memory_init.h
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/amd64/include/context.h
0,0 → 1,71
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 amd64
* @{
*/
/** @file
*/
 
#ifndef __amd64_CONTEXT_H__
#define __amd64_CONTEXT_H__
 
#ifndef __amd64_TYPES_H__
# include <arch/types.h>
#endif
 
 
/* According to ABI the stack MUST be aligned on
* 16-byte boundary. If it is not, the va_arg calling will
* panic sooner or later
*/
#define SP_DELTA 16
 
/* We include only registers that must be preserved
* during function call
*/
struct context {
uintptr_t sp;
uintptr_t pc;
uint64_t rbx;
uint64_t rbp;
 
uint64_t r12;
uint64_t r13;
uint64_t r14;
uint64_t r15;
 
ipl_t ipl;
} __attribute__ ((packed));
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/include/cpu.h
0,0 → 1,87
/*
* 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 amd64
* @{
*/
/** @file
*/
 
#ifndef __amd64_CPU_H__
#define __amd64_CPU_H__
 
#define RFLAGS_IF (1 << 9)
#define RFLAGS_RF (1 << 16)
 
#define EFER_MSR_NUM 0xc0000080
#define AMD_SCE_FLAG 0
#define AMD_LME_FLAG 8
#define AMD_LMA_FLAG 10
#define AMD_FFXSR_FLAG 14
#define AMD_NXE_FLAG 11
 
/* MSR registers */
#define AMD_MSR_STAR 0xc0000081
#define AMD_MSR_LSTAR 0xc0000082
#define AMD_MSR_SFMASK 0xc0000084
#define AMD_MSR_FS 0xc0000100
#define AMD_MSR_GS 0xc0000101
 
#ifndef __ASM__
 
#include <typedefs.h>
#include <arch/pm.h>
 
struct cpu_arch {
int vendor;
int family;
int model;
int stepping;
struct tss *tss;
count_t iomapver_copy; /** Copy of TASK's I/O Permission bitmap generation count. */
};
 
struct star_msr {
};
 
struct lstar_msr {
};
 
extern void set_efer_flag(int flag);
extern uint64_t read_efer_flag(void);
void cpu_setup_fpu(void);
 
#endif /* __ASM__ */
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/amd64/include/context_offset.h
0,0 → 1,14
/* This file is automatically generated by gencontext.c. */
#define OFFSET_SP 0x0
#define OFFSET_PC 0x8
#define OFFSET_RBX 0x10
#define OFFSET_RBP 0x18
#define OFFSET_R12 0x20
#define OFFSET_R13 0x28
#define OFFSET_R14 0x30
#define OFFSET_R15 0x38
#define OFFSET_IPL 0x40
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/include/elf.h
0,0 → 1,46
/*
* Copyright (C) 2006 Sergey Bondari
* 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 amd64
* @{
*/
/** @file
*/
 
#ifndef __amd64_ELF_H__
#define __amd64_ELF_H__
 
#define ELF_MACHINE EM_X86_64
#define ELF_DATA_ENCODING ELFDATA2LSB
#define ELF_CLASS ELFCLASS64
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/include/arg.h
0,0 → 1,44
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 amd64
* @{
*/
/** @file
*/
 
#ifndef __amd64_ARG_H__
#define __amd64_ARG_H__
 
#include <stdarg.h>
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/include/ddi/ddi.h
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 amd64ddi
* @{
*/
 
/**
* @file
* @brief amd64 specific DDI declarations and macros.
*/
 
#ifndef __amd64_DDI_H__
#define __amd64_DDI_H__
 
extern void io_perm_bitmap_install(void);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/include/syscall.h
0,0 → 1,46
/*
* Copyright (C) 2006 Ondrej Palkovsky
* 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 amd64
* @{
*/
/** @file
*/
 
#ifndef __amd64_SYSCALL_H__
#define __amd64_SYSCALL_H__
 
#include <arch/types.h>
 
extern void syscall_setup_cpu(void);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/include/arch.h
0,0 → 1,42
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 amd64
* @{
*/
/** @file
*/
 
#ifndef __amd64_ARCH_H__
#define __amd64_ARCH_H__
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/include/debugger.h
0,0 → 1,58
/*
* Copyright (C) 2006 Ondrej Palkovsky
* 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 amd64debug
* @{
*/
/** @file
*/
 
#ifndef __amd64_DEBUGGER_H__
#define __amd64_DEBUGGER_H__
 
#include <arch/types.h>
 
#define BKPOINTS_MAX 4
 
/* Flags that are passed to breakpoint_add function */
#define BKPOINT_INSTR 0x1
#define BKPOINT_WRITE 0x2
#define BKPOINT_READ_WRITE 0x4
 
#define BKPOINT_CHECK_ZERO 0x8
 
 
extern void debugger_init(void);
extern int breakpoint_add(void * where, int flags, int curidx);
extern void breakpoint_del(int slot);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/include/drivers/vesa.h
0,0 → 1,47
/*
* Copyright (C) 2006-2006 Jakub Vana
* 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 amd64
* @{
*/
/** @file
*/
 
#ifndef __VESA_H__
#define __VESA_H__
 
 
int vesa_present(void);
void vesa_init(void);
 
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/amd64/include/drivers/i8254.h
0,0 → 1,0
link ../../../ia32/include/drivers/i8254.h
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/amd64/include/drivers/i8259.h
0,0 → 1,0
link ../../../ia32/include/drivers/i8259.h
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/amd64/include/drivers/ega.h
0,0 → 1,0
link ../../../ia32/include/drivers/ega.h
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/amd64/include/drivers/i8042.h
0,0 → 1,0
link ../../../ia32/include/drivers/i8042.h
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/amd64/include/debug.h
0,0 → 1,0
link ../../ia32/include/debug.h
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/amd64/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
/tags/0.2.0.3/kernel/arch/amd64/include/bios
0,0 → 1,0
link ../../ia32/include/bios
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/amd64/include/smp
0,0 → 1,0
link ../../ia32/include/smp
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/amd64/include/barrier.h
0,0 → 1,0
link ../../ia32/include/barrier.h
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/amd64/Makefile.inc
0,0 → 1,114
#
# Copyright (C) 2005 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 = elf64-x86-64
BFD_ARCH = i386:x86-64
BFD = binary
TARGET = amd64-linux-gnu
TOOLCHAIN_DIR = /usr/local/amd64/bin
 
CFLAGS += -fno-unwind-tables -m64 -mcmodel=kernel -mno-red-zone
DEFS += -DMACHINE=$(MACHINE) -D__64_BITS__
 
## Accepted CPUs
#
 
ifeq ($(MACHINE),opteron)
CFLAGS += -march=opteron
DEFS += -DFENCES=p4
endif
 
## Own configuration directives
#
 
CONFIG_ACPI = y
 
## Compile with hierarchical page tables support.
#
 
CONFIG_PAGE_PT = y
DEFS += -DCONFIG_PAGE_PT
 
## Compile with i8042 support.
#
 
CONFIG_I8042 = y
 
## Accepted configuration directives
#
 
ifeq ($(CONFIG_SMP),y)
DEFS += -DCONFIG_SMP
endif
ifeq ($(CONFIG_HT),y)
DEFS += -DCONFIG_HT
endif
 
ifeq ($(CONFIG_SIMICS_FIX),y)
DEFS += -DCONFIG_SIMICS_FIX
endif
 
ARCH_SOURCES = \
arch/$(ARCH)/src/fpu_context.c \
arch/$(ARCH)/src/boot/boot.S \
arch/$(ARCH)/src/pm.c \
arch/$(ARCH)/src/context.S \
arch/$(ARCH)/src/ddi/ddi.c \
arch/$(ARCH)/src/drivers/ega.c \
arch/$(ARCH)/src/drivers/vesa.c \
arch/$(ARCH)/src/drivers/i8254.c \
arch/$(ARCH)/src/drivers/i8259.c \
arch/$(ARCH)/src/delay.S \
arch/$(ARCH)/src/amd64.c \
arch/$(ARCH)/src/bios/bios.c \
arch/$(ARCH)/src/interrupt.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/asm_utils.S \
arch/$(ARCH)/src/mm/memory_init.c \
arch/$(ARCH)/src/cpu/cpu.c \
arch/$(ARCH)/src/proc/scheduler.c \
arch/$(ARCH)/src/proc/task.c \
arch/$(ARCH)/src/proc/thread.c \
arch/$(ARCH)/src/userspace.c \
arch/$(ARCH)/src/syscall.c \
arch/$(ARCH)/src/debugger.c
 
ifeq ($(CONFIG_SMP),y)
ARCH_SOURCES += \
arch/$(ARCH)/src/smp/ap.S \
arch/$(ARCH)/src/smp/apic.c \
arch/$(ARCH)/src/smp/ipi.c \
arch/$(ARCH)/src/smp/mps.c \
arch/$(ARCH)/src/smp/smp.c
endif
/tags/0.2.0.3/kernel/arch/amd64/_link.ld.in
0,0 → 1,64
/** AMD64 linker script
*
* umapped section:
* kernel text
* kernel data
* mapped section:
* kernel text
* kernel data
*/
 
#define __ASM__
#include <arch/boot/boot.h>
#include <arch/mm/page.h>
 
SECTIONS {
.unmapped BOOT_OFFSET: AT (0) {
unmapped_ktext_start = .;
*(K_TEXT_START);
unmapped_ktext_end = .;
 
unmapped_kdata_start = .;
*(K_DATA_START);
unmapped_kdata_end = .;
}
 
.mapped (PA2KA(BOOT_OFFSET)+SIZEOF(.unmapped)) : AT (SIZEOF(.unmapped)) {
ktext_start = .;
*(.text);
ktext_end = .;
 
kdata_start = .;
*(.data); /* initialized data */
*(.rodata*); /* string literals */
hardcoded_load_address = .;
QUAD(PA2KA(BOOT_OFFSET));
hardcoded_ktext_size = .;
QUAD(ktext_end - ktext_start + (unmapped_ktext_end - unmapped_ktext_start));
hardcoded_kdata_size = .;
QUAD(kdata_end - kdata_start + (unmapped_kdata_end - unmapped_kdata_start));
hardcoded_unmapped_ktext_size = .;
QUAD(unmapped_ktext_end - unmapped_ktext_start);
hardcoded_unmapped_kdata_size = .;
QUAD(unmapped_kdata_end - unmapped_kdata_start);
*(COMMON); /* global variables */
 
*(.eh_frame);
 
symbol_table = .;
*(symtab.*); /* Symbol table, must be LAST symbol!*/
 
*(.bss); /* uninitialized static variables */
 
kdata_end = .;
}
#ifdef CONFIG_SMP
_hardcoded_unmapped_size = (unmapped_ktext_end - unmapped_ktext_start) + (unmapped_kdata_end - unmapped_kdata_start);
ap_boot = unmapped_ap_boot - BOOT_OFFSET + AP_BOOT_OFFSET;
ap_gdtr = unmapped_ap_gdtr - BOOT_OFFSET + AP_BOOT_OFFSET;
protected_ap_gdtr = PA2KA(ap_gdtr);
 
#endif /* CONFIG_SMP */
 
}
/tags/0.2.0.3/kernel/arch/sparc64/include/boot/boot.h
0,0 → 1,100
/*
* 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_BOOT_H_
#define KERN_sparc64_BOOT_H_
 
 
#define VMA 0x400000
#define LMA VMA
 
#ifndef __ASM__
#ifndef __LINKER__
 
#include <arch/types.h>
#include <typedefs.h>
 
#define TASKMAP_MAX_RECORDS 32
#define MEMMAP_MAX_RECORDS 32
 
typedef struct {
void * addr;
uint32_t size;
} utask_t;
 
typedef struct {
uint32_t count;
utask_t tasks[TASKMAP_MAX_RECORDS];
} taskmap_t;
 
typedef struct {
uintptr_t start;
uint32_t size;
} memzone_t;
 
typedef struct {
uint32_t total;
uint32_t count;
memzone_t zones[MEMMAP_MAX_RECORDS];
} memmap_t;
 
typedef struct {
uintptr_t addr;
uint32_t width;
uint32_t height;
uint32_t bpp;
uint32_t scanline;
} screen_t;
 
typedef struct {
uintptr_t addr;
uint32_t size;
} keyboard_t;
 
typedef struct {
taskmap_t taskmap;
memmap_t memmap;
screen_t screen;
keyboard_t keyboard;
} bootinfo_t;
 
extern bootinfo_t bootinfo;
 
#endif
#endif
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/sparc64/include/arch.h
0,0 → 1,42
/*
* 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef __sparc64_ARCH_H__
#define __sparc64_ARCH_H__
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/sparc64/include/trap/trap.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 sparc64interrupt
* @{
*/
/** @file
*/
 
#ifndef __sparc64_TRAP_H__
#define __sparc64_TRAP_H__
 
extern void trap_init(void);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/sparc64/include/trap/interrupt.h
0,0 → 1,80
/*
* 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 sparc64interrupt
* @{
*/
/**
* @file
* @brief This file contains interrupt vector trap handler.
*/
 
#ifndef __sparc64_TRAP_INTERRUPT_H__
#define __sparc64_TRAP_INTERRUPT_H__
 
#include <arch/trap/trap_table.h>
#include <arch/stack.h>
 
#define TT_INTERRUPT_LEVEL_1 0x41
#define TT_INTERRUPT_LEVEL_2 0x42
#define TT_INTERRUPT_LEVEL_3 0x43
#define TT_INTERRUPT_LEVEL_4 0x44
#define TT_INTERRUPT_LEVEL_5 0x45
#define TT_INTERRUPT_LEVEL_6 0x46
#define TT_INTERRUPT_LEVEL_7 0x47
#define TT_INTERRUPT_LEVEL_8 0x48
#define TT_INTERRUPT_LEVEL_9 0x49
#define TT_INTERRUPT_LEVEL_10 0x4a
#define TT_INTERRUPT_LEVEL_11 0x4b
#define TT_INTERRUPT_LEVEL_12 0x4c
#define TT_INTERRUPT_LEVEL_13 0x4d
#define TT_INTERRUPT_LEVEL_14 0x4e
#define TT_INTERRUPT_LEVEL_15 0x4f
 
#define TT_INTERRUPT_VECTOR_TRAP 0x60
 
#define INTERRUPT_LEVEL_N_HANDLER_SIZE TRAP_TABLE_ENTRY_SIZE
#define INTERRUPT_VECTOR_TRAP_HANDLER_SIZE TRAP_TABLE_ENTRY_SIZE
 
#ifdef __ASM__
.macro INTERRUPT_LEVEL_N_HANDLER n
save %sp, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp
mov \n - 1, %o0
mov %fp, %o1
PREEMPTIBLE_HANDLER exc_dispatch
.endm
 
.macro INTERRUPT_VECTOR_TRAP_HANDLER
retry
.endm
#endif /* __ASM__ */
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/sparc64/include/trap/trap_table.h
0,0 → 1,102
/*
* 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 sparc64interrupt
* @{
*/
/** @file
*/
 
#ifndef __sparc64_TRAP_TABLE_H__
#define __sparc64_TRAP_TABLE_H__
 
#ifndef __ASM__
#include <arch/types.h>
#endif /* __ASM__ */
 
#include <arch/stack.h>
 
#define TRAP_TABLE_ENTRY_COUNT 1024
#define TRAP_TABLE_ENTRY_SIZE 32
#define TRAP_TABLE_SIZE (TRAP_TABLE_ENTRY_COUNT*TRAP_TABLE_ENTRY_SIZE)
 
#ifndef __ASM__
struct trap_table_entry {
uint8_t octets[TRAP_TABLE_ENTRY_SIZE];
} __attribute__ ((packed));
 
typedef struct trap_table_entry trap_table_entry_t;
 
extern trap_table_entry_t trap_table[TRAP_TABLE_ENTRY_COUNT];
extern trap_table_entry_t trap_table_save[TRAP_TABLE_ENTRY_COUNT];
#endif /* !__ASM__ */
 
#ifdef __ASM__
.macro SAVE_GLOBALS
mov %g1, %l1
mov %g2, %l2
mov %g3, %l3
mov %g4, %l4
mov %g5, %l5
mov %g6, %l6
mov %g7, %l7
.endm
 
.macro RESTORE_GLOBALS
mov %l1, %g1
mov %l2, %g2
mov %l3, %g3
mov %l4, %g4
mov %l5, %g5
mov %l6, %g6
mov %l7, %g7
.endm
 
#define PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE (STACK_WINDOW_SAVE_AREA_SIZE+(4*8))
#define SAVED_TSTATE -(1*8)
#define SAVED_TPC -(2*8)
#define SAVED_TNPC -(3*8)
#define SAVED_PSTATE -(4*8)
 
.macro PREEMPTIBLE_HANDLER f
set \f, %l0
b preemptible_handler
nop
.endm
 
.macro SIMPLE_HANDLER f
call \f
nop
.endm
#endif /* __ASM__ */
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/sparc64/include/trap/regwin.h
0,0 → 1,141
/*
* 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 sparc64interrupt
* @{
*/
/**
* @file
* @brief This file contains register window trap handlers.
*/
 
#ifndef __sparc64_REGWIN_H__
#define __sparc64_REGWIN_H__
 
#include <arch/stack.h>
 
#define TT_CLEAN_WINDOW 0x24
#define TT_SPILL_0_NORMAL 0x80
#define TT_FILL_0_NORMAL 0xc0
 
#define REGWIN_HANDLER_SIZE 128
 
#define CLEAN_WINDOW_HANDLER_SIZE REGWIN_HANDLER_SIZE
#define SPILL_HANDLER_SIZE REGWIN_HANDLER_SIZE
#define FILL_HANDLER_SIZE REGWIN_HANDLER_SIZE
 
/** Window Save Area offsets. */
#define L0_OFFSET 0
#define L1_OFFSET 8
#define L2_OFFSET 16
#define L3_OFFSET 24
#define L4_OFFSET 32
#define L5_OFFSET 40
#define L6_OFFSET 48
#define L7_OFFSET 56
#define I0_OFFSET 64
#define I1_OFFSET 72
#define I2_OFFSET 80
#define I3_OFFSET 88
#define I4_OFFSET 96
#define I5_OFFSET 104
#define I6_OFFSET 112
#define I7_OFFSET 120
 
#ifdef __ASM__
.macro SPILL_NORMAL_HANDLER
stx %l0, [%sp + STACK_BIAS + L0_OFFSET]
stx %l1, [%sp + STACK_BIAS + L1_OFFSET]
stx %l2, [%sp + STACK_BIAS + L2_OFFSET]
stx %l3, [%sp + STACK_BIAS + L3_OFFSET]
stx %l4, [%sp + STACK_BIAS + L4_OFFSET]
stx %l5, [%sp + STACK_BIAS + L5_OFFSET]
stx %l6, [%sp + STACK_BIAS + L6_OFFSET]
stx %l7, [%sp + STACK_BIAS + L7_OFFSET]
stx %i0, [%sp + STACK_BIAS + I0_OFFSET]
stx %i1, [%sp + STACK_BIAS + I1_OFFSET]
stx %i2, [%sp + STACK_BIAS + I2_OFFSET]
stx %i3, [%sp + STACK_BIAS + I3_OFFSET]
stx %i4, [%sp + STACK_BIAS + I4_OFFSET]
stx %i5, [%sp + STACK_BIAS + I5_OFFSET]
stx %i6, [%sp + STACK_BIAS + I6_OFFSET]
stx %i7, [%sp + STACK_BIAS + I7_OFFSET]
saved
retry
.endm
 
.macro FILL_NORMAL_HANDLER
ldx [%sp + STACK_BIAS + L0_OFFSET], %l0
ldx [%sp + STACK_BIAS + L1_OFFSET], %l1
ldx [%sp + STACK_BIAS + L2_OFFSET], %l2
ldx [%sp + STACK_BIAS + L3_OFFSET], %l3
ldx [%sp + STACK_BIAS + L4_OFFSET], %l4
ldx [%sp + STACK_BIAS + L5_OFFSET], %l5
ldx [%sp + STACK_BIAS + L6_OFFSET], %l6
ldx [%sp + STACK_BIAS + L7_OFFSET], %l7
ldx [%sp + STACK_BIAS + I0_OFFSET], %i0
ldx [%sp + STACK_BIAS + I1_OFFSET], %i1
ldx [%sp + STACK_BIAS + I2_OFFSET], %i2
ldx [%sp + STACK_BIAS + I3_OFFSET], %i3
ldx [%sp + STACK_BIAS + I4_OFFSET], %i4
ldx [%sp + STACK_BIAS + I5_OFFSET], %i5
ldx [%sp + STACK_BIAS + I6_OFFSET], %i6
ldx [%sp + STACK_BIAS + I7_OFFSET], %i7
restored
retry
.endm
 
.macro CLEAN_WINDOW_HANDLER
rdpr %cleanwin, %l0
add %l0, 1, %l0
wrpr %l0, 0, %cleanwin
mov %r0, %l0
mov %r0, %l1
mov %r0, %l2
mov %r0, %l3
mov %r0, %l4
mov %r0, %l5
mov %r0, %l6
mov %r0, %l7
mov %r0, %o0
mov %r0, %o1
mov %r0, %o2
mov %r0, %o3
mov %r0, %o4
mov %r0, %o5
mov %r0, %o6
mov %r0, %o7
retry
.endm
#endif /* __ASM__ */
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/sparc64/include/trap/exception.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 sparc64interrupt
* @{
*/
/**
* @file
*/
 
#ifndef __sparc64_EXCEPTION_H__
#define __sparc64_EXCEPTION_H__
 
#define TT_INSTRUCTION_ACCESS_EXCEPTION 0x08
#define TT_ILLEGAL_INSTRUCTION 0x10
#define TT_DATA_ACCESS_ERROR 0x32
#define TT_MEM_ADDRESS_NOT_ALIGNED 0x34
 
#ifndef __ASM__
extern void do_instruction_access_exc(void);
extern void do_mem_address_not_aligned(void);
extern void do_data_access_error(void);
extern void do_illegal_instruction(void);
#endif /* !__ASM__ */
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/sparc64/include/trap/mmu.h
0,0 → 1,77
/*
* 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 sparc64interrupt
* @{
*/
/**
* @file
* @brief This file contains fast MMU trap handlers.
*/
 
#ifndef __sparc64_MMU_TRAP_H__
#define __sparc64_MMU_TRAP_H__
 
#include <arch/stack.h>
 
#define TT_FAST_INSTRUCTION_ACCESS_MMU_MISS 0x64
#define TT_FAST_DATA_ACCESS_MMU_MISS 0x68
#define TT_FAST_DATA_ACCESS_PROTECTION 0x6c
 
#define FAST_MMU_HANDLER_SIZE 128
 
#ifdef __ASM__
.macro FAST_INSTRUCTION_ACCESS_MMU_MISS_HANDLER
save %sp, -STACK_WINDOW_SAVE_AREA_SIZE, %sp
call fast_instruction_access_mmu_miss
nop
restore
retry
.endm
 
.macro FAST_DATA_ACCESS_MMU_MISS_HANDLER
save %sp, -STACK_WINDOW_SAVE_AREA_SIZE, %sp
call fast_data_access_mmu_miss
nop
restore
retry
.endm
 
.macro FAST_DATA_ACCESS_PROTECTION_HANDLER
save %sp, -STACK_WINDOW_SAVE_AREA_SIZE, %sp
call fast_data_access_protection
nop
restore
retry
.endm
#endif /* __ASM__ */
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/sparc64/include/mm/tte.h
0,0 → 1,96
/*
* 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 sparc64mm
* @{
*/
/** @file
*/
 
#ifndef __sparc64_TTE_H__
#define __sparc64_TTE_H__
 
#define TTE_G (1<<0)
#define TTE_W (1<<1)
#define TTE_P (1<<2)
#define TTE_E (1<<3)
#define TTE_CV (1<<4)
#define TTE_CP (1<<5)
#define TTE_L (1<<6)
 
#define TTE_V_SHIFT 63
#define TTE_SIZE_SHIFT 61
 
#ifndef __ASM__
 
#include <arch/types.h>
 
/** Translation Table Entry - Tag. */
union tte_tag {
uint64_t value;
struct {
unsigned g : 1; /**< Global. */
unsigned : 2; /**< Reserved. */
unsigned context : 13; /**< Context identifier. */
unsigned : 6; /**< Reserved. */
uint64_t va_tag : 42; /**< Virtual Address Tag, bits 63:22. */
} __attribute__ ((packed));
};
 
typedef union tte_tag tte_tag_t;
 
/** Translation Table Entry - Data. */
union tte_data {
uint64_t value;
struct {
unsigned v : 1; /**< Valid. */
unsigned size : 2; /**< Page size of this entry. */
unsigned nfo : 1; /**< No-Fault-Only. */
unsigned ie : 1; /**< Invert Endianness. */
unsigned soft2 : 9; /**< Software defined field. */
unsigned diag : 9; /**< Diagnostic data. */
unsigned pfn : 28; /**< Physical Address bits, bits 40:13. */
unsigned soft : 6; /**< Software defined field. */
unsigned l : 1; /**< Lock. */
unsigned cp : 1; /**< Cacheable in physically indexed cache. */
unsigned cv : 1; /**< Cacheable in virtually indexed cache. */
unsigned e : 1; /**< Side-effect. */
unsigned p : 1; /**< Privileged. */
unsigned w : 1; /**< Writable. */
unsigned g : 1; /**< Global. */
} __attribute__ ((packed));
};
 
typedef union tte_data tte_data_t;
 
#endif /* !def __ASM__ */
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/sparc64/include/mm/mmu.h
0,0 → 1,111
/*
* 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 sparc64mm
* @{
*/
/** @file
*/
 
#ifndef __sparc64_MMU_H__
#define __sparc64_MMU_H__
 
/** LSU Control Register ASI. */
#define ASI_LSU_CONTROL_REG 0x45 /**< Load/Store Unit Control Register. */
 
/** I-MMU ASIs. */
#define ASI_IMMU 0x50
#define ASI_IMMU_TSB_8KB_PTR_REG 0x51
#define ASI_IMMU_TSB_64KB_PTR_REG 0x52
#define ASI_ITLB_DATA_IN_REG 0x54
#define ASI_ITLB_DATA_ACCESS_REG 0x55
#define ASI_ITLB_TAG_READ_REG 0x56
#define ASI_IMMU_DEMAP 0x57
 
/** Virtual Addresses within ASI_IMMU. */
#define VA_IMMU_TAG_TARGET 0x0 /**< IMMU tag target register. */
#define VA_IMMU_SFSR 0x18 /**< IMMU sync fault status register. */
#define VA_IMMU_TSB_BASE 0x28 /**< IMMU TSB base register. */
#define VA_IMMU_TAG_ACCESS 0x30 /**< IMMU TLB tag access register. */
 
/** D-MMU ASIs. */
#define ASI_DMMU 0x58
#define ASI_DMMU_TSB_8KB_PTR_REG 0x59
#define ASI_DMMU_TSB_64KB_PTR_REG 0x5a
#define ASI_DMMU_TSB_DIRECT_PTR_REG 0x5b
#define ASI_DTLB_DATA_IN_REG 0x5c
#define ASI_DTLB_DATA_ACCESS_REG 0x5d
#define ASI_DTLB_TAG_READ_REG 0x5e
#define ASI_DMMU_DEMAP 0x5f
 
/** Virtual Addresses within ASI_DMMU. */
#define VA_DMMU_TAG_TARGET 0x0 /**< DMMU tag target register. */
#define VA_PRIMARY_CONTEXT_REG 0x8 /**< DMMU primary context register. */
#define VA_SECONDARY_CONTEXT_REG 0x10 /**< DMMU secondary context register. */
#define VA_DMMU_SFSR 0x18 /**< DMMU sync fault status register. */
#define VA_DMMU_SFAR 0x20 /**< DMMU sync fault address register. */
#define VA_DMMU_TSB_BASE 0x28 /**< DMMU TSB base register. */
#define VA_DMMU_TAG_ACCESS 0x30 /**< DMMU TLB tag access register. */
#define VA_DMMU_VA_WATCHPOINT_REG 0x38 /**< DMMU VA data watchpoint register. */
#define VA_DMMU_PA_WATCHPOINT_REG 0x40 /**< DMMU PA data watchpoint register. */
 
#ifndef __ASM__
 
#include <arch/asm.h>
#include <arch/barrier.h>
#include <arch/types.h>
#include <typedefs.h>
 
/** LSU Control Register. */
union lsu_cr_reg {
uint64_t value;
struct {
unsigned : 23;
unsigned pm : 8;
unsigned vm : 8;
unsigned pr : 1;
unsigned pw : 1;
unsigned vr : 1;
unsigned vw : 1;
unsigned : 1;
unsigned fm : 16;
unsigned dm : 1; /**< D-MMU enable. */
unsigned im : 1; /**< I-MMU enable. */
unsigned dc : 1; /**< D-Cache enable. */
unsigned ic : 1; /**< I-Cache enable. */
} __attribute__ ((packed));
};
typedef union lsu_cr_reg lsu_cr_reg_t;
 
#endif /* !def __ASM__ */
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/sparc64/include/mm/tlb.h
0,0 → 1,439
/*
* 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 sparc64mm
* @{
*/
/** @file
*/
 
#ifndef __sparc64_TLB_H__
#define __sparc64_TLB_H__
 
 
#define ITLB_ENTRY_COUNT 64
#define DTLB_ENTRY_COUNT 64
 
#define MEM_CONTEXT_KERNEL 0
#define MEM_CONTEXT_TEMP 1
 
/** Page sizes. */
#define PAGESIZE_8K 0
#define PAGESIZE_64K 1
#define PAGESIZE_512K 2
#define PAGESIZE_4M 3
 
/** Bit width of the TLB-locked portion of kernel address space. */
#define KERNEL_PAGE_WIDTH 22 /* 4M */
 
/* TLB Demap Operation types. */
#define TLB_DEMAP_PAGE 0
#define TLB_DEMAP_CONTEXT 1
 
#define TLB_DEMAP_TYPE_SHIFT 6
 
/* TLB Demap Operation Context register encodings. */
#define TLB_DEMAP_PRIMARY 0
#define TLB_DEMAP_SECONDARY 1
#define TLB_DEMAP_NUCLEUS 2
 
#define TLB_DEMAP_CONTEXT_SHIFT 4
 
/* TLB Tag Access shifts */
#define TLB_TAG_ACCESS_CONTEXT_SHIFT 0
#define TLB_TAG_ACCESS_VPN_SHIFT 13
 
#ifndef __ASM__
 
#include <arch/mm/tte.h>
#include <arch/mm/mmu.h>
#include <arch/mm/page.h>
#include <arch/asm.h>
#include <arch/barrier.h>
#include <arch/types.h>
#include <typedefs.h>
 
union tlb_context_reg {
uint64_t v;
struct {
unsigned long : 51;
unsigned context : 13; /**< Context/ASID. */
} __attribute__ ((packed));
};
typedef union tlb_context_reg tlb_context_reg_t;
 
/** I-/D-TLB Data In/Access Register type. */
typedef tte_data_t tlb_data_t;
 
/** I-/D-TLB Data Access Address in Alternate Space. */
union tlb_data_access_addr {
uint64_t value;
struct {
uint64_t : 55;
unsigned tlb_entry : 6;
unsigned : 3;
} __attribute__ ((packed));
};
typedef union tlb_data_access_addr tlb_data_access_addr_t;
typedef union tlb_data_access_addr tlb_tag_read_addr_t;
 
/** I-/D-TLB Tag Read Register. */
union tlb_tag_read_reg {
uint64_t value;
struct {
uint64_t vpn : 51; /**< Virtual Address bits 63:13. */
unsigned context : 13; /**< Context identifier. */
} __attribute__ ((packed));
};
typedef union tlb_tag_read_reg tlb_tag_read_reg_t;
typedef union tlb_tag_read_reg tlb_tag_access_reg_t;
 
 
/** TLB Demap Operation Address. */
union tlb_demap_addr {
uint64_t value;
struct {
uint64_t vpn: 51; /**< Virtual Address bits 63:13. */
unsigned : 6; /**< Ignored. */
unsigned type : 1; /**< The type of demap operation. */
unsigned context : 2; /**< Context register selection. */
unsigned : 4; /**< Zero. */
} __attribute__ ((packed));
};
typedef union tlb_demap_addr tlb_demap_addr_t;
 
/** TLB Synchronous Fault Status Register. */
union tlb_sfsr_reg {
uint64_t value;
struct {
unsigned long : 39; /**< Implementation dependent. */
unsigned nf : 1; /**< Nonfaulting load. */
unsigned asi : 8; /**< ASI. */
unsigned tm : 1; /**< TLB miss. */
unsigned : 1;
unsigned ft : 7; /**< Fault type. */
unsigned e : 1; /**< Side-effect bit. */
unsigned ct : 2; /**< Context Register selection. */
unsigned pr : 1; /**< Privilege bit. */
unsigned w : 1; /**< Write bit. */
unsigned ow : 1; /**< Overwrite bit. */
unsigned fv : 1; /**< Fault Valid bit. */
} __attribute__ ((packed));
};
typedef union tlb_sfsr_reg tlb_sfsr_reg_t;
 
/** Read MMU Primary Context Register.
*
* @return Current value of Primary Context Register.
*/
static inline uint64_t mmu_primary_context_read(void)
{
return asi_u64_read(ASI_DMMU, VA_PRIMARY_CONTEXT_REG);
}
 
/** Write MMU Primary Context Register.
*
* @param v New value of Primary Context Register.
*/
static inline void mmu_primary_context_write(uint64_t v)
{
asi_u64_write(ASI_DMMU, VA_PRIMARY_CONTEXT_REG, v);
flush();
}
 
/** Read MMU Secondary Context Register.
*
* @return Current value of Secondary Context Register.
*/
static inline uint64_t mmu_secondary_context_read(void)
{
return asi_u64_read(ASI_DMMU, VA_SECONDARY_CONTEXT_REG);
}
 
/** Write MMU Primary Context Register.
*
* @param v New value of Primary Context Register.
*/
static inline void mmu_secondary_context_write(uint64_t v)
{
asi_u64_write(ASI_DMMU, VA_PRIMARY_CONTEXT_REG, v);
flush();
}
 
/** Read IMMU TLB Data Access Register.
*
* @param entry TLB Entry index.
*
* @return Current value of specified IMMU TLB Data Access Register.
*/
static inline uint64_t itlb_data_access_read(index_t entry)
{
tlb_data_access_addr_t reg;
reg.value = 0;
reg.tlb_entry = entry;
return asi_u64_read(ASI_ITLB_DATA_ACCESS_REG, reg.value);
}
 
/** Write IMMU TLB Data Access Register.
*
* @param entry TLB Entry index.
* @param value Value to be written.
*/
static inline void itlb_data_access_write(index_t entry, uint64_t value)
{
tlb_data_access_addr_t reg;
reg.value = 0;
reg.tlb_entry = entry;
asi_u64_write(ASI_ITLB_DATA_ACCESS_REG, reg.value, value);
flush();
}
 
/** Read DMMU TLB Data Access Register.
*
* @param entry TLB Entry index.
*
* @return Current value of specified DMMU TLB Data Access Register.
*/
static inline uint64_t dtlb_data_access_read(index_t entry)
{
tlb_data_access_addr_t reg;
reg.value = 0;
reg.tlb_entry = entry;
return asi_u64_read(ASI_DTLB_DATA_ACCESS_REG, reg.value);
}
 
/** Write DMMU TLB Data Access Register.
*
* @param entry TLB Entry index.
* @param value Value to be written.
*/
static inline void dtlb_data_access_write(index_t entry, uint64_t value)
{
tlb_data_access_addr_t reg;
reg.value = 0;
reg.tlb_entry = entry;
asi_u64_write(ASI_DTLB_DATA_ACCESS_REG, reg.value, value);
membar();
}
 
/** Read IMMU TLB Tag Read Register.
*
* @param entry TLB Entry index.
*
* @return Current value of specified IMMU TLB Tag Read Register.
*/
static inline uint64_t itlb_tag_read_read(index_t entry)
{
tlb_tag_read_addr_t tag;
 
tag.value = 0;
tag.tlb_entry = entry;
return asi_u64_read(ASI_ITLB_TAG_READ_REG, tag.value);
}
 
/** Read DMMU TLB Tag Read Register.
*
* @param entry TLB Entry index.
*
* @return Current value of specified DMMU TLB Tag Read Register.
*/
static inline uint64_t dtlb_tag_read_read(index_t entry)
{
tlb_tag_read_addr_t tag;
 
tag.value = 0;
tag.tlb_entry = entry;
return asi_u64_read(ASI_DTLB_TAG_READ_REG, tag.value);
}
 
/** Write IMMU TLB Tag Access Register.
*
* @param v Value to be written.
*/
static inline void itlb_tag_access_write(uint64_t v)
{
asi_u64_write(ASI_IMMU, VA_IMMU_TAG_ACCESS, v);
flush();
}
 
/** Read IMMU TLB Tag Access Register.
*
* @return Current value of IMMU TLB Tag Access Register.
*/
static inline uint64_t itlb_tag_access_read(void)
{
return asi_u64_read(ASI_IMMU, VA_IMMU_TAG_ACCESS);
}
 
/** Write DMMU TLB Tag Access Register.
*
* @param v Value to be written.
*/
static inline void dtlb_tag_access_write(uint64_t v)
{
asi_u64_write(ASI_DMMU, VA_DMMU_TAG_ACCESS, v);
membar();
}
 
/** Read DMMU TLB Tag Access Register.
*
* @return Current value of DMMU TLB Tag Access Register.
*/
static inline uint64_t dtlb_tag_access_read(void)
{
return asi_u64_read(ASI_DMMU, VA_DMMU_TAG_ACCESS);
}
 
 
/** Write IMMU TLB Data in Register.
*
* @param v Value to be written.
*/
static inline void itlb_data_in_write(uint64_t v)
{
asi_u64_write(ASI_ITLB_DATA_IN_REG, 0, v);
flush();
}
 
/** Write DMMU TLB Data in Register.
*
* @param v Value to be written.
*/
static inline void dtlb_data_in_write(uint64_t v)
{
asi_u64_write(ASI_DTLB_DATA_IN_REG, 0, v);
membar();
}
 
/** Read ITLB Synchronous Fault Status Register.
*
* @return Current content of I-SFSR register.
*/
static inline uint64_t itlb_sfsr_read(void)
{
return asi_u64_read(ASI_IMMU, VA_IMMU_SFSR);
}
 
/** Write ITLB Synchronous Fault Status Register.
*
* @param v New value of I-SFSR register.
*/
static inline void itlb_sfsr_write(uint64_t v)
{
asi_u64_write(ASI_IMMU, VA_IMMU_SFSR, v);
flush();
}
 
/** Read DTLB Synchronous Fault Status Register.
*
* @return Current content of D-SFSR register.
*/
static inline uint64_t dtlb_sfsr_read(void)
{
return asi_u64_read(ASI_DMMU, VA_DMMU_SFSR);
}
 
/** Write DTLB Synchronous Fault Status Register.
*
* @param v New value of D-SFSR register.
*/
static inline void dtlb_sfsr_write(uint64_t v)
{
asi_u64_write(ASI_DMMU, VA_DMMU_SFSR, v);
membar();
}
 
/** Read DTLB Synchronous Fault Address Register.
*
* @return Current content of D-SFAR register.
*/
static inline uint64_t dtlb_sfar_read(void)
{
return asi_u64_read(ASI_DMMU, VA_DMMU_SFAR);
}
 
/** Perform IMMU TLB Demap Operation.
*
* @param type Selects between context and page demap.
* @param context_encoding Specifies which Context register has Context ID for demap.
* @param page Address which is on the page to be demapped.
*/
static inline void itlb_demap(int type, int context_encoding, uintptr_t page)
{
tlb_demap_addr_t da;
page_address_t pg;
da.value = 0;
pg.address = page;
da.type = type;
da.context = context_encoding;
da.vpn = pg.vpn;
asi_u64_write(ASI_IMMU_DEMAP, da.value, 0); /* da.value is the address within the ASI */
flush();
}
 
/** Perform DMMU TLB Demap Operation.
*
* @param type Selects between context and page demap.
* @param context_encoding Specifies which Context register has Context ID for demap.
* @param page Address which is on the page to be demapped.
*/
static inline void dtlb_demap(int type, int context_encoding, uintptr_t page)
{
tlb_demap_addr_t da;
page_address_t pg;
da.value = 0;
pg.address = page;
da.type = type;
da.context = context_encoding;
da.vpn = pg.vpn;
asi_u64_write(ASI_DMMU_DEMAP, da.value, 0); /* da.value is the address within the ASI */
membar();
}
 
extern void fast_instruction_access_mmu_miss(void);
extern void fast_data_access_mmu_miss(void);
extern void fast_data_access_protection(void);
 
extern void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize, bool locked, bool cacheable);
 
#endif /* !def __ASM__ */
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/sparc64/include/mm/page.h
0,0 → 1,69
/*
* 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 sparc64mm
* @{
*/
/** @file
*/
 
#ifndef __sparc64_PAGE_H__
#define __sparc64_PAGE_H__
 
#include <arch/mm/frame.h>
 
#define PAGE_WIDTH FRAME_WIDTH
#define PAGE_SIZE FRAME_SIZE
 
#ifdef KERNEL
 
#include <mm/page.h>
#include <arch/types.h>
#include <genarch/mm/page_ht.h>
 
#define KA2PA(x) ((uintptr_t) (x))
#define PA2KA(x) ((uintptr_t) (x))
 
union page_address {
uintptr_t address;
struct {
uint64_t vpn : 51; /**< Virtual Page Number. */
unsigned offset : 13; /**< Offset. */
} __attribute__ ((packed));
};
 
typedef union page_address page_address_t;
 
extern void page_arch_init(void);
 
#endif /* KERNEL */
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/sparc64/include/mm/frame.h
0,0 → 1,66
/*
* 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 sparc64mm
* @{
*/
/** @file
*/
 
#ifndef __sparc64_FRAME_H__
#define __sparc64_FRAME_H__
 
#define FRAME_WIDTH 13 /* 8K */
#define FRAME_SIZE (1<<FRAME_WIDTH)
 
#ifdef KERNEL
#ifndef __ASM__
 
#include <arch/types.h>
 
union frame_address {
uintptr_t address;
struct {
unsigned : 23;
uint64_t pfn : 28; /**< Physical Frame Number. */
unsigned offset : 13; /**< Offset. */
} __attribute__ ((packed));
};
 
typedef union frame_address frame_address_t;
 
extern uintptr_t last_frame;
extern void frame_arch_init(void);
 
#endif
#endif
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/sparc64/include/mm/asid.h
0,0 → 1,50
/*
* 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 sparc64mm
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_ASID_H_
#define KERN_sparc64_ASID_H_
 
#include <arch/types.h>
 
/*
* On SPARC, Context means the same thing as ASID trough out the kernel.
*/
typedef uint16_t asid_t;
 
#define ASID_MAX_ARCH 8191 /* 2^13 - 1 */
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/sparc64/include/mm/memory_init.h
0,0 → 1,46
/*
* 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 sparc64mm
* @{
*/
/** @file
*/
 
#ifndef __sparc64_MEMORY_INIT_H__
#define __sparc64_MEMORY_INIT_H__
 
#include <typedefs.h>
 
extern size_t get_memory_size(void);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/sparc64/include/mm/as.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 sparc64mm
* @{
*/
/** @file
*/
 
#ifndef __sparc64_AS_H__
#define __sparc64_AS_H__
 
#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH 1
 
#define KERNEL_ADDRESS_SPACE_START_ARCH (unsigned long) 0x0000000000000000
#define KERNEL_ADDRESS_SPACE_END_ARCH (unsigned long) 0xffffffffffffffff
#define USER_ADDRESS_SPACE_START_ARCH (unsigned long) 0x0000000000000000
#define USER_ADDRESS_SPACE_END_ARCH (unsigned long) 0xffffffffffffffff
 
#define USTACK_ADDRESS_ARCH (0x7fffffffffffffff-(PAGE_SIZE-1))
 
#define as_install_arch(as)
 
extern void as_arch_init(void);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/sparc64/include/barrier.h
0,0 → 1,69
/*
* 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef __sparc64_BARRIER_H__
#define __sparc64_BARRIER_H__
 
/*
* TODO: Implement true SPARC V9 memory barriers for macros below.
*/
#define CS_ENTER_BARRIER() __asm__ volatile ("" ::: "memory")
#define CS_LEAVE_BARRIER() __asm__ volatile ("" ::: "memory")
 
#define memory_barrier()
#define read_barrier()
#define write_barrier()
 
/** Flush Instruction Memory instruction. */
static inline void flush(void)
{
/*
* The FLUSH instruction takes address parameter.
* As such, it may trap if the address is not found in DTLB.
* However, JPS1 implementations are free to ignore the trap.
*/
__asm__ volatile ("flush %0\n" :: "r" (0x400000));
}
 
/** Memory Barrier instruction. */
static inline void membar(void)
{
__asm__ volatile ("membar #Sync\n");
}
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/sparc64/include/drivers/tick.h
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 sparc64
* @{
*/
/** @file
*/
 
#ifndef __sparc64_TICK_H__
#define __sparc64_TICK_H__
 
#include <typedefs.h>
 
#define TICK_DELTA 500000
 
extern void tick_init(void);
extern void tick_interrupt(int n, istate_t *istate);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/sparc64/include/drivers/i8042.h
0,0 → 1,73
/*
* 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_I8042_H_
#define KERN_sparc64_I8042_H_
 
#include <arch/types.h>
 
#define STATUS_REG 4
#define COMMAND_REG 4
#define DATA_REG 6
 
#define LAST_REG DATA_REG
 
extern volatile uint8_t *kbd_virt_address;
 
static inline void i8042_data_write(uint8_t data)
{
kbd_virt_address[DATA_REG] = data;
}
 
static inline uint8_t i8042_data_read(void)
{
return kbd_virt_address[DATA_REG];
}
 
static inline uint8_t i8042_status_read(void)
{
return kbd_virt_address[STATUS_REG];
}
 
static inline void i8042_command_write(uint8_t command)
{
kbd_virt_address[COMMAND_REG] = command;
}
 
extern void kbd_init(void);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/sparc64/include/drivers/fb.h
0,0 → 1,41
/*
* 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_FB_H_
#define KERN_sparc64_FB_H_
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/sparc64/include/regdef.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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_REGDEF_H_
#define KERN_sparc64_REGDEF_H_
 
#define PSTATE_IE_BIT 2
#define PSTATE_AM_BIT 8
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/sparc64/include/register.h
0,0 → 1,111
/*
* 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_REGISTER_H_
#define KERN_sparc64_REGISTER_H_
 
#include <arch/regdef.h>
#include <arch/types.h>
 
/** Version Register. */
union ver_reg {
uint64_t value;
struct {
uint16_t manuf; /**< Manufacturer code. */
uint16_t impl; /**< Implementation code. */
uint8_t mask; /**< Mask set revision. */
unsigned : 8;
uint8_t maxtl;
unsigned : 3;
unsigned maxwin : 5;
} __attribute__ ((packed));
};
typedef union ver_reg ver_reg_t;
 
/** Processor State Register. */
union pstate_reg {
uint64_t value;
struct {
uint64_t : 52;
unsigned ig : 1; /**< Interrupt Globals. */
unsigned mg : 1; /**< MMU Globals. */
unsigned cle : 1; /**< Current Little Endian. */
unsigned tle : 1; /**< Trap Little Endian. */
unsigned mm : 2; /**< Memory Model. */
unsigned red : 1; /**< RED state. */
unsigned pef : 1; /**< Enable floating-point. */
unsigned am : 1; /**< 32-bit Address Mask. */
unsigned priv : 1; /**< Privileged Mode. */
unsigned ie : 1; /**< Interrupt Enable. */
unsigned ag : 1; /**< Alternate Globals*/
} __attribute__ ((packed));
};
typedef union pstate_reg pstate_reg_t;
 
/** TICK Register. */
union tick_reg {
uint64_t value;
struct {
unsigned npt : 1; /**< Non-privileged Trap enable. */
uint64_t counter : 63; /**< Elapsed CPU clck cycle counter. */
} __attribute__ ((packed));
};
typedef union tick_reg tick_reg_t;
 
/** TICK_compare Register. */
union tick_compare_reg {
uint64_t value;
struct {
unsigned int_dis : 1; /**< TICK_INT interrupt disabled flag. */
uint64_t tick_cmpr : 63; /**< Compare value for TICK interrupts. */
} __attribute__ ((packed));
};
typedef union tick_compare_reg tick_compare_reg_t;
 
/** SOFTINT Register. */
union softint_reg {
uint64_t value;
struct {
uint64_t : 47;
unsigned stick_int : 1;
unsigned int_level : 15;
unsigned tick_int : 1;
} __attribute__ ((packed));
};
typedef union softint_reg softint_reg_t;
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/sparc64/include/console.h
0,0 → 1,45
/*
* 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_CONSOLE_H_
#define KERN_sparc64_CONSOLE_H_
 
extern void kkbdpoll(void *arg);
extern void ofw_sparc64_console_init(void);
extern void standalone_sparc64_console_init(void);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/sparc64/include/stack.h
0,0 → 1,56
/*
* 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_STACK_H_
#define KERN_sparc64_STACK_H_
 
#define STACK_ITEM_SIZE 8
 
/** According to SPARC Compliance Definition, every stack frame is 16-byte aligned. */
#define STACK_ALIGNMENT 16
 
/**
* 16-extended-word save area for %i[0-7] and %l[0-7] registers.
*/
#define STACK_WINDOW_SAVE_AREA_SIZE (16*STACK_ITEM_SIZE)
 
/**
* By convention, the actual top of the stack is %sp + STACK_BIAS.
*/
#define STACK_BIAS 2047
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/sparc64/include/elf.h
0,0 → 1,45
/*
* Copyright (C) 2006 Sergey Bondari
* 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef __sparc64_ELF_H__
#define __sparc64_ELF_H__
 
#define ELF_MACHINE EM_SPARCV9
#define ELF_DATA_ENCODING ELFDATA2MSB
#define ELF_CLASS ELFCLASS64
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/sparc64/include/atomic.h
0,0 → 1,103
/*
* 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef __sparc64_ATOMIC_H__
#define __sparc64_ATOMIC_H__
 
#include <arch/types.h>
#include <typedefs.h>
 
/** Atomic add operation.
*
* Use atomic compare and swap operation to atomically add signed value.
*
* @param val Atomic variable.
* @param i Signed value to be added.
*
* @return Value of the atomic variable as it existed before addition.
*/
static inline long atomic_add(atomic_t *val, int i)
{
uint64_t a, b;
volatile uint64_t x = (uint64_t) &val->count;
 
__asm__ volatile (
"0:\n"
"ldx %0, %1\n"
"add %1, %3, %2\n"
"casx %0, %1, %2\n"
"cmp %1, %2\n"
"bne 0b\n" /* The operation failed and must be attempted again if a != b. */
"nop\n"
: "=m" (*((uint64_t *)x)), "=r" (a), "=r" (b)
: "r" (i)
);
 
return a;
}
 
static inline long atomic_preinc(atomic_t *val)
{
return atomic_add(val, 1) + 1;
}
 
static inline long atomic_postinc(atomic_t *val)
{
return atomic_add(val, 1);
}
 
static inline long atomic_predec(atomic_t *val)
{
return atomic_add(val, -1) - 1;
}
 
static inline long atomic_postdec(atomic_t *val)
{
return atomic_add(val, -1);
}
 
static inline void atomic_inc(atomic_t *val)
{
(void) atomic_add(val, 1);
}
 
static inline void atomic_dec(atomic_t *val)
{
(void) atomic_add(val, -1);
}
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/sparc64/include/asm.h
0,0 → 1,314
/*
* 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_ASM_H_
#define KERN_sparc64_ASM_H_
 
#include <typedefs.h>
#include <arch/types.h>
#include <arch/register.h>
#include <config.h>
 
/** Read Processor State register.
*
* @return Value of PSTATE register.
*/
static inline uint64_t pstate_read(void)
{
uint64_t v;
__asm__ volatile ("rdpr %%pstate, %0\n" : "=r" (v));
return v;
}
 
/** Write Processor State register.
*
* @param v New value of PSTATE register.
*/
static inline void pstate_write(uint64_t v)
{
__asm__ volatile ("wrpr %0, %1, %%pstate\n" : : "r" (v), "i" (0));
}
 
/** Read TICK_compare Register.
*
* @return Value of TICK_comapre register.
*/
static inline uint64_t tick_compare_read(void)
{
uint64_t v;
__asm__ volatile ("rd %%tick_cmpr, %0\n" : "=r" (v));
return v;
}
 
/** Write TICK_compare Register.
*
* @param v New value of TICK_comapre register.
*/
static inline void tick_compare_write(uint64_t v)
{
__asm__ volatile ("wr %0, %1, %%tick_cmpr\n" : : "r" (v), "i" (0));
}
 
/** Read TICK Register.
*
* @return Value of TICK register.
*/
static inline uint64_t tick_read(void)
{
uint64_t v;
__asm__ volatile ("rdpr %%tick, %0\n" : "=r" (v));
return v;
}
 
/** Write TICK Register.
*
* @param v New value of TICK register.
*/
static inline void tick_write(uint64_t v)
{
__asm__ volatile ("wrpr %0, %1, %%tick\n" : : "r" (v), "i" (0));
}
 
/** Read SOFTINT Register.
*
* @return Value of SOFTINT register.
*/
static inline uint64_t softint_read(void)
{
uint64_t v;
 
__asm__ volatile ("rd %%softint, %0\n" : "=r" (v));
 
return v;
}
 
/** Write SOFTINT Register.
*
* @param v New value of SOFTINT register.
*/
static inline void softint_write(uint64_t v)
{
__asm__ volatile ("wr %0, %1, %%softint\n" : : "r" (v), "i" (0));
}
 
/** Write CLEAR_SOFTINT Register.
*
* Bits set in CLEAR_SOFTINT register will be cleared in SOFTINT register.
*
* @param v New value of CLEAR_SOFTINT register.
*/
static inline void clear_softint_write(uint64_t v)
{
__asm__ volatile ("wr %0, %1, %%clear_softint\n" : : "r" (v), "i" (0));
}
 
/** Enable interrupts.
*
* Enable interrupts and return previous
* value of IPL.
*
* @return Old interrupt priority level.
*/
static inline ipl_t interrupts_enable(void) {
pstate_reg_t pstate;
uint64_t value;
value = pstate_read();
pstate.value = value;
pstate.ie = true;
pstate_write(pstate.value);
return (ipl_t) value;
}
 
/** Disable interrupts.
*
* Disable interrupts and return previous
* value of IPL.
*
* @return Old interrupt priority level.
*/
static inline ipl_t interrupts_disable(void) {
pstate_reg_t pstate;
uint64_t value;
value = pstate_read();
pstate.value = value;
pstate.ie = false;
pstate_write(pstate.value);
return (ipl_t) value;
}
 
/** Restore interrupt priority level.
*
* Restore IPL.
*
* @param ipl Saved interrupt priority level.
*/
static inline void interrupts_restore(ipl_t ipl) {
pstate_reg_t pstate;
pstate.value = pstate_read();
pstate.ie = ((pstate_reg_t) ipl).ie;
pstate_write(pstate.value);
}
 
/** Return interrupt priority level.
*
* Return IPL.
*
* @return Current interrupt priority level.
*/
static inline ipl_t interrupts_read(void) {
return (ipl_t) pstate_read();
}
 
/** 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 ("and %%sp, %1, %0\n" : "=r" (v) : "r" (~(STACK_SIZE-1)));
return v;
}
 
/** Read Version Register.
*
* @return Value of VER register.
*/
static inline uint64_t ver_read(void)
{
uint64_t v;
__asm__ volatile ("rdpr %%ver, %0\n" : "=r" (v));
return v;
}
 
/** Read Trap Base Address register.
*
* @return Current value in TBA.
*/
static inline uint64_t tba_read(void)
{
uint64_t v;
__asm__ volatile ("rdpr %%tba, %0\n" : "=r" (v));
return v;
}
 
/** Read Trap Program Counter register.
*
* @return Current value in TPC.
*/
static inline uint64_t tpc_read(void)
{
uint64_t v;
__asm__ volatile ("rdpr %%tpc, %0\n" : "=r" (v));
return v;
}
 
/** Read Trap Level register.
*
* @return Current value in TL.
*/
static inline uint64_t tl_read(void)
{
uint64_t v;
__asm__ volatile ("rdpr %%tl, %0\n" : "=r" (v));
return v;
}
 
/** Write Trap Base Address register.
*
* @param v New value of TBA.
*/
static inline void tba_write(uint64_t v)
{
__asm__ volatile ("wrpr %0, %1, %%tba\n" : : "r" (v), "i" (0));
}
 
/** Load uint64_t from alternate space.
*
* @param asi ASI determining the alternate space.
* @param va Virtual address within the ASI.
*
* @return Value read from the virtual address in the specified address space.
*/
static inline uint64_t asi_u64_read(asi_t asi, uintptr_t va)
{
uint64_t v;
__asm__ volatile ("ldxa [%1] %2, %0\n" : "=r" (v) : "r" (va), "i" (asi));
return v;
}
 
/** Store uint64_t to alternate space.
*
* @param asi ASI determining the alternate space.
* @param va Virtual address within the ASI.
* @param v Value to be written.
*/
static inline void asi_u64_write(asi_t asi, uintptr_t va, uint64_t v)
{
__asm__ volatile ("stxa %0, [%1] %2\n" : : "r" (v), "r" (va), "i" (asi) : "memory");
}
 
void cpu_halt(void);
void cpu_sleep(void);
void asm_delay_loop(uint32_t t);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/sparc64/include/interrupt.h
0,0 → 1,79
/*
* 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 sparc64interrupt sparc64
* @ingroup interrupt
* @{
*/
/** @file
*/
 
#ifndef __sparc64_INTERRUPT_H__
#define __sparc64_INTERRUPT_H__
 
#include <typedefs.h>
#include <arch/types.h>
 
#define IRQ_COUNT 1 /* TODO */
 
#define IVT_ITEMS 15
#define IVT_FIRST 1
 
/* Dummy macros. */
#define IRQ_KBD 2
#define VECTOR_KBD IRQ_KBD
 
#define trap_virtual_enable_irqs(x)
#define trap_virtual_eoi()
 
struct istate {
};
 
static inline void istate_set_retaddr(istate_t *istate, uintptr_t retaddr)
{
/* TODO */
}
static inline int istate_from_uspace(istate_t *istate)
{
/* TODO */
return 0;
}
static inline unative_t istate_get_pc(istate_t *istate)
{
/* TODO */
return 0;
}
 
 
extern void interrupt_register(int n, const char *name, iroutine f);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/sparc64/include/byteorder.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 sparc64
* @{
*/
/** @file
*/
 
#ifndef __sparc64_BYTEORDER_H__
#define __sparc64_BYTEORDER_H__
 
#include <arch/types.h>
#include <byteorder.h>
 
static inline uint64_t uint64_t_le2host(uint64_t n)
{
return uint64_t_byteorder_swap(n);
}
 
static inline unative_t unative_t_le2host(unative_t n)
{
return uint64_t_byteorder_swap(n);
}
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/sparc64/include/types.h
0,0 → 1,66
/*
* 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef __sparc64_TYPES_H__
#define __sparc64_TYPES_H__
 
#define NULL 0
 
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef signed long int64_t;
 
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long uint64_t;
 
typedef uint64_t uintptr_t;
typedef uint64_t pfn_t;
 
typedef uint64_t ipl_t;
 
typedef uint64_t unative_t;
typedef int64_t native_t;
 
typedef struct pte pte_t;
 
typedef uint8_t asi_t;
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/sparc64/include/memstr.h
0,0 → 1,49
/*
* Copyright (C) 2005 Sergey Bondari
* 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef __sparc64_MEMSTR_H__
#define __sparc64_MEMSTR_H__
 
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt))
 
extern void memsetw(uintptr_t dst, size_t cnt, uint16_t x);
extern void memsetb(uintptr_t dst, size_t cnt, uint8_t x);
 
extern int memcmp(uintptr_t src, uintptr_t dst, int cnt);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/sparc64/include/faddr.h
0,0 → 1,46
/*
* 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef __sparc64_FADDR_H__
#define __sparc64_FADDR_H__
 
#include <arch/types.h>
 
#define FADDR(fptr) ((uintptr_t) (fptr))
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/sparc64/include/context.h
0,0 → 1,94
/*
* 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef __sparc64_CONTEXT_H__
#define __sparc64_CONTEXT_H__
 
#ifndef __sparc64_STACK_H__
# include <arch/stack.h>
#endif
 
#ifndef __sparc64_TYPES_H__
# include <arch/types.h>
#endif
 
#ifndef __ALIGN_H__
# include <align.h>
#endif
 
#define SP_DELTA STACK_WINDOW_SAVE_AREA_SIZE
 
#ifdef context_set
#undef context_set
#endif
 
#define context_set(c, _pc, stack, size) \
(c)->pc = ((uintptr_t) _pc) - 8; \
(c)->sp = ((uintptr_t) stack) + ALIGN_UP((size), STACK_ALIGNMENT) - (STACK_BIAS + SP_DELTA); \
(c)->fp = -STACK_BIAS; \
(c)->cleanwin = 0
 
/*
* Only save registers that must be preserved across
* function calls.
*/
struct context {
uintptr_t sp; /* %o6 */
uintptr_t pc; /* %o7 */
uint64_t i0;
uint64_t i1;
uint64_t i2;
uint64_t i3;
uint64_t i4;
uint64_t i5;
uintptr_t fp; /* %i6 */
uintptr_t i7;
uint64_t l0;
uint64_t l1;
uint64_t l2;
uint64_t l3;
uint64_t l4;
uint64_t l5;
uint64_t l6;
uint64_t l7;
ipl_t ipl;
uint64_t cleanwin;
};
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/sparc64/include/cpu.h
0,0 → 1,60
/*
* 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef __sparc64_CPU_H__
#define __sparc64_CPU_H__
 
#include <arch/register.h>
 
#define MANUF_FUJITSU 0x04
#define MANUF_ULTRASPARC 0x17 /**< UltraSPARC I, UltraSPARC II */
#define MANUF_SUN 0x3e
 
#define IMPL_ULTRASPARCI 0x10
#define IMPL_ULTRASPARCII 0x11
#define IMPL_ULTRASPARCII_I 0x12
#define IMPL_ULTRASPARCII_E 0x13
#define IMPL_ULTRASPARCIII 0x15
#define IMPL_ULTRASPARCIV_PLUS 0x19
 
#define IMPL_SPARC64V 0x5
 
struct cpu_arch {
ver_reg_t ver;
};
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/sparc64/include/debug.h
0,0 → 1,42
/*
* Copyright (C) 2005
* 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 sparc64debug
* @{
*/
/** @file
*/
 
#ifndef __sparc64_DEBUG_H__
#define __sparc64_DEBUG_H__
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/sparc64/include/context_offset.h
0,0 → 1,25
/* This file is automatically generated by gencontext.c. */
/* struct context */
#define OFFSET_SP 0x0
#define OFFSET_PC 0x8
#define OFFSET_I0 0x10
#define OFFSET_I1 0x18
#define OFFSET_I2 0x20
#define OFFSET_I3 0x28
#define OFFSET_I4 0x30
#define OFFSET_I5 0x38
#define OFFSET_FP 0x40
#define OFFSET_I7 0x48
#define OFFSET_L0 0x50
#define OFFSET_L1 0x58
#define OFFSET_L2 0x60
#define OFFSET_L3 0x68
#define OFFSET_L4 0x70
#define OFFSET_L5 0x78
#define OFFSET_L6 0x80
#define OFFSET_L7 0x88
#define OFFSET_CLEANWIN 0x98
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/sparc64/include/fpu_context.h
0,0 → 1,47
/*
* 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef __sparc64_FPU_CONTEXT_H__
#define __sparc64_FPU_CONTEXT_H__
 
#include <arch/types.h>
 
struct fpu_context {
};
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/sparc64/include/arg.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 sparc64
* @{
*/
/** @file
*/
 
#ifndef __sparc64_ARG_H__
#define __sparc64_ARG_H__
 
#include <stdarg.h>
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/sparc64/include/proc/task.h
0,0 → 1,48
/*
* 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 sparc64proc
* @{
*/
/** @file
*/
 
#ifndef __sparc64_TASK_H__
#define __sparc64_TASK_H__
 
typedef struct {
} task_arch_t;
 
#define task_create_arch(t)
#define task_destroy_arch(t)
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/sparc64/include/proc/thread.h
0,0 → 1,47
/*
* 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 sparc64proc
* @{
*/
/** @file
*/
 
#ifndef __sparc64_THREAD_H__
#define __sparc64_THREAD_H__
 
typedef struct {
} thread_arch_t;
 
#define thread_create_arch(t)
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/sparc64/src/sparc64.c
0,0 → 1,95
/*
* 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 sparc64
* @{
*/
/** @file
*/
 
#include <arch.h>
#include <debug.h>
#include <arch/trap/trap.h>
#include <arch/console.h>
#include <arch/drivers/tick.h>
#include <proc/thread.h>
#include <console/console.h>
#include <arch/boot/boot.h>
#include <arch/arch.h>
#include <arch/mm/tlb.h>
#include <mm/asid.h>
 
bootinfo_t bootinfo;
 
void arch_pre_mm_init(void)
{
trap_init();
tick_init();
}
 
void arch_post_mm_init(void)
{
standalone_sparc64_console_init();
}
 
void arch_pre_smp_init(void)
{
}
 
void arch_post_smp_init(void)
{
thread_t *t;
 
/*
* Create thread that polls keyboard.
*/
t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll");
if (!t)
panic("cannot create kkbdpoll\n");
thread_ready(t);
}
 
void calibrate_delay_loop(void)
{
}
 
/** Acquire console back for kernel
*
*/
void arch_grab_console(void)
{
}
/** Return console to userspace
*
*/
void arch_release_console(void)
{
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/sparc64/src/start.S
0,0 → 1,221
#
# 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.
#
 
#include <arch/regdef.h>
#include <arch/boot/boot.h>
 
#include <arch/mm/mmu.h>
#include <arch/mm/tlb.h>
#include <arch/mm/tte.h>
 
.register %g2, #scratch
.register %g3, #scratch
.register %g6, #scratch
.register %g7, #scratch
 
.section K_TEXT_START, "ax"
 
/*
* Here is where the kernel is passed control
* from the boot loader.
*
* The registers are expected to be in this state:
* - %o0 bootinfo structure address
* - %o1 bootinfo structure size
*
* Moreover, we depend on boot having established the
* following environment:
* - TLBs are on
* - identity mapping for the kernel image
* - identity mapping for memory stack
*/
 
.global kernel_image_start
kernel_image_start:
 
/*
* Setup basic runtime environment.
*/
 
flushw ! flush all but the active register window
wrpr %g0, 0, %tl ! TL = 0, primary context register is used
 
! Disable interrupts and disable 32-bit address masking.
rdpr %pstate, %g1
and %g1, ~(PSTATE_AM_BIT|PSTATE_IE_BIT), %g1
wrpr %g1, 0, %pstate
 
wrpr %r0, 0, %pil ! intialize %pil
 
/*
* Copy the bootinfo structure passed from the boot loader
* to the kernel bootinfo structure.
*/
mov %o1, %o2
mov %o0, %o1
set bootinfo, %o0
call memcpy
nop
 
/*
* Switch to kernel trap table.
*/
set trap_table, %g1
wrpr %g1, 0, %tba
 
/*
* Take over the DMMU by installing global locked
* TTE entry identically mapping the first 4M
* of memory.
*
* In case of DMMU, no FLUSH instructions need to be
* issued. Because of that, the old DTLB contents can
* be demapped pretty straightforwardly and without
* causing any traps.
*/
 
wr %g0, ASI_DMMU, %asi
 
#define SET_TLB_DEMAP_CMD(r1, context_id) \
set (TLB_DEMAP_CONTEXT<<TLB_DEMAP_TYPE_SHIFT) | (context_id<<TLB_DEMAP_CONTEXT_SHIFT), %r1
! demap context 0
SET_TLB_DEMAP_CMD(g1, TLB_DEMAP_NUCLEUS)
stxa %g0, [%g1] ASI_DMMU_DEMAP
membar #Sync
 
#define SET_TLB_TAG(r1, context) \
set VMA | (context<<TLB_TAG_ACCESS_CONTEXT_SHIFT), %r1
 
! write DTLB tag
SET_TLB_TAG(g1, MEM_CONTEXT_KERNEL)
stxa %g1, [VA_DMMU_TAG_ACCESS] %asi
membar #Sync
 
#define SET_TLB_DATA(r1, r2, imm) \
set TTE_L | TTE_CP | TTE_P | TTE_W | LMA | imm, %r1; \
set PAGESIZE_4M, %r2; \
sllx %r2, TTE_SIZE_SHIFT, %r2; \
or %r1, %r2, %r1; \
set 1, %r2; \
sllx %r2, TTE_V_SHIFT, %r2; \
or %r1, %r2, %r1;
! write DTLB data and install the kernel mapping
SET_TLB_DATA(g1, g2, TTE_G)
stxa %g1, [%g0] ASI_DTLB_DATA_IN_REG
membar #Sync
/*
* Now is time to take over the IMMU.
* Unfortunatelly, it cannot be done as easily as the DMMU,
* because the IMMU is mapping the code it executes.
*
* [ Note that brave experiments with disabling the IMMU
* and using the DMMU approach failed after a dozen
* of desparate days with only little success. ]
*
* The approach used here is inspired from OpenBSD.
* First, the kernel creates IMMU mapping for itself
* in context 1 (MEM_CONTEXT_TEMP) and switches to
* it. Context 0 (MEM_CONTEXT_KERNEL) can be demapped
* afterwards and replaced with the kernel permanent
* mapping. Finally, the kernel switches back to
* context 0 and demaps context 1.
*
* Moreover, the IMMU requires use of the FLUSH instructions.
* But that is OK because we always use operands with
* addresses already mapped by the taken over DTLB.
*/
set kernel_image_start, %g7
! write ITLB tag of context 1
SET_TLB_TAG(g1, MEM_CONTEXT_TEMP)
set VA_DMMU_TAG_ACCESS, %g2
stxa %g1, [%g2] ASI_IMMU
flush %g7
 
! write ITLB data and install the temporary mapping in context 1
SET_TLB_DATA(g1, g2, 0) ! use non-global mapping
stxa %g1, [%g0] ASI_ITLB_DATA_IN_REG
flush %g7
! switch to context 1
set MEM_CONTEXT_TEMP, %g1
stxa %g1, [VA_PRIMARY_CONTEXT_REG] %asi ! ASI_DMMU is correct here !!!
flush %g7
! demap context 0
SET_TLB_DEMAP_CMD(g1, TLB_DEMAP_NUCLEUS)
stxa %g0, [%g1] ASI_IMMU_DEMAP
flush %g7
! write ITLB tag of context 0
SET_TLB_TAG(g1, MEM_CONTEXT_KERNEL)
set VA_DMMU_TAG_ACCESS, %g2
stxa %g1, [%g2] ASI_IMMU
flush %g7
 
! write ITLB data and install the permanent kernel mapping in context 0
SET_TLB_DATA(g1, g2, 0) ! use non-global mapping
stxa %g1, [%g0] ASI_ITLB_DATA_IN_REG
flush %g7
 
! switch to context 0
stxa %g0, [VA_PRIMARY_CONTEXT_REG] %asi ! ASI_DMMU is correct here !!!
flush %g7
 
! ensure nucleus mapping
wrpr %g0, 1, %tl
 
! set context 1 in the primary context register
set MEM_CONTEXT_TEMP, %g1
stxa %g1, [VA_PRIMARY_CONTEXT_REG] %asi ! ASI_DMMU is correct here !!!
flush %g7
 
! demap context 1
SET_TLB_DEMAP_CMD(g1, TLB_DEMAP_PRIMARY)
stxa %g0, [%g1] ASI_IMMU_DEMAP
flush %g7
! set context 0 in the primary context register
stxa %g0, [VA_PRIMARY_CONTEXT_REG] %asi ! ASI_DMMU is correct here !!!
flush %g7
! set TL back to 0
wrpr %g0, 0, %tl
call main_bsp
nop
 
/* Not reached. */
 
2:
b 2b
nop
/tags/0.2.0.3/kernel/arch/sparc64/src/console.c
0,0 → 1,80
/*
* 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 sparc64
* @{
*/
/** @file
*/
 
#include <arch/console.h>
#include <arch/types.h>
#include <typedefs.h>
#include <genarch/fb/fb.h>
#include <arch/drivers/fb.h>
#include <arch/drivers/i8042.h>
#include <genarch/i8042/i8042.h>
#include <console/chardev.h>
#include <console/console.h>
#include <arch/asm.h>
#include <arch/register.h>
#include <proc/thread.h>
#include <arch/mm/tlb.h>
#include <arch/boot/boot.h>
 
#define KEYBOARD_POLL_PAUSE 50000 /* 50ms */
 
/** Initialize kernel console to use framebuffer and keyboard directly. */
void standalone_sparc64_console_init(void)
{
stdin = NULL;
 
if (bootinfo.keyboard.addr)
kbd_init();
fb_init(bootinfo.screen.addr, bootinfo.screen.width, bootinfo.screen.height,
bootinfo.screen.bpp, bootinfo.screen.scanline);
}
 
/** Kernel thread for polling keyboard.
*
* @param arg Ignored.
*/
void kkbdpoll(void *arg)
{
if (!bootinfo.keyboard.addr)
return;
while (1) {
i8042_poll();
thread_usleep(KEYBOARD_POLL_PAUSE);
}
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/sparc64/src/mm/tlb.c
0,0 → 1,226
/*
* 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 sparc64mm
* @{
*/
/** @file
*/
 
#include <arch/mm/tlb.h>
#include <mm/tlb.h>
#include <arch/mm/frame.h>
#include <arch/mm/page.h>
#include <arch/mm/mmu.h>
#include <mm/asid.h>
#include <print.h>
#include <arch/types.h>
#include <typedefs.h>
#include <config.h>
#include <arch/trap/trap.h>
#include <panic.h>
#include <arch/asm.h>
#include <symtab.h>
 
#include <arch/drivers/fb.h>
#include <arch/drivers/i8042.h>
 
char *context_encoding[] = {
"Primary",
"Secondary",
"Nucleus",
"Reserved"
};
 
void tlb_arch_init(void)
{
/*
* TLBs are actually initialized by
* take_over_tlb_and_tt() early
* in start.S.
*/
}
 
/** Insert privileged mapping into DMMU TLB.
*
* @param page Virtual page address.
* @param frame Physical frame address.
* @param pagesize Page size.
* @param locked True for permanent mappings, false otherwise.
* @param cacheable True if the mapping is cacheable, false otherwise.
*/
void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize, bool locked, bool cacheable)
{
tlb_tag_access_reg_t tag;
tlb_data_t data;
page_address_t pg;
frame_address_t fr;
 
pg.address = page;
fr.address = frame;
 
tag.value = ASID_KERNEL;
tag.vpn = pg.vpn;
 
dtlb_tag_access_write(tag.value);
 
data.value = 0;
data.v = true;
data.size = pagesize;
data.pfn = fr.pfn;
data.l = locked;
data.cp = cacheable;
data.cv = cacheable;
data.p = true;
data.w = true;
data.g = true;
 
dtlb_data_in_write(data.value);
}
 
/** ITLB miss handler. */
void fast_instruction_access_mmu_miss(void)
{
panic("%s\n", __FUNCTION__);
}
 
/** DTLB miss handler. */
void fast_data_access_mmu_miss(void)
{
tlb_tag_access_reg_t tag;
uintptr_t tpc;
char *tpc_str;
 
tag.value = dtlb_tag_access_read();
if (tag.context != ASID_KERNEL || tag.vpn == 0) {
tpc = tpc_read();
tpc_str = get_symtab_entry(tpc);
 
printf("Faulting page: %p, ASID=%d\n", tag.vpn * PAGE_SIZE, tag.context);
printf("TPC=%p, (%s)\n", tpc, tpc_str ? tpc_str : "?");
panic("%s\n", __FUNCTION__);
}
 
/*
* Identity map piece of faulting kernel address space.
*/
dtlb_insert_mapping(tag.vpn * PAGE_SIZE, tag.vpn * FRAME_SIZE, PAGESIZE_8K, false, true);
}
 
/** DTLB protection fault handler. */
void fast_data_access_protection(void)
{
panic("%s\n", __FUNCTION__);
}
 
/** Print contents of both TLBs. */
void tlb_print(void)
{
int i;
tlb_data_t d;
tlb_tag_read_reg_t t;
printf("I-TLB contents:\n");
for (i = 0; i < ITLB_ENTRY_COUNT; i++) {
d.value = itlb_data_access_read(i);
t.value = itlb_tag_read_read(i);
printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, ie=%d, soft2=%#x, diag=%#x, pfn=%#x, soft=%#x, l=%d, cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n",
i, t.vpn, t.context, d.v, d.size, d.nfo, d.ie, d.soft2, d.diag, d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g);
}
 
printf("D-TLB contents:\n");
for (i = 0; i < DTLB_ENTRY_COUNT; i++) {
d.value = dtlb_data_access_read(i);
t.value = dtlb_tag_read_read(i);
printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, ie=%d, soft2=%#x, diag=%#x, pfn=%#x, soft=%#x, l=%d, cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n",
i, t.vpn, t.context, d.v, d.size, d.nfo, d.ie, d.soft2, d.diag, d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g);
}
 
}
 
/** Invalidate all unlocked ITLB and DTLB entries. */
void tlb_invalidate_all(void)
{
int i;
tlb_data_t d;
tlb_tag_read_reg_t t;
 
for (i = 0; i < ITLB_ENTRY_COUNT; i++) {
d.value = itlb_data_access_read(i);
if (!d.l) {
t.value = itlb_tag_read_read(i);
d.v = false;
itlb_tag_access_write(t.value);
itlb_data_access_write(i, d.value);
}
}
for (i = 0; i < DTLB_ENTRY_COUNT; i++) {
d.value = dtlb_data_access_read(i);
if (!d.l) {
t.value = dtlb_tag_read_read(i);
d.v = false;
dtlb_tag_access_write(t.value);
dtlb_data_access_write(i, d.value);
}
}
}
 
/** Invalidate all ITLB and DTLB entries that belong to specified ASID (Context).
*
* @param asid Address Space ID.
*/
void tlb_invalidate_asid(asid_t asid)
{
/* TODO: write asid to some Context register and encode the register in second parameter below. */
itlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_NUCLEUS, 0);
dtlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_NUCLEUS, 0);
}
 
/** Invalidate all ITLB and DTLB entries for specified page range in specified address space.
*
* @param asid Address Space ID.
* @param page First page which to sweep out from ITLB and DTLB.
* @param cnt Number of ITLB and DTLB entries to invalidate.
*/
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt)
{
int i;
for (i = 0; i < cnt; i++) {
/* TODO: write asid to some Context register and encode the register in second parameter below. */
itlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, page + i * PAGE_SIZE);
dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, page + i * PAGE_SIZE);
}
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/sparc64/src/mm/frame.c
0,0 → 1,76
/*
* 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 sparc64mm
* @{
*/
/** @file
*/
 
#include <arch/mm/frame.h>
#include <mm/frame.h>
#include <arch/boot/boot.h>
#include <arch/types.h>
#include <config.h>
#include <align.h>
#include <macros.h>
 
uintptr_t last_frame = NULL;
 
/** Create memory zones according to information stored in bootinfo.
*
* Walk the bootinfo memory map and create frame zones according to it.
* The first frame is not blacklisted here as it is done in generic
* frame_init().
*/
void frame_arch_init(void)
{
int i;
pfn_t confdata;
 
for (i = 0; i < bootinfo.memmap.count; i++) {
uintptr_t start = bootinfo.memmap.zones[i].start;
size_t size = bootinfo.memmap.zones[i].size;
 
/*
* The memmap is created by HelenOS boot loader.
* It already contains no holes.
*/
confdata = ADDR2PFN(start);
if (confdata == 0)
confdata = 2;
zone_create(ADDR2PFN(start), SIZE2FRAMES(ALIGN_DOWN(size, FRAME_SIZE)), confdata, 0);
last_frame = max(last_frame, start + ALIGN_UP(size, FRAME_SIZE));
}
 
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/sparc64/src/mm/page.c
0,0 → 1,96
/*
* 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 sparc64mm
* @{
*/
/** @file
*/
 
#include <arch/mm/page.h>
#include <arch/mm/tlb.h>
#include <genarch/mm/page_ht.h>
#include <mm/frame.h>
#include <arch/mm/frame.h>
#include <bitops.h>
#include <debug.h>
#include <align.h>
 
void page_arch_init(void)
{
page_mapping_operations = &ht_mapping_operations;
}
 
uintptr_t hw_map(uintptr_t physaddr, size_t size)
{
unsigned int order;
int i;
 
struct {
int pagesize;
size_t increment;
count_t count;
} sizemap[] = {
{ PAGESIZE_8K, 0, 1 }, /* 8K */
{ PAGESIZE_8K, PAGE_SIZE, 2 }, /* 16K */
{ PAGESIZE_8K, PAGE_SIZE, 4 }, /* 32K */
{ PAGESIZE_64K, 0, 1}, /* 64K */
{ PAGESIZE_64K, 8*PAGE_SIZE, 2 }, /* 128K */
{ PAGESIZE_64K, 8*PAGE_SIZE, 4 }, /* 256K */
{ PAGESIZE_512K, 0, 1 }, /* 512K */
{ PAGESIZE_512K, 64*PAGE_SIZE, 2 }, /* 1M */
{ PAGESIZE_512K, 64*PAGE_SIZE, 4 }, /* 2M */
{ PAGESIZE_4M, 0, 1 } /* 4M */
};
ASSERT(size <= 4*1024*1024);
if (size <= FRAME_SIZE)
order = 0;
else
order = (fnzb32(size - 1) + 1) - FRAME_WIDTH;
 
/*
* Use virtual addresses that are beyond the limit of physical memory.
* Thus, the physical address space will not be wasted by holes created
* by frame_alloc().
*/
ASSERT(last_frame);
uintptr_t virtaddr = ALIGN_UP(last_frame, 1<<(order + FRAME_WIDTH));
last_frame = ALIGN_UP(virtaddr + size, 1<<(order + FRAME_WIDTH));
for (i = 0; i < sizemap[order].count; i++)
dtlb_insert_mapping(virtaddr + i*sizemap[order].increment,
physaddr + i*sizemap[order].increment,
sizemap[order].pagesize, true, false);
return virtaddr;
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/sparc64/src/mm/memory_init.c
0,0 → 1,49
/*
* 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 sparc64mm
* @{
*/
/** @file
*/
 
#include <arch/mm/memory_init.h>
#include <arch/boot/boot.h>
#include <typedefs.h>
 
/** Return total size of available memory in bytes.
*
* @return Size of available memory in bytes.
*/
size_t get_memory_size(void)
{
return bootinfo.memmap.total;
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/sparc64/src/mm/as.c
0,0 → 1,48
/*
* 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 sparc64mm
* @{
*/
/** @file
*/
 
#include <arch/mm/as.h>
#include <genarch/mm/as_ht.h>
#include <genarch/mm/asid_fifo.h>
 
/** Architecture dependent address space init. */
void as_arch_init(void)
{
as_operations = &as_ht_operations;
asid_fifo_init();
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/sparc64/src/asm.S
0,0 → 1,108
#
# 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.
#
 
#include <arch/stack.h>
#include <arch/regdef.h>
 
.text
 
.global memcpy
.global memcpy_from_uspace
.global memcpy_to_uspace
.global memcpy_from_uspace_failover_address
.global memcpy_to_uspace_failover_address
.global memsetb
 
 
memcpy:
memcpy_from_uspace:
memcpy_to_uspace:
.register %g2, #scratch
.register %g3, #scratch
add %o1, 7, %g1
and %g1, -8, %g1
cmp %o1, %g1
be,pn %xcc, 3f
add %o0, 7, %g1
mov 0, %g3
0:
brz,pn %o2, 2f
mov 0, %g2
1:
ldub [%g3 + %o1], %g1
add %g2, 1, %g2
cmp %o2, %g2
stb %g1, [%g3 + %o0]
bne,pt %xcc, 1b
mov %g2, %g3
2:
jmp %o7 + 8 ! exit point
mov %o1, %o0
3:
and %g1, -8, %g1
cmp %o0, %g1
bne,pt %xcc, 0b
mov 0, %g3
srlx %o2, 3, %g4
brz,pn %g4, 5f
mov 0, %g5
4:
sllx %g3, 3, %g2
add %g5, 1, %g3
ldx [%o1 + %g2], %g1
mov %g3, %g5
cmp %g4, %g3
bne,pt %xcc, 4b
stx %g1, [%o0 + %g2]
5:
and %o2, 7, %o2
brz,pn %o2, 2b
sllx %g4, 3, %g1
mov 0, %g2
add %g1, %o0, %o0
add %g1, %o1, %g4
mov 0, %g3
6:
ldub [%g2 + %g4], %g1
stb %g1, [%g2 + %o0]
add %g3, 1, %g2
cmp %o2, %g2
bne,pt %xcc, 6b
mov %g2, %g3
 
jmp %o7 + 8 ! exit point
mov %o1, %o0
 
memcpy_from_uspace_failover_address:
memcpy_to_uspace_failover_address:
jmp %o7 + 8 ! exit point
mov %g0, %o0 ! return 0 on failure
 
memsetb:
b _memsetb
nop
/tags/0.2.0.3/kernel/arch/sparc64/src/drivers/i8042.c
0,0 → 1,50
/*
* 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 sparc64
* @{
*/
/** @file
*/
 
#include <arch/drivers/i8042.h>
#include <genarch/i8042/i8042.h>
#include <arch/boot/boot.h>
#include <arch/types.h>
#include <arch/mm/page.h>
 
volatile uint8_t *kbd_virt_address = NULL;
 
void kbd_init()
{
kbd_virt_address = (uint8_t *) hw_map(bootinfo.keyboard.addr, LAST_REG);
i8042_init();
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/sparc64/src/drivers/tick.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 sparc64
* @{
*/
/** @file
*/
 
#include <arch/drivers/tick.h>
#include <arch/interrupt.h>
#include <arch/asm.h>
#include <arch/register.h>
#include <debug.h>
#include <time/clock.h>
#include <typedefs.h>
 
/** Initialize tick interrupt. */
void tick_init(void)
{
tick_compare_reg_t compare;
interrupt_register(14, "tick_int", tick_interrupt);
compare.int_dis = false;
compare.tick_cmpr = TICK_DELTA;
tick_compare_write(compare.value);
tick_write(0);
}
 
/** Process tick interrupt.
*
* @param n Interrupt Level, 14, (can be ignored)
* @param istate Interrupted state.
*/
void tick_interrupt(int n, istate_t *istate)
{
softint_reg_t softint, clear;
softint.value = softint_read();
/*
* Make sure we are servicing interrupt_level_14
*/
ASSERT(n == 14);
/*
* Make sure we are servicing TICK_INT.
*/
ASSERT(softint.tick_int);
 
/*
* Clear tick interrupt.
*/
clear.value = 0;
clear.tick_int = 1;
clear_softint_write(clear.value);
/*
* Restart counter.
*/
tick_write(0);
clock();
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/sparc64/src/proc/scheduler.c
0,0 → 1,83
/*
* 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 sparc64proc
* @{
*/
/** @file
*/
 
#include <proc/scheduler.h>
#include <proc/thread.h>
#include <arch.h>
#include <arch/mm/tlb.h>
#include <arch/mm/page.h>
#include <config.h>
#include <align.h>
 
/** Perform sparc64 specific tasks needed before the new task is run. */
void before_task_runs_arch(void)
{
}
 
/** Ensure that thread's kernel stack is locked in TLB. */
void before_thread_runs_arch(void)
{
uintptr_t base;
base = ALIGN_DOWN(config.base, 1<<KERNEL_PAGE_WIDTH);
 
if ((uintptr_t) THREAD->kstack < base || (uintptr_t) THREAD->kstack > base + (1<<KERNEL_PAGE_WIDTH)) {
/*
* Kernel stack of this thread is not locked in DTLB.
* First, make sure it is not mapped already.
* If not, create a locked mapping for it.
*/
dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, (uintptr_t) THREAD->kstack);
dtlb_insert_mapping((uintptr_t) THREAD->kstack, KA2PA(THREAD->kstack), PAGESIZE_8K, true, true);
}
}
 
/** Unlock thread's stack from TLB, if necessary. */
void after_thread_ran_arch(void)
{
uintptr_t base;
 
base = ALIGN_DOWN(config.base, 1<<KERNEL_PAGE_WIDTH);
 
if ((uintptr_t) THREAD->kstack < base || (uintptr_t) THREAD->kstack > base + (1<<KERNEL_PAGE_WIDTH)) {
/*
* Kernel stack of this thread is locked in DTLB.
* Destroy the mapping.
*/
dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, (uintptr_t) THREAD->kstack);
}
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/sparc64/src/ddi/ddi.c
0,0 → 1,57
/*
* 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 sparc64ddi
* @{
*/
/** @file
*/
 
#include <ddi/ddi.h>
#include <proc/task.h>
#include <arch/types.h>
#include <typedefs.h>
 
/** Enable I/O space range for task.
*
* Interrupts are disabled and task is locked.
*
* @param task Task.
* @param ioaddr Startign I/O space address.
* @param size Size of the enabled I/O range.
*
* @return 0 on success or an error code from errno.h.
*/
int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
{
return 0;
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/sparc64/src/trap/interrupt.c
0,0 → 1,63
/*
* 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 sparc64interrupt
* @{
*/
/** @file
*/
 
#include <arch/interrupt.h>
#include <interrupt.h>
#include <arch/types.h>
#include <debug.h>
#include <ipc/sysipc.h>
 
/** Register Interrupt Level Handler.
*
* @param n Interrupt Level (1 - 15).
* @param name Short descriptive string.
* @param f Handler.
*/
void interrupt_register(int n, const char *name, iroutine f)
{
ASSERT(n >= IVT_FIRST && n <= IVT_ITEMS);
exc_register(n - 1, name, f);
}
 
/* Reregister irq to be IPC-ready */
void irq_ipc_bind_arch(unative_t irq)
{
panic("not implemented\n");
/* TODO */
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/sparc64/src/trap/exception.c
0,0 → 1,66
/*
* 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 sparc64interrupt
* @{
*/
/** @file
*
*/
 
#include <arch/trap/exception.h>
#include <arch/asm.h>
#include <debug.h>
 
/** Handle instruction_access_exception. */
void do_instruction_access_exc(void)
{
panic("Instruction Access Exception\n");
}
 
/** Handle mem_address_not_aligned. */
void do_mem_address_not_aligned(void)
{
panic("Memory Address Not Aligned\n");
}
 
/** Handle data_access_error. */
void do_data_access_error(void)
{
panic("Data Access Error: %p\n", tpc_read());
}
 
/** Handle mem_address_not_aligned. */
void do_illegal_instruction(void)
{
panic("Illegal Instruction: %p\n", tpc_read());
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/sparc64/src/trap/trap.c
0,0 → 1,56
/*
* 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 sparc64interrupt
* @{
*/
/** @file
*
*/
 
#include <arch/trap/trap.h>
#include <arch/trap/trap_table.h>
#include <arch/trap/regwin.h>
#include <arch/trap/exception.h>
#include <arch/trap/interrupt.h>
#include <arch/trap/mmu.h>
#include <arch/asm.h>
#include <memstr.h>
#include <debug.h>
#include <arch/types.h>
#include <typedefs.h>
#include <arch/drivers/tick.h>
 
/** Initialize trap table. */
void trap_init(void)
{
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/sparc64/src/trap/trap_table.S
0,0 → 1,379
#
# 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.
#
 
/**
* This file contains kernel trap table.
*/
 
.register %g2, #scratch
.register %g3, #scratch
.register %g6, #scratch
.register %g7, #scratch
 
.text
 
#include <arch/trap/trap_table.h>
#include <arch/trap/regwin.h>
#include <arch/trap/interrupt.h>
#include <arch/trap/exception.h>
#include <arch/trap/mmu.h>
#include <arch/stack.h>
 
#define TABLE_SIZE TRAP_TABLE_SIZE
#define ENTRY_SIZE TRAP_TABLE_ENTRY_SIZE
 
/*
* Kernel trap table.
*/
.align TABLE_SIZE
.global trap_table
trap_table:
 
/* TT = 0x08, TL = 0, instruction_access_exception */
.org trap_table + TT_INSTRUCTION_ACCESS_EXCEPTION*ENTRY_SIZE
.global instruction_access_exception
instruction_access_exception:
SIMPLE_HANDLER do_instruction_access_exc
 
/* TT = 0x10, TL = 0, illegal_instruction */
.org trap_table + TT_ILLEGAL_INSTRUCTION*ENTRY_SIZE
.global illegal_instruction
illegal_instruction:
SIMPLE_HANDLER do_illegal_instruction
 
/* TT = 0x24, TL = 0, clean_window handler */
.org trap_table + TT_CLEAN_WINDOW*ENTRY_SIZE
.global clean_window_handler
clean_window_handler:
CLEAN_WINDOW_HANDLER
 
/* TT = 0x32, TL = 0, data_access_error */
.org trap_table + TT_DATA_ACCESS_ERROR*ENTRY_SIZE
.global data_access_error
data_access_error:
SIMPLE_HANDLER do_data_access_error
 
/* TT = 0x34, TL = 0, mem_address_not_aligned */
.org trap_table + TT_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
.global mem_address_not_aligned
mem_address_not_aligned:
SIMPLE_HANDLER do_mem_address_not_aligned
 
/* TT = 0x41, TL = 0, interrupt_level_1 handler */
.org trap_table + TT_INTERRUPT_LEVEL_1*ENTRY_SIZE
.global interrupt_level_1_handler
interrupt_level_1_handler:
INTERRUPT_LEVEL_N_HANDLER 1
 
/* TT = 0x42, TL = 0, interrupt_level_2 handler */
.org trap_table + TT_INTERRUPT_LEVEL_2*ENTRY_SIZE
.global interrupt_level_2_handler
interrupt_level_2_handler:
INTERRUPT_LEVEL_N_HANDLER 2
 
/* TT = 0x43, TL = 0, interrupt_level_3 handler */
.org trap_table + TT_INTERRUPT_LEVEL_3*ENTRY_SIZE
.global interrupt_level_3_handler
interrupt_level_3_handler:
INTERRUPT_LEVEL_N_HANDLER 3
 
/* TT = 0x44, TL = 0, interrupt_level_4 handler */
.org trap_table + TT_INTERRUPT_LEVEL_4*ENTRY_SIZE
.global interrupt_level_4_handler
interrupt_level_4_handler:
INTERRUPT_LEVEL_N_HANDLER 4
 
/* TT = 0x45, TL = 0, interrupt_level_5 handler */
.org trap_table + TT_INTERRUPT_LEVEL_5*ENTRY_SIZE
.global interrupt_level_5_handler
interrupt_level_5_handler:
INTERRUPT_LEVEL_N_HANDLER 5
 
/* TT = 0x46, TL = 0, interrupt_level_6 handler */
.org trap_table + TT_INTERRUPT_LEVEL_6*ENTRY_SIZE
.global interrupt_level_6_handler
interrupt_level_6_handler:
INTERRUPT_LEVEL_N_HANDLER 6
 
/* TT = 0x47, TL = 0, interrupt_level_7 handler */
.org trap_table + TT_INTERRUPT_LEVEL_7*ENTRY_SIZE
.global interrupt_level_7_handler
interrupt_level_7_handler:
INTERRUPT_LEVEL_N_HANDLER 7
 
/* TT = 0x48, TL = 0, interrupt_level_8 handler */
.org trap_table + TT_INTERRUPT_LEVEL_8*ENTRY_SIZE
.global interrupt_level_8_handler
interrupt_level_8_handler:
INTERRUPT_LEVEL_N_HANDLER 8
 
/* TT = 0x49, TL = 0, interrupt_level_9 handler */
.org trap_table + TT_INTERRUPT_LEVEL_9*ENTRY_SIZE
.global interrupt_level_9_handler
interrupt_level_9_handler:
INTERRUPT_LEVEL_N_HANDLER 9
 
/* TT = 0x4a, TL = 0, interrupt_level_10 handler */
.org trap_table + TT_INTERRUPT_LEVEL_10*ENTRY_SIZE
.global interrupt_level_10_handler
interrupt_level_10_handler:
INTERRUPT_LEVEL_N_HANDLER 10
 
/* TT = 0x4b, TL = 0, interrupt_level_11 handler */
.org trap_table + TT_INTERRUPT_LEVEL_11*ENTRY_SIZE
.global interrupt_level_11_handler
interrupt_level_11_handler:
INTERRUPT_LEVEL_N_HANDLER 11
 
/* TT = 0x4c, TL = 0, interrupt_level_12 handler */
.org trap_table + TT_INTERRUPT_LEVEL_12*ENTRY_SIZE
.global interrupt_level_12_handler
interrupt_level_12_handler:
INTERRUPT_LEVEL_N_HANDLER 12
 
/* TT = 0x4d, TL = 0, interrupt_level_13 handler */
.org trap_table + TT_INTERRUPT_LEVEL_13*ENTRY_SIZE
.global interrupt_level_13_handler
interrupt_level_13_handler:
INTERRUPT_LEVEL_N_HANDLER 13
 
/* TT = 0x4e, TL = 0, interrupt_level_14 handler */
.org trap_table + TT_INTERRUPT_LEVEL_14*ENTRY_SIZE
.global interrupt_level_14_handler
interrupt_level_14_handler:
INTERRUPT_LEVEL_N_HANDLER 14
 
/* TT = 0x4f, TL = 0, interrupt_level_15 handler */
.org trap_table + TT_INTERRUPT_LEVEL_15*ENTRY_SIZE
.global interrupt_level_15_handler
interrupt_level_15_handler:
INTERRUPT_LEVEL_N_HANDLER 15
 
/* TT = 0x60, TL = 0, interrupt_vector_trap handler */
.org trap_table + TT_INTERRUPT_VECTOR_TRAP*ENTRY_SIZE
.global interrupt_vector_trap_handler
interrupt_vector_trap_handler:
INTERRUPT_VECTOR_TRAP_HANDLER
 
/* TT = 0x64, TL = 0, fast_instruction_access_MMU_miss */
.org trap_table + TT_FAST_INSTRUCTION_ACCESS_MMU_MISS*ENTRY_SIZE
.global fast_instruction_access_mmu_miss_handler
fast_instruction_access_mmu_miss_handler:
FAST_INSTRUCTION_ACCESS_MMU_MISS_HANDLER
 
/* TT = 0x68, TL = 0, fast_data_access_MMU_miss */
.org trap_table + TT_FAST_DATA_ACCESS_MMU_MISS*ENTRY_SIZE
.global fast_data_access_mmu_miss_handler
fast_data_access_mmu_miss_handler:
FAST_DATA_ACCESS_MMU_MISS_HANDLER
 
/* TT = 0x6c, TL = 0, fast_data_access_protection */
.org trap_table + TT_FAST_DATA_ACCESS_PROTECTION*ENTRY_SIZE
.global fast_data_access_protection_handler
fast_data_access_protection_handler:
FAST_DATA_ACCESS_PROTECTION_HANDLER
 
/* TT = 0x80, TL = 0, spill_0_normal handler */
.org trap_table + TT_SPILL_0_NORMAL*ENTRY_SIZE
.global spill_0_normal
spill_0_normal:
SPILL_NORMAL_HANDLER
 
/* TT = 0xc0, TL = 0, fill_0_normal handler */
.org trap_table + TT_FILL_0_NORMAL*ENTRY_SIZE
.global fill_0_normal
fill_0_normal:
FILL_NORMAL_HANDLER
 
/*
* Handlers for TL>0.
*/
 
/* TT = 0x08, TL > 0, instruction_access_exception */
.org trap_table + (TT_INSTRUCTION_ACCESS_EXCEPTION+512)*ENTRY_SIZE
.global instruction_access_exception_high
instruction_access_exception_high:
SIMPLE_HANDLER do_instruction_access_exc
 
/* TT = 0x10, TL > 0, illegal_instruction */
.org trap_table + (TT_ILLEGAL_INSTRUCTION+512)*ENTRY_SIZE
.global illegal_instruction_high
illegal_instruction_high:
SIMPLE_HANDLER do_illegal_instruction
 
/* TT = 0x24, TL > 0, clean_window handler */
.org trap_table + (TT_CLEAN_WINDOW+512)*ENTRY_SIZE
.global clean_window_handler_high
clean_window_handler_high:
CLEAN_WINDOW_HANDLER
 
/* TT = 0x32, TL > 0, data_access_error */
.org trap_table + (TT_DATA_ACCESS_ERROR+512)*ENTRY_SIZE
.global data_access_error_high
data_access_error_high:
SIMPLE_HANDLER do_data_access_error
 
/* TT = 0x34, TL > 0, mem_address_not_aligned */
.org trap_table + (TT_MEM_ADDRESS_NOT_ALIGNED+512)*ENTRY_SIZE
.global mem_address_not_aligned_high
mem_address_not_aligned_high:
SIMPLE_HANDLER do_mem_address_not_aligned
 
/* TT = 0x64, TL > 0, fast_instruction_access_MMU_miss */
.org trap_table + (TT_FAST_INSTRUCTION_ACCESS_MMU_MISS+512)*ENTRY_SIZE
.global fast_instruction_access_mmu_miss_handler_high
fast_instruction_access_mmu_miss_handler_high:
FAST_INSTRUCTION_ACCESS_MMU_MISS_HANDLER
 
/* TT = 0x68, TL > 0, fast_data_access_MMU_miss */
.org trap_table + (TT_FAST_DATA_ACCESS_MMU_MISS+512)*ENTRY_SIZE
.global fast_data_access_mmu_miss_handler_high
fast_data_access_mmu_miss_handler_high:
FAST_DATA_ACCESS_MMU_MISS_HANDLER
 
/* TT = 0x6c, TL > 0, fast_data_access_protection */
.org trap_table + (TT_FAST_DATA_ACCESS_PROTECTION+512)*ENTRY_SIZE
.global fast_data_access_protection_handler_high
fast_data_access_protection_handler_high:
FAST_DATA_ACCESS_PROTECTION_HANDLER
 
/* TT = 0x80, TL > 0, spill_0_normal handler */
.org trap_table + (TT_SPILL_0_NORMAL+512)*ENTRY_SIZE
.global spill_0_normal_high
spill_0_normal_high:
SPILL_NORMAL_HANDLER
 
/* TT = 0xc0, TL > 0, fill_0_normal handler */
.org trap_table + (TT_FILL_0_NORMAL+512)*ENTRY_SIZE
.global fill_0_normal_high
fill_0_normal_high:
FILL_NORMAL_HANDLER
 
 
/* Preemptible trap handler.
*
* This trap handler makes arrangements to
* make calling scheduler() possible.
*
* The caller is responsible for doing save
* and allocating PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE
* bytes on stack.
*
* Input registers:
* %l0 Address of function to call.
* Output registers:
* %l1 - %l7 Copy of %g1 - %g7
*/
.global preemptible_handler
preemptible_handler:
/*
* Save TSTATE, TPC, TNPC and PSTATE aside.
*/
rdpr %tstate, %g1
rdpr %tpc, %g2
rdpr %tnpc, %g3
rdpr %pstate, %g4
 
stx %g1, [%fp + STACK_BIAS + SAVED_TSTATE]
stx %g2, [%fp + STACK_BIAS + SAVED_TPC]
stx %g3, [%fp + STACK_BIAS + SAVED_TNPC]
stx %g4, [%fp + STACK_BIAS + SAVED_PSTATE]
/*
* Write 0 to TL.
*/
wrpr %g0, 0, %tl
/*
* Alter PSTATE.
* - switch to normal globals.
*/
and %g4, ~1, %g4 ! mask alternate globals
wrpr %g4, 0, %pstate
/*
* Save the normal globals.
*/
SAVE_GLOBALS
/*
* Call the higher-level handler.
*/
call %l0
nop
/*
* Restore the normal global register set.
*/
RESTORE_GLOBALS
/*
* Restore PSTATE from saved copy.
* Alternate globals become active.
*/
ldx [%fp + STACK_BIAS + SAVED_PSTATE], %l4
wrpr %l4, 0, %pstate
/*
* Write 1 to TL.
*/
wrpr %g0, 1, %tl
/*
* Read TSTATE, TPC and TNPC from saved copy.
*/
ldx [%fp + STACK_BIAS + SAVED_TSTATE], %g1
ldx [%fp + STACK_BIAS + SAVED_TPC], %g2
ldx [%fp + STACK_BIAS + SAVED_TNPC], %g3
 
/*
* Do restore to match the save instruction from the top-level handler.
*/
restore
 
/*
* On execution of retry instruction, CWP will be restored from TSTATE register.
* However, because of scheduling, it is possible that CWP in saved TSTATE
* is different from current CWP. The following chunk of code fixes CWP
* in the saved copy of TSTATE.
*/
rdpr %cwp, %g4 ! read current CWP
and %g1, ~0x1f, %g1 ! clear CWP field in saved TSTATE
or %g1, %g4, %g1 ! write current CWP to TSTATE
/*
* Restore TSTATE, TPC and TNPC from saved copies.
*/
wrpr %g1, 0, %tstate
wrpr %g2, 0, %tpc
wrpr %g3, 0, %tnpc
/*
* Return from interrupt.
*/
retry
/tags/0.2.0.3/kernel/arch/sparc64/src/cpu/cpu.c
0,0 → 1,100
/*
* 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 sparc64
* @{
*/
/** @file
*/
 
#include <cpu.h>
#include <arch.h>
#include <arch/register.h>
#include <arch/asm.h>
#include <print.h>
 
void cpu_arch_init(void)
{
}
 
void cpu_identify(void)
{
CPU->arch.ver.value = ver_read();
}
 
void cpu_print_report(cpu_t *m)
{
char *manuf, *impl;
 
switch (CPU->arch.ver.manuf) {
case MANUF_FUJITSU:
manuf = "Fujitsu";
break;
case MANUF_ULTRASPARC:
manuf = "UltraSPARC";
break;
case MANUF_SUN:
manuf = "Sun";
break;
default:
manuf = "Unknown";
break;
}
switch (CPU->arch.ver.impl) {
case IMPL_ULTRASPARCI:
impl = "UltraSPARC I";
break;
case IMPL_ULTRASPARCII:
impl = "UltraSPARC II";
break;
case IMPL_ULTRASPARCII_I:
impl = "UltraSPARC IIi";
break;
case IMPL_ULTRASPARCII_E:
impl = "UltraSPARC IIe";
break;
case IMPL_ULTRASPARCIII:
impl = "UltraSPARC III";
break;
case IMPL_ULTRASPARCIV_PLUS:
impl = "UltraSPARC IV+";
break;
case IMPL_SPARC64V:
impl = "SPARC 64V";
break;
default:
impl = "Unknown";
break;
}
 
printf("cpu%d: manuf=%s, impl=%s, mask=%d\n", CPU->id, manuf, impl, CPU->arch.ver.mask);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/sparc64/src/dummy.s
0,0 → 1,68
#
# 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.
#
 
.text
 
.global asm_delay_loop
.global cpu_sleep
.global fmath_dpow
.global fmath_fint
.global fmath_get_decimal_exponent
.global fmath_is_infinity
.global fmath_is_nan
.global fpu_context_restore
.global fpu_context_save
.global fpu_enable
.global fpu_init
.global userspace
.global sys_tls_set
 
.global dummy
 
asm_delay_loop:
cpu_sleep:
fmath_dpow:
fmath_fint:
fmath_get_decimal_exponent:
fmath_is_infinity:
fmath_is_nan:
fpu_context_restore:
fpu_context_save:
fpu_enable:
fpu_init:
userspace:
sys_tls_set:
 
dummy:
retl
nop
 
.global cpu_halt
cpu_halt:
b cpu_halt
nop
/tags/0.2.0.3/kernel/arch/sparc64/src/panic.S
0,0 → 1,40
#
# 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.
#
 
.text
 
#include <arch/stack.h>
 
.global panic_printf
panic_printf:
call printf
nop
call halt
nop
/* Not reached. */
 
/tags/0.2.0.3/kernel/arch/sparc64/src/context.S
0,0 → 1,108
#
# 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.
#
 
#include <arch/context_offset.h>
#include <arch/stack.h>
 
/**
* Both context_save_arch() and context_restore_arch() are
* leaf-optimized procedures. This kind of optimization
* is very important and prevents any implicit window
* spill/fill/clean traps in these very core kernel
* functions.
*/
.text
 
.global context_save_arch
.global context_restore_arch
 
.macro CONTEXT_STORE r
stx %sp, [\r + OFFSET_SP]
stx %o7, [\r + OFFSET_PC]
stx %i0, [\r + OFFSET_I0]
stx %i1, [\r + OFFSET_I1]
stx %i2, [\r + OFFSET_I2]
stx %i3, [\r + OFFSET_I3]
stx %i4, [\r + OFFSET_I4]
stx %i5, [\r + OFFSET_I5]
stx %fp, [\r + OFFSET_FP]
stx %i7, [\r + OFFSET_I7]
stx %l0, [\r + OFFSET_L0]
stx %l1, [\r + OFFSET_L1]
stx %l2, [\r + OFFSET_L2]
stx %l3, [\r + OFFSET_L3]
stx %l4, [\r + OFFSET_L4]
stx %l5, [\r + OFFSET_L5]
stx %l6, [\r + OFFSET_L6]
stx %l7, [\r + OFFSET_L7]
rdpr %cleanwin, %g1
stx %g1, [\r + OFFSET_CLEANWIN]
.endm
 
.macro CONTEXT_LOAD r
ldx [\r + OFFSET_SP], %sp
ldx [\r + OFFSET_PC], %o7
ldx [\r + OFFSET_I0], %i0
ldx [\r + OFFSET_I1], %i1
ldx [\r + OFFSET_I2], %i2
ldx [\r + OFFSET_I3], %i3
ldx [\r + OFFSET_I4], %i4
ldx [\r + OFFSET_I5], %i5
ldx [\r + OFFSET_FP], %fp
ldx [\r + OFFSET_I7], %i7
ldx [\r + OFFSET_L0], %l0
ldx [\r + OFFSET_L1], %l1
ldx [\r + OFFSET_L2], %l2
ldx [\r + OFFSET_L3], %l3
ldx [\r + OFFSET_L4], %l4
ldx [\r + OFFSET_L5], %l5
ldx [\r + OFFSET_L6], %l6
ldx [\r + OFFSET_L7], %l7
ldx [\r + OFFSET_CLEANWIN], %g1
wrpr %g1, %g0, %cleanwin
.endm
 
context_save_arch:
CONTEXT_STORE %o0
retl
mov 1, %o0 ! context_save_arch returns 1
 
context_restore_arch:
#
# Flush all active windows.
# This is essential, because CONTEXT_LOAD overwrites
# %sp of CWP - 1 with the value written to %fp of CWP.
# Flushing all active windows mitigates this problem
# as CWP - 1 becomes the overlap window.
#
flushw
CONTEXT_LOAD %o0
retl
xor %o0, %o0, %o0 ! context_restore_arch returns 0
/tags/0.2.0.3/kernel/arch/sparc64/Makefile.inc
0,0 → 1,89
#
# Copyright (C) 2005 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 = elf64-sparc
BFD_ARCH = sparc
BFD = binary
TARGET = sparc64-linux-gnu
TOOLCHAIN_DIR = /usr/local/sparc64/bin
 
CFLAGS += -mcpu=ultrasparc -m64
LFLAGS += -no-check-sections -N
 
DEFS += -D__64_BITS__
 
## Own configuration directives
#
 
## Compile with page hash table support.
#
 
CONFIG_PAGE_HT = y
DEFS += -DCONFIG_PAGE_HT
 
## Compile with support for address space identifiers.
#
 
CONFIG_ASID = y
CONFIG_ASID_FIFO = y
 
## Compile with support for framebuffer.
#
 
CONFIG_FB = y
 
## Compile with support for i8042 controller.
#
 
CONFIG_I8042 = y
 
ARCH_SOURCES = \
arch/$(ARCH)/src/cpu/cpu.c \
arch/$(ARCH)/src/asm.S \
arch/$(ARCH)/src/panic.S \
arch/$(ARCH)/src/console.c \
arch/$(ARCH)/src/context.S \
arch/$(ARCH)/src/dummy.s \
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/mm/memory_init.c \
arch/$(ARCH)/src/sparc64.c \
arch/$(ARCH)/src/start.S \
arch/$(ARCH)/src/proc/scheduler.c \
arch/$(ARCH)/src/trap/trap_table.S \
arch/$(ARCH)/src/trap/trap.c \
arch/$(ARCH)/src/trap/exception.c \
arch/$(ARCH)/src/trap/interrupt.c \
arch/$(ARCH)/src/ddi/ddi.c \
arch/$(ARCH)/src/drivers/tick.c \
arch/$(ARCH)/src/drivers/i8042.c
/tags/0.2.0.3/kernel/arch/sparc64/_link.ld.in
0,0 → 1,49
/** SPARC64 linker script
*
* It is ELF format, but its only section looks like this:
* kernel text
* kernel data
*
*/
 
#define __LINKER__
#include <arch/boot/boot.h>
 
ENTRY(kernel_image_start)
 
SECTIONS {
.image VMA: AT (LMA) {
ktext_start = .;
*(K_TEXT_START)
*(.text);
ktext_end = .;
kdata_start = .;
*(K_DATA_START)
*(.rodata);
*(.rodata.*);
*(.data); /* initialized data */
*(.sdata);
*(.sdata2);
*(.sbss);
hardcoded_ktext_size = .;
QUAD(ktext_end - ktext_start);
hardcoded_kdata_size = .;
QUAD(kdata_end - kdata_start);
hardcoded_load_address = .;
QUAD(VMA);
*(.bss); /* uninitialized static variables */
*(COMMON); /* global variables */
 
symbol_table = .;
*(symtab.*); /* Symbol table, must be LAST symbol!*/
 
kdata_end = .;
}
/DISCARD/ : {
*(.comment);
*(.note*);
}
 
}
/tags/0.2.0.3/kernel/arch/ia32/include/types.h
0,0 → 1,63
/*
* Copyright (C) 2001-2004 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32
* @{
*/
/** @file
*/
 
#ifndef __TYPES_H__
#define __TYPES_H__
 
#define NULL 0
 
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed long int32_t;
typedef signed long long int64_t;
 
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned long uint32_t;
typedef unsigned long long uint64_t;
 
typedef uint32_t uintptr_t;
typedef uint32_t pfn_t;
 
typedef uint32_t ipl_t;
 
typedef uint32_t unative_t;
typedef int32_t native_t;
 
typedef struct page_specifier pte_t;
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ia32/include/pm.h
0,0 → 1,183
/*
* 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 ia32
* @{
*/
/** @file
*/
 
#ifndef __PM_H__
#define __PM_H__
 
#define IDT_ITEMS 64
#define GDT_ITEMS 7
 
#define VESA_INIT_SEGMENT 0x8000
 
#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 */
 
#ifdef CONFIG_FB
 
#define VESA_INIT_SEGMENT 0x8000
#define VESA_INIT_DES 7
#undef GDT_ITEMS
#define GDT_ITEMS 8
 
#endif /* CONFIG_FB */
 
 
#define selector(des) ((des) << 3)
 
#define PL_KERNEL 0
#define PL_USER 3
 
#define AR_PRESENT (1<<7)
#define AR_DATA (2<<3)
#define AR_CODE (3<<3)
#define AR_WRITABLE (1<<1)
#define AR_INTERRUPT (0xe)
#define AR_TSS (0x9)
 
#define DPL_KERNEL (PL_KERNEL<<5)
#define DPL_USER (PL_USER<<5)
 
#define TSS_BASIC_SIZE 104
#define TSS_IOMAP_SIZE (16*1024+1) /* 16K for bitmap + 1 terminating byte for convenience */
 
#define IO_PORTS (64*1024)
 
#ifndef __ASM__
 
#include <arch/types.h>
#include <typedefs.h>
#include <arch/context.h>
 
struct ptr_16_32 {
uint16_t limit;
uint32_t base;
} __attribute__ ((packed));
typedef struct ptr_16_32 ptr_16_32_t;
 
struct descriptor {
unsigned limit_0_15: 16;
unsigned base_0_15: 16;
unsigned base_16_23: 8;
unsigned access: 8;
unsigned limit_16_19: 4;
unsigned available: 1;
unsigned unused: 1;
unsigned special: 1;
unsigned granularity : 1;
unsigned base_24_31: 8;
} __attribute__ ((packed));
typedef struct descriptor descriptor_t;
 
struct idescriptor {
unsigned offset_0_15: 16;
unsigned selector: 16;
unsigned unused: 8;
unsigned access: 8;
unsigned offset_16_31: 16;
} __attribute__ ((packed));
typedef struct idescriptor idescriptor_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 idt_init(void);
extern void idt_setoffset(idescriptor_t *d, uintptr_t offset);
 
extern void tss_initialize(tss_t *t);
extern void set_tls_desc(uintptr_t tls);
 
#endif /* __ASM__ */
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/interrupt.h
0,0 → 1,129
/*
* 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 ia32interrupt
* @{
*/
/** @file
*/
 
#ifndef __ia32_INTERRUPT_H__
#define __ia32_INTERRUPT_H__
 
#include <arch/types.h>
#include <arch/pm.h>
 
#define IVT_ITEMS IDT_ITEMS
 
#define EXC_COUNT 32
#define IRQ_COUNT 16
 
#define IVT_EXCBASE 0
#define IVT_IRQBASE (IVT_EXCBASE+EXC_COUNT)
#define IVT_FREEBASE (IVT_IRQBASE+IRQ_COUNT)
 
#define IRQ_CLK 0
#define IRQ_KBD 1
#define IRQ_PIC1 2
#define IRQ_PIC_SPUR 7
 
/* this one must have four least significant bits set to ones */
#define VECTOR_APIC_SPUR (IVT_ITEMS-1)
 
#if (((VECTOR_APIC_SPUR + 1)%16) || VECTOR_APIC_SPUR >= IVT_ITEMS)
#error Wrong definition of VECTOR_APIC_SPUR
#endif
 
#define VECTOR_DEBUG 1
#define VECTOR_PIC_SPUR (IVT_IRQBASE+IRQ_PIC_SPUR)
#define VECTOR_CLK (IVT_IRQBASE+IRQ_CLK)
#define VECTOR_KBD (IVT_IRQBASE+IRQ_KBD)
 
#define VECTOR_SYSCALL (IVT_FREEBASE+0)
#define VECTOR_TLB_SHOOTDOWN_IPI (IVT_FREEBASE+1)
#define VECTOR_DEBUG_IPI (IVT_FREEBASE+2)
 
struct istate {
uint32_t eax;
uint32_t ecx;
uint32_t edx;
uint32_t esi;
uint32_t edi;
uint32_t ebp;
uint32_t ebx;
 
uint32_t gs;
uint32_t fs;
uint32_t es;
uint32_t ds;
 
uint32_t error_word;
uint32_t eip;
uint32_t cs;
uint32_t eflags;
uint32_t stack[];
};
 
/** Return true if exception happened while in userspace */
static inline int istate_from_uspace(istate_t *istate)
{
return !(istate->eip & 0x80000000);
}
 
static inline void istate_set_retaddr(istate_t *istate, uintptr_t retaddr)
{
istate->eip = retaddr;
}
 
static inline unative_t istate_get_pc(istate_t *istate)
{
return istate->eip;
}
 
extern void (* disable_irqs_function)(uint16_t irqmask);
extern void (* enable_irqs_function)(uint16_t irqmask);
extern void (* eoi_function)(void);
 
extern void PRINT_INFO_ERRCODE(istate_t *istate);
extern void null_interrupt(int n, istate_t *istate);
extern void gp_fault(int n, istate_t *istate);
extern void nm_fault(int n, istate_t *istate);
extern void ss_fault(int n, istate_t *istate);
extern void simd_fp_exception(int n, istate_t *istate);
extern void syscall(int n, istate_t *istate);
extern void tlb_shootdown_ipi(int n, istate_t *istate);
 
extern void trap_virtual_enable_irqs(uint16_t irqmask);
extern void trap_virtual_disable_irqs(uint16_t irqmask);
extern void trap_virtual_eoi(void);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/fpu_context.h
0,0 → 1,56
/*
* Copyright (C) 2005 Jakub Vana
* 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 ia32
* @{
*/
/** @file
*/
 
#ifndef __ia32_FPU_CONTEXT_H__
#define __ia32_FPU_CONTEXT_H__
 
#include <arch/types.h>
 
#define ARCH_HAS_FPU
#define FPU_CONTEXT_ALIGN 16
 
void fpu_fxsr(void);
void fpu_fsr(void);
 
 
struct fpu_context {
uint8_t fpu[512]; /* FXSAVE & FXRSTOR storage area */
};
 
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/byteorder.h
0,0 → 1,46
/*
* 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 ia32
* @{
*/
/** @file
*/
 
#ifndef __ia32_BYTEORDER_H__
#define __ia32_BYTEORDER_H__
 
/* IA-32 is little-endian */
#define unative_t_le2host(n) (n)
#define uint64_t_le2host(n) (n)
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/cpuid.h
0,0 → 1,120
/*
* 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 ia32
* @{
*/
/** @file
*/
 
#ifndef __ia32_CPUID_H__
#define __ia32_CPUID_H__
 
#include <arch/types.h>
 
struct cpu_info {
uint32_t cpuid_eax;
uint32_t cpuid_ebx;
uint32_t cpuid_ecx;
uint32_t cpuid_edx;
} __attribute__ ((packed));
 
struct __cpuid_extended_feature_info {
unsigned sse3 : 1;
unsigned : 31;
} __attribute__ ((packed));
 
typedef union cpuid_extended_feature_info
{
struct __cpuid_extended_feature_info bits;
uint32_t word;
}cpuid_extended_feature_info;
 
 
struct __cpuid_feature_info {
unsigned : 23;
unsigned mmx : 1;
unsigned fxsr : 1;
unsigned sse : 1;
unsigned sse2 : 1;
unsigned : 5;
} __attribute__ ((packed));
 
typedef union cpuid_feature_info
{
struct __cpuid_feature_info bits;
uint32_t word ;
}cpuid_feature_info;
 
 
static inline uint32_t has_cpuid(void)
{
uint32_t val, ret;
__asm__ volatile (
"pushf\n" /* read flags */
"popl %0\n"
"movl %0, %1\n"
"btcl $21, %1\n" /* swap the ID bit */
"pushl %1\n" /* propagate the change into flags */
"popf\n"
"pushf\n"
"popl %1\n"
"andl $(1 << 21), %0\n" /* interrested only in ID bit */
"andl $(1 << 21), %1\n"
"xorl %1, %0\n"
: "=r" (ret), "=r" (val)
);
return ret;
}
 
static inline void cpuid(uint32_t cmd, struct cpu_info *info)
{
__asm__ volatile (
"movl %4, %%eax\n"
"cpuid\n"
"movl %%eax, %0\n"
"movl %%ebx, %1\n"
"movl %%ecx, %2\n"
"movl %%edx, %3\n"
: "=m" (info->cpuid_eax), "=m" (info->cpuid_ebx), "=m" (info->cpuid_ecx), "=m" (info->cpuid_edx)
: "m" (cmd)
: "eax", "ebx", "ecx", "edx"
);
}
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/bios/bios.h
0,0 → 1,50
/*
* 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 ia32
* @{
*/
/** @file
*/
 
#ifndef __BIOS_H__
#define __BIOS_H__
 
#include <arch/types.h>
 
#define BIOS_EBDA_PTR 0x40e
 
extern uintptr_t ebda;
 
extern void bios_init(void);
 
#endif /* __BIOS_H__ */
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/memstr.h
0,0 → 1,152
/*
* Copyright (C) 2005 Sergey Bondari
* 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 ia32
* @{
*/
/** @file
*/
 
#ifndef __ia32_MEMSTR_H__
#define __ia32_MEMSTR_H__
 
/** Copy memory
*
* Copy a given number of bytes (3rd argument)
* from the memory location defined by 2nd argument
* to the memory location defined by 1st argument.
* The memory areas cannot overlap.
*
* @param dst Destination
* @param src Source
* @param cnt Number of bytes
* @return Destination
*/
static inline void * memcpy(void * dst, const void * src, size_t cnt)
{
unative_t d0, d1, d2;
 
__asm__ __volatile__(
/* copy all full dwords */
"rep movsl\n\t"
/* load count again */
"movl %4, %%ecx\n\t"
/* ecx = ecx mod 4 */
"andl $3, %%ecx\n\t"
/* are there last <=3 bytes? */
"jz 1f\n\t"
/* copy last <=3 bytes */
"rep movsb\n\t"
/* exit from asm block */
"1:\n"
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
: "0" ((unative_t) (cnt / 4)), "g" ((unative_t) cnt), "1" ((unative_t) dst), "2" ((unative_t) src)
: "memory");
 
return dst;
}
 
 
/** Compare memory regions for equality
*
* Compare a given number of bytes (3rd argument)
* at memory locations defined by 1st and 2nd argument
* for equality. If bytes are equal function returns 0.
*
* @param src Region 1
* @param dst Region 2
* @param cnt Number of bytes
* @return Zero if bytes are equal, non-zero otherwise
*/
static inline int memcmp(const void * src, const void * dst, size_t cnt)
{
uint32_t d0, d1, d2;
int ret;
__asm__ (
"repe cmpsb\n\t"
"je 1f\n\t"
"movl %3, %0\n\t"
"addl $1, %0\n\t"
"1:\n"
: "=a" (ret), "=%S" (d0), "=&D" (d1), "=&c" (d2)
: "0" (0), "1" ((unative_t) src), "2" ((unative_t) dst), "3" ((unative_t) cnt)
);
return ret;
}
 
/** Fill memory with words
* Fill a given number of words (2nd argument)
* at memory defined by 1st argument with the
* word value defined by 3rd argument.
*
* @param dst Destination
* @param cnt Number of words
* @param x Value to fill
*/
static inline void memsetw(uintptr_t dst, size_t cnt, uint16_t x)
{
uint32_t d0, d1;
__asm__ __volatile__ (
"rep stosw\n\t"
: "=&D" (d0), "=&c" (d1), "=a" (x)
: "0" (dst), "1" (cnt), "2" (x)
: "memory"
);
 
}
 
/** Fill memory with bytes
* Fill a given number of bytes (2nd argument)
* at memory defined by 1st argument with the
* word value defined by 3rd argument.
*
* @param dst Destination
* @param cnt Number of bytes
* @param x Value to fill
*/
static inline void memsetb(uintptr_t dst, size_t cnt, uint8_t x)
{
uint32_t d0, d1;
__asm__ __volatile__ (
"rep stosb\n\t"
: "=&D" (d0), "=&c" (d1), "=a" (x)
: "0" (dst), "1" (cnt), "2" (x)
: "memory"
);
 
}
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/smp/apic.h
0,0 → 1,371
/*
* 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 ia32
* @{
*/
/** @file
*/
 
#ifndef __APIC_H__
#define __APIC_H__
 
#include <arch/types.h>
#include <cpu.h>
 
#define FIXED (0<<0)
#define LOPRI (1<<0)
 
#define APIC_ID_COUNT 16
 
/* local APIC macros */
#define IPI_INIT 0
#define IPI_STARTUP 0
 
/** Delivery modes. */
#define DELMOD_FIXED 0x0
#define DELMOD_LOWPRI 0x1
#define DELMOD_SMI 0x2
/* 0x3 reserved */
#define DELMOD_NMI 0x4
#define DELMOD_INIT 0x5
#define DELMOD_STARTUP 0x6
#define DELMOD_EXTINT 0x7
 
/** Destination modes. */
#define DESTMOD_PHYS 0x0
#define DESTMOD_LOGIC 0x1
 
/** Trigger Modes. */
#define TRIGMOD_EDGE 0x0
#define TRIGMOD_LEVEL 0x1
 
/** Levels. */
#define LEVEL_DEASSERT 0x0
#define LEVEL_ASSERT 0x1
 
/** Destination Shorthands. */
#define SHORTHAND_NONE 0x0
#define SHORTHAND_SELF 0x1
#define SHORTHAND_ALL_INCL 0x2
#define SHORTHAND_ALL_EXCL 0x3
 
/** Interrupt Input Pin Polarities. */
#define POLARITY_HIGH 0x0
#define POLARITY_LOW 0x1
 
/** Divide Values. (Bit 2 is always 0) */
#define DIVIDE_2 0x0
#define DIVIDE_4 0x1
#define DIVIDE_8 0x2
#define DIVIDE_16 0x3
#define DIVIDE_32 0x8
#define DIVIDE_64 0x9
#define DIVIDE_128 0xa
#define DIVIDE_1 0xb
 
/** Timer Modes. */
#define TIMER_ONESHOT 0x0
#define TIMER_PERIODIC 0x1
 
/** Delivery status. */
#define DELIVS_IDLE 0x0
#define DELIVS_PENDING 0x1
 
/** Destination masks. */
#define DEST_ALL 0xff
 
/** Dest format models. */
#define MODEL_FLAT 0xf
#define MODEL_CLUSTER 0x0
 
/** Interrupt Command Register. */
#define ICRlo (0x300/sizeof(uint32_t))
#define ICRhi (0x310/sizeof(uint32_t))
struct icr {
union {
uint32_t lo;
struct {
uint8_t vector; /**< Interrupt Vector. */
unsigned delmod : 3; /**< Delivery Mode. */
unsigned destmod : 1; /**< Destination Mode. */
unsigned delivs : 1; /**< Delivery status (RO). */
unsigned : 1; /**< Reserved. */
unsigned level : 1; /**< Level. */
unsigned trigger_mode : 1; /**< Trigger Mode. */
unsigned : 2; /**< Reserved. */
unsigned shorthand : 2; /**< Destination Shorthand. */
unsigned : 12; /**< Reserved. */
} __attribute__ ((packed));
};
union {
uint32_t hi;
struct {
unsigned : 24; /**< Reserved. */
uint8_t dest; /**< Destination field. */
} __attribute__ ((packed));
};
} __attribute__ ((packed));
typedef struct icr icr_t;
 
/* End Of Interrupt. */
#define EOI (0x0b0/sizeof(uint32_t))
 
/** Error Status Register. */
#define ESR (0x280/sizeof(uint32_t))
union esr {
uint32_t value;
uint8_t err_bitmap;
struct {
unsigned send_checksum_error : 1;
unsigned receive_checksum_error : 1;
unsigned send_accept_error : 1;
unsigned receive_accept_error : 1;
unsigned : 1;
unsigned send_illegal_vector : 1;
unsigned received_illegal_vector : 1;
unsigned illegal_register_address : 1;
unsigned : 24;
} __attribute__ ((packed));
};
typedef union esr esr_t;
 
/* Task Priority Register */
#define TPR (0x080/sizeof(uint32_t))
union tpr {
uint32_t value;
struct {
unsigned pri_sc : 4; /**< Task Priority Sub-Class. */
unsigned pri : 4; /**< Task Priority. */
} __attribute__ ((packed));
};
typedef union tpr tpr_t;
 
/** Spurious-Interrupt Vector Register. */
#define SVR (0x0f0/sizeof(uint32_t))
union svr {
uint32_t value;
struct {
uint8_t vector; /**< Spurious Vector. */
unsigned lapic_enabled : 1; /**< APIC Software Enable/Disable. */
unsigned focus_checking : 1; /**< Focus Processor Checking. */
unsigned : 22; /**< Reserved. */
} __attribute__ ((packed));
};
typedef union svr svr_t;
 
/** Time Divide Configuration Register. */
#define TDCR (0x3e0/sizeof(uint32_t))
union tdcr {
uint32_t value;
struct {
unsigned div_value : 4; /**< Divide Value, bit 2 is always 0. */
unsigned : 28; /**< Reserved. */
} __attribute__ ((packed));
};
typedef union tdcr tdcr_t;
 
/* Initial Count Register for Timer */
#define ICRT (0x380/sizeof(uint32_t))
 
/* Current Count Register for Timer */
#define CCRT (0x390/sizeof(uint32_t))
 
/** LVT Timer register. */
#define LVT_Tm (0x320/sizeof(uint32_t))
union lvt_tm {
uint32_t value;
struct {
uint8_t vector; /**< Local Timer Interrupt vector. */
unsigned : 4; /**< Reserved. */
unsigned delivs : 1; /**< Delivery status (RO). */
unsigned : 3; /**< Reserved. */
unsigned masked : 1; /**< Interrupt Mask. */
unsigned mode : 1; /**< Timer Mode. */
unsigned : 14; /**< Reserved. */
} __attribute__ ((packed));
};
typedef union lvt_tm lvt_tm_t;
 
/** LVT LINT registers. */
#define LVT_LINT0 (0x350/sizeof(uint32_t))
#define LVT_LINT1 (0x360/sizeof(uint32_t))
union lvt_lint {
uint32_t value;
struct {
uint8_t vector; /**< LINT Interrupt vector. */
unsigned delmod : 3; /**< Delivery Mode. */
unsigned : 1; /**< Reserved. */
unsigned delivs : 1; /**< Delivery status (RO). */
unsigned intpol : 1; /**< Interrupt Input Pin Polarity. */
unsigned irr : 1; /**< Remote IRR (RO). */
unsigned trigger_mode : 1; /**< Trigger Mode. */
unsigned masked : 1; /**< Interrupt Mask. */
unsigned : 15; /**< Reserved. */
} __attribute__ ((packed));
};
typedef union lvt_lint lvt_lint_t;
 
/** LVT Error register. */
#define LVT_Err (0x370/sizeof(uint32_t))
union lvt_error {
uint32_t value;
struct {
uint8_t vector; /**< Local Timer Interrupt vector. */
unsigned : 4; /**< Reserved. */
unsigned delivs : 1; /**< Delivery status (RO). */
unsigned : 3; /**< Reserved. */
unsigned masked : 1; /**< Interrupt Mask. */
unsigned : 15; /**< Reserved. */
} __attribute__ ((packed));
};
typedef union lvt_error lvt_error_t;
 
/** Local APIC ID Register. */
#define L_APIC_ID (0x020/sizeof(uint32_t))
union l_apic_id {
uint32_t value;
struct {
unsigned : 24; /**< Reserved. */
uint8_t apic_id; /**< Local APIC ID. */
} __attribute__ ((packed));
};
typedef union l_apic_id l_apic_id_t;
 
/** Local APIC Version Register */
#define LAVR (0x030/sizeof(uint32_t))
#define LAVR_Mask 0xff
#define is_local_apic(x) (((x)&LAVR_Mask&0xf0)==0x1)
#define is_82489DX_apic(x) ((((x)&LAVR_Mask&0xf0)==0x0))
#define is_local_xapic(x) (((x)&LAVR_Mask)==0x14)
 
/** Logical Destination Register. */
#define LDR (0x0d0/sizeof(uint32_t))
union ldr {
uint32_t value;
struct {
unsigned : 24; /**< Reserved. */
uint8_t id; /**< Logical APIC ID. */
} __attribute__ ((packed));
};
typedef union ldr ldr_t;
 
/** Destination Format Register. */
#define DFR (0x0e0/sizeof(uint32_t))
union dfr {
uint32_t value;
struct {
unsigned : 28; /**< Reserved, all ones. */
unsigned model : 4; /**< Model. */
} __attribute__ ((packed));
};
typedef union dfr dfr_t;
 
/* IO APIC */
#define IOREGSEL (0x00/sizeof(uint32_t))
#define IOWIN (0x10/sizeof(uint32_t))
 
#define IOAPICID 0x00
#define IOAPICVER 0x01
#define IOAPICARB 0x02
#define IOREDTBL 0x10
 
/** I/O Register Select Register. */
union io_regsel {
uint32_t value;
struct {
uint8_t reg_addr; /**< APIC Register Address. */
unsigned : 24; /**< Reserved. */
} __attribute__ ((packed));
};
typedef union io_regsel io_regsel_t;
 
/** I/O Redirection Register. */
struct io_redirection_reg {
union {
uint32_t lo;
struct {
uint8_t intvec; /**< Interrupt Vector. */
unsigned delmod : 3; /**< Delivery Mode. */
unsigned destmod : 1; /**< Destination mode. */
unsigned delivs : 1; /**< Delivery status (RO). */
unsigned intpol : 1; /**< Interrupt Input Pin Polarity. */
unsigned irr : 1; /**< Remote IRR (RO). */
unsigned trigger_mode : 1; /**< Trigger Mode. */
unsigned masked : 1; /**< Interrupt Mask. */
unsigned : 15; /**< Reserved. */
} __attribute__ ((packed));
};
union {
uint32_t hi;
struct {
unsigned : 24; /**< Reserved. */
uint8_t dest : 8; /**< Destination Field. */
} __attribute__ ((packed));
};
} __attribute__ ((packed));
typedef struct io_redirection_reg io_redirection_reg_t;
 
 
/** IO APIC Identification Register. */
union io_apic_id {
uint32_t value;
struct {
unsigned : 24; /**< Reserved. */
unsigned apic_id : 4; /**< IO APIC ID. */
unsigned : 4; /**< Reserved. */
} __attribute__ ((packed));
};
typedef union io_apic_id io_apic_id_t;
 
extern volatile uint32_t *l_apic;
extern volatile uint32_t *io_apic;
 
extern uint32_t apic_id_mask;
 
extern void apic_init(void);
 
extern void l_apic_init(void);
extern void l_apic_eoi(void);
extern int l_apic_broadcast_custom_ipi(uint8_t vector);
extern int l_apic_send_init_ipi(uint8_t apicid);
extern void l_apic_debug(void);
extern uint8_t l_apic_id(void);
 
extern uint32_t io_apic_read(uint8_t address);
extern void io_apic_write(uint8_t address , uint32_t x);
extern void io_apic_change_ioredtbl(int pin, int dest, uint8_t v, int flags);
extern void io_apic_disable_irqs(uint16_t irqmask);
extern void io_apic_enable_irqs(uint16_t irqmask);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/smp/mps.h
0,0 → 1,135
/*
* 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 ia32
* @{
*/
/** @file
*/
 
#ifndef __MPS_H__
#define __MPS_H__
 
#include <arch/types.h>
#include <typedefs.h>
#include <synch/waitq.h>
#include <config.h>
#include <arch/smp/smp.h>
 
#define CT_EXT_ENTRY_TYPE 0
#define CT_EXT_ENTRY_LEN 1
 
struct mps_fs {
uint32_t signature;
uint32_t configuration_table;
uint8_t length;
uint8_t revision;
uint8_t checksum;
uint8_t config_type;
uint8_t mpfib2;
uint8_t mpfib3;
uint8_t mpfib4;
uint8_t mpfib5;
} __attribute__ ((packed));
 
struct mps_ct {
uint32_t signature;
uint16_t base_table_length;
uint8_t revision;
uint8_t checksum;
uint8_t oem_id[8];
uint8_t product_id[12];
uint32_t oem_table;
uint16_t oem_table_size;
uint16_t entry_count;
uint32_t l_apic;
uint16_t ext_table_length;
uint8_t ext_table_checksum;
uint8_t xxx;
uint8_t base_table[0];
} __attribute__ ((packed));
 
struct __processor_entry {
uint8_t type;
uint8_t l_apic_id;
uint8_t l_apic_version;
uint8_t cpu_flags;
uint8_t cpu_signature[4];
uint32_t feature_flags;
uint32_t xxx[2];
} __attribute__ ((packed));
 
struct __bus_entry {
uint8_t type;
uint8_t bus_id;
uint8_t bus_type[6];
} __attribute__ ((packed));
 
struct __io_apic_entry {
uint8_t type;
uint8_t io_apic_id;
uint8_t io_apic_version;
uint8_t io_apic_flags;
uint32_t io_apic;
} __attribute__ ((packed));
 
struct __io_intr_entry {
uint8_t type;
uint8_t intr_type;
uint8_t poel;
uint8_t xxx;
uint8_t src_bus_id;
uint8_t src_bus_irq;
uint8_t dst_io_apic_id;
uint8_t dst_io_apic_pin;
} __attribute__ ((packed));
 
struct __l_intr_entry {
uint8_t type;
uint8_t intr_type;
uint8_t poel;
uint8_t xxx;
uint8_t src_bus_id;
uint8_t src_bus_irq;
uint8_t dst_l_apic_id;
uint8_t dst_l_apic_pin;
} __attribute__ ((packed));
 
 
extern waitq_t ap_completion_wq;
 
extern struct smp_config_operations mps_config_operations;
 
extern void mps_init(void);
extern void kmp(void *arg);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/smp/smp.h
0,0 → 1,56
/*
* 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 ia32
* @{
*/
/** @file
*/
 
#ifndef __ia32_SMP_H__
#define __ia32_SMP_H__
 
#include <arch/types.h>
#include <typedefs.h>
 
/** SMP config opertaions interface. */
struct smp_config_operations {
count_t (* cpu_count)(void); /**< Return number of detected processors. */
bool (* cpu_enabled)(index_t i); /**< Check whether the processor of index i is enabled. */
bool (*cpu_bootstrap)(index_t i); /**< Check whether the processor of index i is BSP. */
uint8_t (*cpu_apic_id)(index_t i); /**< Return APIC ID of the processor of index i. */
int (*irq_to_pin)(int irq); /**< Return mapping between irq and APIC pin. */
};
 
extern int smp_irq_to_pin(int irq);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/smp/ap.h
0,0 → 1,44
/*
* 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 ia32
* @{
*/
/** @file
*/
 
#ifndef __AP_H__
#define __AP_H__
 
extern void ap_boot(void);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/atomic.h
0,0 → 1,129
/*
* 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 ia32
* @{
*/
/** @file
*/
 
#ifndef __ia32_ATOMIC_H__
#define __ia32_ATOMIC_H__
 
#include <arch/types.h>
#include <arch/barrier.h>
#include <preemption.h>
#include <typedefs.h>
 
static inline void atomic_inc(atomic_t *val) {
#ifdef CONFIG_SMP
__asm__ volatile ("lock incl %0\n" : "=m" (val->count));
#else
__asm__ volatile ("incl %0\n" : "=m" (val->count));
#endif /* CONFIG_SMP */
}
 
static inline void atomic_dec(atomic_t *val) {
#ifdef CONFIG_SMP
__asm__ volatile ("lock decl %0\n" : "=m" (val->count));
#else
__asm__ volatile ("decl %0\n" : "=m" (val->count));
#endif /* CONFIG_SMP */
}
 
static inline long atomic_postinc(atomic_t *val)
{
long r = 1;
 
__asm__ volatile (
"lock xaddl %1, %0\n"
: "=m" (val->count), "+r" (r)
);
 
return r;
}
 
static inline long atomic_postdec(atomic_t *val)
{
long r = -1;
__asm__ volatile (
"lock xaddl %1, %0\n"
: "=m" (val->count), "+r"(r)
);
return r;
}
 
#define atomic_preinc(val) (atomic_postinc(val)+1)
#define atomic_predec(val) (atomic_postdec(val)-1)
 
static inline uint32_t test_and_set(atomic_t *val) {
uint32_t v;
__asm__ volatile (
"movl $1, %0\n"
"xchgl %0, %1\n"
: "=r" (v),"=m" (val->count)
);
return v;
}
 
/** ia32 specific fast spinlock */
static inline void atomic_lock_arch(atomic_t *val)
{
uint32_t tmp;
 
preemption_disable();
__asm__ volatile (
"0:;"
#ifdef CONFIG_HT
"pause;" /* Pentium 4's HT love this instruction */
#endif
"mov %0, %1;"
"testl %1, %1;"
"jnz 0b;" /* Lightweight looping on locked spinlock */
"incl %1;" /* now use the atomic operation */
"xchgl %0, %1;"
"testl %1, %1;"
"jnz 0b;"
: "=m"(val->count),"=r"(tmp)
);
/*
* Prevent critical section code from bleeding out this way up.
*/
CS_ENTER_BARRIER();
}
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/boot/memmap.h
0,0 → 1,78
/*
* Copyright (C) 2005 Josef Cejka
* 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 ia32
* @{
*/
/** @file
*/
 
#ifndef __ia32_MEMMAP_H__
#define __ia32_MEMMAP_H__
 
/* E820h memory range types - other values*/
/* Free memory */
#define MEMMAP_MEMORY_AVAILABLE 1
/* Not available for OS */
#define MEMMAP_MEMORY_RESERVED 2
/* OS may use it after reading ACPI table */
#define MEMMAP_MEMORY_ACPI 3
/* Unusable, required to be saved and restored across an NVS sleep */
#define MEMMAP_MEMORY_NVS 4
/* Corrupted memory */
#define MEMMAP_MEMORY_UNUSABLE 5
 
/* size of one entry */
#define MEMMAP_E820_RECORD_SIZE 20
/* maximum entries */
#define MEMMAP_E820_MAX_RECORDS 32
 
 
#ifndef __ASM__
 
#include <arch/types.h>
 
struct e820memmap_ {
uint64_t base_address;
uint64_t size;
uint32_t type;
} __attribute__ ((packed));
 
extern struct e820memmap_ e820table[MEMMAP_E820_MAX_RECORDS];
 
extern uint8_t e820counter;
 
extern uint32_t e801memorysize; /**< Size of available memory in KB. */
 
#endif
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/boot/boot.h
0,0 → 1,51
/*
* Copyright (C) 2005 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 ia32
* @{
*/
/** @file
*/
 
#ifndef __ia32_BOOT_H__
#define __ia32_BOOT_H__
 
#define BOOT_OFFSET 0x108000
#define AP_BOOT_OFFSET 0x8000
#define BOOT_STACK_SIZE 0x400
 
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
#define MULTIBOOT_HEADER_FLAGS 0x00010003
 
#define MULTIBOOT_LOADER_MAGIC 0x2BADB002
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/proc/thread.h
0,0 → 1,48
/*
* 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 ia32proc
* @{
*/
/** @file
*/
 
#ifndef __ia32_THREAD_H__
#define __ia32_THREAD_H__
 
#include <arch/types.h>
 
typedef struct {
unative_t tls;
} thread_arch_t;
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/proc/task.h
0,0 → 1,51
/*
* 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 ia32proc
* @{
*/
/** @file
*/
 
#ifndef __ia32_TASK_H__
#define __ia32_TASK_H__
 
#include <typedefs.h>
#include <arch/types.h>
#include <adt/bitmap.h>
 
typedef struct {
count_t iomapver; /**< I/O Permission bitmap Generation counter. */
bitmap_t iomap; /**< I/O Permission bitmap. */
} task_arch_t;
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/asm.h
0,0 → 1,301
/*
* Copyright (C) 2001-2004 Jakub Jermar
* Copyright (C) 2005 Sergey Bondari
* 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 ia32
* @{
*/
/** @file
*/
 
#ifndef __ia32_ASM_H__
#define __ia32_ASM_H__
 
#include <arch/pm.h>
#include <arch/types.h>
#include <config.h>
 
extern uint32_t interrupt_handler_size;
 
extern void paging_on(void);
 
extern void interrupt_handlers(void);
 
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.
*/
static inline void cpu_halt(void) { __asm__("hlt\n"); };
static inline void cpu_sleep(void) { __asm__("hlt\n"); };
 
#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(cr3);
GEN_WRITE_REG(cr3);
 
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)
{
ipl_t v;
__asm__ volatile (
"pushf\n\t"
"popl %0\n\t"
"sti\n"
: "=r" (v)
);
return v;
}
 
/** Disable interrupts.
*
* Disable interrupts and return previous
* value of EFLAGS.
*
* @return Old interrupt priority level.
*/
static inline ipl_t interrupts_disable(void)
{
ipl_t v;
__asm__ volatile (
"pushf\n\t"
"popl %0\n\t"
"cli\n"
: "=r" (v)
);
return v;
}
 
/** Restore interrupt priority level.
*
* Restore EFLAGS.
*
* @param ipl Saved interrupt priority level.
*/
static inline void interrupts_restore(ipl_t ipl)
{
__asm__ volatile (
"pushl %0\n\t"
"popf\n"
: : "r" (ipl)
);
}
 
/** Return interrupt priority level.
*
* @return EFLAFS.
*/
static inline ipl_t interrupts_read(void)
{
ipl_t v;
__asm__ volatile (
"pushf\n\t"
"popl %0\n"
: "=r" (v)
);
return v;
}
 
/** Return base address of current stack
*
* Return the base address of the current stack.
* The stack is assumed to be STACK_SIZE bytes long.
* The stack must start on page boundary.
*/
static inline uintptr_t get_stack_base(void)
{
uintptr_t v;
__asm__ volatile ("andl %%esp, %0\n" : "=r" (v) : "0" (~(STACK_SIZE-1)));
return v;
}
 
static inline uint64_t rdtsc(void)
{
uint64_t v;
__asm__ volatile("rdtsc\n" : "=A" (v));
return v;
}
 
/** Return current IP address */
static inline uintptr_t * get_ip()
{
uintptr_t *ip;
 
__asm__ volatile (
"mov %%eip, %0"
: "=r" (ip)
);
return ip;
}
 
/** Invalidate TLB Entry.
*
* @param addr Address on a page whose TLB entry is to be invalidated.
*/
static inline void invlpg(uintptr_t addr)
{
__asm__ volatile ("invlpg %0\n" :: "m" (*(unative_t *)addr));
}
 
/** Load GDTR register from memory.
*
* @param gdtr_reg Address of memory from where to load GDTR.
*/
static inline void gdtr_load(ptr_16_32_t *gdtr_reg)
{
__asm__ volatile ("lgdtl %0\n" : : "m" (*gdtr_reg));
}
 
/** Store GDTR register to memory.
*
* @param gdtr_reg Address of memory to where to load GDTR.
*/
static inline void gdtr_store(ptr_16_32_t *gdtr_reg)
{
__asm__ volatile ("sgdtl %0\n" : : "m" (*gdtr_reg));
}
 
/** Load IDTR register from memory.
*
* @param idtr_reg Address of memory from where to load IDTR.
*/
static inline void idtr_load(ptr_16_32_t *idtr_reg)
{
__asm__ volatile ("lidtl %0\n" : : "m" (*idtr_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
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/faddr.h
0,0 → 1,46
/*
* 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 ia32
* @{
*/
/** @file
*/
 
#ifndef __ia32_FADDR_H__
#define __ia32_FADDR_H__
 
#include <arch/types.h>
 
#define FADDR(fptr) ((uintptr_t) (fptr))
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/mm/frame.h
0,0 → 1,58
/*
* 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 ia32mm
* @{
*/
/** @file
*/
 
#ifndef __ia32_FRAME_H__
#define __ia32_FRAME_H__
 
#define FRAME_WIDTH 12 /* 4K */
#define FRAME_SIZE (1<<FRAME_WIDTH)
 
 
#ifdef KERNEL
#ifndef __ASM__
 
#include <arch/types.h>
 
extern uintptr_t last_frame;
 
extern void frame_arch_init(void);
 
#endif /* __ASM__ */
#endif /* KERNEL */
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/mm/page.h
0,0 → 1,173
/*
* 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 ia32mm
* @{
*/
/** @file
*/
 
#ifndef __ia32_PAGE_H__
#define __ia32_PAGE_H__
 
#include <arch/mm/frame.h>
 
#define PAGE_WIDTH FRAME_WIDTH
#define PAGE_SIZE FRAME_SIZE
 
#ifdef KERNEL
 
#ifndef __ASM__
# define KA2PA(x) (((uintptr_t) (x)) - 0x80000000)
# define PA2KA(x) (((uintptr_t) (x)) + 0x80000000)
#else
# define KA2PA(x) ((x) - 0x80000000)
# define PA2KA(x) ((x) + 0x80000000)
#endif
 
/*
* Implementation of generic 4-level page table interface.
* IA-32 has 2-level page tables, so PTL1 and PTL2 are left out.
*/
#define PTL0_ENTRIES_ARCH 1024
#define PTL1_ENTRIES_ARCH 0
#define PTL2_ENTRIES_ARCH 0
#define PTL3_ENTRIES_ARCH 1024
 
#define PTL0_INDEX_ARCH(vaddr) (((vaddr)>>22)&0x3ff)
#define PTL1_INDEX_ARCH(vaddr) 0
#define PTL2_INDEX_ARCH(vaddr) 0
#define PTL3_INDEX_ARCH(vaddr) (((vaddr)>>12)&0x3ff)
 
#define GET_PTL1_ADDRESS_ARCH(ptl0, i) ((pte_t *)((((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)((((pte_t *)(ptl3))[(i)].frame_address)<<12))
 
#define SET_PTL0_ADDRESS_ARCH(ptl0) (write_cr3((uintptr_t) (ptl0)))
#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) (((pte_t *)(ptl0))[(i)].frame_address = (a)>>12)
#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) (((pte_t *)(ptl3))[(i)].frame_address = (a)>>12)
 
#define GET_PTL1_FLAGS_ARCH(ptl0, i) get_pt_flags((pte_t *)(ptl0), (index_t)(i))
#define GET_PTL2_FLAGS_ARCH(ptl1, i) PAGE_PRESENT
#define GET_PTL3_FLAGS_ARCH(ptl2, i) PAGE_PRESENT
#define GET_FRAME_FLAGS_ARCH(ptl3, i) get_pt_flags((pte_t *)(ptl3), (index_t)(i))
 
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) set_pt_flags((pte_t *)(ptl0), (index_t)(i), (x))
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x)
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) set_pt_flags((pte_t *)(ptl3), (index_t)(i), (x))
 
#define PTE_VALID_ARCH(p) (*((uint32_t *) (p)) != 0)
#define PTE_PRESENT_ARCH(p) ((p)->present != 0)
#define PTE_GET_FRAME_ARCH(p) ((p)->frame_address<<FRAME_WIDTH)
#define PTE_WRITABLE_ARCH(p) ((p)->writeable != 0)
#define PTE_EXECUTABLE_ARCH(p) 1
 
#ifndef __ASM__
 
#include <mm/page.h>
#include <arch/types.h>
#include <arch/mm/frame.h>
#include <typedefs.h>
 
/* Page fault error codes. */
 
/** When bit on this position is 0, the page fault was caused by a not-present page. */
#define PFERR_CODE_P (1<<0)
 
/** When bit on this position is 1, the page fault was caused by a write. */
#define PFERR_CODE_RW (1<<1)
 
/** When bit on this position is 1, the page fault was caused in user mode. */
#define PFERR_CODE_US (1<<2)
 
/** When bit on this position is 1, a reserved bit was set in page directory. */
#define PFERR_CODE_RSVD (1<<3)
 
/** Page Table Entry. */
struct page_specifier {
unsigned present : 1;
unsigned writeable : 1;
unsigned uaccessible : 1;
unsigned page_write_through : 1;
unsigned page_cache_disable : 1;
unsigned accessed : 1;
unsigned dirty : 1;
unsigned pat : 1;
unsigned global : 1;
unsigned soft_valid : 1; /**< Valid content even if the present bit is not set. */
unsigned avl : 2;
unsigned frame_address : 20;
} __attribute__ ((packed));
 
static inline int get_pt_flags(pte_t *pt, index_t i)
{
pte_t *p = &pt[i];
return (
(!p->page_cache_disable)<<PAGE_CACHEABLE_SHIFT |
(!p->present)<<PAGE_PRESENT_SHIFT |
p->uaccessible<<PAGE_USER_SHIFT |
1<<PAGE_READ_SHIFT |
p->writeable<<PAGE_WRITE_SHIFT |
1<<PAGE_EXEC_SHIFT |
p->global<<PAGE_GLOBAL_SHIFT
);
}
 
static inline void set_pt_flags(pte_t *pt, index_t i, int flags)
{
pte_t *p = &pt[i];
p->page_cache_disable = !(flags & PAGE_CACHEABLE);
p->present = !(flags & PAGE_NOT_PRESENT);
p->uaccessible = (flags & PAGE_USER) != 0;
p->writeable = (flags & PAGE_WRITE) != 0;
p->global = (flags & PAGE_GLOBAL) != 0;
/*
* Ensure that there is at least one bit set even if the present bit is cleared.
*/
p->soft_valid = true;
}
 
extern void page_arch_init(void);
extern void page_fault(int n, istate_t *istate);
 
#endif /* __ASM__ */
 
#endif /* KERNEL */
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/mm/memory_init.h
0,0 → 1,49
/*
* Copyright (C) 2005 Josef Cejka
* 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 ia32mm
* @{
*/
/** @file
* @ingroup ia32mm, am64mm
*/
 
#ifndef __ia32_MEMORY_INIT_H__
#define __ia32_MEMORY_INIT_H__
 
#include <typedefs.h>
 
size_t get_memory_size(void);
 
void memory_print_map(void);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/mm/asid.h
0,0 → 1,56
/*
* 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 ia32mm
* @{
*/
/** @file
* @ingroup ia32mm, amd64mm
*/
 
/*
* ia32 has no hardware support for address space identifiers.
* This file is provided to do nop-implementation of mm/asid.h
* interface.
*/
 
#ifndef __ia32_ASID_H__
#define __ia32_ASID_H__
 
typedef int asid_t;
 
#define ASID_MAX_ARCH 3
 
#define asid_get() (ASID_START+1)
#define asid_put(asid)
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/mm/tlb.h
0,0 → 1,45
/*
* 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 ia32mm
* @{
*/
/** @file
*/
 
#ifndef __ia32_TLB_H__
#define __ia32_TLB_H__
 
#define tlb_arch_init()
#define tlb_print()
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/mm/as.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 ia32mm
* @{
*/
/** @file
*/
 
#ifndef __ia32_AS_H__
#define __ia32_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))
 
#define as_install_arch(as)
 
extern void as_arch_init(void);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/context.h
0,0 → 1,68
/*
* 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 ia32
* @{
*/
/** @file
*/
 
#ifndef __ia32_CONTEXT_H__
#define __ia32_CONTEXT_H__
 
#include <arch/types.h>
 
#define STACK_ITEM_SIZE 4
 
/*
* Both context_save() and context_restore() eat two doublewords from the stack.
* First for pop of the saved register, second during ret instruction.
*
* One item is put onto stack to support get_stack_base().
*/
#define SP_DELTA (8+STACK_ITEM_SIZE)
 
/*
* Only save registers that must be preserved across
* function calls.
*/
struct context {
uintptr_t sp;
uintptr_t pc;
uint32_t ebx;
uint32_t esi;
uint32_t edi;
uint32_t ebp;
ipl_t ipl;
} __attribute__ ((packed));
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/drivers/i8259.h
0,0 → 1,58
/*
* 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 ia32
* @{
*/
/** @file
*/
 
#ifndef __I8259_H__
#define __I8259_H__
 
#include <arch/types.h>
#include <arch/interrupt.h>
 
#define PIC_PIC0PORT1 0x20
#define PIC_PIC0PORT2 0x21
#define PIC_PIC1PORT1 0xa0
#define PIC_PIC1PORT2 0xa1
 
#define PIC_NEEDICW4 (1<<0)
#define PIC_ICW1 (1<<4)
 
extern void i8259_init(void);
extern void pic_enable_irqs(uint16_t irqmask);
extern void pic_disable_irqs(uint16_t irqmask);
extern void pic_eoi(void);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/drivers/i8042.h
0,0 → 1,72
/*
* 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 ia32
* @{
*/
/** @file
*/
 
/**
* This file implements ia32 specific access to i8042 registers.
*/
 
#ifndef __ia32_I8042_H__
#define __ia32_I8042_H__
 
#include <arch/asm.h>
#include <arch/types.h>
 
#define i8042_DATA 0x60
#define i8042_STATUS 0x64
 
static inline void i8042_data_write(uint8_t data)
{
outb(i8042_DATA, data);
}
 
static inline uint8_t i8042_data_read(void)
{
return inb(i8042_DATA);
}
 
static inline uint8_t i8042_status_read(void)
{
return inb(i8042_STATUS);
}
 
static inline void i8042_command_write(uint8_t command)
{
outb(i8042_STATUS, command);
}
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/drivers/i8254.h
0,0 → 1,48
/*
* 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 ia32
* @{
*/
/** @file
*/
 
#ifndef __I8254_H__
#define __I8254_H__
 
#include <arch/types.h>
 
extern void i8254_init(void);
extern void i8254_calibrate_delay_loop(void);
extern void i8254_normal_operation(void);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/drivers/ega.h
0,0 → 1,49
/*
* 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 ia32
* @{
*/
/** @file
*/
 
#ifndef __EGA_H__
#define __EGA_H__
 
#define VIDEORAM 0xb8000
#define ROW 80
#define ROWS 25
#define SCREEN (ROW * ROWS)
 
extern void ega_init(void);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/drivers/vesa.h
0,0 → 1,45
/*
* Copyright (C) 2006 Jakub Vana
* 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 ia32
* @{
*/
/** @file
*/
 
#ifndef __VESA_H__
#define __VESA_H__
 
extern int vesa_present(void);
extern void vesa_init(void);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/ddi/ddi.h
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 ia32ddi
* @{
*/
/**
* @file
* @brief ia32 specific DDI declarations and macros.
*/
 
#ifndef __ia32_DDI_H__
#define __ia32_DDI_H__
 
extern void io_perm_bitmap_install(void);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/cpu.h
0,0 → 1,61
/*
* 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 ia32
* @{
*/
/** @file
*/
 
#ifndef __ia32_CPU_H__
#define __ia32_CPU_H__
 
#include <typedefs.h>
#include <arch/pm.h>
#include <arch/asm.h>
 
#define EFLAGS_IF (1 << 9)
#define EFLAGS_RF (1 << 16)
 
struct cpu_arch {
int vendor;
int family;
int model;
int stepping;
struct tss *tss;
count_t iomapver_copy; /** Copy of TASK's I/O Permission bitmap generation count. */
};
 
 
#define CR4_OSFXSR_MASK (1<<9)
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ia32/include/elf.h
0,0 → 1,46
/*
* Copyright (C) 2006 Sergey Bondari
* 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 ia32
* @{
*/
/** @file
*/
 
#ifndef __ia32_ELF_H__
#define __ia32_ELF_H__
 
#define ELF_MACHINE EM_386
#define ELF_DATA_ENCODING ELFDATA2LSB
#define ELF_CLASS ELFCLASS32
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/arg.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 ia32
* @{
*/
/** @file
*/
 
#ifndef __ia32_ARG_H__
#define __ia32_ARG_H__
 
#include <stackarg.h>
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/arch.h
0,0 → 1,42
/*
* Copyright (C) 2005 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 ia32
* @{
*/
/** @file
*/
 
#ifndef __ia32_ARCH_H__
#define __ia32_ARCH_H__
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/debug.h
0,0 → 1,46
/*
* Copyright (C) 2005 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 amd64debug
* @{
*/
/** @file
*/
 
#ifndef __ia32_DEBUG_H__
#define __ia32_DEBUG_H__
 
#include <arch/asm.h>
 
#define HERE get_ip()
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/barrier.h
0,0 → 1,91
/*
* 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 ia32
* @{
*/
/** @file
*/
 
#ifndef __ia32_BARRIER_H__
#define __ia32_BARRIER_H__
 
/*
* NOTE:
* No barriers for critical section (i.e. spinlock) on IA-32 are needed:
* - spinlock_lock() and spinlock_trylock() use serializing XCHG instruction
* - writes cannot pass reads on IA-32 => spinlock_unlock() needs no barriers
*/
 
/*
* Provisions are made to prevent compiler from reordering instructions itself.
*/
 
#define CS_ENTER_BARRIER() __asm__ volatile ("" ::: "memory")
#define CS_LEAVE_BARRIER() __asm__ volatile ("" ::: "memory")
 
static inline void cpuid_serialization(void)
{
__asm__ volatile (
"xorl %%eax, %%eax\n"
"cpuid\n"
::: "eax", "ebx", "ecx", "edx", "memory"
);
}
 
#ifdef CONFIG_FENCES_P4
# define memory_barrier() __asm__ volatile ("mfence\n" ::: "memory")
# define read_barrier() __asm__ volatile ("lfence\n" ::: "memory")
# ifdef CONFIG_WEAK_MEMORY
# define write_barrier() __asm__ volatile ("sfence\n" ::: "memory")
# else
# define write_barrier() __asm__ volatile( "" ::: "memory");
# endif
#elif CONFIG_FENCES_P3
# define memory_barrier() cpuid_serialization()
# define read_barrier() cpuid_serialization()
# ifdef CONFIG_WEAK_MEMORY
# define write_barrier() __asm__ volatile ("sfence\n" ::: "memory")
# else
# define write_barrier() __asm__ volatile( "" ::: "memory");
# endif
#else
# define memory_barrier() cpuid_serialization()
# define read_barrier() cpuid_serialization()
# ifdef CONFIG_WEAK_MEMORY
# define write_barrier() cpuid_serialization()
# else
# define write_barrier() __asm__ volatile( "" ::: "memory");
# endif
#endif
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/include/debugger.h
0,0 → 1,0
link ../../amd64/include/debugger.h
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/ia32/src/boot/boot.S
0,0 → 1,428
#
# Copyright (C) 2001-2004 Jakub Jermar
# Copyright (C) 2005-2006 Martin Decky
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# - The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
#include <arch/boot/boot.h>
#include <arch/boot/memmap.h>
#include <arch/mm/page.h>
#include <arch/pm.h>
 
#define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE)
 
.section K_TEXT_START, "ax"
 
.code32
.align 4
.global multiboot_image_start
multiboot_header:
.long MULTIBOOT_HEADER_MAGIC
.long MULTIBOOT_HEADER_FLAGS
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) # checksum
.long multiboot_header
.long unmapped_ktext_start
.long 0
.long 0
.long multiboot_image_start
multiboot_image_start:
movl $START_STACK, %esp # initialize stack pointer
lgdt KA2PA(bootstrap_gdtr) # initialize Global Descriptor Table register
 
movw $selector(KDATA_DES), %cx
movw %cx, %es
movw %cx, %fs
movw %cx, %gs
movw %cx, %ds # kernel data + stack
movw %cx, %ss
jmpl $selector(KTEXT_DES), $multiboot_meeting_point
multiboot_meeting_point:
pushl %ebx # save parameters from GRUB
pushl %eax
#ifdef CONFIG_FB
mov $vesa_init, %esi
mov $VESA_INIT_SEGMENT << 4, %edi
mov $e_vesa_init - vesa_init, %ecx
cld
rep movsb
 
mov $VESA_INIT_SEGMENT << 4, %edi
jmpl %edi
vesa_meeting_point:
mov %esi, KA2PA(vesa_ph_addr)
mov %di, KA2PA(vesa_height)
shr $16, %edi
mov %di, KA2PA(vesa_width)
mov %bx, KA2PA(vesa_scanline)
shr $16, %ebx
mov %bx, KA2PA(vesa_bpp)
#endif
call map_kernel # map kernel and turn paging on
popl %eax
popl %ebx
cmpl $MULTIBOOT_LOADER_MAGIC, %eax # compare GRUB signature
je valid_boot
xorl %ecx, %ecx # no memory size or map available
movl %ecx, e801memorysize
movl %ecx, e820counter
jmp invalid_boot
valid_boot:
movl (%ebx), %eax # ebx = physical address of struct multiboot_info
bt $0, %eax # mbi->flags[0] (mem_lower, mem_upper valid)
jc mem_valid
xorl %ecx, %ecx
jmp mem_invalid
mem_valid:
movl 4(%ebx), %ecx # mbi->mem_lower
addl 8(%ebx), %ecx # mbi->mem_upper
mem_invalid:
movl %ecx, e801memorysize
bt $3, %eax # mbi->flags[3] (mods_count, mods_addr valid)
jc mods_valid
xorl %ecx, %ecx
movl %ecx, init
jmp mods_end
mods_valid:
movl 20(%ebx), %ecx # mbi->mods_count
movl %ecx, init
cmpl $0, %ecx
je mods_end
movl 24(%ebx), %esi # mbi->mods_addr
movl $init, %edi
mods_loop:
movl 0(%esi), %edx # mods->mod_start
addl $0x80000000, %edx
movl %edx, 4(%edi)
movl 4(%esi), %edx
subl 0(%esi), %edx # mods->mod_end - mods->mod_start
movl %edx, 8(%edi)
addl $16, %esi
addl $8 , %edi
loop mods_loop
mods_end:
bt $6, %eax # mbi->flags[6] (mmap_length, mmap_addr valid)
jc mmap_valid
xorl %edx, %edx
jmp mmap_invalid
mmap_valid:
movl 44(%ebx), %ecx # mbi->mmap_length
movl 48(%ebx), %esi # mbi->mmap_addr
movl $e820table, %edi
xorl %edx, %edx
mmap_loop:
cmpl $0, %ecx
jle mmap_end
movl 4(%esi), %eax # mmap->base_addr_low
movl %eax, (%edi)
movl 8(%esi), %eax # mmap->base_addr_high
movl %eax, 4(%edi)
movl 12(%esi), %eax # mmap->length_low
movl %eax, 8(%edi)
movl 16(%esi), %eax # mmap->length_high
movl %eax, 12(%edi)
movl 20(%esi), %eax # mmap->type
movl %eax, 16(%edi)
movl (%esi), %eax # mmap->size
addl $0x4, %eax
addl %eax, %esi
subl %eax, %ecx
addl $MEMMAP_E820_RECORD_SIZE, %edi
incl %edx
jmp mmap_loop
mmap_end:
mmap_invalid:
movl %edx, e820counter
invalid_boot:
#ifdef CONFIG_SMP
# copy AP bootstrap routines below 1 MB
movl $BOOT_OFFSET, %esi
movl $AP_BOOT_OFFSET, %edi
movl $_hardcoded_unmapped_size, %ecx
cld
rep movsb
#endif
call main_bsp # never returns
 
cli
hlt
 
.global map_kernel
map_kernel:
#
# Here we setup mapping for both the unmapped and mapped sections of the kernel.
# For simplicity, we map the entire 4G space.
#
movl %cr4, %ecx
orl $(1<<4), %ecx
movl %ecx, %cr4 # turn PSE on
movl $(page_directory+0), %esi
movl $(page_directory+2048), %edi
xorl %ecx, %ecx
xorl %ebx, %ebx
0:
movl $((1<<7)|(1<<0)), %eax
orl %ebx, %eax
movl %eax, (%esi,%ecx,4) # mapping 0x00000000+%ecx*4M => 0x00000000+%ecx*4M
movl %eax, (%edi,%ecx,4) # mapping 0x80000000+%ecx*4M => 0x00000000+%ecx*4M
addl $(4*1024*1024), %ebx
 
incl %ecx
cmpl $512, %ecx
jl 0b
 
movl %esi, %cr3
# turn paging on
movl %cr0, %ebx
orl $(1<<31), %ebx
movl %ebx, %cr0
ret
 
#ifdef CONFIG_FB
vesa_init:
jmp $selector(VESA_INIT_DES), $vesa_init_real - vesa_init
.code16
vesa_init_real:
mov %cr0, %eax
and $~1, %eax
mov %eax, %cr0
jmp $VESA_INIT_SEGMENT, $vesa_init_real2 - vesa_init
vesa_init_real2:
mov $VESA_INIT_SEGMENT, %bx
mov %bx, %es
mov %bx, %fs
mov %bx, %gs
mov %bx, %ds
mov %bx, %ss
movl %esp, %eax
movl $0x0000fffc, %esp
movl $0x0000fffc, %ebp
pushl %eax
#define VESA_INFO_SIZE 1024
 
#define VESA_MODE_LIST_PTR_OFFSET 14
#define VESA_MODE_WIDTH_OFFSET 18
#define VESA_MODE_HEIGHT_OFFSET 20
#define VESA_MODE_BPP_OFFSET 25
#define VESA_MODE_SCANLINE_OFFSET 16
#define VESA_MODE_PHADDR_OFFSET 40
 
#define VESA_END_OF_MODES 0xffff
 
#define VESA_OK 0x4f
 
#define VESA_GET_INFO 0x4f00
#define VESA_GET_MODE_INFO 0x4f01
#define VESA_SET_MODE 0x4f02
 
#define CONFIG_VESA_BPP_a 255
 
#if CONFIG_VESA_BPP == 24
#undef CONFIG_VESA_BPP_a
#define CONFIG_VESA_BPP_a 32
#endif
 
mov $VESA_GET_INFO, %ax
mov $e_vesa_init - vesa_init, %di
push %di
int $0x10
pop %di
cmp $VESA_OK, %al
jnz 0f
mov 2 + VESA_MODE_LIST_PTR_OFFSET(%di), %si
mov %si, %gs
mov VESA_MODE_LIST_PTR_OFFSET(%di), %si
add $VESA_INFO_SIZE, %di
 
1:# Try next mode
mov %gs:(%si), %cx
cmp $VESA_END_OF_MODES, %cx
jz 0f
inc %si
inc %si
push %cx
push %di
push %si
mov $VESA_GET_MODE_INFO, %ax
int $0x10
pop %si
pop %di
pop %cx
cmp $VESA_OK, %al
jnz 0f
mov $CONFIG_VESA_WIDTH, %ax
cmp VESA_MODE_WIDTH_OFFSET(%di), %ax
jnz 1b
mov $CONFIG_VESA_HEIGHT,%ax
cmp VESA_MODE_HEIGHT_OFFSET(%di), %ax
jnz 1b
mov $CONFIG_VESA_BPP, %al
cmp VESA_MODE_BPP_OFFSET(%di), %al
jz 2f
mov $CONFIG_VESA_BPP_a, %al
cmp VESA_MODE_BPP_OFFSET(%di), %al
jnz 1b
2:
mov %cx, %bx
or $0xc000, %bx
push %di
mov $VESA_SET_MODE, %ax
int $0x10
pop %di
cmp $VESA_OK, %al
jnz 0f
mov VESA_MODE_PHADDR_OFFSET(%di), %esi
mov VESA_MODE_WIDTH_OFFSET(%di), %ax
shl $16, %eax
mov VESA_MODE_HEIGHT_OFFSET(%di), %ax
mov VESA_MODE_BPP_OFFSET(%di), %bl
xor %bh, %bh
shl $16, %ebx
mov VESA_MODE_SCANLINE_OFFSET(%di), %bx
mov %eax, %edi
8:
mov %cr0, %eax
or $1, %eax
mov %eax, %cr0
jmp 9f
9:
ljmpl $selector(KTEXT_DES), $(vesa_init_protect - vesa_init + VESA_INIT_SEGMENT << 4)
 
0:# No prefered mode found
mov $0x111, %cx
push %di
push %cx
mov $VESA_GET_MODE_INFO, %ax
int $0x10
pop %cx
pop %di
cmp $VESA_OK, %al
jnz 1f
jz 2b # Force relative jump
1:
mov $0x0003, %ax
int $0x10
mov $0xffffffff, %edi # EGA text mode used, because of problems with VESA
xor %ax, %ax
jz 8b # Force relative jump
 
.code32
vesa_init_protect:
popl %esp
 
movw $selector(KDATA_DES), %cx
movw %cx, %es
movw %cx, %fs
movw %cx, %gs
movw %cx, %ds # kernel data + stack
movw %cx, %ss
jmpl $selector(KTEXT_DES), $vesa_meeting_point
 
.align 4
e_vesa_init:
#endif
 
.section K_DATA_START, "aw", @progbits
 
.align 4096
page_directory:
.space 4096, 0
/tags/0.2.0.3/kernel/arch/ia32/src/mm/frame.c
0,0 → 1,148
/*
* 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 ia32mm
* @{
*/
/** @file
* @ingroup ia32mm, amd64mm
*/
 
#include <mm/frame.h>
#include <arch/mm/frame.h>
#include <mm/as.h>
#include <config.h>
#include <arch/boot/boot.h>
#include <arch/boot/memmap.h>
#include <panic.h>
#include <debug.h>
#include <align.h>
#include <macros.h>
 
#include <print.h>
#include <console/cmd.h>
#include <console/kconsole.h>
 
size_t hardcoded_unmapped_ktext_size = 0;
size_t hardcoded_unmapped_kdata_size = 0;
 
uintptr_t last_frame = 0;
 
static void init_e820_memory(pfn_t minconf)
{
int i;
pfn_t start, conf;
size_t size;
 
for (i = 0; i < e820counter; i++) {
if (e820table[i].type == MEMMAP_MEMORY_AVAILABLE) {
start = ADDR2PFN(ALIGN_UP(e820table[i].base_address,
FRAME_SIZE));
size = SIZE2FRAMES(ALIGN_DOWN(e820table[i].size,
FRAME_SIZE));
if (minconf < start || minconf >= start+size)
conf = start;
else
conf = minconf;
zone_create(start, size, conf, 0);
if (last_frame < ALIGN_UP(e820table[i].base_address + e820table[i].size, FRAME_SIZE))
last_frame = ALIGN_UP(e820table[i].base_address + e820table[i].size, FRAME_SIZE);
}
}
}
 
static int cmd_e820mem(cmd_arg_t *argv);
static cmd_info_t e820_info = {
.name = "e820list",
.description = "List e820 memory.",
.func = cmd_e820mem,
.argc = 0
};
 
static char *e820names[] = { "invalid", "available", "reserved",
"acpi", "nvs", "unusable" };
 
 
static int cmd_e820mem(cmd_arg_t *argv)
{
int i;
char *name;
 
for (i = 0; i < e820counter; i++) {
if (e820table[i].type <= MEMMAP_MEMORY_UNUSABLE)
name = e820names[e820table[i].type];
else
name = "invalid";
printf("%.*p %#.16llXB %s\n",
sizeof(unative_t) * 2,
(unative_t) e820table[i].base_address,
(uint64_t) e820table[i].size,
name);
}
return 0;
}
 
 
void frame_arch_init(void)
{
static pfn_t minconf;
 
if (config.cpu_active == 1) {
cmd_initialize(&e820_info);
cmd_register(&e820_info);
 
 
minconf = 1;
#ifdef CONFIG_SMP
minconf = max(minconf,
ADDR2PFN(AP_BOOT_OFFSET+hardcoded_unmapped_ktext_size + hardcoded_unmapped_kdata_size));
#endif
#ifdef CONFIG_SIMICS_FIX
minconf = max(minconf, ADDR2PFN(0x10000));
#endif
init_e820_memory(minconf);
 
/* Reserve frame 0 (BIOS data) */
frame_mark_unavailable(0, 1);
#ifdef CONFIG_SMP
/* Reserve AP real mode bootstrap memory */
frame_mark_unavailable(AP_BOOT_OFFSET >> FRAME_WIDTH,
(hardcoded_unmapped_ktext_size + hardcoded_unmapped_kdata_size) >> FRAME_WIDTH);
#ifdef CONFIG_SIMICS_FIX
/* Don't know why, but these addresses help */
frame_mark_unavailable(0xd000 >> FRAME_WIDTH,3);
#endif
#endif
}
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/src/mm/tlb.c
0,0 → 1,72
/*
* 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 ia32mm
* @{
*/
/** @file
* @ingroup ia32mm, amd64mm
*/
 
#include <mm/tlb.h>
#include <arch/mm/asid.h>
#include <arch/asm.h>
#include <arch/types.h>
 
/** Invalidate all entries in TLB. */
void tlb_invalidate_all(void)
{
write_cr3(read_cr3());
}
 
/** Invalidate all entries in TLB that belong to specified address space.
*
* @param asid This parameter is ignored as the architecture doesn't support it.
*/
void tlb_invalidate_asid(asid_t asid)
{
tlb_invalidate_all();
}
 
/** Invalidate TLB entries for specified page range belonging to specified address space.
*
* @param asid This parameter is ignored as the architecture doesn't support it.
* @param page Address of the first page whose entry is to be invalidated.
* @param cnt Number of entries to invalidate.
*/
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt)
{
int i;
 
for (i = 0; i < cnt; i++)
invlpg(page + i * PAGE_SIZE);
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/src/mm/memory_init.c
0,0 → 1,81
/*
* Copyright (C) 2005 Josef Cejka
* 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 ia32mm
* @{
*/
/** @file
*/
 
#include <arch/boot/memmap.h>
#include <arch/mm/memory_init.h>
#include <arch/mm/page.h>
#include <print.h>
 
uint8_t e820counter = 0xff;
struct e820memmap_ e820table[MEMMAP_E820_MAX_RECORDS];
uint32_t e801memorysize;
 
size_t get_memory_size(void)
{
return e801memorysize*1024;
}
 
void memory_print_map(void)
{
uint8_t i;
for (i=0;i<e820counter;i++) {
printf("E820 base: %#.16llx size: %#.16llx type: ", e820table[i].base_address, e820table[i].size);
switch (e820table[i].type) {
case MEMMAP_MEMORY_AVAILABLE:
printf("available memory\n");
break;
case MEMMAP_MEMORY_RESERVED:
printf("reserved memory\n");
break;
case MEMMAP_MEMORY_ACPI:
printf("ACPI table\n");
break;
case MEMMAP_MEMORY_NVS:
printf("NVS\n");
break;
case MEMMAP_MEMORY_UNUSABLE:
printf("unusable memory\n");
break;
default:
printf("undefined memory type\n");
}
}
 
}
 
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/src/mm/page.c
0,0 → 1,122
/*
* 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 ia32mm
* @{
*/
/** @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)
{
uintptr_t cur;
int flags;
 
if (config.cpu_active == 1) {
page_mapping_operations = &pt_mapping_operations;
/*
* PA2KA(identity) mapping for all frames until last_frame.
*/
for (cur = 0; cur < last_frame; cur += FRAME_SIZE) {
flags = PAGE_CACHEABLE;
if ((PA2KA(cur) >= config.base) && (PA2KA(cur) < config.base + config.kernel_size))
flags |= PAGE_GLOBAL;
page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags);
}
 
exc_register(14, "page_fault", (iroutine) page_fault);
write_cr3((uintptr_t) AS_KERNEL->page_table);
}
else {
write_cr3((uintptr_t) AS_KERNEL->page_table);
}
 
paging_on();
}
 
 
uintptr_t hw_map(uintptr_t physaddr, size_t size)
{
if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH))
panic("Unable to map physical memory %p (%d bytes)", physaddr, size)
uintptr_t virtaddr = PA2KA(last_frame);
pfn_t i;
for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++)
page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE);
last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE);
return virtaddr;
}
 
void page_fault(int n, istate_t *istate)
{
uintptr_t page;
pf_access_t access;
page = read_cr2();
if (istate->error_word & PFERR_CODE_RSVD)
panic("Reserved bit set in page directory.\n");
 
if (istate->error_word & PFERR_CODE_RW)
access = PF_ACCESS_WRITE;
else
access = PF_ACCESS_READ;
 
if (as_page_fault(page, access, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate, "Page fault: %#x", page);
 
PRINT_INFO_ERRCODE(istate);
printf("page fault address: %#x\n", page);
panic("page fault\n");
}
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/src/mm/as.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 ia32mm
* @{
*/
/** @file
* @ingroup ia32mm, amd64mm
*/
 
#include <arch/mm/as.h>
#include <genarch/mm/as_pt.h>
 
/** Architecture dependent address space init. */
void as_arch_init(void)
{
as_operations = &as_pt_operations;
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/src/ia32.c
0,0 → 1,160
/*
* 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 ia32
* @{
*/
/** @file
*/
 
#include <arch.h>
 
#include <arch/types.h>
#include <typedefs.h>
 
#include <arch/pm.h>
 
#include <arch/drivers/ega.h>
#include <arch/drivers/vesa.h>
#include <genarch/i8042/i8042.h>
#include <arch/drivers/i8254.h>
#include <arch/drivers/i8259.h>
 
#include <arch/context.h>
 
#include <config.h>
 
#include <arch/interrupt.h>
#include <arch/asm.h>
#include <genarch/acpi/acpi.h>
 
#include <arch/bios/bios.h>
 
#include <arch/mm/memory_init.h>
#include <interrupt.h>
#include <arch/debugger.h>
#include <proc/thread.h>
#include <syscall/syscall.h>
#include <console/console.h>
 
void arch_pre_mm_init(void)
{
pm_init();
 
if (config.cpu_active == 1) {
bios_init();
i8259_init(); /* PIC */
i8254_init(); /* hard clock */
exc_register(VECTOR_SYSCALL, "syscall", (iroutine) syscall);
#ifdef CONFIG_SMP
exc_register(VECTOR_TLB_SHOOTDOWN_IPI, "tlb_shootdown",
(iroutine) tlb_shootdown_ipi);
#endif /* CONFIG_SMP */
}
}
 
void arch_post_mm_init(void)
{
if (config.cpu_active == 1) {
 
#ifdef CONFIG_FB
if (vesa_present())
vesa_init();
else
#endif
ega_init(); /* video */
/* Enable debugger */
debugger_init();
/* Merge all memory zones to 1 big zone */
zone_merge_all();
}
}
 
void arch_pre_smp_init(void)
{
if (config.cpu_active == 1) {
memory_print_map();
#ifdef CONFIG_SMP
acpi_init();
#endif /* CONFIG_SMP */
}
}
 
void arch_post_smp_init(void)
{
i8042_init(); /* keyboard controller */
}
 
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)
{
i8042_grab();
}
/** Return console to userspace
*
*/
void arch_release_console(void)
{
i8042_release();
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/src/fpu_context.c
0,0 → 1,126
/*
* Copyright (C) 2005 Jakub Vana
* 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 ia32
* @{
*/
/** @file
*
*/
 
#include <fpu_context.h>
#include <arch.h>
#include <cpu.h>
 
typedef void (*fpu_context_function)(fpu_context_t *fctx);
 
static fpu_context_function fpu_save,fpu_restore;
 
 
 
static void fpu_context_f_save(fpu_context_t *fctx)
{
__asm__ volatile (
"fnsave %0"
: "=m"(*fctx)
);
}
 
static void fpu_context_f_restore(fpu_context_t *fctx)
{
__asm__ volatile (
"frstor %0"
: "=m"(*fctx)
);
}
 
static void fpu_context_fx_save(fpu_context_t *fctx)
{
__asm__ volatile (
"fxsave %0"
: "=m"(*fctx)
);
}
 
static void fpu_context_fx_restore(fpu_context_t *fctx)
{
__asm__ volatile (
"fxrstor %0"
: "=m"(*fctx)
);
}
 
/*
Setup using fxsr instruction
*/
void fpu_fxsr(void)
{
fpu_save=fpu_context_fx_save;
fpu_restore=fpu_context_fx_restore;
}
/*
Setup using not fxsr instruction
*/
void fpu_fsr(void)
{
fpu_save=fpu_context_f_save;
fpu_restore=fpu_context_f_restore;
}
 
 
 
void fpu_context_save(fpu_context_t *fctx)
{
fpu_save(fctx);
}
 
void fpu_context_restore(fpu_context_t *fctx)
{
fpu_restore(fctx);
}
 
 
 
void fpu_init()
{
uint32_t help0=0,help1=0;
__asm__ volatile (
"fninit;\n"
"stmxcsr %0\n"
"mov %0,%1;\n"
"or %2,%1;\n"
"mov %1,%0;\n"
"ldmxcsr %0;\n"
:"+m"(help0),"+r"(help1)
:"i"(0x1f80)
);
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/src/cpu/cpu.c
0,0 → 1,166
/*
* 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 ia32
* @{
*/
/** @file
*/
 
#include <arch/cpu.h>
#include <arch/cpuid.h>
#include <arch/pm.h>
 
#include <arch.h>
#include <arch/types.h>
#include <print.h>
#include <typedefs.h>
#include <fpu_context.h>
 
#include <arch/smp/apic.h>
 
/*
* Identification of CPUs.
* Contains only non-MP-Specification specific SMP code.
*/
#define AMD_CPUID_EBX 0x68747541
#define AMD_CPUID_ECX 0x444d4163
#define AMD_CPUID_EDX 0x69746e65
 
#define INTEL_CPUID_EBX 0x756e6547
#define INTEL_CPUID_ECX 0x6c65746e
#define INTEL_CPUID_EDX 0x49656e69
 
 
enum vendor {
VendorUnknown=0,
VendorAMD,
VendorIntel
};
 
static char *vendor_str[] = {
"Unknown Vendor",
"AuthenticAMD",
"GenuineIntel"
};
 
void fpu_disable(void)
{
__asm__ volatile (
"mov %%cr0,%%eax;"
"or $8,%%eax;"
"mov %%eax,%%cr0;"
:
:
:"%eax"
);
}
 
void fpu_enable(void)
{
__asm__ volatile (
"mov %%cr0,%%eax;"
"and $0xffFFffF7,%%eax;"
"mov %%eax,%%cr0;"
:
:
:"%eax"
);
}
 
void cpu_arch_init(void)
{
cpuid_feature_info fi;
cpuid_extended_feature_info efi;
cpu_info_t info;
uint32_t help = 0;
CPU->arch.tss = tss_p;
CPU->arch.tss->iomap_base = &CPU->arch.tss->iomap[0] - ((uint8_t *) CPU->arch.tss);
 
CPU->fpu_owner = NULL;
 
cpuid(1, &info);
 
fi.word = info.cpuid_edx;
efi.word = info.cpuid_ecx;
if (fi.bits.fxsr)
fpu_fxsr();
else
fpu_fsr();
if (fi.bits.sse) {
asm volatile (
"mov %%cr4,%0\n"
"or %1,%0\n"
"mov %0,%%cr4\n"
: "+r" (help)
: "i" (CR4_OSFXSR_MASK|(1<<10))
);
}
}
 
void cpu_identify(void)
{
cpu_info_t info;
 
CPU->arch.vendor = VendorUnknown;
if (has_cpuid()) {
cpuid(0, &info);
 
/*
* Check for AMD processor.
*/
if (info.cpuid_ebx==AMD_CPUID_EBX && info.cpuid_ecx==AMD_CPUID_ECX && info.cpuid_edx==AMD_CPUID_EDX) {
CPU->arch.vendor = VendorAMD;
}
 
/*
* Check for Intel processor.
*/
if (info.cpuid_ebx==INTEL_CPUID_EBX && info.cpuid_ecx==INTEL_CPUID_ECX && info.cpuid_edx==INTEL_CPUID_EDX) {
CPU->arch.vendor = VendorIntel;
}
cpuid(1, &info);
CPU->arch.family = (info.cpuid_eax>>8)&0xf;
CPU->arch.model = (info.cpuid_eax>>4)&0xf;
CPU->arch.stepping = (info.cpuid_eax>>0)&0xf;
}
}
 
void cpu_print_report(cpu_t* m)
{
printf("cpu%d: (%s family=%d model=%d stepping=%d) %dMHz\n",
m->id, vendor_str[m->arch.vendor], m->arch.family, m->arch.model, m->arch.stepping,
m->frequency_mhz);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ia32/src/bios/bios.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 ia32
* @{
*/
/** @file
*/
 
#include <arch/bios/bios.h>
#include <arch/types.h>
 
uintptr_t ebda = 0;
 
void bios_init(void)
{
/* Copy the EBDA address out from BIOS Data Area */
ebda = *((uint16_t *) BIOS_EBDA_PTR) * 0x10;
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/src/pm.c
0,0 → 1,241
/*
* 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 ia32
* @{
*/
/** @file
*/
 
#include <arch/pm.h>
#include <config.h>
#include <arch/types.h>
#include <typedefs.h>
#include <arch/interrupt.h>
#include <arch/asm.h>
#include <arch/context.h>
#include <panic.h>
#include <arch/mm/page.h>
#include <mm/slab.h>
#include <memstr.h>
#include <arch/boot/boot.h>
#include <interrupt.h>
 
/*
* Early ia32 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 },
/* VESA Init descriptor */
#ifdef CONFIG_FB
{ 0xffff, 0, VESA_INIT_SEGMENT>>12, AR_PRESENT | AR_CODE | DPL_KERNEL, 0xf, 0, 0, 0, 0, 0 }
#endif
};
 
static idescriptor_t idt[IDT_ITEMS];
 
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 idt_setoffset(idescriptor_t *d, uintptr_t offset)
{
/*
* Offset is a linear address.
*/
d->offset_0_15 = offset & 0xffff;
d->offset_16_31 = offset >> 16;
}
 
void tss_initialize(tss_t *t)
{
memsetb((uintptr_t) t, sizeof(struct tss), 0);
}
 
/*
* This function takes care of proper setup of IDT and IDTR.
*/
void idt_init(void)
{
idescriptor_t *d;
int i;
 
for (i = 0; i < IDT_ITEMS; i++) {
d = &idt[i];
 
d->unused = 0;
d->selector = selector(KTEXT_DES);
 
d->access = AR_PRESENT | AR_INTERRUPT; /* masking interrupt */
 
if (i == VECTOR_SYSCALL) {
/*
* The syscall interrupt gate must be calleable from userland.
*/
d->access |= DPL_USER;
}
idt_setoffset(d, ((uintptr_t) interrupt_handlers) + i*interrupt_handler_size);
exc_register(i, "undef", (iroutine) null_interrupt);
}
exc_register(13, "gp_fault", (iroutine) gp_fault);
exc_register( 7, "nm_fault", (iroutine) nm_fault);
exc_register(12, "ss_fault", (iroutine) ss_fault);
exc_register(19, "simd_fp", (iroutine) simd_fp_exception);
}
 
 
/* Clean IOPL(12,13) and NT(14) flags in EFLAGS register */
static void clean_IOPL_NT_flags(void)
{
__asm__ volatile (
"pushfl\n"
"pop %%eax\n"
"and $0xffff8fff, %%eax\n"
"push %%eax\n"
"popfl\n"
: : : "eax"
);
}
 
/* Clean AM(18) flag in CR0 register */
static void clean_AM_flag(void)
{
__asm__ volatile (
"mov %%cr0, %%eax\n"
"and $0xfffbffff, %%eax\n"
"mov %%eax, %%cr0\n"
: : : "eax"
);
}
 
void pm_init(void)
{
descriptor_t *gdt_p = (descriptor_t *) gdtr.base;
ptr_16_32_t idtr;
 
/*
* Update addresses in GDT and IDT to their virtual counterparts.
*/
idtr.limit = sizeof(idt);
idtr.base = (uintptr_t) idt;
gdtr_load(&gdtr);
idtr_load(&idtr);
/*
* Each CPU has its private GDT and TSS.
* All CPUs share one IDT.
*/
 
if (config.cpu_active == 1) {
idt_init();
/*
* 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);
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/src/smp/mps.c
0,0 → 1,435
/*
* 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 ia32
* @{
*/
/** @file
*/
 
#ifdef CONFIG_SMP
 
#include <config.h>
#include <print.h>
#include <debug.h>
#include <arch/smp/mps.h>
#include <arch/smp/apic.h>
#include <arch/smp/smp.h>
#include <func.h>
#include <arch/types.h>
#include <typedefs.h>
#include <cpu.h>
#include <arch/asm.h>
#include <arch/bios/bios.h>
#include <mm/frame.h>
 
/*
* MultiProcessor Specification detection code.
*/
 
#define FS_SIGNATURE 0x5f504d5f
#define CT_SIGNATURE 0x504d4350
 
int mps_fs_check(uint8_t *base);
int mps_ct_check(void);
 
int configure_via_ct(void);
int configure_via_default(uint8_t n);
 
int ct_processor_entry(struct __processor_entry *pr);
void ct_bus_entry(struct __bus_entry *bus);
void ct_io_apic_entry(struct __io_apic_entry *ioa);
void ct_io_intr_entry(struct __io_intr_entry *iointr);
void ct_l_intr_entry(struct __l_intr_entry *lintr);
 
void ct_extended_entries(void);
 
static struct mps_fs *fs;
static struct mps_ct *ct;
 
struct __processor_entry *processor_entries = NULL;
struct __bus_entry *bus_entries = NULL;
struct __io_apic_entry *io_apic_entries = NULL;
struct __io_intr_entry *io_intr_entries = NULL;
struct __l_intr_entry *l_intr_entries = NULL;
 
int processor_entry_cnt = 0;
int bus_entry_cnt = 0;
int io_apic_entry_cnt = 0;
int io_intr_entry_cnt = 0;
int l_intr_entry_cnt = 0;
 
waitq_t ap_completion_wq;
 
/*
* Implementation of IA-32 SMP configuration interface.
*/
static count_t get_cpu_count(void);
static bool is_cpu_enabled(index_t i);
static bool is_bsp(index_t i);
static uint8_t get_cpu_apic_id(index_t i);
static int mps_irq_to_pin(int irq);
 
struct smp_config_operations mps_config_operations = {
.cpu_count = get_cpu_count,
.cpu_enabled = is_cpu_enabled,
.cpu_bootstrap = is_bsp,
.cpu_apic_id = get_cpu_apic_id,
.irq_to_pin = mps_irq_to_pin
};
 
count_t get_cpu_count(void)
{
return processor_entry_cnt;
}
 
bool is_cpu_enabled(index_t i)
{
ASSERT(i < processor_entry_cnt);
return processor_entries[i].cpu_flags & 0x1;
}
 
bool is_bsp(index_t i)
{
ASSERT(i < processor_entry_cnt);
return processor_entries[i].cpu_flags & 0x2;
}
 
uint8_t get_cpu_apic_id(index_t i)
{
ASSERT(i < processor_entry_cnt);
return processor_entries[i].l_apic_id;
}
 
 
/*
* Used to check the integrity of the MP Floating Structure.
*/
int mps_fs_check(uint8_t *base)
{
int i;
uint8_t sum;
for (i = 0, sum = 0; i < 16; i++)
sum += base[i];
return !sum;
}
 
/*
* Used to check the integrity of the MP Configuration Table.
*/
int mps_ct_check(void)
{
uint8_t *base = (uint8_t *) ct;
uint8_t *ext = base + ct->base_table_length;
uint8_t sum;
int i;
/* count the checksum for the base table */
for (i=0,sum=0; i < ct->base_table_length; i++)
sum += base[i];
if (sum)
return 0;
/* count the checksum for the extended table */
for (i=0,sum=0; i < ct->ext_table_length; i++)
sum += ext[i];
return sum == ct->ext_table_checksum;
}
 
void mps_init(void)
{
uint8_t *addr[2] = { NULL, (uint8_t *) PA2KA(0xf0000) };
int i, j, length[2] = { 1024, 64*1024 };
 
/*
* Find MP Floating Pointer Structure
* 1a. search first 1K of EBDA
* 1b. if EBDA is undefined, search last 1K of base memory
* 2. search 64K starting at 0xf0000
*/
 
addr[0] = (uint8_t *) PA2KA(ebda ? ebda : 639 * 1024);
for (i = 0; i < 2; i++) {
for (j = 0; j < length[i]; j += 16) {
if (*((uint32_t *) &addr[i][j]) == FS_SIGNATURE && mps_fs_check(&addr[i][j])) {
fs = (struct mps_fs *) &addr[i][j];
goto fs_found;
}
}
}
 
return;
fs_found:
printf("%p: MPS Floating Pointer Structure\n", fs);
 
if (fs->config_type == 0 && fs->configuration_table) {
if (fs->mpfib2 >> 7) {
printf("%s: PIC mode not supported\n", __FUNCTION__);
return;
}
 
ct = (struct mps_ct *)PA2KA((uintptr_t)fs->configuration_table);
config.cpu_count = configure_via_ct();
}
else
config.cpu_count = configure_via_default(fs->config_type);
 
return;
}
 
int configure_via_ct(void)
{
uint8_t *cur;
int i, cnt;
if (ct->signature != CT_SIGNATURE) {
printf("%s: bad ct->signature\n", __FUNCTION__);
return 1;
}
if (!mps_ct_check()) {
printf("%s: bad ct checksum\n", __FUNCTION__);
return 1;
}
if (ct->oem_table) {
printf("%s: ct->oem_table not supported\n", __FUNCTION__);
return 1;
}
l_apic = (uint32_t *)(uintptr_t)ct->l_apic;
 
cnt = 0;
cur = &ct->base_table[0];
for (i=0; i < ct->entry_count; i++) {
switch (*cur) {
/* Processor entry */
case 0:
processor_entries = processor_entries ? processor_entries : (struct __processor_entry *) cur;
processor_entry_cnt++;
cnt += ct_processor_entry((struct __processor_entry *) cur);
cur += 20;
break;
 
/* Bus entry */
case 1:
bus_entries = bus_entries ? bus_entries : (struct __bus_entry *) cur;
bus_entry_cnt++;
ct_bus_entry((struct __bus_entry *) cur);
cur += 8;
break;
/* I/O Apic */
case 2:
io_apic_entries = io_apic_entries ? io_apic_entries : (struct __io_apic_entry *) cur;
io_apic_entry_cnt++;
ct_io_apic_entry((struct __io_apic_entry *) cur);
cur += 8;
break;
/* I/O Interrupt Assignment */
case 3:
io_intr_entries = io_intr_entries ? io_intr_entries : (struct __io_intr_entry *) cur;
io_intr_entry_cnt++;
ct_io_intr_entry((struct __io_intr_entry *) cur);
cur += 8;
break;
 
/* Local Interrupt Assignment */
case 4:
l_intr_entries = l_intr_entries ? l_intr_entries : (struct __l_intr_entry *) cur;
l_intr_entry_cnt++;
ct_l_intr_entry((struct __l_intr_entry *) cur);
cur += 8;
break;
 
default:
/*
* Something is wrong. Fallback to UP mode.
*/
printf("%s: ct badness\n", __FUNCTION__);
return 1;
}
}
/*
* Process extended entries.
*/
ct_extended_entries();
return cnt;
}
 
int configure_via_default(uint8_t n)
{
/*
* Not yet implemented.
*/
printf("%s: not supported\n", __FUNCTION__);
return 1;
}
 
 
int ct_processor_entry(struct __processor_entry *pr)
{
/*
* Ignore processors which are not marked enabled.
*/
if ((pr->cpu_flags & (1<<0)) == 0)
return 0;
apic_id_mask |= (1<<pr->l_apic_id);
return 1;
}
 
void ct_bus_entry(struct __bus_entry *bus)
{
#ifdef MPSCT_VERBOSE
char buf[7];
memcpy((void *) buf, (void *) bus->bus_type, 6);
buf[6] = 0;
printf("bus%d: %s\n", bus->bus_id, buf);
#endif
}
 
void ct_io_apic_entry(struct __io_apic_entry *ioa)
{
static int io_apic_count = 0;
 
/* this ioapic is marked unusable */
if ((ioa->io_apic_flags & 1) == 0)
return;
if (io_apic_count++ > 0) {
/*
* Multiple IO APIC's are currently not supported.
*/
return;
}
io_apic = (uint32_t *)(uintptr_t)ioa->io_apic;
}
 
//#define MPSCT_VERBOSE
void ct_io_intr_entry(struct __io_intr_entry *iointr)
{
#ifdef MPSCT_VERBOSE
switch (iointr->intr_type) {
case 0: printf("INT"); break;
case 1: printf("NMI"); break;
case 2: printf("SMI"); break;
case 3: printf("ExtINT"); break;
}
putchar(',');
switch (iointr->poel&3) {
case 0: printf("bus-like"); break;
case 1: printf("active high"); break;
case 2: printf("reserved"); break;
case 3: printf("active low"); break;
}
putchar(',');
switch ((iointr->poel>>2)&3) {
case 0: printf("bus-like"); break;
case 1: printf("edge-triggered"); break;
case 2: printf("reserved"); break;
case 3: printf("level-triggered"); break;
}
putchar(',');
printf("bus%d,irq%d", iointr->src_bus_id, iointr->src_bus_irq);
putchar(',');
printf("io_apic%d,pin%d", iointr->dst_io_apic_id, iointr->dst_io_apic_pin);
putchar('\n');
#endif
}
 
void ct_l_intr_entry(struct __l_intr_entry *lintr)
{
#ifdef MPSCT_VERBOSE
switch (lintr->intr_type) {
case 0: printf("INT"); break;
case 1: printf("NMI"); break;
case 2: printf("SMI"); break;
case 3: printf("ExtINT"); break;
}
putchar(',');
switch (lintr->poel&3) {
case 0: printf("bus-like"); break;
case 1: printf("active high"); break;
case 2: printf("reserved"); break;
case 3: printf("active low"); break;
}
putchar(',');
switch ((lintr->poel>>2)&3) {
case 0: printf("bus-like"); break;
case 1: printf("edge-triggered"); break;
case 2: printf("reserved"); break;
case 3: printf("level-triggered"); break;
}
putchar(',');
printf("bus%d,irq%d", lintr->src_bus_id, lintr->src_bus_irq);
putchar(',');
printf("l_apic%d,pin%d", lintr->dst_l_apic_id, lintr->dst_l_apic_pin);
putchar('\n');
#endif
}
 
void ct_extended_entries(void)
{
uint8_t *ext = (uint8_t *) ct + ct->base_table_length;
uint8_t *cur;
 
for (cur = ext; cur < ext + ct->ext_table_length; cur += cur[CT_EXT_ENTRY_LEN]) {
switch (cur[CT_EXT_ENTRY_TYPE]) {
default:
printf("%p: skipping MP Configuration Table extended entry type %d\n", cur, cur[CT_EXT_ENTRY_TYPE]);
break;
}
}
}
 
int mps_irq_to_pin(int irq)
{
int i;
for(i=0;i<io_intr_entry_cnt;i++) {
if (io_intr_entries[i].src_bus_irq == irq && io_intr_entries[i].intr_type == 0)
return io_intr_entries[i].dst_io_apic_pin;
}
return -1;
}
 
#endif /* CONFIG_SMP */
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/src/smp/smp.c
0,0 → 1,185
/*
* 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 ia32
* @{
*/
/** @file
*/
 
#include <smp/smp.h>
#include <arch/smp/smp.h>
#include <arch/smp/mps.h>
#include <arch/smp/ap.h>
#include <arch/boot/boot.h>
#include <genarch/acpi/acpi.h>
#include <genarch/acpi/madt.h>
#include <config.h>
#include <synch/waitq.h>
#include <synch/synch.h>
#include <arch/pm.h>
#include <func.h>
#include <panic.h>
#include <debug.h>
#include <arch/asm.h>
#include <mm/frame.h>
#include <mm/page.h>
#include <mm/slab.h>
#include <mm/as.h>
#include <print.h>
#include <memstr.h>
#include <arch/drivers/i8259.h>
 
#ifdef CONFIG_SMP
 
static struct smp_config_operations *ops = NULL;
 
void smp_init(void)
{
uintptr_t l_apic_address, io_apic_address;
 
if (acpi_madt) {
acpi_madt_parse();
ops = &madt_config_operations;
}
if (config.cpu_count == 1) {
mps_init();
ops = &mps_config_operations;
}
 
l_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, FRAME_ATOMIC | FRAME_KA);
if (!l_apic_address)
panic("cannot allocate address for l_apic\n");
 
io_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, FRAME_ATOMIC | FRAME_KA);
if (!io_apic_address)
panic("cannot allocate address for io_apic\n");
 
if (config.cpu_count > 1) {
page_mapping_insert(AS_KERNEL, l_apic_address, (uintptr_t) l_apic,
PAGE_NOT_CACHEABLE);
page_mapping_insert(AS_KERNEL, io_apic_address, (uintptr_t) io_apic,
PAGE_NOT_CACHEABLE);
l_apic = (uint32_t *) l_apic_address;
io_apic = (uint32_t *) io_apic_address;
}
}
 
/*
* Kernel thread for bringing up application processors. It becomes clear
* that we need an arrangement like this (AP's being initialized by a kernel
* thread), for a thread has its dedicated stack. (The stack used during the
* BSP initialization (prior the very first call to scheduler()) will be used
* as an initialization stack for each AP.)
*/
void kmp(void *arg)
{
int i;
ASSERT(ops != NULL);
 
waitq_initialize(&ap_completion_wq);
 
/*
* We need to access data in frame 0.
* We boldly make use of kernel address space mapping.
*/
 
/*
* Set the warm-reset vector to the real-mode address of 4K-aligned ap_boot()
*/
*((uint16_t *) (PA2KA(0x467+0))) = ((uintptr_t) ap_boot) >> 4; /* segment */
*((uint16_t *) (PA2KA(0x467+2))) = 0; /* offset */
/*
* Save 0xa to address 0xf of the CMOS RAM.
* BIOS will not do the POST after the INIT signal.
*/
outb(0x70,0xf);
outb(0x71,0xa);
 
pic_disable_irqs(0xffff);
apic_init();
 
for (i = 0; i < ops->cpu_count(); i++) {
struct descriptor *gdt_new;
/*
* Skip processors marked unusable.
*/
if (!ops->cpu_enabled(i))
continue;
 
/*
* The bootstrap processor is already up.
*/
if (ops->cpu_bootstrap(i))
continue;
 
if (ops->cpu_apic_id(i) == l_apic_id()) {
printf("%s: bad processor entry #%d, will not send IPI to myself\n", __FUNCTION__, i);
continue;
}
/*
* Prepare new GDT for CPU in question.
*/
if (!(gdt_new = (struct descriptor *) malloc(GDT_ITEMS*sizeof(struct descriptor), FRAME_ATOMIC)))
panic("couldn't allocate memory for GDT\n");
 
memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(struct descriptor));
memsetb((uintptr_t)(&gdt_new[TSS_DES]), sizeof(struct descriptor), 0);
protected_ap_gdtr.limit = GDT_ITEMS * sizeof(struct descriptor);
protected_ap_gdtr.base = KA2PA((uintptr_t) gdt_new);
gdtr.base = (uintptr_t) gdt_new;
 
if (l_apic_send_init_ipi(ops->cpu_apic_id(i))) {
/*
* There may be just one AP being initialized at
* the time. After it comes completely up, it is
* supposed to wake us up.
*/
if (waitq_sleep_timeout(&ap_completion_wq, 1000000, SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT)
printf("%s: waiting for cpu%d (APIC ID = %d) timed out\n", __FUNCTION__, config.cpu_active > i ? config.cpu_active : i, ops->cpu_apic_id(i));
} else
printf("INIT IPI for l_apic%d failed\n", ops->cpu_apic_id(i));
}
}
 
int smp_irq_to_pin(int irq)
{
ASSERT(ops != NULL);
return ops->irq_to_pin(irq);
}
 
#endif /* CONFIG_SMP */
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/src/smp/ap.S
0,0 → 1,95
#
# Copyright (C) 2001-2004 Jakub Jermar
# Copyright (C) 2005-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.
#
 
#
# Init code for application processors.
#
 
#include <arch/boot/boot.h>
#include <arch/boot/memmap.h>
#include <arch/mm/page.h>
#include <arch/pm.h>
 
.section K_TEXT_START, "ax"
 
#ifdef CONFIG_SMP
 
.global unmapped_ap_boot
 
KTEXT=8
KDATA=16
 
# This piece of code is real-mode and is meant to be alligned at 4K boundary.
# The requirement for such an alignment comes from MP Specification's STARTUP IPI
# requirements.
 
.align 4096
unmapped_ap_boot:
.code16
cli
xorw %ax, %ax
movw %ax, %ds
 
lgdtl ap_gdtr # initialize Global Descriptor Table register
movl %cr0, %eax
orl $1, %eax
movl %eax, %cr0 # switch to protected mode
jmpl $KTEXT, $jump_to_kernel - BOOT_OFFSET + AP_BOOT_OFFSET
jump_to_kernel:
.code32
movw $KDATA, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
movl $KA2PA(ctx), %eax # KA2PA((uintptr_t) &ctx)
movl (%eax), %esp
subl $0x80000000, %esp # KA2PA(ctx.sp)
 
call map_kernel # map kernel and turn paging on
addl $0x80000000, %esp # PA2KA(ctx.sp)
jmpl $KTEXT, $main_ap
 
#endif /* CONFIG_SMP */
 
 
.section K_DATA_START, "aw", @progbits
 
#ifdef CONFIG_SMP
 
.global unmapped_ap_gdtr
 
unmapped_ap_gdtr:
.word 0
.long 0
 
#endif /* CONFIG_SMP */
/tags/0.2.0.3/kernel/arch/ia32/src/smp/ipi.c
0,0 → 1,49
/*
* 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 ia32
* @{
*/
/** @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 */
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/src/smp/apic.c
0,0 → 1,582
/*
* 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 ia32
* @{
*/
/** @file
*/
 
#include <arch/types.h>
#include <arch/smp/apic.h>
#include <arch/smp/ap.h>
#include <arch/smp/mps.h>
#include <arch/boot/boot.h>
#include <mm/page.h>
#include <time/delay.h>
#include <interrupt.h>
#include <arch/interrupt.h>
#include <print.h>
#include <arch/asm.h>
#include <arch.h>
 
#ifdef CONFIG_SMP
 
/*
* Advanced Programmable Interrupt Controller for SMP systems.
* Tested on:
* Bochs 2.0.2 - Bochs 2.2.6 with 2-8 CPUs
* Simics 2.0.28 - Simics 2.2.19 2-15 CPUs
* VMware Workstation 5.5 with 2 CPUs
* QEMU 0.8.0 with 2-15 CPUs
* ASUS P/I-P65UP5 + ASUS C-P55T2D REV. 1.41 with 2x 200Mhz Pentium CPUs
* ASUS PCH-DL with 2x 3000Mhz Pentium 4 Xeon (HT) CPUs
* MSI K7D Master-L with 2x 2100MHz Athlon MP CPUs
*/
 
/*
* These variables either stay configured as initilalized, or are changed by
* the MP configuration code.
*
* Pay special attention to the volatile keyword. Without it, gcc -O2 would
* optimize the code too much and accesses to l_apic and io_apic, that must
* always be 32-bit, would use byte oriented instructions.
*/
volatile uint32_t *l_apic = (uint32_t *) 0xfee00000;
volatile uint32_t *io_apic = (uint32_t *) 0xfec00000;
 
uint32_t apic_id_mask = 0;
 
static int apic_poll_errors(void);
 
#ifdef LAPIC_VERBOSE
static char *delmod_str[] = {
"Fixed",
"Lowest Priority",
"SMI",
"Reserved",
"NMI",
"INIT",
"STARTUP",
"ExtInt"
};
 
static char *destmod_str[] = {
"Physical",
"Logical"
};
 
static char *trigmod_str[] = {
"Edge",
"Level"
};
 
static char *mask_str[] = {
"Unmasked",
"Masked"
};
 
static char *delivs_str[] = {
"Idle",
"Send Pending"
};
 
static char *tm_mode_str[] = {
"One-shot",
"Periodic"
};
 
static char *intpol_str[] = {
"Polarity High",
"Polarity Low"
};
#endif /* LAPIC_VERBOSE */
 
 
static void apic_spurious(int n, istate_t *istate);
static void l_apic_timer_interrupt(int n, istate_t *istate);
 
/** Initialize APIC on BSP. */
void apic_init(void)
{
io_apic_id_t idreg;
int i;
 
exc_register(VECTOR_APIC_SPUR, "apic_spurious", (iroutine) apic_spurious);
 
enable_irqs_function = io_apic_enable_irqs;
disable_irqs_function = io_apic_disable_irqs;
eoi_function = l_apic_eoi;
/*
* Configure interrupt routing.
* IRQ 0 remains masked as the time signal is generated by l_apic's themselves.
* Other interrupts will be forwarded to the lowest priority CPU.
*/
io_apic_disable_irqs(0xffff);
exc_register(VECTOR_CLK, "l_apic_timer", (iroutine) l_apic_timer_interrupt);
for (i = 0; i < IRQ_COUNT; i++) {
int pin;
if ((pin = smp_irq_to_pin(i)) != -1) {
io_apic_change_ioredtbl(pin, DEST_ALL, IVT_IRQBASE+i, LOPRI);
}
}
/*
* Ensure that io_apic has unique ID.
*/
idreg.value = io_apic_read(IOAPICID);
if ((1<<idreg.apic_id) & apic_id_mask) { /* see if IO APIC ID is used already */
for (i = 0; i < APIC_ID_COUNT; i++) {
if (!((1<<i) & apic_id_mask)) {
idreg.apic_id = i;
io_apic_write(IOAPICID, idreg.value);
break;
}
}
}
 
/*
* Configure the BSP's lapic.
*/
l_apic_init();
 
l_apic_debug();
}
 
/** APIC spurious interrupt handler.
*
* @param n Interrupt vector.
* @param istate Interrupted state.
*/
void apic_spurious(int n, istate_t *istate)
{
#ifdef CONFIG_DEBUG
printf("cpu%d: APIC spurious interrupt\n", CPU->id);
#endif
}
 
/** Poll for APIC errors.
*
* Examine Error Status Register and report all errors found.
*
* @return 0 on error, 1 on success.
*/
int apic_poll_errors(void)
{
esr_t esr;
esr.value = l_apic[ESR];
if (esr.send_checksum_error)
printf("Send Checksum Error\n");
if (esr.receive_checksum_error)
printf("Receive Checksum Error\n");
if (esr.send_accept_error)
printf("Send Accept Error\n");
if (esr.receive_accept_error)
printf("Receive Accept Error\n");
if (esr.send_illegal_vector)
printf("Send Illegal Vector\n");
if (esr.received_illegal_vector)
printf("Received Illegal Vector\n");
if (esr.illegal_register_address)
printf("Illegal Register Address\n");
 
return !esr.err_bitmap;
}
 
/** Send all CPUs excluding CPU IPI vector.
*
* @param vector Interrupt vector to be sent.
*
* @return 0 on failure, 1 on success.
*/
int l_apic_broadcast_custom_ipi(uint8_t vector)
{
icr_t icr;
 
icr.lo = l_apic[ICRlo];
icr.delmod = DELMOD_FIXED;
icr.destmod = DESTMOD_LOGIC;
icr.level = LEVEL_ASSERT;
icr.shorthand = SHORTHAND_ALL_EXCL;
icr.trigger_mode = TRIGMOD_LEVEL;
icr.vector = vector;
 
l_apic[ICRlo] = icr.lo;
 
icr.lo = l_apic[ICRlo];
if (icr.delivs == DELIVS_PENDING) {
#ifdef CONFIG_DEBUG
printf("IPI is pending.\n");
#endif
}
 
return apic_poll_errors();
}
 
/** Universal Start-up Algorithm for bringing up the AP processors.
*
* @param apicid APIC ID of the processor to be brought up.
*
* @return 0 on failure, 1 on success.
*/
int l_apic_send_init_ipi(uint8_t apicid)
{
icr_t icr;
int i;
 
/*
* Read the ICR register in and zero all non-reserved fields.
*/
icr.lo = l_apic[ICRlo];
icr.hi = l_apic[ICRhi];
icr.delmod = DELMOD_INIT;
icr.destmod = DESTMOD_PHYS;
icr.level = LEVEL_ASSERT;
icr.trigger_mode = TRIGMOD_LEVEL;
icr.shorthand = SHORTHAND_NONE;
icr.vector = 0;
icr.dest = apicid;
l_apic[ICRhi] = icr.hi;
l_apic[ICRlo] = icr.lo;
 
/*
* According to MP Specification, 20us should be enough to
* deliver the IPI.
*/
delay(20);
 
if (!apic_poll_errors())
return 0;
 
icr.lo = l_apic[ICRlo];
if (icr.delivs == DELIVS_PENDING) {
#ifdef CONFIG_DEBUG
printf("IPI is pending.\n");
#endif
}
 
icr.delmod = DELMOD_INIT;
icr.destmod = DESTMOD_PHYS;
icr.level = LEVEL_DEASSERT;
icr.shorthand = SHORTHAND_NONE;
icr.trigger_mode = TRIGMOD_LEVEL;
icr.vector = 0;
l_apic[ICRlo] = icr.lo;
 
/*
* Wait 10ms as MP Specification specifies.
*/
delay(10000);
 
if (!is_82489DX_apic(l_apic[LAVR])) {
/*
* If this is not 82489DX-based l_apic we must send two STARTUP IPI's.
*/
for (i = 0; i<2; i++) {
icr.lo = l_apic[ICRlo];
icr.vector = ((uintptr_t) ap_boot) / 4096; /* calculate the reset vector */
icr.delmod = DELMOD_STARTUP;
icr.destmod = DESTMOD_PHYS;
icr.level = LEVEL_ASSERT;
icr.shorthand = SHORTHAND_NONE;
icr.trigger_mode = TRIGMOD_LEVEL;
l_apic[ICRlo] = icr.lo;
delay(200);
}
}
return apic_poll_errors();
}
 
/** Initialize Local APIC. */
void l_apic_init(void)
{
lvt_error_t error;
lvt_lint_t lint;
tpr_t tpr;
svr_t svr;
icr_t icr;
tdcr_t tdcr;
lvt_tm_t tm;
ldr_t ldr;
dfr_t dfr;
uint32_t t1, t2;
 
/* Initialize LVT Error register. */
error.value = l_apic[LVT_Err];
error.masked = true;
l_apic[LVT_Err] = error.value;
 
/* Initialize LVT LINT0 register. */
lint.value = l_apic[LVT_LINT0];
lint.masked = true;
l_apic[LVT_LINT0] = lint.value;
 
/* Initialize LVT LINT1 register. */
lint.value = l_apic[LVT_LINT1];
lint.masked = true;
l_apic[LVT_LINT1] = lint.value;
 
/* Task Priority Register initialization. */
tpr.value = l_apic[TPR];
tpr.pri_sc = 0;
tpr.pri = 0;
l_apic[TPR] = tpr.value;
/* Spurious-Interrupt Vector Register initialization. */
svr.value = l_apic[SVR];
svr.vector = VECTOR_APIC_SPUR;
svr.lapic_enabled = true;
svr.focus_checking = true;
l_apic[SVR] = svr.value;
 
if (CPU->arch.family >= 6)
enable_l_apic_in_msr();
/* Interrupt Command Register initialization. */
icr.lo = l_apic[ICRlo];
icr.delmod = DELMOD_INIT;
icr.destmod = DESTMOD_PHYS;
icr.level = LEVEL_DEASSERT;
icr.shorthand = SHORTHAND_ALL_INCL;
icr.trigger_mode = TRIGMOD_LEVEL;
l_apic[ICRlo] = icr.lo;
/* Timer Divide Configuration Register initialization. */
tdcr.value = l_apic[TDCR];
tdcr.div_value = DIVIDE_1;
l_apic[TDCR] = tdcr.value;
 
/* Program local timer. */
tm.value = l_apic[LVT_Tm];
tm.vector = VECTOR_CLK;
tm.mode = TIMER_PERIODIC;
tm.masked = false;
l_apic[LVT_Tm] = tm.value;
 
/*
* Measure and configure the timer to generate timer
* interrupt with period 1s/HZ seconds.
*/
t1 = l_apic[CCRT];
l_apic[ICRT] = 0xffffffff;
 
while (l_apic[CCRT] == t1)
;
t1 = l_apic[CCRT];
delay(1000000/HZ);
t2 = l_apic[CCRT];
l_apic[ICRT] = t1-t2;
/* Program Logical Destination Register. */
ldr.value = l_apic[LDR];
if (CPU->id < sizeof(CPU->id)*8) /* size in bits */
ldr.id = (1<<CPU->id);
l_apic[LDR] = ldr.value;
/* Program Destination Format Register for Flat mode. */
dfr.value = l_apic[DFR];
dfr.model = MODEL_FLAT;
l_apic[DFR] = dfr.value;
}
 
/** Local APIC End of Interrupt. */
void l_apic_eoi(void)
{
l_apic[EOI] = 0;
}
 
/** Dump content of Local APIC registers. */
void l_apic_debug(void)
{
#ifdef LAPIC_VERBOSE
lvt_tm_t tm;
lvt_lint_t lint;
lvt_error_t error;
printf("LVT on cpu%d, LAPIC ID: %d\n", CPU->id, l_apic_id());
 
tm.value = l_apic[LVT_Tm];
printf("LVT Tm: vector=%hhd, %s, %s, %s\n", tm.vector, delivs_str[tm.delivs], mask_str[tm.masked], tm_mode_str[tm.mode]);
lint.value = l_apic[LVT_LINT0];
printf("LVT LINT0: vector=%hhd, %s, %s, %s, irr=%d, %s, %s\n", tm.vector, delmod_str[lint.delmod], delivs_str[lint.delivs], intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode], mask_str[lint.masked]);
lint.value = l_apic[LVT_LINT1];
printf("LVT LINT1: vector=%hhd, %s, %s, %s, irr=%d, %s, %s\n", tm.vector, delmod_str[lint.delmod], delivs_str[lint.delivs], intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode], mask_str[lint.masked]);
error.value = l_apic[LVT_Err];
printf("LVT Err: vector=%hhd, %s, %s\n", error.vector, delivs_str[error.delivs], mask_str[error.masked]);
#endif
}
 
/** Local APIC Timer Interrupt.
*
* @param n Interrupt vector number.
* @param istate Interrupted state.
*/
void l_apic_timer_interrupt(int n, istate_t *istate)
{
l_apic_eoi();
clock();
}
 
/** Get Local APIC ID.
*
* @return Local APIC ID.
*/
uint8_t l_apic_id(void)
{
l_apic_id_t idreg;
idreg.value = l_apic[L_APIC_ID];
return idreg.apic_id;
}
 
/** Read from IO APIC register.
*
* @param address IO APIC register address.
*
* @return Content of the addressed IO APIC register.
*/
uint32_t io_apic_read(uint8_t address)
{
io_regsel_t regsel;
regsel.value = io_apic[IOREGSEL];
regsel.reg_addr = address;
io_apic[IOREGSEL] = regsel.value;
return io_apic[IOWIN];
}
 
/** Write to IO APIC register.
*
* @param address IO APIC register address.
* @param x Content to be written to the addressed IO APIC register.
*/
void io_apic_write(uint8_t address, uint32_t x)
{
io_regsel_t regsel;
regsel.value = io_apic[IOREGSEL];
regsel.reg_addr = address;
io_apic[IOREGSEL] = regsel.value;
io_apic[IOWIN] = x;
}
 
/** Change some attributes of one item in I/O Redirection Table.
*
* @param pin IO APIC pin number.
* @param dest Interrupt destination address.
* @param v Interrupt vector to trigger.
* @param flags Flags.
*/
void io_apic_change_ioredtbl(int pin, int dest, uint8_t v, int flags)
{
io_redirection_reg_t reg;
int dlvr = DELMOD_FIXED;
if (flags & LOPRI)
dlvr = DELMOD_LOWPRI;
 
reg.lo = io_apic_read(IOREDTBL + pin*2);
reg.hi = io_apic_read(IOREDTBL + pin*2 + 1);
reg.dest = dest;
reg.destmod = DESTMOD_LOGIC;
reg.trigger_mode = TRIGMOD_EDGE;
reg.intpol = POLARITY_HIGH;
reg.delmod = dlvr;
reg.intvec = v;
 
io_apic_write(IOREDTBL + pin*2, reg.lo);
io_apic_write(IOREDTBL + pin*2 + 1, reg.hi);
}
 
/** Mask IRQs in IO APIC.
*
* @param irqmask Bitmask of IRQs to be masked (0 = do not mask, 1 = mask).
*/
void io_apic_disable_irqs(uint16_t irqmask)
{
io_redirection_reg_t reg;
int i, pin;
for (i=0;i<16;i++) {
if (irqmask & (1<<i)) {
/*
* Mask the signal input in IO APIC if there is a
* mapping for the respective IRQ number.
*/
pin = smp_irq_to_pin(i);
if (pin != -1) {
reg.lo = io_apic_read(IOREDTBL + pin*2);
reg.masked = true;
io_apic_write(IOREDTBL + pin*2, reg.lo);
}
}
}
}
 
/** Unmask IRQs in IO APIC.
*
* @param irqmask Bitmask of IRQs to be unmasked (0 = do not unmask, 1 = unmask).
*/
void io_apic_enable_irqs(uint16_t irqmask)
{
int i, pin;
io_redirection_reg_t reg;
for (i=0;i<16;i++) {
if (irqmask & (1<<i)) {
/*
* Unmask the signal input in IO APIC if there is a
* mapping for the respective IRQ number.
*/
pin = smp_irq_to_pin(i);
if (pin != -1) {
reg.lo = io_apic_read(IOREDTBL + pin*2);
reg.masked = false;
io_apic_write(IOREDTBL + pin*2, reg.lo);
}
}
}
}
 
#endif /* CONFIG_SMP */
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/src/ddi/ddi.c
0,0 → 1,165
/*
* 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 ia32ddi
* @{
*/
/** @file
*/
 
#include <ddi/ddi.h>
#include <arch/ddi/ddi.h>
#include <proc/task.h>
#include <arch/types.h>
#include <typedefs.h>
#include <adt/bitmap.h>
#include <mm/slab.h>
#include <arch/pm.h>
#include <errno.h>
#include <arch/cpu.h>
#include <cpu.h>
#include <arch.h>
#include <align.h>
 
/** Enable I/O space range for task.
*
* Interrupts are disabled and task is locked.
*
* @param task Task.
* @param ioaddr Startign I/O space address.
* @param size Size of the enabled I/O range.
*
* @return 0 on success or an error code from errno.h.
*/
int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
{
count_t bits;
 
bits = ioaddr + size;
if (bits > IO_PORTS)
return ENOENT;
 
if (task->arch.iomap.bits < bits) {
bitmap_t oldiomap;
uint8_t *newmap;
/*
* The I/O permission bitmap is too small and needs to be grown.
*/
newmap = (uint8_t *) malloc(BITS2BYTES(bits), FRAME_ATOMIC);
if (!newmap)
return ENOMEM;
bitmap_initialize(&oldiomap, task->arch.iomap.map, task->arch.iomap.bits);
bitmap_initialize(&task->arch.iomap, newmap, bits);
 
/*
* Mark the new range inaccessible.
*/
bitmap_set_range(&task->arch.iomap, oldiomap.bits, bits - oldiomap.bits);
 
/*
* In case there really existed smaller iomap,
* copy its contents and deallocate it.
*/
if (oldiomap.bits) {
bitmap_copy(&task->arch.iomap, &oldiomap, oldiomap.bits);
free(oldiomap.map);
}
}
 
/*
* Enable the range and we are done.
*/
bitmap_clear_range(&task->arch.iomap, (index_t) ioaddr, (count_t) size);
 
/*
* Increment I/O Permission bitmap generation counter.
*/
task->arch.iomapver++;
 
return 0;
}
 
/** Install I/O Permission bitmap.
*
* Current task's I/O permission bitmap, if any, is installed
* in the current CPU's TSS.
*
* Interrupts must be disabled prior this call.
*/
void io_perm_bitmap_install(void)
{
count_t bits;
ptr_16_32_t cpugdtr;
descriptor_t *gdt_p;
count_t ver;
 
/* First, copy the I/O Permission Bitmap. */
spinlock_lock(&TASK->lock);
ver = TASK->arch.iomapver;
if ((bits = TASK->arch.iomap.bits)) {
bitmap_t iomap;
ASSERT(TASK->arch.iomap.map);
bitmap_initialize(&iomap, CPU->arch.tss->iomap, TSS_IOMAP_SIZE * 8);
bitmap_copy(&iomap, &TASK->arch.iomap, TASK->arch.iomap.bits);
/*
* It is safe to set the trailing eight bits because of the extra
* convenience byte in TSS_IOMAP_SIZE.
*/
bitmap_set_range(&iomap, ALIGN_UP(TASK->arch.iomap.bits, 8), 8);
}
spinlock_unlock(&TASK->lock);
 
/*
* Second, adjust TSS segment limit.
* Take the extra ending byte with all bits set into account.
*/
gdtr_store(&cpugdtr);
gdt_p = (descriptor_t *) cpugdtr.base;
gdt_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE + BITS2BYTES(bits));
gdtr_load(&cpugdtr);
 
/*
* Before we load new TSS limit, the current TSS descriptor
* type must be changed to describe inactive TSS.
*/
gdt_p[TSS_DES].access = AR_PRESENT | AR_TSS | DPL_KERNEL;
tr_load(selector(TSS_DES));
/*
* Update the generation count so that faults caused by
* early accesses can be serviced.
*/
CPU->arch.iomapver_copy = ver;
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ia32/src/proc/scheduler.c
0,0 → 1,82
/*
* 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 ia32proc
* @{
*/
/** @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)
{
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/src/proc/task.c
0,0 → 1,62
/*
* 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 ia32proc
* @{
*/
/** @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);
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/src/proc/thread.c
0,0 → 1,48
/*
* 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 ia32proc
* @{
*/
/** @file
*/
 
#include <proc/thread.h>
 
/** Perform ia32 specific thread initialization.
*
* @param t Thread to be initialized.
*/
void thread_create_arch(thread_t *t)
{
t->arch.tls = 0;
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/src/interrupt.c
0,0 → 1,210
/*
* 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 ia32interrupt
* @{
*/
/** @file
*/
 
#include <arch/interrupt.h>
#include <syscall/syscall.h>
#include <print.h>
#include <debug.h>
#include <panic.h>
#include <arch/drivers/i8259.h>
#include <func.h>
#include <cpu.h>
#include <arch/asm.h>
#include <mm/tlb.h>
#include <mm/as.h>
#include <arch.h>
#include <symtab.h>
#include <proc/thread.h>
#include <proc/task.h>
#include <synch/spinlock.h>
#include <arch/ddi/ddi.h>
#include <ipc/sysipc.h>
#include <interrupt.h>
 
/*
* Interrupt and exception dispatching.
*/
 
void (* disable_irqs_function)(uint16_t irqmask) = NULL;
void (* enable_irqs_function)(uint16_t irqmask) = NULL;
void (* eoi_function)(void) = NULL;
 
void PRINT_INFO_ERRCODE(istate_t *istate)
{
char *symbol = get_symtab_entry(istate->eip);
 
if (!symbol)
symbol = "";
 
if (CPU)
printf("----------------EXCEPTION OCCURED (cpu%d)----------------\n", CPU->id);
else
printf("----------------EXCEPTION OCCURED----------------\n");
printf("%%eip: %#x (%s)\n",istate->eip,symbol);
printf("ERROR_WORD=%#x\n", istate->error_word);
printf("%%cs=%#x,flags=%#x\n", istate->cs, istate->eflags);
printf("%%eax=%#x, %%ecx=%#x, %%edx=%#x, %%esp=%#x\n", istate->eax,istate->ecx,istate->edx,&istate->stack[0]);
#ifdef CONFIG_DEBUG_ALLREGS
printf("%%esi=%#x, %%edi=%#x, %%ebp=%#x, %%ebx=%#x\n", istate->esi,istate->edi,istate->ebp,istate->ebx);
#endif
printf("stack: %#x, %#x, %#x, %#x\n", istate->stack[0], istate->stack[1], istate->stack[2], istate->stack[3]);
printf(" %#x, %#x, %#x, %#x\n", istate->stack[4], istate->stack[5], istate->stack[6], istate->stack[7]);
}
 
void null_interrupt(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "unserviced interrupt: %d", n);
 
PRINT_INFO_ERRCODE(istate);
panic("unserviced interrupt: %d\n", n);
}
 
/** General Protection Fault. */
void gp_fault(int n, istate_t *istate)
{
if (TASK) {
count_t ver;
spinlock_lock(&TASK->lock);
ver = TASK->arch.iomapver;
spinlock_unlock(&TASK->lock);
if (CPU->arch.iomapver_copy != ver) {
/*
* This fault can be caused by an early access
* to I/O port because of an out-dated
* I/O Permission bitmap installed on CPU.
* Install the fresh copy and restart
* the instruction.
*/
io_perm_bitmap_install();
return;
}
fault_if_from_uspace(istate, "general protection fault");
}
 
PRINT_INFO_ERRCODE(istate);
panic("general protection fault\n");
}
 
void ss_fault(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "stack fault");
 
PRINT_INFO_ERRCODE(istate);
panic("stack fault\n");
}
 
void simd_fp_exception(int n, istate_t *istate)
{
uint32_t mxcsr;
asm
(
"stmxcsr %0;\n"
:"=m"(mxcsr)
);
fault_if_from_uspace(istate, "SIMD FP exception(19), MXCSR: %#zx",
(unative_t)mxcsr);
 
PRINT_INFO_ERRCODE(istate);
printf("MXCSR: %#zx\n",(unative_t)(mxcsr));
panic("SIMD FP exception(19)\n");
}
 
void nm_fault(int n, istate_t *istate)
{
#ifdef CONFIG_FPU_LAZY
scheduler_fpu_lazy_request();
#else
fault_if_from_uspace(istate, "fpu fault");
panic("fpu fault");
#endif
}
 
void syscall(int n, istate_t *istate)
{
panic("Obsolete syscall handler.");
}
 
void tlb_shootdown_ipi(int n, istate_t *istate)
{
trap_virtual_eoi();
tlb_shootdown_ipi_recv();
}
 
void trap_virtual_enable_irqs(uint16_t irqmask)
{
if (enable_irqs_function)
enable_irqs_function(irqmask);
else
panic("no enable_irqs_function\n");
}
 
void trap_virtual_disable_irqs(uint16_t irqmask)
{
if (disable_irqs_function)
disable_irqs_function(irqmask);
else
panic("no disable_irqs_function\n");
}
 
void trap_virtual_eoi(void)
{
if (eoi_function)
eoi_function();
else
panic("no eoi_function\n");
 
}
 
static void ipc_int(int n, istate_t *istate)
{
ipc_irq_send_notif(n-IVT_IRQBASE);
trap_virtual_eoi();
}
 
 
/* Reregister irq to be IPC-ready */
void irq_ipc_bind_arch(unative_t irq)
{
if (irq == IRQ_CLK)
return;
exc_register(IVT_IRQBASE+irq, "ipc_int", ipc_int);
trap_virtual_enable_irqs(1 << irq);
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/src/drivers/vesa.c
0,0 → 1,76
/*
* Copyright (C) 2006 Jakub Vana
* 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 ia32
* @{
*/
/**
* @file
* @brief VESA frame buffer driver.
*/
 
#ifdef CONFIG_FB
 
#include <genarch/fb/fb.h>
#include <arch/drivers/vesa.h>
#include <putchar.h>
#include <mm/page.h>
#include <mm/frame.h>
#include <mm/as.h>
#include <arch/mm/page.h>
#include <synch/spinlock.h>
#include <arch/asm.h>
#include <arch/types.h>
#include <typedefs.h>
#include <memstr.h>
#include <bitops.h>
 
uint32_t vesa_ph_addr;
uint16_t vesa_width;
uint16_t vesa_height;
uint16_t vesa_bpp;
uint16_t vesa_scanline;
 
int vesa_present(void)
{
if (vesa_width != 0xffff)
return true;
if (vesa_height != 0xffff)
return true;
return false;
}
 
void vesa_init(void)
{
fb_init(vesa_ph_addr, vesa_width, vesa_height, vesa_bpp, vesa_scanline);
}
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ia32/src/drivers/i8259.c
0,0 → 1,134
/*
* 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 ia32
* @{
*/
/**
* @file
* @brief PIC driver.
*
* Programmable Interrupt Controller for UP systems based on i8259 chip.
*/
 
#include <arch/drivers/i8259.h>
#include <cpu.h>
#include <arch/types.h>
#include <arch/asm.h>
#include <arch.h>
#include <print.h>
#include <interrupt.h>
 
static void pic_spurious(int n, istate_t *istate);
 
void i8259_init(void)
{
/* ICW1: this is ICW1, ICW4 to follow */
outb(PIC_PIC0PORT1, PIC_ICW1 | PIC_NEEDICW4);
 
/* ICW2: IRQ 0 maps to INT IRQBASE */
outb(PIC_PIC0PORT2, IVT_IRQBASE);
 
/* ICW3: pic1 using IRQ IRQ_PIC1 */
outb(PIC_PIC0PORT2, 1 << IRQ_PIC1);
 
/* ICW4: i8086 mode */
outb(PIC_PIC0PORT2, 1);
 
/* ICW1: ICW1, ICW4 to follow */
outb(PIC_PIC1PORT1, PIC_ICW1 | PIC_NEEDICW4);
 
/* ICW2: IRQ 8 maps to INT (IVT_IRQBASE + 8) */
outb(PIC_PIC1PORT2, IVT_IRQBASE + 8);
 
/* ICW3: pic1 is known as IRQ_PIC1 */
outb(PIC_PIC1PORT2, IRQ_PIC1);
 
/* ICW4: i8086 mode */
outb(PIC_PIC1PORT2, 1);
 
/*
* Register interrupt handler for the PIC spurious interrupt.
*/
exc_register(VECTOR_PIC_SPUR, "pic_spurious", (iroutine) pic_spurious);
 
/*
* Set the enable/disable IRQs handlers.
* Set the End-of-Interrupt handler.
*/
enable_irqs_function = pic_enable_irqs;
disable_irqs_function = pic_disable_irqs;
eoi_function = pic_eoi;
 
pic_disable_irqs(0xffff); /* disable all irq's */
pic_enable_irqs(1<<IRQ_PIC1); /* but enable pic1 */
}
 
void pic_enable_irqs(uint16_t irqmask)
{
uint8_t x;
 
if (irqmask & 0xff) {
x = inb(PIC_PIC0PORT2);
outb(PIC_PIC0PORT2, x & (~(irqmask & 0xff)));
}
if (irqmask >> 8) {
x = inb(PIC_PIC1PORT2);
outb(PIC_PIC1PORT2, x & (~(irqmask >> 8)));
}
}
 
void pic_disable_irqs(uint16_t irqmask)
{
uint8_t x;
 
if (irqmask & 0xff) {
x = inb(PIC_PIC0PORT2);
outb(PIC_PIC0PORT2, x | (irqmask & 0xff));
}
if (irqmask >> 8) {
x = inb(PIC_PIC1PORT2);
outb(PIC_PIC1PORT2, x | (irqmask >> 8));
}
}
 
void pic_eoi(void)
{
outb(0x20,0x20);
outb(0xa0,0x20);
}
 
void pic_spurious(int n, istate_t *istate)
{
#ifdef CONFIG_DEBUG
printf("cpu%d: PIC spurious interrupt\n", CPU->id);
#endif
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ia32/src/drivers/i8254.c
0,0 → 1,139
/*
* 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 ia32
* @{
*/
/**
* @file
* @brief i8254 chip driver.
*
* Low level time functions.
*/
 
#include <arch/types.h>
#include <time/clock.h>
#include <time/delay.h>
#include <arch/interrupt.h>
#include <arch/drivers/i8259.h>
#include <arch/drivers/i8254.h>
#include <cpu.h>
#include <config.h>
#include <arch/pm.h>
#include <arch/asm.h>
#include <arch/cpuid.h>
#include <arch.h>
#include <time/delay.h>
#include <interrupt.h>
 
#define CLK_PORT1 0x40
#define CLK_PORT4 0x43
 
#define CLK_CONST 1193180
#define MAGIC_NUMBER 1194
 
static void i8254_interrupt(int n, istate_t *istate);
 
void i8254_init(void)
{
i8254_normal_operation();
}
 
void i8254_normal_operation(void)
{
outb(CLK_PORT4, 0x36);
pic_disable_irqs(1<<IRQ_CLK);
outb(CLK_PORT1, (CLK_CONST/HZ) & 0xf);
outb(CLK_PORT1, (CLK_CONST/HZ) >> 8);
pic_enable_irqs(1<<IRQ_CLK);
exc_register(VECTOR_CLK, "i8254_clock", (iroutine) i8254_interrupt);
}
 
#define LOOPS 150000
#define SHIFT 11
void i8254_calibrate_delay_loop(void)
{
uint64_t clk1, clk2;
uint32_t t1, t2, o1, o2;
uint8_t not_ok;
 
 
/*
* One-shot timer. Count-down from 0xffff at 1193180Hz
* MAGIC_NUMBER is the magic value for 1ms.
*/
outb(CLK_PORT4, 0x30);
outb(CLK_PORT1, 0xff);
outb(CLK_PORT1, 0xff);
 
do {
/* will read both status and count */
outb(CLK_PORT4, 0xc2);
not_ok = (inb(CLK_PORT1)>>6)&1;
t1 = inb(CLK_PORT1);
t1 |= inb(CLK_PORT1) << 8;
} while (not_ok);
 
asm_delay_loop(LOOPS);
 
outb(CLK_PORT4, 0xd2);
t2 = inb(CLK_PORT1);
t2 |= inb(CLK_PORT1) << 8;
 
/*
* We want to determine the overhead of the calibrating mechanism.
*/
outb(CLK_PORT4, 0xd2);
o1 = inb(CLK_PORT1);
o1 |= inb(CLK_PORT1) << 8;
 
asm_fake_loop(LOOPS);
 
outb(CLK_PORT4, 0xd2);
o2 = inb(CLK_PORT1);
o2 |= inb(CLK_PORT1) << 8;
 
CPU->delay_loop_const = ((MAGIC_NUMBER*LOOPS)/1000) / ((t1-t2)-(o1-o2)) + (((MAGIC_NUMBER*LOOPS)/1000) % ((t1-t2)-(o1-o2)) ? 1 : 0);
 
clk1 = rdtsc();
delay(1<<SHIFT);
clk2 = rdtsc();
CPU->frequency_mhz = (clk2-clk1)>>SHIFT;
 
return;
}
 
void i8254_interrupt(int n, istate_t *istate)
{
trap_virtual_eoi();
clock();
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ia32/src/drivers/ega.c
0,0 → 1,150
/*
* 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 ia32
* @{
*/
/**
* @file
* @brief EGA driver.
*/
 
#include <arch/drivers/ega.h>
#include <putchar.h>
#include <mm/page.h>
#include <mm/as.h>
#include <arch/mm/page.h>
#include <synch/spinlock.h>
#include <arch/types.h>
#include <arch/asm.h>
#include <memstr.h>
#include <console/chardev.h>
#include <console/console.h>
#include <sysinfo/sysinfo.h>
 
/*
* The EGA driver.
* Simple and short. Function for displaying characters and "scrolling".
*/
 
SPINLOCK_INITIALIZE(egalock);
static uint32_t ega_cursor;
static uint8_t *videoram;
 
static void ega_putchar(chardev_t *d, const char ch);
 
chardev_t ega_console;
static chardev_operations_t ega_ops = {
.write = ega_putchar
};
 
void ega_move_cursor(void);
 
void ega_init(void)
{
uint8_t hi, lo;
videoram = (uint8_t *) hw_map(VIDEORAM, SCREEN * 2);
outb(0x3d4, 0xe);
hi = inb(0x3d5);
outb(0x3d4, 0xf);
lo = inb(0x3d5);
ega_cursor = (hi << 8) | lo;
 
chardev_initialize("ega_out", &ega_console, &ega_ops);
stdout = &ega_console;
sysinfo_set_item_val("fb", NULL, true);
sysinfo_set_item_val("fb.kind", NULL, 2);
sysinfo_set_item_val("fb.width", NULL, ROW);
sysinfo_set_item_val("fb.height", NULL, ROWS);
sysinfo_set_item_val("fb.address.physical", NULL, VIDEORAM);
#ifndef CONFIG_FB
putchar('\n');
#endif
}
 
static void ega_display_char(char ch)
{
videoram[ega_cursor * 2] = ch;
}
 
/*
* This function takes care of scrolling.
*/
static void ega_check_cursor(void)
{
if (ega_cursor < SCREEN)
return;
 
memcpy((void *) videoram, (void *) (videoram + ROW * 2), (SCREEN - ROW) * 2);
memsetw((uintptr_t) (videoram + (SCREEN - ROW) * 2), ROW, 0x0720);
ega_cursor = ega_cursor - ROW;
}
 
void ega_putchar(chardev_t *d, const char ch)
{
ipl_t ipl;
 
ipl = interrupts_disable();
spinlock_lock(&egalock);
 
switch (ch) {
case '\n':
ega_cursor = (ega_cursor + ROW) - ega_cursor % ROW;
break;
case '\t':
ega_cursor = (ega_cursor + 8) - ega_cursor % 8;
break;
case '\b':
if (ega_cursor % ROW)
ega_cursor--;
break;
default:
ega_display_char(ch);
ega_cursor++;
break;
}
ega_check_cursor();
ega_move_cursor();
 
spinlock_unlock(&egalock);
interrupts_restore(ipl);
}
 
void ega_move_cursor(void)
{
outb(0x3d4, 0xe);
outb(0x3d5, (ega_cursor >> 8) & 0xff);
outb(0x3d4, 0xf);
outb(0x3d5, ega_cursor & 0xff);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ia32/src/userspace.c
0,0 → 1,88
/*
* 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 ia32
* @{
*/
/** @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)
{
ipl_t ipl;
 
ipl = interrupts_disable();
 
__asm__ volatile (
/*
* Clear nested task flag.
*/
"pushfl\n"
"pop %%eax\n"
"and $0xffffbfff, %%eax\n"
"push %%eax\n"
"popfl\n"
 
/* Set up GS register (TLS) */
"movl %6, %%gs\n"
 
"pushl %0\n"
"pushl %1\n"
"pushl %2\n"
"pushl %3\n"
"pushl %4\n"
"movl %5, %%eax\n"
"iret\n"
:
: "i" (selector(UDATA_DES) | PL_USER), "r" (kernel_uarg->uspace_stack+THREAD_STACK_SIZE),
"r" (ipl), "i" (selector(UTEXT_DES) | PL_USER), "r" (kernel_uarg->uspace_entry),
"r" (kernel_uarg->uspace_uarg),
"r" (selector(TLS_DES))
: "eax");
/* Unreachable */
for(;;)
;
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia32/src/asm.S
0,0 → 1,276
#
# 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 paging_on
.global enable_l_apic_in_msr
.global interrupt_handlers
.global memcpy
.global memcpy_from_uspace
.global memcpy_from_uspace_failover_address
.global memcpy_to_uspace
.global memcpy_to_uspace_failover_address
 
 
#define MEMCPY_DST 4
#define MEMCPY_SRC 8
#define MEMCPY_SIZE 12
 
/** Copy memory to/from userspace.
*
* This is almost conventional memcpy().
* The difference is that there is a failover part
* to where control is returned from a page fault
* if the page fault occurs during copy_from_uspace()
* or copy_to_uspace().
*
* @param MEMCPY_DST(%esp) Destination address.
* @param MEMCPY_SRC(%esp) Source address.
* @param MEMCPY_SIZE(%esp) Size.
*
* @return MEMCPY_SRC(%esp) on success and 0 on failure.
*/
memcpy:
memcpy_from_uspace:
memcpy_to_uspace:
movl %edi, %edx /* save %edi */
movl %esi, %eax /* save %esi */
movl MEMCPY_SIZE(%esp), %ecx
shrl $2, %ecx /* size / 4 */
movl MEMCPY_DST(%esp), %edi
movl MEMCPY_SRC(%esp), %esi
rep movsl /* copy as much as possible word by word */
 
movl MEMCPY_SIZE(%esp), %ecx
andl $3, %ecx /* size % 4 */
jz 0f
rep movsb /* copy the rest byte by byte */
 
0:
movl %edx, %edi
movl %eax, %esi
movl MEMCPY_SRC(%esp), %eax /* MEMCPY_SRC(%esp), success */
ret
/*
* We got here from as_page_fault() after the memory operations
* above had caused a page fault.
*/
memcpy_from_uspace_failover_address:
memcpy_to_uspace_failover_address:
movl %edx, %edi
movl %eax, %esi
xorl %eax, %eax /* return 0, failure */
ret
 
## Turn paging on
#
# Enable paging and write-back caching in CR0.
#
paging_on:
movl %cr0,%edx
orl $(1<<31),%edx # paging on
andl $~((1<<30)|(1<<29)),%edx # clear Cache Disable and not Write Though
movl %edx,%cr0
jmp 0f
0:
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
 
# Clear nested flag
# overwrites %ecx
.macro CLEAR_NT_FLAG
pushfl
pop %ecx
and $0xffffbfff,%ecx
push %ecx
popfl
.endm
 
## Declare interrupt handlers
#
# Declare interrupt handlers for n interrupt
# vectors starting at vector i.
#
# The handlers setup data segment registers
# and call exc_dispatch().
#
#define INTERRUPT_ALIGN 64
.macro handler i n
 
.ifeq \i-0x30 # Syscall handler
push %ds
push %es
push %fs
push %gs
 
# Push arguments on stack
push %edi
push %esi
push %edx
push %ecx
push %eax
# we must fill the data segment registers
movw $16,%ax
movw %ax,%ds
movw %ax,%es
sti
call syscall_handler # syscall_handler(ax,cx,dx,si,di)
cli
addl $20, %esp # clean-up of parameters
pop %gs
pop %fs
pop %es
pop %ds
CLEAR_NT_FLAG
iret
.else
/*
* This macro distinguishes between two versions of ia32 exceptions.
* One version has error word and the other does not have it.
* The latter version fakes the error word on the stack so that the
* handlers and istate_t can be the same for both types.
*/
.iflt \i-32
.if (1 << \i) & ERROR_WORD_INTERRUPT_LIST
/*
* With error word, do nothing
*/
.else
/*
* Version without error word,
*/
subl $4, %esp
.endif
.else
/*
* Version without error word,
*/
subl $4, %esp
.endif
push %ds
push %es
push %fs
push %gs
 
#ifdef CONFIG_DEBUG_ALLREGS
push %ebx
push %ebp
push %edi
push %esi
#else
sub $16, %esp
#endif
push %edx
push %ecx
push %eax
# we must fill the data segment registers
movw $16,%ax
movw %ax,%ds
movw %ax,%es
 
pushl %esp # *istate
pushl $(\i) # intnum
call exc_dispatch # excdispatch(intnum, *istate)
addl $8,%esp # Clear arguments from stack
 
CLEAR_NT_FLAG # Modifies %ecx
pop %eax
pop %ecx
pop %edx
#ifdef CONFIG_DEBUG_ALLREGS
pop %esi
pop %edi
pop %ebp
pop %ebx
#else
add $16, %esp
#endif
pop %gs
pop %fs
pop %es
pop %ds
 
addl $4,%esp # Skip error word, no matter whether real or fake.
iret
.endif
 
.align INTERRUPT_ALIGN
.if (\n-\i)-1
handler "(\i+1)",\n
.endif
.endm
 
# keep in sync with pm.h !!!
IDT_ITEMS=64
.align INTERRUPT_ALIGN
interrupt_handlers:
h_start:
handler 0 IDT_ITEMS
h_end:
 
.data
.global interrupt_handler_size
 
interrupt_handler_size: .long (h_end-h_start)/IDT_ITEMS
/tags/0.2.0.3/kernel/arch/ia32/src/debugger.c
0,0 → 1,0
link ../../amd64/src/debugger.c
Property changes:
Added: svn:special
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/arch/ia32/src/atomic.S
0,0 → 1,60
#
# 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.
#
 
.text
 
#ifdef CONFIG_SMP
 
.global spinlock_arch
 
#
# This is a bus-and-hyperthreading-friendly implementation of spinlock
#
spinlock_arch:
pushl %eax
pushl %ebx
movl 12(%esp),%ebx
 
0:
#ifdef CONFIG_HT
pause # Pentium 4's with HT love this instruction
#endif
movl (%ebx),%eax
testl %eax,%eax
jnz 0b # lightweight looping while it is locked
incl %eax
xchgl %eax,(%ebx) # now use the atomic operation
testl %eax,%eax
jnz 0b
 
popl %ebx
popl %eax
ret
#endif
/tags/0.2.0.3/kernel/arch/ia32/src/context.s
0,0 → 1,72
#
# 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.
#
 
.text
 
.global context_save_arch
.global context_restore_arch
 
 
## Save current CPU context
#
# Save CPU context to the context_t variable
# pointed by the 1st argument. Returns 1 in EAX.
#
context_save_arch:
movl 0(%esp),%eax # the caller's return %eip
movl 4(%esp),%edx # address of the kernel_context variable to save context to
 
movl %esp,0(%edx) # %esp -> ctx->sp
movl %eax,4(%edx) # %eip -> ctx->pc
movl %ebx,8(%edx) # %ebx -> ctx->ebx
movl %esi,12(%edx) # %esi -> ctx->esi
movl %edi,16(%edx) # %edi -> ctx->edi
movl %ebp,20(%edx) # %ebp -> ctx->ebp
 
xorl %eax,%eax # context_save returns 1
incl %eax
ret
 
 
## Restore saved CPU context
#
# Restore CPU context from context_t variable
# pointed by the 1st argument. Returns 0 in EAX.
#
context_restore_arch:
movl 4(%esp),%eax # address of the kernel_context variable to restore context from
movl 0(%eax),%esp # ctx->sp -> %esp
movl 4(%eax),%edx # ctx->pc -> %edx
movl 8(%eax),%ebx # ctx->ebx -> %ebx
movl 12(%eax),%esi # ctx->esi -> %esi
movl 16(%eax),%edi # ctx->edi -> %edi
movl 20(%eax),%ebp # ctx->ebp -> %ebp
 
movl %edx,0(%esp) # ctx->pc -> saver's return %eip
xorl %eax,%eax # context_restore returns 0
ret
/tags/0.2.0.3/kernel/arch/ia32/src/delay.s
0,0 → 1,50
#
# 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.
#
 
#
# Micro second delay loop functions.
#
 
.text
 
.global asm_delay_loop
.global asm_fake_loop
 
asm_delay_loop:
movl 4(%esp),%ecx # move argument to %ecx
0: lahf
dec %ecx
jnz 0b
ret
 
asm_fake_loop:
movl 4(%esp),%ecx # move argument to %ecx
0: lahf
dec %ecx
jz 0b
ret
/tags/0.2.0.3/kernel/arch/ia32/src/debug/panic.s
0,0 → 1,34
#
# 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.
#
 
.text
.global panic_printf
 
panic_printf:
movl $halt,(%esp) # fake stack to make printf return to halt
jmp printf
/tags/0.2.0.3/kernel/arch/ia32/Makefile.inc
0,0 → 1,135
#
# Copyright (C) 2005 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 = binary
TARGET = i686-pc-linux-gnu
TOOLCHAIN_DIR = /usr/local/i686/bin
 
DEFS += -DMACHINE=$(MACHINE) -D__32_BITS__
 
## Accepted CPUs
#
 
ifeq ($(MACHINE),athlon-xp)
CFLAGS += -march=athlon-xp -mmmx -msse -m3dnow
DEFS += -DCONFIG_FENCES_P3
CONFIG_SMP = n
CONFIG_HT = n
endif
ifeq ($(MACHINE),athlon-mp)
CFLAGS += -march=athlon-mp -mmmx -msse -m3dnow
DEFS += -DCONFIG_FENCES_P3
CONFIG_HT = n
endif
ifeq ($(MACHINE),pentium3)
CFLAGS += -march=pentium3 -mmmx -msse
DEFS += -DCONFIG_FENCES_P3
CONFIG_HT = n
endif
ifeq ($(MACHINE),prescott)
CFLAGS += -march=pentium4 -mfpmath=sse -mmmx -msse -msse2 -msse3
DEFS += -DCONFIG_FENCES_P4
endif
ifeq ($(MACHINE),pentium4)
CFLAGS += -march=pentium4 -mfpmath=sse -mmmx -msse -msse2
DEFS += -DCONFIG_FENCES_P4
endif
 
## Own configuration directives
#
 
CONFIG_ACPI = y
 
## Compile with hierarchical page tables support.
#
 
CONFIG_PAGE_PT = y
DEFS += -DCONFIG_PAGE_PT
 
## Compile with i8042 controller support
#
 
CONFIG_I8042 = y
 
 
## Accepted configuration directives
#
 
ifeq ($(CONFIG_SMP),y)
DEFS += -DCONFIG_SMP
endif
ifeq ($(CONFIG_HT),y)
DEFS += -DCONFIG_HT
endif
ifeq ($(CONFIG_SIMICS_FIX),y)
DEFS += -DCONFIG_SIMICS_FIX
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/ap.S \
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/ia32.c \
arch/$(ARCH)/src/interrupt.c \
arch/$(ARCH)/src/pm.c \
arch/$(ARCH)/src/userspace.c \
arch/$(ARCH)/src/cpu/cpu.c \
arch/$(ARCH)/src/mm/as.c \
arch/$(ARCH)/src/mm/frame.c \
arch/$(ARCH)/src/mm/memory_init.c \
arch/$(ARCH)/src/mm/page.c \
arch/$(ARCH)/src/mm/tlb.c \
arch/$(ARCH)/src/ddi/ddi.c \
arch/$(ARCH)/src/drivers/i8254.c \
arch/$(ARCH)/src/drivers/i8259.c \
arch/$(ARCH)/src/drivers/ega.c \
arch/$(ARCH)/src/drivers/vesa.c \
arch/$(ARCH)/src/boot/boot.S \
arch/$(ARCH)/src/fpu_context.c \
arch/$(ARCH)/src/debugger.c
/tags/0.2.0.3/kernel/arch/ia32/_link.ld.in
0,0 → 1,65
/** IA-32 linker script
*
* umapped section:
* kernel text
* kernel data
* mapped section:
* kernel text
* kernel data
*/
 
#define __ASM__
#include <arch/boot/boot.h>
#include <arch/mm/page.h>
 
SECTIONS {
.unmapped BOOT_OFFSET: AT (0) {
unmapped_ktext_start = .;
*(K_TEXT_START);
unmapped_ktext_end = .;
unmapped_kdata_start = .;
*(K_DATA_START);
unmapped_kdata_end = .;
}
.mapped (PA2KA(BOOT_OFFSET)+SIZEOF(.unmapped)): AT (SIZEOF(.unmapped)) {
ktext_start = .;
*(.text);
ktext_end = .;
kdata_start = .;
*(.data); /* initialized data */
*(.rodata*); /* string literals */
*(COMMON); /* global variables */
hardcoded_load_address = .;
LONG(PA2KA(BOOT_OFFSET));
hardcoded_ktext_size = .;
LONG((ktext_end - ktext_start) + (unmapped_ktext_end - unmapped_ktext_start));
hardcoded_kdata_size = .;
LONG((kdata_end - kdata_start) + (unmapped_kdata_end - unmapped_kdata_start));
hardcoded_unmapped_ktext_size = .;
LONG(unmapped_ktext_end - unmapped_ktext_start);
hardcoded_unmapped_kdata_size = .;
LONG(unmapped_kdata_end - unmapped_kdata_start);
symbol_table = .;
*(symtab.*); /* Symbol table, must be LAST symbol! */
*(.bss); /* uninitialized static variables */
kdata_end = .;
}
 
/DISCARD/ : {
*(.note.GNU-stack);
*(.comment);
}
#ifdef CONFIG_SMP
_hardcoded_unmapped_size = (unmapped_ktext_end - unmapped_ktext_start) + (unmapped_kdata_end - unmapped_kdata_start);
ap_boot = unmapped_ap_boot - BOOT_OFFSET + AP_BOOT_OFFSET;
ap_gdtr = unmapped_ap_gdtr - BOOT_OFFSET + AP_BOOT_OFFSET;
protected_ap_gdtr = PA2KA(ap_gdtr);
 
#endif /* CONFIG_SMP */
 
}
/tags/0.2.0.3/kernel/arch/mips32/src/mips32.c
0,0 → 1,184
/*
* Copyright (C) 2003-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 mips32
* @{
*/
/** @file
*/
 
 
#include <arch.h>
#include <arch/boot.h>
#include <arch/cp0.h>
#include <arch/exception.h>
#include <arch/asm.h>
#include <mm/as.h>
 
#include <userspace.h>
#include <arch/console.h>
#include <memstr.h>
#include <proc/thread.h>
#include <proc/uarg.h>
#include <print.h>
#include <syscall/syscall.h>
#include <sysinfo/sysinfo.h>
 
#include <arch/interrupt.h>
#include <arch/drivers/arc.h>
#include <console/chardev.h>
#include <arch/debugger.h>
#include <genarch/fb/fb.h>
#include <macros.h>
 
#include <arch/asm/regname.h>
 
/* Size of the code jumping to the exception handler code
* - J+NOP
*/
#define EXCEPTION_JUMP_SIZE 8
 
#define TLB_EXC ((char *) 0x80000000)
#define NORM_EXC ((char *) 0x80000180)
#define CACHE_EXC ((char *) 0x80000100)
 
 
/* Why the linker moves the variable 64K away in assembler
* when not in .text section ????????
*/
uintptr_t supervisor_sp __attribute__ ((section (".text")));
/* Stack pointer saved when entering user mode */
/* TODO: How do we do it on SMP system???? */
bootinfo_t bootinfo __attribute__ ((section (".text")));
 
void arch_pre_main(void)
{
/* Setup usermode */
init.cnt = bootinfo.cnt;
uint32_t i;
for (i = 0; i < bootinfo.cnt; i++) {
init.tasks[i].addr = bootinfo.tasks[i].addr;
init.tasks[i].size = bootinfo.tasks[i].size;
}
}
 
void arch_pre_mm_init(void)
{
/* It is not assumed by default */
interrupts_disable();
/* Initialize dispatch table */
exception_init();
arc_init();
 
/* Copy the exception vectors to the right places */
memcpy(TLB_EXC, (char *)tlb_refill_entry, EXCEPTION_JUMP_SIZE);
memcpy(NORM_EXC, (char *)exception_entry, EXCEPTION_JUMP_SIZE);
memcpy(CACHE_EXC, (char *)cache_error_entry, EXCEPTION_JUMP_SIZE);
 
interrupt_init();
/*
* Switch to BEV normal level so that exception vectors point to the kernel.
* Clear the error level.
*/
cp0_status_write(cp0_status_read() & ~(cp0_status_bev_bootstrap_bit|cp0_status_erl_error_bit));
 
/*
* Mask all interrupts
*/
cp0_mask_all_int();
 
/*
* Unmask hardware clock interrupt.
*/
cp0_unmask_int(TIMER_IRQ);
 
console_init();
debugger_init();
}
 
void arch_post_mm_init(void)
{
#ifdef CONFIG_FB
fb_init(0x12000000, 640, 480, 24, 1920); // gxemul framebuffer
#endif
sysinfo_set_item_val("machine." STRING(MACHINE),NULL,1);
}
 
void arch_pre_smp_init(void)
{
}
 
void arch_post_smp_init(void)
{
}
 
void userspace(uspace_arg_t *kernel_uarg)
{
/* EXL=1, UM=1, IE=1 */
cp0_status_write(cp0_status_read() | (cp0_status_exl_exception_bit |
cp0_status_um_bit |
cp0_status_ie_enabled_bit));
cp0_epc_write((uintptr_t) kernel_uarg->uspace_entry);
userspace_asm(((uintptr_t) kernel_uarg->uspace_stack+PAGE_SIZE),
(uintptr_t) kernel_uarg->uspace_uarg,
(uintptr_t) kernel_uarg->uspace_entry);
while (1)
;
}
 
/** Perform mips32 specific tasks needed before the new task is run. */
void before_task_runs_arch(void)
{
}
 
/** Perform mips32 specific tasks needed before the new thread is scheduled. */
void before_thread_runs_arch(void)
{
supervisor_sp = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE-SP_DELTA];
}
 
void after_thread_ran_arch(void)
{
}
 
/** Set thread-local-storage pointer
*
* We have it currently in K1, it is
* possible to have it separately in the future.
*/
unative_t sys_tls_set(unative_t addr)
{
return 0;
}
 
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/mips32/src/exception.c
0,0 → 1,179
/*
* Copyright (C) 2003-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 mips32
* @{
*/
/** @file
*/
 
#include <arch/exception.h>
#include <arch/interrupt.h>
#include <panic.h>
#include <arch/cp0.h>
#include <arch/types.h>
#include <arch.h>
#include <debug.h>
#include <proc/thread.h>
#include <symtab.h>
#include <print.h>
#include <interrupt.h>
#include <func.h>
#include <console/kconsole.h>
#include <arch/debugger.h>
 
static char * exctable[] = {
"Interrupt",
"TLB Modified",
"TLB Invalid",
"TLB Invalid Store",
"Address Error - load/instr. fetch",
"Address Error - store",
"Bus Error - fetch instruction",
"Bus Error - data reference",
"Syscall",
"BreakPoint",
"Reserved Instruction",
"Coprocessor Unusable",
"Arithmetic Overflow",
"Trap",
"Virtual Coherency - instruction",
"Floating Point",
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"WatchHi/WatchLo", /* 23 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"Virtual Coherency - data",
};
 
static void print_regdump(istate_t *istate)
{
char *pcsymbol = "";
char *rasymbol = "";
 
char *s = get_symtab_entry(istate->epc);
if (s)
pcsymbol = s;
s = get_symtab_entry(istate->ra);
if (s)
rasymbol = s;
printf("PC: %#x(%s) RA: %#x(%s), SP(%p)\n", istate->epc, pcsymbol, istate->ra, rasymbol, istate->sp);
}
 
static void unhandled_exception(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "unhandled exception %s", exctable[n]);
print_regdump(istate);
panic("unhandled exception %s\n", exctable[n]);
}
 
static void reserved_instr_exception(int n, istate_t *istate)
{
if (*((uint32_t *)istate->epc) == 0x7c03e83b) {
ASSERT(THREAD);
istate->epc += 4;
istate->v1 = istate->k1;
} else
unhandled_exception(n, istate);
}
 
static void breakpoint_exception(int n, istate_t *istate)
{
#ifdef CONFIG_DEBUG
debugger_bpoint(istate);
#else
/* it is necessary to not re-execute BREAK instruction after
returning from Exception handler
(see page 138 in R4000 Manual for more information) */
istate->epc += 4;
#endif
}
 
static void tlbmod_exception(int n, istate_t *istate)
{
tlb_modified(istate);
}
 
static void tlbinv_exception(int n, istate_t *istate)
{
tlb_invalid(istate);
}
 
#ifdef CONFIG_FPU_LAZY
static void cpuns_exception(int n, istate_t *istate)
{
if (cp0_cause_coperr(cp0_cause_read()) == fpu_cop_id)
scheduler_fpu_lazy_request();
else {
fault_if_from_uspace(istate, "unhandled Coprocessor Unusable Exception");
panic("unhandled Coprocessor Unusable Exception\n");
}
}
#endif
 
static void interrupt_exception(int n, istate_t *istate)
{
uint32_t cause;
int i;
/* decode interrupt number and process the interrupt */
cause = (cp0_cause_read() >> 8) &0xff;
for (i = 0; i < 8; i++)
if (cause & (1 << i))
exc_dispatch(i+INT_OFFSET, istate);
}
 
/** Handle syscall userspace call */
static void syscall_exception(int n, istate_t *istate)
{
panic("Syscall is handled through shortcut");
}
 
void exception_init(void)
{
int i;
 
/* Clear exception table */
for (i=0;i < IVT_ITEMS; i++)
exc_register(i, "undef", (iroutine) unhandled_exception);
exc_register(EXC_Bp, "bkpoint", (iroutine) breakpoint_exception);
exc_register(EXC_RI, "resinstr", (iroutine) reserved_instr_exception);
exc_register(EXC_Mod, "tlb_mod", (iroutine) tlbmod_exception);
exc_register(EXC_TLBL, "tlbinvl", (iroutine) tlbinv_exception);
exc_register(EXC_TLBS, "tlbinvl", (iroutine) tlbinv_exception);
exc_register(EXC_Int, "interrupt", (iroutine) interrupt_exception);
#ifdef CONFIG_FPU_LAZY
exc_register(EXC_CpU, "cpunus", (iroutine) cpuns_exception);
#endif
exc_register(EXC_Sys, "syscall", (iroutine) syscall_exception);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/mips32/src/ddi/ddi.c
0,0 → 1,60
/*
* 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 mips32ddi
* @{
*/
/** @file
*/
 
#include <ddi/ddi.h>
#include <proc/task.h>
#include <arch/types.h>
#include <typedefs.h>
#include <security/cap.h>
#include <arch.h>
#include <arch/cp0.h>
 
/** Enable I/O space range for task.
*
* Interrupts are disabled and task is locked.
*
* @param task Task.
* @param ioaddr Startign I/O space address.
* @param size Size of the enabled I/O range.
*
* @return 0 on success or an error code from errno.h.
*/
int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
{
return 0;
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/mips32/src/debugger.c
0,0 → 1,388
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 mips32debug
* @{
*/
/** @file
*/
 
#include <arch/debugger.h>
#include <memstr.h>
#include <console/kconsole.h>
#include <console/cmd.h>
#include <symtab.h>
#include <print.h>
#include <panic.h>
#include <arch.h>
#include <arch/cp0.h>
#include <func.h>
 
bpinfo_t breakpoints[BKPOINTS_MAX];
SPINLOCK_INITIALIZE(bkpoint_lock);
 
static int cmd_print_breakpoints(cmd_arg_t *argv);
static cmd_info_t bkpts_info = {
.name = "bkpts",
.description = "Print breakpoint table.",
.func = cmd_print_breakpoints,
.argc = 0,
};
 
static int cmd_del_breakpoint(cmd_arg_t *argv);
static cmd_arg_t del_argv = {
.type = ARG_TYPE_INT
};
static cmd_info_t delbkpt_info = {
.name = "delbkpt",
.description = "delbkpt <number> - Delete breakpoint.",
.func = cmd_del_breakpoint,
.argc = 1,
.argv = &del_argv
};
 
static int cmd_add_breakpoint(cmd_arg_t *argv);
static cmd_arg_t add_argv = {
.type = ARG_TYPE_INT
};
static cmd_info_t addbkpt_info = {
.name = "addbkpt",
.description = "addbkpt <&symbol> - new bkpoint. Break on J/Branch insts unsupported.",
.func = cmd_add_breakpoint,
.argc = 1,
.argv = &add_argv
};
 
static cmd_arg_t adde_argv[] = {
{ .type = ARG_TYPE_INT },
{ .type = ARG_TYPE_INT }
};
static cmd_info_t addbkpte_info = {
.name = "addbkpte",
.description = "addebkpte <&symbol> <&func> - new bkpoint. Call func(or Nothing if 0).",
.func = cmd_add_breakpoint,
.argc = 2,
.argv = adde_argv
};
 
static struct {
uint32_t andmask;
uint32_t value;
}jmpinstr[] = {
{0xf3ff0000, 0x41000000}, /* BCzF */
{0xf3ff0000, 0x41020000}, /* BCzFL */
{0xf3ff0000, 0x41010000}, /* BCzT */
{0xf3ff0000, 0x41030000}, /* BCzTL */
{0xfc000000, 0x10000000}, /* BEQ */
{0xfc000000, 0x50000000}, /* BEQL */
{0xfc1f0000, 0x04010000}, /* BEQL */
{0xfc1f0000, 0x04110000}, /* BGEZAL */
{0xfc1f0000, 0x04130000}, /* BGEZALL */
{0xfc1f0000, 0x04030000}, /* BGEZL */
{0xfc1f0000, 0x1c000000}, /* BGTZ */
{0xfc1f0000, 0x5c000000}, /* BGTZL */
{0xfc1f0000, 0x18000000}, /* BLEZ */
{0xfc1f0000, 0x58000000}, /* BLEZL */
{0xfc1f0000, 0x04000000}, /* BLTZ */
{0xfc1f0000, 0x04100000}, /* BLTZAL */
{0xfc1f0000, 0x04120000}, /* BLTZALL */
{0xfc1f0000, 0x04020000}, /* BLTZL */
{0xfc000000, 0x14000000}, /* BNE */
{0xfc000000, 0x54000000}, /* BNEL */
{0xfc000000, 0x08000000}, /* J */
{0xfc000000, 0x0c000000}, /* JAL */
{0xfc1f07ff, 0x00000009}, /* JALR */
{0,0} /* EndOfTable */
};
 
/** Test, if the given instruction is a jump or branch instruction
*
* @param instr Instruction code
* @return true - it is jump instruction, false otherwise
*/
static bool is_jump(unative_t instr)
{
int i;
 
for (i=0;jmpinstr[i].andmask;i++) {
if ((instr & jmpinstr[i].andmask) == jmpinstr[i].value)
return true;
}
 
return false;
}
 
/** Add new breakpoint to table */
int cmd_add_breakpoint(cmd_arg_t *argv)
{
bpinfo_t *cur = NULL;
ipl_t ipl;
int i;
 
if (argv->intval & 0x3) {
printf("Not aligned instruction, forgot to use &symbol?\n");
return 1;
}
ipl = interrupts_disable();
spinlock_lock(&bkpoint_lock);
 
/* Check, that the breakpoints do not conflict */
for (i=0; i<BKPOINTS_MAX; i++) {
if (breakpoints[i].address == (uintptr_t)argv->intval) {
printf("Duplicate breakpoint %d.\n", i);
spinlock_unlock(&bkpoints_lock);
return 0;
} else if (breakpoints[i].address == (uintptr_t)argv->intval + sizeof(unative_t) || \
breakpoints[i].address == (uintptr_t)argv->intval - sizeof(unative_t)) {
printf("Adjacent breakpoints not supported, conflict with %d.\n", i);
spinlock_unlock(&bkpoints_lock);
return 0;
}
}
 
for (i=0; i<BKPOINTS_MAX; i++)
if (!breakpoints[i].address) {
cur = &breakpoints[i];
break;
}
if (!cur) {
printf("Too many breakpoints.\n");
spinlock_unlock(&bkpoint_lock);
interrupts_restore(ipl);
return 0;
}
cur->address = (uintptr_t) argv->intval;
printf("Adding breakpoint on address: %p\n", argv->intval);
cur->instruction = ((unative_t *)cur->address)[0];
cur->nextinstruction = ((unative_t *)cur->address)[1];
if (argv == &add_argv) {
cur->flags = 0;
} else { /* We are add extended */
cur->flags = BKPOINT_FUNCCALL;
cur->bkfunc = (void (*)(void *, istate_t *)) argv[1].intval;
}
if (is_jump(cur->instruction))
cur->flags |= BKPOINT_ONESHOT;
cur->counter = 0;
 
/* Set breakpoint */
*((unative_t *)cur->address) = 0x0d;
 
spinlock_unlock(&bkpoint_lock);
interrupts_restore(ipl);
 
return 1;
}
 
 
 
/** Remove breakpoint from table */
int cmd_del_breakpoint(cmd_arg_t *argv)
{
bpinfo_t *cur;
ipl_t ipl;
 
if (argv->intval < 0 || argv->intval > BKPOINTS_MAX) {
printf("Invalid breakpoint number.\n");
return 0;
}
ipl = interrupts_disable();
spinlock_lock(&bkpoint_lock);
 
cur = &breakpoints[argv->intval];
if (!cur->address) {
printf("Breakpoint does not exist.\n");
spinlock_unlock(&bkpoint_lock);
interrupts_restore(ipl);
return 0;
}
if ((cur->flags & BKPOINT_INPROG) && (cur->flags & BKPOINT_ONESHOT)) {
printf("Cannot remove one-shot breakpoint in-progress\n");
spinlock_unlock(&bkpoint_lock);
interrupts_restore(ipl);
return 0;
}
((uint32_t *)cur->address)[0] = cur->instruction;
((uint32_t *)cur->address)[1] = cur->nextinstruction;
 
cur->address = NULL;
 
spinlock_unlock(&bkpoint_lock);
interrupts_restore(ipl);
return 1;
}
 
/** Print table of active breakpoints */
int cmd_print_breakpoints(cmd_arg_t *argv)
{
int i;
char *symbol;
 
printf("Breakpoint table.\n");
for (i=0; i < BKPOINTS_MAX; i++)
if (breakpoints[i].address) {
symbol = get_symtab_entry(breakpoints[i].address);
printf("%d. %p in %s\n",i,
breakpoints[i].address, symbol);
printf(" Count(%d) ", breakpoints[i].counter);
if (breakpoints[i].flags & BKPOINT_INPROG)
printf("INPROG ");
if (breakpoints[i].flags & BKPOINT_ONESHOT)
printf("ONESHOT ");
if (breakpoints[i].flags & BKPOINT_FUNCCALL)
printf("FUNCCALL ");
printf("\n");
}
return 1;
}
 
/** Initialize debugger */
void debugger_init()
{
int i;
 
for (i=0; i<BKPOINTS_MAX; i++)
breakpoints[i].address = NULL;
cmd_initialize(&bkpts_info);
if (!cmd_register(&bkpts_info))
panic("could not register command %s\n", bkpts_info.name);
 
cmd_initialize(&delbkpt_info);
if (!cmd_register(&delbkpt_info))
panic("could not register command %s\n", delbkpt_info.name);
 
cmd_initialize(&addbkpt_info);
if (!cmd_register(&addbkpt_info))
panic("could not register command %s\n", addbkpt_info.name);
 
cmd_initialize(&addbkpte_info);
if (!cmd_register(&addbkpte_info))
panic("could not register command %s\n", addbkpte_info.name);
}
 
/** Handle breakpoint
*
* Find breakpoint in breakpoint table.
* If found, call kconsole, set break on next instruction and reexecute.
* If we are on "next instruction", set it back on the first and reexecute.
* If breakpoint not found in breakpoint table, call kconsole and start
* next instruction.
*/
void debugger_bpoint(istate_t *istate)
{
bpinfo_t *cur = NULL;
uintptr_t fireaddr = istate->epc;
int i;
 
/* test branch delay slot */
if (cp0_cause_read() & 0x80000000)
panic("Breakpoint in branch delay slot not supported.\n");
 
spinlock_lock(&bkpoint_lock);
for (i=0; i<BKPOINTS_MAX; i++) {
/* Normal breakpoint */
if (fireaddr == breakpoints[i].address \
&& !(breakpoints[i].flags & BKPOINT_REINST)) {
cur = &breakpoints[i];
break;
}
/* Reinst only breakpoint */
if ((breakpoints[i].flags & BKPOINT_REINST) \
&& (fireaddr ==breakpoints[i].address+sizeof(unative_t))) {
cur = &breakpoints[i];
break;
}
}
if (cur) {
if (cur->flags & BKPOINT_REINST) {
/* Set breakpoint on first instruction */
((uint32_t *)cur->address)[0] = 0x0d;
/* Return back the second */
((uint32_t *)cur->address)[1] = cur->nextinstruction;
cur->flags &= ~BKPOINT_REINST;
spinlock_unlock(&bkpoint_lock);
return;
}
if (cur->flags & BKPOINT_INPROG)
printf("Warning: breakpoint recursion\n");
if (!(cur->flags & BKPOINT_FUNCCALL))
printf("***Breakpoint %d: %p in %s.\n", i,
fireaddr, get_symtab_entry(istate->epc));
 
/* Return first instruction back */
((uint32_t *)cur->address)[0] = cur->instruction;
 
if (! (cur->flags & BKPOINT_ONESHOT)) {
/* Set Breakpoint on next instruction */
((uint32_t *)cur->address)[1] = 0x0d;
cur->flags |= BKPOINT_REINST;
}
cur->flags |= BKPOINT_INPROG;
} else {
printf("***Breakpoint %p in %s.\n", fireaddr,
get_symtab_entry(fireaddr));
/* Move on to next instruction */
istate->epc += 4;
}
if (cur)
cur->counter++;
if (cur && (cur->flags & BKPOINT_FUNCCALL)) {
/* Allow zero bkfunc, just for counting */
if (cur->bkfunc)
cur->bkfunc(cur, istate);
} else {
printf("***Type 'exit' to exit kconsole.\n");
/* This disables all other processors - we are not SMP,
* actually this gets us to cpu_halt, if scheduler() is run
* - we generally do not want scheduler to be run from debug,
* so this is a good idea
*/
atomic_set(&haltstate,1);
spinlock_unlock(&bkpoint_lock);
 
kconsole("debug");
 
spinlock_lock(&bkpoint_lock);
atomic_set(&haltstate,0);
}
if (cur && cur->address == fireaddr && (cur->flags & BKPOINT_INPROG)) {
/* Remove one-shot breakpoint */
if ((cur->flags & BKPOINT_ONESHOT))
cur->address = NULL;
/* Remove in-progress flag */
cur->flags &= ~BKPOINT_INPROG;
}
spinlock_unlock(&bkpoint_lock);
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/mips32/src/mm/tlb.c
0,0 → 1,613
/*
* Copyright (C) 2003-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 mips32mm
* @{
*/
/** @file
*/
 
#include <arch/mm/tlb.h>
#include <mm/asid.h>
#include <mm/tlb.h>
#include <mm/page.h>
#include <mm/as.h>
#include <arch/cp0.h>
#include <panic.h>
#include <arch.h>
#include <symtab.h>
#include <synch/spinlock.h>
#include <print.h>
#include <debug.h>
#include <align.h>
#include <interrupt.h>
 
static void tlb_refill_fail(istate_t *istate);
static void tlb_invalid_fail(istate_t *istate);
static void tlb_modified_fail(istate_t *istate);
 
static pte_t *find_mapping_and_check(uintptr_t badvaddr, int access, istate_t *istate, int *pfrc);
 
static void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, uintptr_t pfn);
static void prepare_entry_hi(entry_hi_t *hi, asid_t asid, uintptr_t addr);
 
/** Initialize TLB
*
* Initialize TLB.
* Invalidate all entries and mark wired entries.
*/
void tlb_arch_init(void)
{
int i;
 
cp0_pagemask_write(TLB_PAGE_MASK_16K);
cp0_entry_hi_write(0);
cp0_entry_lo0_write(0);
cp0_entry_lo1_write(0);
 
/* Clear and initialize TLB. */
for (i = 0; i < TLB_ENTRY_COUNT; i++) {
cp0_index_write(i);
tlbwi();
}
 
/*
* The kernel is going to make use of some wired
* entries (e.g. mapping kernel stacks in kseg3).
*/
cp0_wired_write(TLB_WIRED);
}
 
/** Process TLB Refill Exception
*
* Process TLB Refill Exception.
*
* @param istate Interrupted register context.
*/
void tlb_refill(istate_t *istate)
{
entry_lo_t lo;
entry_hi_t hi;
asid_t asid;
uintptr_t badvaddr;
pte_t *pte;
int pfrc;
 
badvaddr = cp0_badvaddr_read();
 
spinlock_lock(&AS->lock);
asid = AS->asid;
spinlock_unlock(&AS->lock);
 
page_table_lock(AS, true);
 
pte = find_mapping_and_check(badvaddr, PF_ACCESS_READ, istate, &pfrc);
if (!pte) {
switch (pfrc) {
case AS_PF_FAULT:
goto fail;
break;
case AS_PF_DEFER:
/*
* The page fault came during copy_from_uspace()
* or copy_to_uspace().
*/
page_table_unlock(AS, true);
return;
default:
panic("unexpected pfrc (%d)\n", pfrc);
}
}
 
/*
* Record access to PTE.
*/
pte->a = 1;
 
prepare_entry_hi(&hi, asid, badvaddr);
prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn);
 
/*
* New entry is to be inserted into TLB
*/
cp0_entry_hi_write(hi.value);
if ((badvaddr/PAGE_SIZE) % 2 == 0) {
cp0_entry_lo0_write(lo.value);
cp0_entry_lo1_write(0);
}
else {
cp0_entry_lo0_write(0);
cp0_entry_lo1_write(lo.value);
}
cp0_pagemask_write(TLB_PAGE_MASK_16K);
tlbwr();
 
page_table_unlock(AS, true);
return;
fail:
page_table_unlock(AS, true);
tlb_refill_fail(istate);
}
 
/** Process TLB Invalid Exception
*
* Process TLB Invalid Exception.
*
* @param istate Interrupted register context.
*/
void tlb_invalid(istate_t *istate)
{
tlb_index_t index;
uintptr_t badvaddr;
entry_lo_t lo;
entry_hi_t hi;
pte_t *pte;
int pfrc;
 
badvaddr = cp0_badvaddr_read();
 
/*
* Locate the faulting entry in TLB.
*/
hi.value = cp0_entry_hi_read();
prepare_entry_hi(&hi, hi.asid, badvaddr);
cp0_entry_hi_write(hi.value);
tlbp();
index.value = cp0_index_read();
 
page_table_lock(AS, true);
/*
* Fail if the entry is not in TLB.
*/
if (index.p) {
printf("TLB entry not found.\n");
goto fail;
}
 
pte = find_mapping_and_check(badvaddr, PF_ACCESS_READ, istate, &pfrc);
if (!pte) {
switch (pfrc) {
case AS_PF_FAULT:
goto fail;
break;
case AS_PF_DEFER:
/*
* The page fault came during copy_from_uspace()
* or copy_to_uspace().
*/
page_table_unlock(AS, true);
return;
default:
panic("unexpected pfrc (%d)\n", pfrc);
}
}
 
/*
* Read the faulting TLB entry.
*/
tlbr();
 
/*
* Record access to PTE.
*/
pte->a = 1;
 
prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn);
 
/*
* The entry is to be updated in TLB.
*/
if ((badvaddr/PAGE_SIZE) % 2 == 0)
cp0_entry_lo0_write(lo.value);
else
cp0_entry_lo1_write(lo.value);
cp0_pagemask_write(TLB_PAGE_MASK_16K);
tlbwi();
 
page_table_unlock(AS, true);
return;
fail:
page_table_unlock(AS, true);
tlb_invalid_fail(istate);
}
 
/** Process TLB Modified Exception
*
* Process TLB Modified Exception.
*
* @param istate Interrupted register context.
*/
void tlb_modified(istate_t *istate)
{
tlb_index_t index;
uintptr_t badvaddr;
entry_lo_t lo;
entry_hi_t hi;
pte_t *pte;
int pfrc;
 
badvaddr = cp0_badvaddr_read();
 
/*
* Locate the faulting entry in TLB.
*/
hi.value = cp0_entry_hi_read();
prepare_entry_hi(&hi, hi.asid, badvaddr);
cp0_entry_hi_write(hi.value);
tlbp();
index.value = cp0_index_read();
 
page_table_lock(AS, true);
/*
* Fail if the entry is not in TLB.
*/
if (index.p) {
printf("TLB entry not found.\n");
goto fail;
}
 
pte = find_mapping_and_check(badvaddr, PF_ACCESS_WRITE, istate, &pfrc);
if (!pte) {
switch (pfrc) {
case AS_PF_FAULT:
goto fail;
break;
case AS_PF_DEFER:
/*
* The page fault came during copy_from_uspace()
* or copy_to_uspace().
*/
page_table_unlock(AS, true);
return;
default:
panic("unexpected pfrc (%d)\n", pfrc);
}
}
 
/*
* Fail if the page is not writable.
*/
if (!pte->w)
goto fail;
 
/*
* Read the faulting TLB entry.
*/
tlbr();
 
/*
* Record access and write to PTE.
*/
pte->a = 1;
pte->d = 1;
 
prepare_entry_lo(&lo, pte->g, pte->p, pte->w, pte->cacheable, pte->pfn);
 
/*
* The entry is to be updated in TLB.
*/
if ((badvaddr/PAGE_SIZE) % 2 == 0)
cp0_entry_lo0_write(lo.value);
else
cp0_entry_lo1_write(lo.value);
cp0_pagemask_write(TLB_PAGE_MASK_16K);
tlbwi();
 
page_table_unlock(AS, true);
return;
fail:
page_table_unlock(AS, true);
tlb_modified_fail(istate);
}
 
void tlb_refill_fail(istate_t *istate)
{
char *symbol = "";
char *sym2 = "";
 
char *s = get_symtab_entry(istate->epc);
if (s)
symbol = s;
s = get_symtab_entry(istate->ra);
if (s)
sym2 = s;
 
fault_if_from_uspace(istate, "TLB Refill Exception on %p", cp0_badvaddr_read());
panic("%x: TLB Refill Exception at %x(%s<-%s)\n", cp0_badvaddr_read(), istate->epc, symbol, sym2);
}
 
 
void tlb_invalid_fail(istate_t *istate)
{
char *symbol = "";
 
char *s = get_symtab_entry(istate->epc);
if (s)
symbol = s;
fault_if_from_uspace(istate, "TLB Invalid Exception on %p", cp0_badvaddr_read());
panic("%x: TLB Invalid Exception at %x(%s)\n", cp0_badvaddr_read(), istate->epc, symbol);
}
 
void tlb_modified_fail(istate_t *istate)
{
char *symbol = "";
 
char *s = get_symtab_entry(istate->epc);
if (s)
symbol = s;
fault_if_from_uspace(istate, "TLB Modified Exception on %p", cp0_badvaddr_read());
panic("%x: TLB Modified Exception at %x(%s)\n", cp0_badvaddr_read(), istate->epc, symbol);
}
 
/** Try to find PTE for faulting address
*
* Try to find PTE for faulting address.
* The AS->lock must be held on entry to this function.
*
* @param badvaddr Faulting virtual address.
* @param access Access mode that caused the fault.
* @param istate Pointer to interrupted state.
* @param pfrc Pointer to variable where as_page_fault() return code will be stored.
*
* @return PTE on success, NULL otherwise.
*/
pte_t *find_mapping_and_check(uintptr_t badvaddr, int access, istate_t *istate, int *pfrc)
{
entry_hi_t hi;
pte_t *pte;
 
hi.value = cp0_entry_hi_read();
 
/*
* Handler cannot succeed if the ASIDs don't match.
*/
if (hi.asid != AS->asid) {
printf("EntryHi.asid=%d, AS->asid=%d\n", hi.asid, AS->asid);
return NULL;
}
 
/*
* Check if the mapping exists in page tables.
*/
pte = page_mapping_find(AS, badvaddr);
if (pte && pte->p) {
/*
* Mapping found in page tables.
* Immediately succeed.
*/
return pte;
} else {
int rc;
/*
* Mapping not found in page tables.
* Resort to higher-level page fault handler.
*/
page_table_unlock(AS, true);
switch (rc = as_page_fault(badvaddr, access, istate)) {
case AS_PF_OK:
/*
* The higher-level page fault handler succeeded,
* The mapping ought to be in place.
*/
page_table_lock(AS, true);
pte = page_mapping_find(AS, badvaddr);
ASSERT(pte && pte->p);
return pte;
break;
case AS_PF_DEFER:
page_table_lock(AS, true);
*pfrc = AS_PF_DEFER;
return NULL;
break;
case AS_PF_FAULT:
page_table_lock(AS, true);
printf("Page fault.\n");
*pfrc = AS_PF_FAULT;
return NULL;
break;
default:
panic("unexpected rc (%d)\n", rc);
}
}
}
 
void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, uintptr_t pfn)
{
lo->value = 0;
lo->g = g;
lo->v = v;
lo->d = d;
lo->c = cacheable ? PAGE_CACHEABLE_EXC_WRITE : PAGE_UNCACHED;
lo->pfn = pfn;
}
 
void prepare_entry_hi(entry_hi_t *hi, asid_t asid, uintptr_t addr)
{
hi->value = ALIGN_DOWN(addr, PAGE_SIZE * 2);
hi->asid = asid;
}
 
/** Print contents of TLB. */
void tlb_print(void)
{
page_mask_t mask;
entry_lo_t lo0, lo1;
entry_hi_t hi, hi_save;
int i;
 
hi_save.value = cp0_entry_hi_read();
 
printf("TLB:\n");
for (i = 0; i < TLB_ENTRY_COUNT; i++) {
cp0_index_write(i);
tlbr();
mask.value = cp0_pagemask_read();
hi.value = cp0_entry_hi_read();
lo0.value = cp0_entry_lo0_read();
lo1.value = cp0_entry_lo1_read();
printf("%d: asid=%d, vpn2=%d, mask=%d\tg[0]=%d, v[0]=%d, d[0]=%d, c[0]=%hhd, pfn[0]=%d\n"
"\t\t\t\tg[1]=%d, v[1]=%d, d[1]=%d, c[1]=%hhd, pfn[1]=%d\n",
i, hi.asid, hi.vpn2, mask.mask, lo0.g, lo0.v, lo0.d, lo0.c, lo0.pfn,
lo1.g, lo1.v, lo1.d, lo1.c, lo1.pfn);
}
cp0_entry_hi_write(hi_save.value);
}
 
/** Invalidate all not wired TLB entries. */
void tlb_invalidate_all(void)
{
ipl_t ipl;
entry_lo_t lo0, lo1;
entry_hi_t hi_save;
int i;
 
hi_save.value = cp0_entry_hi_read();
ipl = interrupts_disable();
 
for (i = TLB_WIRED; i < TLB_ENTRY_COUNT; i++) {
cp0_index_write(i);
tlbr();
 
lo0.value = cp0_entry_lo0_read();
lo1.value = cp0_entry_lo1_read();
 
lo0.v = 0;
lo1.v = 0;
 
cp0_entry_lo0_write(lo0.value);
cp0_entry_lo1_write(lo1.value);
tlbwi();
}
interrupts_restore(ipl);
cp0_entry_hi_write(hi_save.value);
}
 
/** Invalidate all TLB entries belonging to specified address space.
*
* @param asid Address space identifier.
*/
void tlb_invalidate_asid(asid_t asid)
{
ipl_t ipl;
entry_lo_t lo0, lo1;
entry_hi_t hi, hi_save;
int i;
 
ASSERT(asid != ASID_INVALID);
 
hi_save.value = cp0_entry_hi_read();
ipl = interrupts_disable();
for (i = 0; i < TLB_ENTRY_COUNT; i++) {
cp0_index_write(i);
tlbr();
hi.value = cp0_entry_hi_read();
if (hi.asid == asid) {
lo0.value = cp0_entry_lo0_read();
lo1.value = cp0_entry_lo1_read();
 
lo0.v = 0;
lo1.v = 0;
 
cp0_entry_lo0_write(lo0.value);
cp0_entry_lo1_write(lo1.value);
 
tlbwi();
}
}
interrupts_restore(ipl);
cp0_entry_hi_write(hi_save.value);
}
 
/** Invalidate TLB entries for specified page range belonging to specified address space.
*
* @param asid Address space identifier.
* @param page First page whose TLB entry is to be invalidated.
* @param cnt Number of entries to invalidate.
*/
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt)
{
int i;
ipl_t ipl;
entry_lo_t lo0, lo1;
entry_hi_t hi, hi_save;
tlb_index_t index;
 
ASSERT(asid != ASID_INVALID);
 
hi_save.value = cp0_entry_hi_read();
ipl = interrupts_disable();
 
for (i = 0; i < cnt+1; i+=2) {
hi.value = 0;
prepare_entry_hi(&hi, asid, page + i * PAGE_SIZE);
cp0_entry_hi_write(hi.value);
 
tlbp();
index.value = cp0_index_read();
 
if (!index.p) {
/* Entry was found, index register contains valid index. */
tlbr();
 
lo0.value = cp0_entry_lo0_read();
lo1.value = cp0_entry_lo1_read();
 
lo0.v = 0;
lo1.v = 0;
 
cp0_entry_lo0_write(lo0.value);
cp0_entry_lo1_write(lo1.value);
 
tlbwi();
}
}
interrupts_restore(ipl);
cp0_entry_hi_write(hi_save.value);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/mips32/src/mm/page.c
0,0 → 1,55
/*
* Copyright (C) 2003-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 mips32mm
* @{
*/
/** @file
*/
 
#include <arch/mm/page.h>
#include <genarch/mm/page_pt.h>
#include <mm/page.h>
 
void page_arch_init(void)
{
page_mapping_operations = &pt_mapping_operations;
}
 
/** Map device into kernel space
* - on mips, all devices are already mapped into kernel space,
* translate the physical address to uncached area
*/
uintptr_t hw_map(uintptr_t physaddr, size_t size)
{
return physaddr + 0xa0000000;
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/mips32/src/mm/frame.c
0,0 → 1,60
/*
* 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 mips32mm
* @{
*/
/** @file
*/
 
#include <arch/mm/frame.h>
#include <mm/frame.h>
#include <config.h>
#include <arch/drivers/arc.h>
 
/** Create memory zones
*
* If ARC is known, read information from ARC, otherwise
* assume some defaults.
* - blacklist first FRAME because there is an exception vector
*/
void frame_arch_init(void)
{
if (arc_enabled())
arc_frame_init();
else {
zone_create(0, ADDR2PFN(config.memory_size), 1, 0);
/*
* Blacklist interrupt vector
*/
frame_mark_unavailable(0, 1);
}
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/mips32/src/mm/as.c
0,0 → 1,78
/*
* 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 mips32mm
* @{
*/
/** @file
*/
 
#include <arch/mm/as.h>
#include <genarch/mm/as_pt.h>
#include <genarch/mm/asid_fifo.h>
#include <arch/mm/tlb.h>
#include <mm/tlb.h>
#include <mm/as.h>
#include <arch/cp0.h>
#include <arch.h>
 
/** Architecture dependent address space init. */
void as_arch_init(void)
{
as_operations = &as_pt_operations;
asid_fifo_init();
}
 
/** Install address space.
*
* Install ASID.
*
* @param as Address space structure.
*/
void as_install_arch(as_t *as)
{
entry_hi_t hi;
ipl_t ipl;
 
/*
* Install ASID.
*/
hi.value = cp0_entry_hi_read();
 
ipl = interrupts_disable();
spinlock_lock(&as->lock);
hi.asid = as->asid;
cp0_entry_hi_write(hi.value);
spinlock_unlock(&as->lock);
interrupts_restore(ipl);
}
 
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/mips32/src/interrupt.c
0,0 → 1,146
/*
* Copyright (C) 2003-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 mips32interrupt
* @{
*/
/** @file
*/
 
#include <interrupt.h>
#include <arch/interrupt.h>
#include <arch/types.h>
#include <arch.h>
#include <arch/cp0.h>
#include <time/clock.h>
#include <arch/drivers/arc.h>
 
#include <ipc/sysipc.h>
 
/** Disable interrupts.
*
* @return Old interrupt priority level.
*/
ipl_t interrupts_disable(void)
{
ipl_t ipl = (ipl_t) cp0_status_read();
cp0_status_write(ipl & ~cp0_status_ie_enabled_bit);
return ipl;
}
 
/** Enable interrupts.
*
* @return Old interrupt priority level.
*/
ipl_t interrupts_enable(void)
{
ipl_t ipl = (ipl_t) cp0_status_read();
cp0_status_write(ipl | cp0_status_ie_enabled_bit);
return ipl;
}
 
/** Restore interrupt priority level.
*
* @param ipl Saved interrupt priority level.
*/
void interrupts_restore(ipl_t ipl)
{
cp0_status_write(cp0_status_read() | (ipl & cp0_status_ie_enabled_bit));
}
 
/** Read interrupt priority level.
*
* @return Current interrupt priority level.
*/
ipl_t interrupts_read(void)
{
return cp0_status_read();
}
 
/* TODO: This is SMP unsafe!!! */
static unsigned long nextcount;
/** Start hardware clock */
static void timer_start(void)
{
nextcount = cp0_compare_value + cp0_count_read();
cp0_compare_write(nextcount);
}
 
static void timer_exception(int n, istate_t *istate)
{
unsigned long drift;
 
drift = cp0_count_read() - nextcount;
while (drift > cp0_compare_value) {
drift -= cp0_compare_value;
CPU->missed_clock_ticks++;
}
nextcount = cp0_count_read() + cp0_compare_value - drift;
cp0_compare_write(nextcount);
clock();
}
 
static void swint0(int n, istate_t *istate)
{
cp0_cause_write(cp0_cause_read() & ~(1 << 8)); /* clear SW0 interrupt */
ipc_irq_send_notif(0);
}
 
static void swint1(int n, istate_t *istate)
{
cp0_cause_write(cp0_cause_read() & ~(1 << 9)); /* clear SW1 interrupt */
ipc_irq_send_notif(1);
}
 
/* Initialize basic tables for exception dispatching */
void interrupt_init(void)
{
int_register(TIMER_IRQ, "timer", timer_exception);
int_register(0, "swint0", swint0);
int_register(1, "swint1", swint1);
timer_start();
}
 
static void ipc_int(int n, istate_t *istate)
{
ipc_irq_send_notif(n-INT_OFFSET);
}
 
/* Reregister irq to be IPC-ready */
void irq_ipc_bind_arch(unative_t irq)
{
/* Do not allow to redefine timer */
/* Swint0, Swint1 are already handled */
if (irq == TIMER_IRQ || irq < 2)
return;
int_register(irq, "ipc_int", ipc_int);
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/mips32/src/drivers/arc.c
0,0 → 1,413
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 mips32
* @{
*/
/** @file
*/
 
#include <arch/drivers/arc.h>
#include <arch/mm/page.h>
#include <print.h>
#include <arch.h>
#include <arch/byteorder.h>
#include <arch/mm/frame.h>
#include <mm/frame.h>
#include <interrupt.h>
#include <align.h>
#include <console/console.h>
#include <console/kconsole.h>
#include <console/cmd.h>
#include <mm/slab.h>
 
/* This is a good joke, SGI HAS different types than NT bioses... */
/* Here is the SGI type */
static char *basetypes[] = {
"ExceptionBlock",
"SystemParameterBlock",
"FreeContiguous",
"FreeMemory",
"BadMemory",
"LoadedProgram",
"FirmwareTemporary",
"FirmwarePermanent"
};
 
static char *ctypes[] = {
"ARC_type",
"CPU_type",
"FPU_type",
"PrimaryICache",
"PrimaryDCache",
"SecondaryICache",
"SecondaryDCache",
"SecondaryCache",
"Memory",
"EISAAdapter",
"TCAdapter",
"SCSIAdapter",
"DTIAdapter",
"MultiFunctionAdapter",
"DiskController",
"TapeController",
"CDROMController",
"WORMController",
"SerialController",
"NetworkController",
"DisplayController",
"ParallelController",
"PointerController",
"KeyboardController",
"AudioController",
"OtherController",
"DiskPeripheral",
"FloppyDiskPeripheral",
"TapePeripheral",
"ModemPeripheral",
"MonitorPeripheral",
"PrinterPeripheral",
"PointerPeripheral",
"KeyboardPeripheral",
"TerminalPeripheral",
"OtherPeripheral",
"LinePeripheral",
"NetworkPeripheral"
"OtherPeripheral",
"XTalkAdapter",
"PCIAdapter",
"GIOAdapter",
"TPUAdapter",
"Anonymous"
};
 
static arc_sbp *sbp = (arc_sbp *)PA2KA(0x1000);
static arc_func_vector_t *arc_entry;
 
 
static void arc_putchar(char ch);
 
/** Return true if ARC is available */
int arc_enabled(void)
{
return sbp != NULL;
}
 
 
/** Print configuration data that ARC reports about component */
static void arc_print_confdata(arc_component *c)
{
cm_resource_list *configdata;
int i;
 
if (!c->configdatasize)
return; /* No configuration data */
 
configdata = malloc(c->configdatasize, 0);
 
if (arc_entry->getconfigurationdata(configdata, c)) {
free(configdata);
return;
}
/* Does not seem to return meaningful data, don't use now */
free(configdata);
return;
for (i=0; i < configdata->count; i++) {
switch (configdata->descr[i].type) {
case CmResourceTypePort:
printf("Port: %p-size:%d ",
(uintptr_t)configdata->descr[i].u.port.start,
configdata->descr[i].u.port.length);
break;
case CmResourceTypeInterrupt:
printf("Irq: level(%d) vector(%d) ",
configdata->descr[i].u.interrupt.level,
configdata->descr[i].u.interrupt.vector);
break;
case CmResourceTypeMemory:
printf("Memory: %p-size:%d ",
(uintptr_t)configdata->descr[i].u.port.start,
configdata->descr[i].u.port.length);
break;
default:
break;
}
}
 
free(configdata);
}
 
/** Print information about component */
static void arc_print_component(arc_component *c)
{
int i;
 
printf("%s: ",ctypes[c->type]);
for (i=0;i < c->identifier_len;i++)
printf("%c",c->identifier[i]);
 
printf(" ");
arc_print_confdata(c);
printf("\n");
}
 
/**
* Read from ARC bios configuration data and print it
*/
static int cmd_arc_print_devices(cmd_arg_t *argv)
{
arc_component *c,*next;
 
c = arc_entry->getchild(NULL);
while (c) {
arc_print_component(c);
next = arc_entry->getchild(c);
while (!next) {
next = arc_entry->getpeer(c);
if (!next)
c = arc_entry->getparent(c);
if (!c)
return 0;
}
c = next;
}
return 1;
}
static cmd_info_t devlist_info = {
.name = "arcdevlist",
.description = "Print arc device list",
.func = cmd_arc_print_devices,
.argc = 0
};
 
 
/** Read from arc bios memory map and print it
*
*/
static int cmd_arc_print_memmap(cmd_arg_t *argv)
{
arc_memdescriptor_t *desc;
 
printf("Memory map:\n");
 
desc = arc_entry->getmemorydescriptor(NULL);
while (desc) {
printf("%s: %d(%p) (size: %dKB)\n",basetypes[desc->type],
desc->basepage * ARC_FRAME,
desc->basepage * ARC_FRAME,
desc->basecount*ARC_FRAME/1024);
desc = arc_entry->getmemorydescriptor(desc);
}
return 1;
}
static cmd_info_t memmap_info = {
.name = "arcmemmap",
.description = "Print arc memory map",
.func = cmd_arc_print_memmap,
.argc = 0
};
 
/** Print charactor to console */
static void arc_putchar(char ch)
{
uint32_t cnt;
ipl_t ipl;
 
/* TODO: Should be spinlock? */
ipl = interrupts_disable();
arc_entry->write(1, &ch, 1, &cnt);
interrupts_restore(ipl);
}
 
static int cmd_reboot(cmd_arg_t *argv)
{
arc_entry->reboot();
return 0;
}
static cmd_info_t reboot_info = {
.name = "reboot",
.description = "Reboot computer",
.func = cmd_reboot,
.argc = 0
};
 
/** Initialize ARC structure
*
* @return 0 - ARC OK, -1 - ARC does not exist
*/
int arc_init(void)
{
if (sbp->signature != ARC_MAGIC) {
sbp = NULL;
return -1;
}
arc_entry = sbp->firmwarevector;
 
arc_putchar('A');
arc_putchar('R');
arc_putchar('C');
arc_putchar('\n');
 
/* Add command for resetting the computer */
cmd_initialize(&reboot_info);
cmd_register(&reboot_info);
cmd_initialize(&memmap_info);
cmd_register(&memmap_info);
cmd_initialize(&devlist_info);
cmd_register(&devlist_info);
 
return 0;
}
 
static bool kbd_polling_enabled;
static chardev_t console;
 
/** Try to get character, return character or -1 if not available */
static void arc_keyboard_poll(void)
{
char ch;
uint32_t count;
long result;
if (! kbd_polling_enabled)
return;
 
if (arc_entry->getreadstatus(0))
return;
result = arc_entry->read(0, &ch, 1, &count);
if (result || count!=1) {
return;
}
if (ch == '\r')
ch = '\n';
if (ch == 0x7f)
ch = '\b';
chardev_push_character(&console, ch);
}
 
static char arc_read(chardev_t *dev)
{
char ch;
uint32_t count;
long result;
 
result = arc_entry->read(0, &ch, 1, &count);
if (result || count!=1) {
printf("Error reading from ARC keyboard.\n");
cpu_halt();
}
if (ch == '\r')
return '\n';
if (ch == 0x7f)
return '\b';
return ch;
}
 
static void arc_write(chardev_t *dev, const char ch)
{
arc_putchar(ch);
}
 
static void arc_enable(chardev_t *dev)
{
kbd_polling_enabled = true;
}
 
static void arc_disable(chardev_t *dev)
{
kbd_polling_enabled = false;
}
 
static chardev_operations_t arc_ops = {
.resume = arc_enable,
.suspend = arc_disable,
.write = arc_write,
.read = arc_read
};
 
iroutine old_timer;
/** Do polling on timer interrupt */
static void timer_replace(int n, istate_t *istate)
{
arc_keyboard_poll();
old_timer(n, istate);
arc_keyboard_poll();
}
 
void arc_console(void)
{
kbd_polling_enabled = true;
chardev_initialize("arc_console", &console, &arc_ops);
old_timer = int_register(TIMER_IRQ, "arc_kb_poll", timer_replace);
stdin = &console;
stdout = &console;
}
 
/* Initialize frame zones from ARC firmware.
* In the future we may use even the FirmwareTemporary regions,
* currently we use the FreeMemory (what about the LoadedProgram?)
*/
void arc_frame_init(void)
{
arc_memdescriptor_t *desc;
int total = 0;
uintptr_t base;
size_t basesize;
 
desc = arc_entry->getmemorydescriptor(NULL);
while (desc) {
if (desc->type == FreeMemory ||
desc->type == FreeContiguous) {
base = desc->basepage*ARC_FRAME;
basesize = desc->basecount*ARC_FRAME;
 
if (base % FRAME_SIZE ) {
basesize -= FRAME_SIZE - (base % FRAME_SIZE);
base = ALIGN_UP(base, FRAME_SIZE);
}
basesize = ALIGN_DOWN(basesize, FRAME_SIZE);
 
total += basesize;
zone_create(ADDR2PFN(base), SIZE2FRAMES(basesize),
ADDR2PFN(base), 0);
}
desc = arc_entry->getmemorydescriptor(desc);
}
 
config.memory_size = total;
}
 
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/mips32/src/drivers/msim.c
0,0 → 1,131
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 mips32
* @{
*/
/** @file
*/
 
#include <interrupt.h>
#include <console/chardev.h>
#include <arch/drivers/msim.h>
#include <arch/cp0.h>
#include <console/console.h>
 
static chardev_t console;
 
static void msim_write(chardev_t *dev, const char ch);
static void msim_enable(chardev_t *dev);
static void msim_disable(chardev_t *dev);
static char msim_do_read(chardev_t *dev);
 
static chardev_operations_t msim_ops = {
.resume = msim_enable,
.suspend = msim_disable,
.write = msim_write,
.read = msim_do_read,
};
 
/** Putchar that works with MSIM & gxemul */
void msim_write(chardev_t *dev, const char ch)
{
*((char *) MSIM_VIDEORAM) = ch;
}
 
/* Called from getc(). */
void msim_enable(chardev_t *dev)
{
cp0_unmask_int(MSIM_KBD_IRQ);
}
 
/* Called from getc(). */
void msim_disable(chardev_t *dev)
{
cp0_mask_int(MSIM_KBD_IRQ);
}
 
#include <print.h>
/** Read character using polling, assume interrupts disabled */
static char msim_do_read(chardev_t *dev)
{
char ch;
 
while (1) {
ch = *((volatile char *) MSIM_KBD_ADDRESS);
if (ch) {
if (ch == '\r')
return '\n';
if (ch == 0x7f)
return '\b';
return ch;
}
}
}
 
/** Process keyboard interrupt. */
static void msim_interrupt(int n, istate_t *istate)
{
char ch = 0;
 
ch = *((char *) MSIM_KBD_ADDRESS);
if (ch =='\r')
ch = '\n';
if (ch == 0x7f)
ch = '\b';
chardev_push_character(&console, ch);
}
 
 
/* Return console object representing msim console */
void msim_console(void)
{
chardev_initialize("msim_console", &console, &msim_ops);
 
int_register(MSIM_KBD_IRQ, "msim_kbd", msim_interrupt);
 
cp0_unmask_int(MSIM_KBD_IRQ);
 
stdin = &console;
stdout = &console;
}
 
static iroutine oldvector;
void msim_kbd_grab(void)
{
oldvector = int_register(MSIM_KBD_IRQ, "msim_kbd", msim_interrupt);
}
void msim_kbd_release(void)
{
if (oldvector)
int_register(MSIM_KBD_IRQ, "user_interrupt", oldvector);
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/mips32/src/drivers/serial.c
0,0 → 1,148
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 mips32
* @{
*/
/** @file
*/
 
#include <interrupt.h>
#include <arch/cp0.h>
#include <arch/drivers/serial.h>
#include <console/chardev.h>
#include <console/console.h>
 
static chardev_t console;
static serial_t sconf[SERIAL_MAX];
static bool kb_enabled;
 
static void serial_write(chardev_t *d, const char ch)
{
serial_t *sd = (serial_t *)d->data;
 
if (ch == '\n')
serial_write(d, '\r');
/* Wait until transmit buffer empty */
while (! (SERIAL_READ_LSR(sd->port) & (1<<TRANSMIT_EMPTY_BIT)))
;
SERIAL_WRITE(sd->port, ch);
}
 
static void serial_enable(chardev_t *d)
{
kb_enabled = true;
}
 
static void serial_disable(chardev_t *d)
{
kb_enabled = false;
}
 
int serial_init(void)
{
int i = 0;
if (SERIAL_READ_LSR(SERIAL_COM1) == 0x60) {
sconf[i].port = SERIAL_COM1;
sconf[i].irq = SERIAL_COM1_IRQ;
/* Enable interrupt on available data */
i++;
}
return i;
}
 
/** Read character from serial port, wait until available */
static char serial_do_read(chardev_t *dev)
{
serial_t *sd = (serial_t *)dev->data;
char ch;
 
while (!(SERIAL_READ_LSR(sd->port) & 1))
;
ch = SERIAL_READ(sd->port);
 
if (ch =='\r')
ch = '\n';
return ch;
}
 
 
/** Process keyboard interrupt. Does not work in simics? */
static void serial_interrupt(int n, void *stack)
{
serial_t *sd = (serial_t *)console.data;
char ch;
 
if (!(SERIAL_READ_LSR(sd->port) & 1))
return;
ch = SERIAL_READ(sd->port);
 
if (ch =='\r')
ch = '\n';
chardev_push_character(&console, ch);
}
 
 
 
static chardev_operations_t serial_ops = {
.resume = serial_enable,
.suspend = serial_disable,
.write = serial_write,
.read = serial_do_read
};
 
iroutine old_timer;
/** Do polling on timer interrupt */
static void timer_replace(int n, istate_t *istate)
{
old_timer(n, istate);
serial_interrupt(n, istate);
}
 
void serial_console(void)
{
serial_t *sd = &sconf[0];
 
 
chardev_initialize("serial_console", &console, &serial_ops);
console.data = sd;
kb_enabled = true;
 
// int_register(2, "serial_drvr", serial_interrupt);
/* I don't know why, but the serial interrupts simply
* don't work on simics
*/
old_timer = int_register(TIMER_IRQ, "serial_drvr_poll", timer_replace);
stdin = &console;
stdout = &console;
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/mips32/src/cache.c
0,0 → 1,47
/*
* Copyright (C) 2003-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 mips32
* @{
*/
/** @file
*/
 
#include <arch/cache.h>
#include <arch/exception.h>
#include <typedefs.h>
#include <panic.h>
 
void cache_error(istate_t *istate)
{
panic("cache_error exception (epc=%p)\n", istate->epc);
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/mips32/src/start.S
0,0 → 1,337
#
# Copyright (C) 2003-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.
#
 
#include <arch/asm/regname.h>
#include <arch/mm/page.h>
#include <arch/asm/boot.h>
#include <arch/context_offset.h>
.text
 
.set noat
.set noreorder
.set nomacro
 
.global kernel_image_start
.global tlb_refill_entry
.global cache_error_entry
.global exception_entry
.global userspace_asm
 
# Which status bits should are thread-local
#define REG_SAVE_MASK 0x1f # KSU(UM), EXL, ERL, IE
# Save registers to space defined by \r
# We will change status: Disable ERL,EXL,UM,IE
# These changes will be automatically reversed in REGISTER_LOAD
# SP is NOT saved as part of these registers
.macro REGISTERS_STORE_AND_EXC_RESET r
sw $at,EOFFSET_AT(\r)
sw $v0,EOFFSET_V0(\r)
sw $v1,EOFFSET_V1(\r)
sw $a0,EOFFSET_A0(\r)
sw $a1,EOFFSET_A1(\r)
sw $a2,EOFFSET_A2(\r)
sw $a3,EOFFSET_A3(\r)
sw $t0,EOFFSET_T0(\r)
sw $t1,EOFFSET_T1(\r)
sw $t2,EOFFSET_T2(\r)
sw $t3,EOFFSET_T3(\r)
sw $t4,EOFFSET_T4(\r)
sw $t5,EOFFSET_T5(\r)
sw $t6,EOFFSET_T6(\r)
sw $t7,EOFFSET_T7(\r)
sw $t8,EOFFSET_T8(\r)
sw $t9,EOFFSET_T9(\r)
 
mflo $at
sw $at, EOFFSET_LO(\r)
mfhi $at
sw $at, EOFFSET_HI(\r)
#ifdef CONFIG_DEBUG_ALLREGS
sw $s0,EOFFSET_S0(\r)
sw $s1,EOFFSET_S1(\r)
sw $s2,EOFFSET_S2(\r)
sw $s3,EOFFSET_S3(\r)
sw $s4,EOFFSET_S4(\r)
sw $s5,EOFFSET_S5(\r)
sw $s6,EOFFSET_S6(\r)
sw $s7,EOFFSET_S7(\r)
sw $s8,EOFFSET_S8(\r)
#endif
sw $gp,EOFFSET_GP(\r)
sw $ra,EOFFSET_RA(\r)
sw $k1,EOFFSET_K1(\r)
 
mfc0 $t0, $status
mfc0 $t1, $epc
and $t2, $t0, REG_SAVE_MASK # Save only KSU,EXL,ERL,IE
li $t3, ~(0x1f)
and $t0, $t0, $t3 # Clear KSU,EXL,ERL,IE
sw $t2,EOFFSET_STATUS(\r)
sw $t1,EOFFSET_EPC(\r)
mtc0 $t0, $status
.endm
 
.macro REGISTERS_LOAD r
# Update only UM,EXR,IE from status, the rest
# is controlled by OS and not bound to task
mfc0 $t0, $status
lw $t1,EOFFSET_STATUS(\r)
 
li $t2, ~REG_SAVE_MASK # Mask UM,EXL,ERL,IE
and $t0, $t0, $t2
or $t0, $t0, $t1 # Copy UM,EXL,ERL,IE from saved status
mtc0 $t0, $status
lw $v0,EOFFSET_V0(\r)
lw $v1,EOFFSET_V1(\r)
lw $a0,EOFFSET_A0(\r)
lw $a1,EOFFSET_A1(\r)
lw $a2,EOFFSET_A2(\r)
lw $a3,EOFFSET_A3(\r)
lw $t0,EOFFSET_T0(\r)
lw $t1,EOFFSET_T1(\r)
lw $t2,EOFFSET_T2(\r)
lw $t3,EOFFSET_T3(\r)
lw $t4,EOFFSET_T4(\r)
lw $t5,EOFFSET_T5(\r)
lw $t6,EOFFSET_T6(\r)
lw $t7,EOFFSET_T7(\r)
lw $t8,EOFFSET_T8(\r)
lw $t9,EOFFSET_T9(\r)
#ifdef CONFIG_DEBUG_ALLREGS
lw $s0,EOFFSET_S0(\r)
lw $s1,EOFFSET_S1(\r)
lw $s2,EOFFSET_S2(\r)
lw $s3,EOFFSET_S3(\r)
lw $s4,EOFFSET_S4(\r)
lw $s5,EOFFSET_S5(\r)
lw $s6,EOFFSET_S6(\r)
lw $s7,EOFFSET_S7(\r)
lw $s8,EOFFSET_S8(\r)
#endif
lw $gp,EOFFSET_GP(\r)
lw $ra,EOFFSET_RA(\r)
lw $k1,EOFFSET_K1(\r)
lw $at,EOFFSET_LO(\r)
mtlo $at
lw $at,EOFFSET_HI(\r)
mthi $at
 
lw $at,EOFFSET_EPC(\r)
mtc0 $at, $epc
lw $at,EOFFSET_AT(\r)
lw $sp,EOFFSET_SP(\r)
.endm
 
# Move kernel stack pointer address to register K0
# - if we are in user mode, load the appropriate stack
# address
.macro KERNEL_STACK_TO_K0
# If we are in user mode
mfc0 $k0, $status
andi $k0, 0x10
beq $k0, $0, 1f
add $k0, $sp, 0
# Move $k0 pointer to kernel stack
lui $k0, %hi(supervisor_sp)
ori $k0, $k0, %lo(supervisor_sp)
# Move $k0 (superveisor_sp)
lw $k0, 0($k0)
1:
.endm
.org 0x0
kernel_image_start:
/* Load temporary stack */
lui $sp, %hi(end_stack)
ori $sp, $sp, %lo(end_stack)
/* $a1 contains physical address of bootinfo_t */
/* $a2 contains size of bootinfo_t */
beq $a2, $0, bootinfo_end
/* Not sure about this, but might be needed for PIC code???? */
lui $gp, 0x8000
lui $a3, %hi(bootinfo)
ori $a3, $a3, %lo(bootinfo)
bootinfo_loop:
lw $v0, 0($a1)
sw $v0, 0($a3)
addi $a1, $a1, 4
addi $a3, $a3, 4
addi $a2, $a2, -4
bgtz $a2, bootinfo_loop
nop
bootinfo_end:
jal arch_pre_main
nop
j main_bsp
nop
 
.space TEMP_STACK_SIZE
end_stack:
 
tlb_refill_entry:
j tlb_refill_handler
nop
 
cache_error_entry:
j cache_error_handler
nop
 
exception_entry:
j exception_handler
nop
 
exception_handler:
KERNEL_STACK_TO_K0
sub $k0, REGISTER_SPACE
sw $sp,EOFFSET_SP($k0)
move $sp, $k0
mfc0 $k0, $cause
sra $k0, $k0, 0x2 # cp0_exc_cause() part 1
andi $k0, $k0, 0x1f # cp0_exc_cause() part 2
sub $k0, 8 # 8=SYSCALL
beqz $k0, syscall_shortcut
add $k0, 8 # Revert $k0 back to correct exc number
REGISTERS_STORE_AND_EXC_RESET $sp
move $a1, $sp
jal exc_dispatch # exc_dispatch(excno, register_space)
move $a0, $k0
 
REGISTERS_LOAD $sp
# The $sp is automatically restored to former value
eret
 
# it seems that mips reserves some space on stack for varfuncs???
#define SS_ARG4 16
#define SS_SP EOFFSET_SP
#define SS_STATUS EOFFSET_STATUS
#define SS_EPC EOFFSET_EPC
#define SS_K1 EOFFSET_K1
syscall_shortcut:
# We have a lot of space on the stack, with free use
mfc0 $t1, $epc
mfc0 $t0, $status
sw $t1,SS_EPC($sp) # Save EPC
sw $k1,SS_K1($sp) # Save k1, which is not saved during context switch
and $t2, $t0, REG_SAVE_MASK # Save only KSU,EXL,ERL,IE
li $t3, ~(0x1f)
and $t0, $t0, $t3 # Clear KSU,EXL,ERL
ori $t0, $t0, 0x1 # Set IE
 
sw $t2,SS_STATUS($sp)
mtc0 $t0, $status
 
# CALL Syscall handler
jal syscall_handler
sw $v0, SS_ARG4($sp) # save v0 - arg4 to stack
 
# restore status
mfc0 $t0, $status
lw $t1,SS_STATUS($sp)
 
# Change back to EXL=1(from last exception), otherwise
# an interrupt could rewrite the CP0-EPC
li $t2, ~REG_SAVE_MASK # Mask UM,EXL,ERL,IE
and $t0, $t0, $t2
or $t0, $t0, $t1 # Copy UM,EXL,ERL,IE from saved status
mtc0 $t0, $status
# restore epc+4
lw $t0,SS_EPC($sp)
lw $k1,SS_K1($sp)
addi $t0, $t0, 4
mtc0 $t0, $epc
lw $sp,SS_SP($sp) # restore sp
eret
tlb_refill_handler:
KERNEL_STACK_TO_K0
sub $k0, REGISTER_SPACE
REGISTERS_STORE_AND_EXC_RESET $k0
sw $sp,EOFFSET_SP($k0)
add $sp, $k0, 0
 
jal tlb_refill
add $a0, $sp, 0
 
REGISTERS_LOAD $sp
 
eret
 
cache_error_handler:
KERNEL_STACK_TO_K0
sub $k0, REGISTER_SPACE
REGISTERS_STORE_AND_EXC_RESET $k0
sw $sp,EOFFSET_SP($k0)
add $sp, $k0, 0
 
jal cache_error
add $a0, $sp, 0
 
REGISTERS_LOAD $sp
 
eret
 
userspace_asm:
add $sp, $a0, 0
add $v0, $a1, 0
add $t9, $a2, 0 # Set up correct entry into PIC code
eret
/tags/0.2.0.3/kernel/arch/mips32/src/cpu/cpu.c
0,0 → 1,138
/*
* Copyright (C) 2003-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 mips32
* @{
*/
/** @file
*/
 
#include <arch/cpu.h>
#include <cpu.h>
 
#include <arch.h>
 
#include <arch/cp0.h>
 
#include <typedefs.h>
#include <print.h>
 
struct data_t {
char *vendor;
char *model;
};
 
static struct data_t imp_data[] = {
{ "Invalid", "Invalid" }, /* 0x00 */
{ "MIPS", "R2000" }, /* 0x01 */
{ "MIPS", "R3000" }, /* 0x02 */
{ "MIPS", "R6000" }, /* 0x03 */
{ "MIPS", " R4000/R4400" }, /* 0x04 */
{ "LSI Logic", "R3000" }, /* 0x05 */
{ "MIPS", "R6000A" }, /* 0x06 */
{ "IDT", "3051/3052" }, /* 0x07 */
{ "Invalid", "Invalid" }, /* 0x08 */
{ "MIPS", "R10000/T5" }, /* 0x09 */
{ "MIPS", "R4200" }, /* 0x0a */
{ "Unknown", "Unknown" }, /* 0x0b */
{ "Unknown", "Unknown" }, /* 0x0c */
{ "Invalid", "Invalid" }, /* 0x0d */
{ "Invalid", "Invalid" }, /* 0x0e */
{ "Invalid", "Invalid" }, /* 0x0f */
{ "MIPS", "R8000" }, /* 0x10 */
{ "Invalid", "Invalid" }, /* 0x11 */
{ "Invalid", "Invalid" }, /* 0x12 */
{ "Invalid", "Invalid" }, /* 0x13 */
{ "Invalid", "Invalid" }, /* 0x14 */
{ "Invalid", "Invalid" }, /* 0x15 */
{ "Invalid", "Invalid" }, /* 0x16 */
{ "Invalid", "Invalid" }, /* 0x17 */
{ "Invalid", "Invalid" }, /* 0x18 */
{ "Invalid", "Invalid" }, /* 0x19 */
{ "Invalid", "Invalid" }, /* 0x1a */
{ "Invalid", "Invalid" }, /* 0x1b */
{ "Invalid", "Invalid" }, /* 0x1c */
{ "Invalid", "Invalid" }, /* 0x1d */
{ "Invalid", "Invalid" }, /* 0x1e */
{ "Invalid", "Invalid" }, /* 0x1f */
{ "QED", "R4600" }, /* 0x20 */
{ "Sony", "R3000" }, /* 0x21 */
{ "Toshiba", "R3000" }, /* 0x22 */
{ "NKK", "R3000" }, /* 0x23 */
{ NULL, NULL }
};
 
static struct data_t imp_data80[] = {
{ "MIPS", "4Kc" }, /* 0x80 */
{"Invalid","Invalid"}, /* 0x81 */
{"Invalid","Invalid"}, /* 0x82 */
{"MIPS","4Km & 4Kp"}, /* 0x83 */
{ NULL, NULL}
};
 
void cpu_arch_init(void)
{
}
 
void cpu_identify(void)
{
CPU->arch.rev_num = cp0_prid_read() & 0xff;
CPU->arch.imp_num = (cp0_prid_read() >> 8) & 0xff;
}
 
void cpu_print_report(cpu_t *m)
{
struct data_t *data;
int i;
 
if (m->arch.imp_num & 0x80) {
/* Count records */
for (i=0;imp_data80[i].vendor;i++)
;
if ((m->arch.imp_num & 0x7f) >= i) {
printf("imp=%d\n",m->arch.imp_num);
return;
}
data = &imp_data80[m->arch.imp_num & 0x7f];
} else {
for (i=0;imp_data[i].vendor;i++)
;
if (m->arch.imp_num >= i) {
printf("imp=%d\n",m->arch.imp_num);
return;
}
data = &imp_data[m->arch.imp_num];
}
 
printf("cpu%d: %s %s (rev=%d.%d, imp=%d)\n",
m->id, data->vendor, data->model, m->arch.rev_num >> 4,
m->arch.rev_num & 0xf, m->arch.imp_num);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/mips32/src/fpu_context.c
0,0 → 1,62
/*
* Copyright (C) 2005 Jakub Vana
* 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 mips32
* @{
*/
/** @file
*
*/
 
#include <fpu_context.h>
#include <arch.h>
#include <arch/cp0.h>
#include <proc/thread.h>
 
void fpu_disable(void)
{
#ifdef ARCH_HAS_FPU
cp0_status_write(cp0_status_read() & ~cp0_status_fpu_bit);
#endif
}
 
void fpu_enable(void)
{
#ifdef ARCH_HAS_FPU
cp0_status_write(cp0_status_read() | cp0_status_fpu_bit);
#endif
}
 
void fpu_init()
{
/* TODO: Zero all registers */
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/mips32/src/console.c
0,0 → 1,69
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 mips32
* @{
*/
/** @file
*/
 
#include <console/console.h>
#include <arch/console.h>
#include <arch/drivers/arc.h>
#include <arch/drivers/serial.h>
#include <arch/drivers/msim.h>
 
void console_init(void)
{
if (arc_enabled()) {
arc_console();
} else if (serial_init()) {
serial_console();
} else {
msim_console();
}
}
 
/** Acquire console back for kernel
*
*/
void arch_grab_console(void)
{
msim_kbd_grab();
}
/** Return console to userspace
*
*/
void arch_release_console(void)
{
msim_kbd_release();
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/mips32/src/asm.S
0,0 → 1,299
#
# Copyright (C) 2003-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.
#
 
#include <arch/asm/regname.h>
.text
 
.macro cp0_read reg
mfc0 $2,\reg
j $31
nop
.endm
 
.macro cp0_write reg
mtc0 $4,\reg
j $31
nop
.endm
 
.set noat
.set noreorder
.set nomacro
 
.global cpu_halt
cpu_halt:
j cpu_halt
nop
 
 
.global memsetb
memsetb:
j _memsetb
nop
 
 
.global memcpy
.global memcpy_from_uspace
.global memcpy_to_uspace
.global memcpy_from_uspace_failover_address
.global memcpy_to_uspace_failover_address
memcpy:
memcpy_from_uspace:
memcpy_to_uspace:
addiu $v0,$a1,3
li $v1,-4 # 0xfffffffffffffffc
and $v0,$v0,$v1
beq $a1,$v0,3f
move $t0,$a0
 
0:
beq $a2,$zero,2f
move $a3,$zero
 
1:
addu $v0,$a1,$a3
lbu $a0,0($v0)
addu $v1,$t0,$a3
addiu $a3,$a3,1
bne $a3,$a2,1b
sb $a0,0($v1)
 
2:
jr $ra
move $v0,$a1
 
3:
addiu $v0,$a0,3
and $v0,$v0,$v1
bne $a0,$v0,0b
srl $t1,$a2,2
 
beq $t1,$zero,5f
move $a3,$zero
 
move $a3,$zero
move $a0,$zero
4:
addu $v0,$a1,$a0
lw $v1,0($v0)
addiu $a3,$a3,1
addu $v0,$t0,$a0
sw $v1,0($v0)
bne $a3,$t1,4b
addiu $a0,$a0,4
 
5:
andi $a2,$a2,0x3
beq $a2,$zero,2b
nop
 
sll $v0,$a3,2
addu $t1,$v0,$t0
move $a3,$zero
addu $t0,$v0,$a1
6:
addu $v0,$t0,$a3
lbu $a0,0($v0)
addu $v1,$t1,$a3
addiu $a3,$a3,1
bne $a3,$a2,6b
sb $a0,0($v1)
 
jr $ra
move $v0,$a1
 
memcpy_from_uspace_failover_address:
memcpy_to_uspace_failover_address:
jr $ra
move $v0, $zero
 
 
 
.macro fpu_gp_save reg ctx
mfc1 $t0,$\reg
sw $t0, \reg*4(\ctx)
.endm
 
.macro fpu_gp_restore reg ctx
lw $t0, \reg*4(\ctx)
mtc1 $t0,$\reg
.endm
 
.macro fpu_ct_save reg ctx
cfc1 $t0,$1
sw $t0, (\reg+32)*4(\ctx)
.endm
 
.macro fpu_ct_restore reg ctx
lw $t0, (\reg+32)*4(\ctx)
ctc1 $t0,$\reg
.endm
 
 
.global fpu_context_save
fpu_context_save:
#ifdef ARCH_HAS_FPU
fpu_gp_save 0,$a0
fpu_gp_save 1,$a0
fpu_gp_save 2,$a0
fpu_gp_save 3,$a0
fpu_gp_save 4,$a0
fpu_gp_save 5,$a0
fpu_gp_save 6,$a0
fpu_gp_save 7,$a0
fpu_gp_save 8,$a0
fpu_gp_save 9,$a0
fpu_gp_save 10,$a0
fpu_gp_save 11,$a0
fpu_gp_save 12,$a0
fpu_gp_save 13,$a0
fpu_gp_save 14,$a0
fpu_gp_save 15,$a0
fpu_gp_save 16,$a0
fpu_gp_save 17,$a0
fpu_gp_save 18,$a0
fpu_gp_save 19,$a0
fpu_gp_save 20,$a0
fpu_gp_save 21,$a0
fpu_gp_save 22,$a0
fpu_gp_save 23,$a0
fpu_gp_save 24,$a0
fpu_gp_save 25,$a0
fpu_gp_save 26,$a0
fpu_gp_save 27,$a0
fpu_gp_save 28,$a0
fpu_gp_save 29,$a0
fpu_gp_save 30,$a0
fpu_gp_save 31,$a0
 
fpu_ct_save 1,$a0
fpu_ct_save 2,$a0
fpu_ct_save 3,$a0
fpu_ct_save 4,$a0
fpu_ct_save 5,$a0
fpu_ct_save 6,$a0
fpu_ct_save 7,$a0
fpu_ct_save 8,$a0
fpu_ct_save 9,$a0
fpu_ct_save 10,$a0
fpu_ct_save 11,$a0
fpu_ct_save 12,$a0
fpu_ct_save 13,$a0
fpu_ct_save 14,$a0
fpu_ct_save 15,$a0
fpu_ct_save 16,$a0
fpu_ct_save 17,$a0
fpu_ct_save 18,$a0
fpu_ct_save 19,$a0
fpu_ct_save 20,$a0
fpu_ct_save 21,$a0
fpu_ct_save 22,$a0
fpu_ct_save 23,$a0
fpu_ct_save 24,$a0
fpu_ct_save 25,$a0
fpu_ct_save 26,$a0
fpu_ct_save 27,$a0
fpu_ct_save 28,$a0
fpu_ct_save 29,$a0
fpu_ct_save 30,$a0
fpu_ct_save 31,$a0
#endif
j $ra
nop
 
.global fpu_context_restore
fpu_context_restore:
#ifdef ARCH_HAS_FPU
fpu_gp_restore 0,$a0
fpu_gp_restore 1,$a0
fpu_gp_restore 2,$a0
fpu_gp_restore 3,$a0
fpu_gp_restore 4,$a0
fpu_gp_restore 5,$a0
fpu_gp_restore 6,$a0
fpu_gp_restore 7,$a0
fpu_gp_restore 8,$a0
fpu_gp_restore 9,$a0
fpu_gp_restore 10,$a0
fpu_gp_restore 11,$a0
fpu_gp_restore 12,$a0
fpu_gp_restore 13,$a0
fpu_gp_restore 14,$a0
fpu_gp_restore 15,$a0
fpu_gp_restore 16,$a0
fpu_gp_restore 17,$a0
fpu_gp_restore 18,$a0
fpu_gp_restore 19,$a0
fpu_gp_restore 20,$a0
fpu_gp_restore 21,$a0
fpu_gp_restore 22,$a0
fpu_gp_restore 23,$a0
fpu_gp_restore 24,$a0
fpu_gp_restore 25,$a0
fpu_gp_restore 26,$a0
fpu_gp_restore 27,$a0
fpu_gp_restore 28,$a0
fpu_gp_restore 29,$a0
fpu_gp_restore 30,$a0
fpu_gp_restore 31,$a0
 
fpu_ct_restore 1,$a0
fpu_ct_restore 2,$a0
fpu_ct_restore 3,$a0
fpu_ct_restore 4,$a0
fpu_ct_restore 5,$a0
fpu_ct_restore 6,$a0
fpu_ct_restore 7,$a0
fpu_ct_restore 8,$a0
fpu_ct_restore 9,$a0
fpu_ct_restore 10,$a0
fpu_ct_restore 11,$a0
fpu_ct_restore 12,$a0
fpu_ct_restore 13,$a0
fpu_ct_restore 14,$a0
fpu_ct_restore 15,$a0
fpu_ct_restore 16,$a0
fpu_ct_restore 17,$a0
fpu_ct_restore 18,$a0
fpu_ct_restore 19,$a0
fpu_ct_restore 20,$a0
fpu_ct_restore 21,$a0
fpu_ct_restore 22,$a0
fpu_ct_restore 23,$a0
fpu_ct_restore 24,$a0
fpu_ct_restore 25,$a0
fpu_ct_restore 26,$a0
fpu_ct_restore 27,$a0
fpu_ct_restore 28,$a0
fpu_ct_restore 29,$a0
fpu_ct_restore 30,$a0
fpu_ct_restore 31,$a0
#endif
j $ra
nop
/tags/0.2.0.3/kernel/arch/mips32/src/panic.S
0,0 → 1,48
#
# Copyright (C) 2003-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.
#
 
.text
 
.set noat
.set noreorder
.set nomacro
 
#include <arch/asm/regname.h>
.global panic_printf
 
/* From printf return directly to halt() */
panic_printf:
jal printf
nop
j halt
nop
/* This code does not work, god knows why */
/* lui $ra, %hi(halt)
j printf
ori $ra, %lo(halt) */
/tags/0.2.0.3/kernel/arch/mips32/src/context.S
0,0 → 1,86
#
# Copyright (C) 2003-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.
#
 
#include <arch/asm/regname.h>
#include <arch/context_offset.h>
.text
 
.set noat
.set noreorder
.set nomacro
 
.global context_save_arch
.global context_restore_arch
 
.macro CONTEXT_STORE r
sw $s0,OFFSET_S0(\r)
sw $s1,OFFSET_S1(\r)
sw $s2,OFFSET_S2(\r)
sw $s3,OFFSET_S3(\r)
sw $s4,OFFSET_S4(\r)
sw $s5,OFFSET_S5(\r)
sw $s6,OFFSET_S6(\r)
sw $s7,OFFSET_S7(\r)
sw $s8,OFFSET_S8(\r)
sw $gp,OFFSET_GP(\r)
sw $ra,OFFSET_PC(\r)
sw $sp,OFFSET_SP(\r)
.endm
 
.macro CONTEXT_LOAD r
lw $s0,OFFSET_S0(\r)
lw $s1,OFFSET_S1(\r)
lw $s2,OFFSET_S2(\r)
lw $s3,OFFSET_S3(\r)
lw $s4,OFFSET_S4(\r)
lw $s5,OFFSET_S5(\r)
lw $s6,OFFSET_S6(\r)
lw $s7,OFFSET_S7(\r)
lw $s8,OFFSET_S8(\r)
lw $gp,OFFSET_GP(\r)
lw $ra,OFFSET_PC(\r)
lw $sp,OFFSET_SP(\r)
.endm
 
context_save_arch:
CONTEXT_STORE $a0
 
# context_save returns 1
j $31
li $2, 1
context_restore_arch:
CONTEXT_LOAD $a0
 
# context_restore returns 0
j $31
xor $2, $2
/tags/0.2.0.3/kernel/arch/mips32/src/dummy.S
0,0 → 1,41
#
# Copyright (C) 2003-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.
#
 
.text
.set noat
 
.global calibrate_delay_loop
.global asm_delay_loop
.global dummy
calibrate_delay_loop:
asm_delay_loop:
 
dummy:
j $31
nop
/tags/0.2.0.3/kernel/arch/mips32/Makefile.inc
0,0 → 1,128
#
# Copyright (C) 2005 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_ARCH = mips
TARGET = mipsel-linux-gnu
TOOLCHAIN_DIR = /usr/local/mipsel/bin
 
KERNEL_LOAD_ADDRESS = 0x80100000
INIT_ADDRESS = 0x81000000
INIT_SIZE = 262144
 
CFLAGS += -mno-abicalls -G 0 -fno-zero-initialized-in-bss
 
DEFS += -D__32_BITS__ -DMACHINE=$(MACHINE) -DKERNEL_LOAD_ADDRESS=${KERNEL_LOAD_ADDRESS} -DINIT_ADDRESS=${INIT_ADDRESS} -DINIT_SIZE=${INIT_SIZE}
 
## Compile with hierarchical page tables support.
#
 
CONFIG_PAGE_PT = y
DEFS += -DCONFIG_PAGE_PT
 
## Compile with support for address space identifiers.
#
 
CONFIG_ASID = y
CONFIG_ASID_FIFO = y
 
## Accepted MACHINEs
#
 
ifeq ($(MACHINE),indy)
# GCC 4.0.1 compiled for mipsEL has problems compiling in
# BigEndian mode with the swl/swr/lwl/lwr instructions.
# We have to compile it with mips-sgi-irix5 to get it right.
BFD_NAME = elf32-bigmips
BFD = ecoff-bigmips --impure
TARGET = mips-sgi-irix5
TOOLCHAIN_DIR = /usr/local/mips/bin
KERNEL_LOAD_ADDRESS = 0x88002000
CFLAGS += -EB -DBIG_ENDIAN -DARCH_HAS_FPU -march=r4600
INIT_ADDRESS = 0
INIT_SIZE = 0
endif
ifeq ($(MACHINE),lgxemul)
BFD_NAME = elf32-tradlittlemips
BFD = binary
CFLAGS += -DFB_BIG_ENDIAN -DARCH_HAS_FPU -mips3
endif
ifeq ($(MACHINE),bgxemul)
BFD_NAME = elf32-bigmips
BFD = ecoff-bigmips
TARGET = mips-sgi-irix5
TOOLCHAIN_DIR = /usr/local/mips/bin
CFLAGS += -EB -DBIG_ENDIAN -DARCH_HAS_FPU -mips3
INIT_ADDRESS = 0x81800000
endif
ifeq ($(MACHINE),simics)
# SIMICS 4kc emulation is broken, although for instructions
# that do not bother us
BFD_NAME = elf32-tradlittlemips
BFD = elf32-tradlittlemips
CFLAGS += -mhard-float -mips3 -DTLBCNT=16
TLBCNT = 16
endif
ifeq ($(MACHINE),msim)
BFD_NAME = elf32-tradlittlemips
BFD = binary
CFLAGS += -mhard-float -mips3
endif
 
## Compile with support for software integer division.
#
 
CONFIG_SOFTINT = y
 
 
ARCH_SOURCES = \
arch/$(ARCH)/src/start.S \
arch/$(ARCH)/src/context.S \
arch/$(ARCH)/src/panic.S \
arch/$(ARCH)/src/mips32.c \
arch/$(ARCH)/src/dummy.S \
arch/$(ARCH)/src/console.c \
arch/$(ARCH)/src/asm.S \
arch/$(ARCH)/src/exception.c \
arch/$(ARCH)/src/interrupt.c \
arch/$(ARCH)/src/cache.c \
arch/$(ARCH)/src/debugger.c \
arch/$(ARCH)/src/cpu/cpu.c \
arch/$(ARCH)/src/mm/frame.c \
arch/$(ARCH)/src/mm/page.c \
arch/$(ARCH)/src/mm/tlb.c \
arch/$(ARCH)/src/mm/as.c \
arch/$(ARCH)/src/fpu_context.c \
arch/$(ARCH)/src/ddi/ddi.c \
arch/$(ARCH)/src/drivers/arc.c \
arch/$(ARCH)/src/drivers/msim.c \
arch/$(ARCH)/src/drivers/serial.c
/tags/0.2.0.3/kernel/arch/mips32/include/exception.h
0,0 → 1,127
/*
* Copyright (C) 2003-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 mips32
* @{
*/
/** @file
*/
 
#ifndef __mips32_EXCEPTION_H__
#define __mips32_EXCEPTION_H__
 
#ifndef __mips32_TYPES_H__
# include <arch/types.h>
#endif
 
#include <typedefs.h>
#include <arch/cp0.h>
 
#define EXC_Int 0
#define EXC_Mod 1
#define EXC_TLBL 2
#define EXC_TLBS 3
#define EXC_AdEL 4
#define EXC_AdES 5
#define EXC_IBE 6
#define EXC_DBE 7
#define EXC_Sys 8
#define EXC_Bp 9
#define EXC_RI 10
#define EXC_CpU 11
#define EXC_Ov 12
#define EXC_Tr 13
#define EXC_VCEI 14
#define EXC_FPE 15
#define EXC_WATCH 23
#define EXC_VCED 31
 
struct istate {
uint32_t at;
uint32_t v0;
uint32_t v1;
uint32_t a0;
uint32_t a1;
uint32_t a2;
uint32_t a3;
uint32_t t0;
uint32_t t1;
uint32_t t2;
uint32_t t3;
uint32_t t4;
uint32_t t5;
uint32_t t6;
uint32_t t7;
uint32_t s0;
uint32_t s1;
uint32_t s2;
uint32_t s3;
uint32_t s4;
uint32_t s5;
uint32_t s6;
uint32_t s7;
uint32_t t8;
uint32_t t9;
uint32_t gp;
uint32_t sp;
uint32_t s8;
uint32_t ra;
uint32_t lo;
uint32_t hi;
 
uint32_t status; /* cp0_status */
uint32_t epc; /* cp0_epc */
uint32_t k1; /* We use it as thread-local pointer */
};
 
static inline void istate_set_retaddr(istate_t *istate, uintptr_t retaddr)
{
istate->epc = retaddr;
}
 
/** Return true if exception happened while in userspace */
static inline int istate_from_uspace(istate_t *istate)
{
return istate->status & cp0_status_um_bit;
}
static inline unative_t istate_get_pc(istate_t *istate)
{
return istate->epc;
}
 
extern void exception(istate_t *istate);
extern void tlb_refill_entry(void);
extern void exception_entry(void);
extern void cache_error_entry(void);
extern void exception_init(void);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/mips32/include/fpu_context.h
0,0 → 1,50
/*
* Copyright (C) 2005 Jakub Vana
* 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 mips32
* @{
*/
/** @file
*/
 
#ifndef __mips32_FPU_CONTEXT_H__
#define __mips32_FPU_CONTEXT_H__
 
#include <arch/types.h>
 
#define FPU_CONTEXT_ALIGN sizeof(unative_t)
 
struct fpu_context {
unative_t dregs[32];
unative_t cregs[32];
};
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/mips32/include/byteorder.h
0,0 → 1,60
/*
* 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 mips32
* @{
*/
/** @file
*/
 
#ifndef __mips32_BYTEORDER_H__
#define __mips32_BYTEORDER_H__
 
#include <arch/types.h>
#include <byteorder.h>
 
#ifdef BIG_ENDIAN
static inline uint64_t uint64_t_le2host(uint64_t n)
{
return uint64_t_byteorder_swap(n);
}
 
static inline unative_t unative_t_le2host(unative_t n)
{
return uint32_t_byteorder_swap(n);
}
 
#else
# define unative_t_le2host(n) (n)
# define uint64_t_le2host(n) (n)
#endif
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/mips32/include/boot.h
0,0 → 1,48
/*
* Copyright (C) 2006 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#ifndef __mips32_BOOT_H__
#define __mips32_BOOT_H__
 
#define TASKMAP_MAX_RECORDS 32
 
#include <arch/types.h>
 
typedef struct {
uintptr_t addr;
uint32_t size;
} utask_t;
 
typedef struct {
uint32_t cnt;
utask_t tasks[TASKMAP_MAX_RECORDS];
} bootinfo_t;
 
extern bootinfo_t bootinfo;
 
#endif
/tags/0.2.0.3/kernel/arch/mips32/include/types.h
0,0 → 1,66
/*
* Copyright (C) 2003-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 mips32
* @{
*/
/** @file
*/
 
#ifndef __mips32_TYPES_H__
#define __mips32_TYPES_H__
 
#define NULL 0
 
typedef signed char int8_t;
typedef unsigned char uint8_t;
 
typedef signed short int16_t;
typedef unsigned short uint16_t;
 
typedef unsigned long uint32_t;
typedef signed long int32_t;
 
typedef unsigned long long uint64_t;
typedef signed long long int64_t;
 
typedef uint32_t uintptr_t;
 
typedef uint32_t ipl_t;
 
typedef uint32_t unative_t;
typedef int32_t native_t;
 
typedef struct pte pte_t;
 
typedef uint32_t pfn_t;
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/mips32/include/memstr.h
0,0 → 1,48
/*
* Copyright (C) 2005 Sergey Bondari
* 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 mips32
* @{
*/
/** @file
*/
 
#ifndef __mips32_MEMSTR_H__
#define __mips32_MEMSTR_H__
 
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt))
 
extern void memsetw(uintptr_t dst, size_t cnt, uint16_t x);
extern void memsetb(uintptr_t dst, size_t cnt, uint8_t x);
 
extern int memcmp(uintptr_t src, uintptr_t dst, int cnt);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/mips32/include/arg.h
0,0 → 1,60
/*
* 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 mips32
* @{
*/
/** @file
*/
 
#ifndef __mips32_ARG_H__
#define __mips32_ARG_H__
 
#include <arch/types.h>
 
/**
* va_arg macro for MIPS32 - problem is that 64 bit values must be aligned on an 8-byte boundary (32bit values not)
* To satisfy this, paddings must be sometimes inserted.
*/
 
typedef uintptr_t va_list;
 
#define va_start(ap, lst) \
((ap) = (va_list)&(lst) + sizeof(lst))
 
#define va_arg(ap, type) \
(((type *)((ap) = (va_list)( (sizeof(type) <= 4) ? ((uintptr_t)((ap) + 2*4 - 1) & (~3)) : ((uintptr_t)((ap) + 2*8 -1) & (~7)) )))[-1])
 
#define va_copy(dst,src) ((dst)=(src))
 
#define va_end(ap)
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/mips32/include/asm.h
0,0 → 1,72
/*
* Copyright (C) 2003-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 mips32
* @{
*/
/** @file
*/
 
#ifndef __mips32_ASM_H__
#define __mips32_ASM_H__
 
#include <arch/types.h>
#include <typedefs.h>
#include <config.h>
 
 
static inline void cpu_sleep(void)
{
/* Most of the simulators do not support */
/* __asm__ volatile ("wait"); */
}
 
/** 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 ("and %0, $29, %1\n" : "=r" (v) : "r" (~(STACK_SIZE-1)));
return v;
}
 
extern void cpu_halt(void);
extern void asm_delay_loop(uint32_t t);
extern void userspace_asm(uintptr_t ustack, uintptr_t uspace_uarg,
uintptr_t entry);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/mips32/include/faddr.h
0,0 → 1,45
/*
* 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 mips32
* @{
*/
/** @file
*/
 
#ifndef __mips32_FADDR_H__
#define __mips32_FADDR_H__
 
#include <arch/types.h>
 
#define FADDR(fptr) ((uintptr_t) (fptr))
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/mips32/include/cp0.h
0,0 → 1,123
/*
* Copyright (C) 2003-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 mips32
* @{
*/
/** @file
*/
 
#ifndef __mips32_CP0_H__
#define __mips32_CP0_H__
 
#include <arch/types.h>
#include <arch/mm/tlb.h>
 
#define cp0_status_ie_enabled_bit (1<<0)
#define cp0_status_exl_exception_bit (1<<1)
#define cp0_status_erl_error_bit (1<<2)
#define cp0_status_um_bit (1<<4)
#define cp0_status_bev_bootstrap_bit (1<<22)
#define cp0_status_fpu_bit (1<<29)
 
#define cp0_status_im_shift 8
#define cp0_status_im_mask 0xff00
 
#define cp0_cause_excno(cause) ((cause >> 2) & 0x1f)
#define cp0_cause_coperr(cause) ((cause >> 28) & 0x3)
 
#define fpu_cop_id 1
 
/*
* Magic value for use in msim.
*/
#define cp0_compare_value 100000
 
#define cp0_mask_all_int() cp0_status_write(cp0_status_read() & ~(cp0_status_im_mask))
#define cp0_unmask_all_int() cp0_status_write(cp0_status_read() | cp0_status_im_mask)
#define cp0_mask_int(it) cp0_status_write(cp0_status_read() & ~(1<<(cp0_status_im_shift+(it))))
#define cp0_unmask_int(it) cp0_status_write(cp0_status_read() | (1<<(cp0_status_im_shift+(it))))
 
#define GEN_READ_CP0(nm,reg) static inline uint32_t cp0_ ##nm##_read(void) \
{ \
uint32_t retval; \
asm("mfc0 %0, $" #reg : "=r"(retval)); \
return retval; \
}
 
#define GEN_WRITE_CP0(nm,reg) static inline void cp0_ ##nm##_write(uint32_t val) \
{ \
asm("mtc0 %0, $" #reg : : "r"(val) ); \
}
 
GEN_READ_CP0(index, 0);
GEN_WRITE_CP0(index, 0);
 
GEN_READ_CP0(random, 1);
 
GEN_READ_CP0(entry_lo0, 2);
GEN_WRITE_CP0(entry_lo0, 2);
 
GEN_READ_CP0(entry_lo1, 3);
GEN_WRITE_CP0(entry_lo1, 3);
 
GEN_READ_CP0(context, 4);
GEN_WRITE_CP0(context, 4);
 
GEN_READ_CP0(pagemask, 5);
GEN_WRITE_CP0(pagemask, 5);
 
GEN_READ_CP0(wired, 6);
GEN_WRITE_CP0(wired, 6);
 
GEN_READ_CP0(badvaddr, 8);
 
GEN_READ_CP0(count, 9);
GEN_WRITE_CP0(count, 9);
 
GEN_READ_CP0(entry_hi, 10);
GEN_WRITE_CP0(entry_hi, 10);
 
GEN_READ_CP0(compare, 11);
GEN_WRITE_CP0(compare, 11);
 
GEN_READ_CP0(status, 12);
GEN_WRITE_CP0(status, 12);
 
GEN_READ_CP0(cause, 13);
GEN_WRITE_CP0(cause, 13);
 
GEN_READ_CP0(epc, 14);
GEN_WRITE_CP0(epc, 14);
 
GEN_READ_CP0(prid, 15);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/mips32/include/mm/page.h
0,0 → 1,156
/*
* Copyright (C) 2003-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 mips32mm
* @{
*/
/** @file
*/
 
#ifndef __mips32_PAGE_H__
#define __mips32_PAGE_H__
 
#include <arch/mm/frame.h>
 
#define PAGE_WIDTH FRAME_WIDTH
#define PAGE_SIZE FRAME_SIZE
 
#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
 
#ifdef KERNEL
 
/*
* Implementation of generic 4-level page table interface.
* NOTE: this implementation is under construction
*
* Page table layout:
* - 32-bit virtual addresses
* - Offset is 14 bits => pages are 16K long
* - PTE's use similar format as CP0 EntryLo[01] registers => PTE is therefore 4 bytes long
* - PTE's replace EntryLo v (valid) bit with p (present) bit
* - PTE's use only one bit to distinguish between cacheable and uncacheable mappings
* - PTE's define soft_valid field to ensure there is at least one 1 bit even if the p bit is cleared
* - PTE's make use of CP0 EntryLo's two-bit reserved field for bit W (writable) and bit A (accessed)
* - PTL0 has 64 entries (6 bits)
* - PTL1 is not used
* - PTL2 is not used
* - PTL3 has 4096 entries (12 bits)
*/
#define PTL0_ENTRIES_ARCH 64
#define PTL1_ENTRIES_ARCH 0
#define PTL2_ENTRIES_ARCH 0
#define PTL3_ENTRIES_ARCH 4096
 
#define PTL0_INDEX_ARCH(vaddr) ((vaddr)>>26)
#define PTL1_INDEX_ARCH(vaddr) 0
#define PTL2_INDEX_ARCH(vaddr) 0
#define PTL3_INDEX_ARCH(vaddr) (((vaddr)>>14) & 0xfff)
 
#define SET_PTL0_ADDRESS_ARCH(ptl0)
 
#define GET_PTL1_ADDRESS_ARCH(ptl0, i) (((pte_t *)(ptl0))[(i)].pfn<<12)
#define GET_PTL2_ADDRESS_ARCH(ptl1, i) (ptl1)
#define GET_PTL3_ADDRESS_ARCH(ptl2, i) (ptl2)
#define GET_FRAME_ADDRESS_ARCH(ptl3, i) (((pte_t *)(ptl3))[(i)].pfn<<12)
 
#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) (((pte_t *)(ptl0))[(i)].pfn = (a)>>12)
#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) (((pte_t *)(ptl3))[(i)].pfn = (a)>>12)
 
#define GET_PTL1_FLAGS_ARCH(ptl0, i) get_pt_flags((pte_t *)(ptl0), (index_t)(i))
#define GET_PTL2_FLAGS_ARCH(ptl1, i) PAGE_PRESENT
#define GET_PTL3_FLAGS_ARCH(ptl2, i) PAGE_PRESENT
#define GET_FRAME_FLAGS_ARCH(ptl3, i) get_pt_flags((pte_t *)(ptl3), (index_t)(i))
 
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) set_pt_flags((pte_t *)(ptl0), (index_t)(i), (x))
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x)
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) set_pt_flags((pte_t *)(ptl3), (index_t)(i), (x))
 
#define PTE_VALID_ARCH(pte) (*((uint32_t *) (pte)) != 0)
#define PTE_PRESENT_ARCH(pte) ((pte)->p != 0)
#define PTE_GET_FRAME_ARCH(pte) ((pte)->pfn<<12)
#define PTE_WRITABLE_ARCH(pte) ((pte)->w != 0)
#define PTE_EXECUTABLE_ARCH(pte) 1
 
#ifndef __ASM__
 
#include <arch/mm/tlb.h>
#include <mm/page.h>
#include <arch/mm/frame.h>
#include <arch/types.h>
 
static inline int get_pt_flags(pte_t *pt, index_t i)
{
pte_t *p = &pt[i];
return (
(p->cacheable<<PAGE_CACHEABLE_SHIFT) |
((!p->p)<<PAGE_PRESENT_SHIFT) |
(1<<PAGE_USER_SHIFT) |
(1<<PAGE_READ_SHIFT) |
((p->w)<<PAGE_WRITE_SHIFT) |
(1<<PAGE_EXEC_SHIFT) |
(p->g<<PAGE_GLOBAL_SHIFT)
);
}
 
static inline void set_pt_flags(pte_t *pt, index_t i, int flags)
{
pte_t *p = &pt[i];
p->cacheable = (flags & PAGE_CACHEABLE) != 0;
p->p = !(flags & PAGE_NOT_PRESENT);
p->g = (flags & PAGE_GLOBAL) != 0;
p->w = (flags & PAGE_WRITE) != 0;
/*
* Ensure that valid entries have at least one bit set.
*/
p->soft_valid = 1;
}
 
extern void page_arch_init(void);
 
#endif /* __ASM__ */
 
#endif /* KERNEL */
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/mips32/include/mm/asid.h
0,0 → 1,48
/*
* Copyright (C) 2005 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 mips32mm
* @{
*/
/** @file
*/
 
#ifndef __mips32_ASID_H__
#define __mips32_ASID_H__
 
#include <arch/types.h>
 
#define ASID_MAX_ARCH 255 /* 2^8 - 1 */
 
typedef uint8_t asid_t;
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/mips32/include/mm/tlb.h
0,0 → 1,185
/*
* Copyright (C) 2003-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 mips32mm
* @{
*/
/** @file
*/
 
#ifndef __mips32_TLB_H__
#define __mips32_TLB_H__
 
#include <arch/exception.h>
#include <typedefs.h>
 
#ifdef TLBCNT
# define TLB_ENTRY_COUNT TLBCNT
#else
# define TLB_ENTRY_COUNT 48
#endif
 
#define TLB_WIRED 1
#define TLB_KSTACK_WIRED_INDEX 0
 
#define TLB_PAGE_MASK_16K (0x3<<13)
 
#define PAGE_UNCACHED 2
#define PAGE_CACHEABLE_EXC_WRITE 5
 
typedef union entry_lo entry_lo_t;
typedef union entry_hi entry_hi_t;
typedef union page_mask page_mask_t;
typedef union index tlb_index_t;
 
union entry_lo {
struct {
#ifdef BIG_ENDIAN
unsigned : 2; /* zero */
unsigned pfn : 24; /* frame number */
unsigned c : 3; /* cache coherency attribute */
unsigned d : 1; /* dirty/write-protect bit */
unsigned v : 1; /* valid bit */
unsigned g : 1; /* global bit */
#else
unsigned g : 1; /* global bit */
unsigned v : 1; /* valid bit */
unsigned d : 1; /* dirty/write-protect bit */
unsigned c : 3; /* cache coherency attribute */
unsigned pfn : 24; /* frame number */
unsigned : 2; /* zero */
#endif
} __attribute__ ((packed));
uint32_t value;
};
 
/** Page Table Entry. */
struct pte {
unsigned g : 1; /**< Global bit. */
unsigned p : 1; /**< Present bit. */
unsigned d : 1; /**< Dirty bit. */
unsigned cacheable : 1; /**< Cacheable bit. */
unsigned : 1; /**< Unused. */
unsigned soft_valid : 1; /**< Valid content even if not present. */
unsigned pfn : 24; /**< Physical frame number. */
unsigned w : 1; /**< Page writable bit. */
unsigned a : 1; /**< Accessed bit. */
};
 
union entry_hi {
struct {
#ifdef BIG_ENDIAN
unsigned vpn2 : 19;
unsigned : 5;
unsigned asid : 8;
#else
unsigned asid : 8;
unsigned : 5;
unsigned vpn2 : 19;
#endif
} __attribute__ ((packed));
uint32_t value;
};
 
union page_mask {
struct {
#ifdef BIG_ENDIAN
unsigned : 7;
unsigned mask : 12;
unsigned : 13;
#else
unsigned : 13;
unsigned mask : 12;
unsigned : 7;
#endif
} __attribute__ ((packed));
uint32_t value;
};
 
union index {
struct {
#ifdef BIG_ENDIAN
unsigned p : 1;
unsigned : 27;
unsigned index : 4;
#else
unsigned index : 4;
unsigned : 27;
unsigned p : 1;
#endif
} __attribute__ ((packed));
uint32_t value;
};
 
/** Probe TLB for Matching Entry
*
* Probe TLB for Matching Entry.
*/
static inline void tlbp(void)
{
__asm__ volatile ("tlbp\n\t");
}
 
 
/** Read Indexed TLB Entry
*
* Read Indexed TLB Entry.
*/
static inline void tlbr(void)
{
__asm__ volatile ("tlbr\n\t");
}
 
/** Write Indexed TLB Entry
*
* Write Indexed TLB Entry.
*/
static inline void tlbwi(void)
{
__asm__ volatile ("tlbwi\n\t");
}
 
/** Write Random TLB Entry
*
* Write Random TLB Entry.
*/
static inline void tlbwr(void)
{
__asm__ volatile ("tlbwr\n\t");
}
 
#define tlb_invalidate(asid) tlb_invalidate_asid(asid)
 
extern void tlb_invalid(istate_t *istate);
extern void tlb_refill(istate_t *istate);
extern void tlb_modified(istate_t *istate);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/mips32/include/mm/frame.h
0,0 → 1,52
/*
* 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 mips32mm
* @{
*/
/** @file
*/
 
#ifndef __mips32_FRAME_H__
#define __mips32_FRAME_H__
 
#define FRAME_WIDTH 14 /* 16K */
#define FRAME_SIZE (1<<FRAME_WIDTH)
 
#ifdef KERNEL
#ifndef __ASM__
 
extern void frame_arch_init(void);
 
#endif /* __ASM__ */
#endif /* KERNEL */
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/mips32/include/mm/memory_init.h
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 mips32mm
* @{
*/
/** @file
*/
 
#ifndef __mips32_MEMORY_INIT_H__
#define __mips32_MEMORY_INIT_H__
 
#include <config.h>
 
/* When this function is called, we do not have ARC initiated
* - provide some reasonable minimum and update it later
*/
#define get_memory_size() CONFIG_MEMORY_SIZE
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/mips32/include/mm/as.h
0,0 → 1,52
/*
* 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 mips32mm
* @{
*/
/** @file
*/
 
#ifndef __mips32_AS_H__
#define __mips32_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 (0x80000000-PAGE_SIZE)
 
extern void as_arch_init(void);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/mips32/include/debugger.h
0,0 → 1,69
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 mips32debug
* @{
*/
/** @file
*/
 
#ifndef _mips32_DEBUGGER_H_
#define _mips32_DEBUGGER_H_
 
#include <typedefs.h>
#include <arch/exception.h>
#include <arch/types.h>
 
#define BKPOINTS_MAX 10
 
#define BKPOINT_INPROG (1 << 0) /**< Breakpoint was shot */
#define BKPOINT_ONESHOT (1 << 1) /**< One-time breakpoint,mandatory for j/b
instructions */
#define BKPOINT_REINST (1 << 2) /**< Breakpoint is set on the next
instruction, so that it could be
reinstalled on the previous one */
#define BKPOINT_FUNCCALL (1 << 3) /**< Call a predefined function */
 
typedef struct {
uintptr_t address; /**< Breakpoint address */
unative_t instruction; /**< Original instruction */
unative_t nextinstruction; /**< Original instruction following break */
int flags; /**< Flags regarding breakpoint */
count_t counter;
void (*bkfunc)(void *b, istate_t *istate);
} bpinfo_t;
 
extern void debugger_init(void);
void debugger_bpoint(istate_t *istate);
 
extern bpinfo_t breakpoints[BKPOINTS_MAX];
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/mips32/include/context.h
0,0 → 1,80
/*
* Copyright (C) 2003-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 mips32
* @{
*/
/** @file
*/
 
#ifndef __mips32_CONTEXT_H__
#define __mips32_CONTEXT_H__
 
#include <align.h>
#include <arch/stack.h>
 
/*
* Put one item onto the stack to support get_stack_base() and align it up.
*/
#define SP_DELTA (0 + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
 
 
#ifndef __ASM__
 
#ifndef __mips32_TYPES_H__
# include <arch/types.h>
#endif
 
/*
* Only save registers that must be preserved across
* function calls.
*/
struct context {
uintptr_t sp;
uintptr_t pc;
uint32_t s0;
uint32_t s1;
uint32_t s2;
uint32_t s3;
uint32_t s4;
uint32_t s5;
uint32_t s6;
uint32_t s7;
uint32_t s8;
uint32_t gp;
 
ipl_t ipl;
};
 
#endif /* __ASM__ */
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/mips32/include/cpu.h
0,0 → 1,48
/*
* Copyright (C) 2003-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 mips32
* @{
*/
/** @file
*/
 
#ifndef __mips32_CPU_H__
#define __mips32_CPU_H__
 
#include <arch/types.h>
 
struct cpu_arch {
uint32_t imp_num;
uint32_t rev_num;
};
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/mips32/include/drivers/arc.h
0,0 → 1,268
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 mips32
* @{
*/
/** @file
*/
 
#ifndef __mips32_ARC_H__
#define __mips32_ARC_H__
 
#include <arch/types.h>
#include <console/chardev.h>
 
#define ARC_BASE_ADDR 0x1000;
#define ARC_MAGIC 0x53435241
/* Frame size used by ARC */
#define ARC_FRAME 4096
 
typedef enum {
CmResourceTypeNull = 0,
CmResourceTypePort,
CmResourceTypeInterrupt,
CmResourceTypeMemory,
CmResourceTypeDma,
CmResourceTypeDeviceSpecific,
CmResourceTypeVendor,
CmResourceTypeProductName,
CmResourceTypeSerialNumber
}cm_resource_type;
 
typedef struct {
uint8_t type;
uint8_t sharedisposition;
uint16_t flags;
union {
struct {
long long start; /* 64-bit phys address */
unsigned long length;
}port;
struct {
unsigned long level;
unsigned long vector;
unsigned long reserved1;
}interrupt;
struct {
long long start; /* 64-bit phys address */
unsigned long length;
}memory;
}u;
}__attribute__ ((packed)) cm_resource_descriptor;
 
typedef struct {
uint16_t version;
uint16_t revision;
unsigned long count;
cm_resource_descriptor descr[1];
}__attribute__ ((packed)) cm_resource_list;
 
typedef enum {
SystemClass = 0,
ProcessorClass,
CacheClass,
AdapterClass,
ControllerClass,
PeripheralClass,
MemoryClass
} arc_component_class;
 
typedef enum {
ARC_type = 0,
CPU_type,
FPU_type,
PrimaryICache,
PrimaryDCache,
SecondaryICache,
SecondaryDCache,
SecondaryCache,
Memory, /* Not in NT PROM */
EISAAdapter,
TCAdapter,
SCSIAdapter,
DTIAdapter,
MultiFunctionAdapter,
DiskController,
TapeController,
CDROMController,
WORMController,
SerialController,
NetworkController,
DisplayController,
ParallelController,
PointerController,
KeyboardController,
AudioController,
OtherController,
DiskPeripheral,
FloppyDiskPeripheral,
TapePeripheral,
ModemPeripheral,
MonitorPeripheral,
PrinterPeripheral,
PointerPeripheral,
KeyboardPeripheral,
TerminalPeripheral,
LinePeripheral,
NetworkPeripheral,
OtherPeripheral,
XTalkAdapter,
PCIAdapter,
GIOAdapter,
TPUAdapter,
Anonymous
}arc_component_type;
 
typedef enum {
Failed = 1,
ReadOnly = 2,
Removable = 4,
ConsoleIn = 8,
ConsoleOut = 16,
Input = 32,
Output = 64
}arc_component_flags;
 
typedef struct {
arc_component_class class;
arc_component_type type;
arc_component_flags flags;
uint16_t revision;
uint16_t version;
uint32_t key;
uint32_t affinitymask;
uint32_t configdatasize;
uint32_t identifier_len;
char *identifier;
} __attribute__ ((packed)) arc_component;
 
typedef struct {
uint16_t year;
uint16_t month;
uint16_t day;
uint16_t hour;
uint16_t minutes;
uint16_t seconds;
uint16_t mseconds;
} __attribute__ ((packed)) arc_timeinfo;
 
/* This is the SGI block structure, WinNT has it different */
typedef enum {
ExceptionBlock,
SystemParameterBlock,
FreeContiguous,
FreeMemory,
BadMemory,
LoadedProgram,
FirmwareTemporary,
FirmwarePermanent
}arc_memorytype_t;
 
typedef struct {
arc_memorytype_t type;
uint32_t basepage; /* *4096 = baseaddr */
uint32_t basecount;
}arc_memdescriptor_t;
 
typedef struct {
char vendorid[8];
char prodid[8];
}arc_sysid_t;
 
typedef struct {
long (*load)(void); /* ... */
long (*invoke)(uint32_t eaddr,uint32_t saddr,uint32_t argc,char **argv,
char **envp);
long (*execute)(char *path,uint32_t argc,char **argv,char **envp);
void (*halt)(void);
void (*powerdown)(void);
void (*restart)(void);
void (*reboot)(void);
void (*enterinteractivemode)(void);
long (*reserved)(void);
/* 10 */
arc_component * (*getpeer)(arc_component *c);
arc_component * (*getchild)(arc_component *c);
arc_component * (*getparent)(arc_component *c);
long (*getconfigurationdata)(void *configdata, arc_component *c);
long (*addchild)(arc_component *c, arc_component *template,
void *configdata);
long (*deletecomponet)(arc_component *current);
long (*getcomponent)(char *path);
long (*saveconfiguration)(void);
arc_sysid_t (*getsystemid)(void);
arc_memdescriptor_t * (*getmemorydescriptor)(arc_memdescriptor_t *cur);
/* 20 */
long (*reserved2)(void);
arc_timeinfo * (*gettime)(void);
uint32_t (*getrelativetime)(void);
long (*getdirectoryentry)();
long (*open)(void); /* ... */
long (*close)(uint32_t fileid);
long (*read)(uint32_t fileid,void *buf,uint32_t n,uint32_t *cnt);
long (*getreadstatus)(uint32_t fileid);
long (*write)(uint32_t fileid, void *buf,uint32_t n,uint32_t *cnt);
long (*seek)(void); /* ... */
/* 30 */
long (*mount)(void); /* ... */
char * (*getenvironmentvariable)(char *name);
char * (*setenvironmentvariable)(char *name, char *value);
long (*getfileinformation)(void); /* ... */
long (*setfileinformation)(uint32_t fileid,uint32_t attflags,uint32_t attmask);
void (*flushallcaches)(void);
long (*testunicodecharacter)(void); /* ... */
long (*getdisplaystatus)(void); /* ... */
} arc_func_vector_t;
 
typedef struct {
uint32_t signature;
uint32_t length;
uint16_t version;
uint16_t revision;
void *restartblock;
void *debugblock;
void *gevector;
void *utlbmissvector;
uint32_t firmwarevectorlen;
arc_func_vector_t *firmwarevector;
uint32_t privvectorlen;
void *privvector;
uint32_t adaptercount;
}__attribute__ ((packed)) arc_sbp;
 
extern int arc_init(void);
extern int arc_enabled(void);
void arc_frame_init(void);
void arc_console(void);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/mips32/include/drivers/serial.h
0,0 → 1,72
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 mips32
* @{
*/
/** @file
*/
 
#ifndef __DRV_SERIAL_H__
#define __DRV_SERIAL_H__
 
#include <console/chardev.h>
 
#define SERIAL_MAX 4
#define SERIAL_COM1 0x3f8
#define SERIAL_COM1_IRQ 4
#define SERIAL_COM2 0x2f8
#define SERIAL_COM2_IRQ 3
 
#define P_WRITEB(where,what) (*((volatile char *) (0xB8000000+where))=what)
#define P_READB(where) (*((volatile char *)(0xB8000000+where)))
 
#define SERIAL_READ(x) P_READB(x)
#define SERIAL_WRITE(x,c) P_WRITEB(x,c)
/* Interrupt enable register */
#define SERIAL_READ_IER(x) (P_READB((x) + 1))
#define SERIAL_WRITE_IER(x,c) (P_WRITEB((x)+1,c))
/* Interrupt identification register */
#define SERIAL_READ_IIR(x) (P_READB((x) + 2))
/* Line status register */
#define SERIAL_READ_LSR(x) (P_READB((x) + 5))
#define TRANSMIT_EMPTY_BIT 5
 
typedef struct {
int port;
int irq;
}serial_t;
 
void serial_console(void);
int serial_init(void);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/mips32/include/drivers/msim.h
0,0 → 1,53
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 mips32
* @{
*/
/** @file
*/
 
#ifndef _MSIM_H_
#define _MSIM_H_
 
#include <console/chardev.h>
 
#define MSIM_VIDEORAM 0xB0000000
/** Address of 'keyboard' device. */
#define MSIM_KBD_ADDRESS 0xB0000000
#define MSIM_KBD_IRQ 2
 
void msim_console(void);
void msim_kbd_release(void);
void msim_kbd_grab(void);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/mips32/include/context_offset.h
0,0 → 1,52
/* This file is automatically generated by gencontext.c. */
/* struct context */
#define OFFSET_SP 0x0
#define OFFSET_PC 0x4
#define OFFSET_S0 0x8
#define OFFSET_S1 0xc
#define OFFSET_S2 0x10
#define OFFSET_S3 0x14
#define OFFSET_S4 0x18
#define OFFSET_S5 0x1c
#define OFFSET_S6 0x20
#define OFFSET_S7 0x24
#define OFFSET_S8 0x28
#define OFFSET_GP 0x2c
 
 
/* struct register_dump */
#define EOFFSET_AT 0x0
#define EOFFSET_V0 0x4
#define EOFFSET_V1 0x8
#define EOFFSET_A0 0xc
#define EOFFSET_A1 0x10
#define EOFFSET_A2 0x14
#define EOFFSET_A3 0x18
#define EOFFSET_T0 0x1c
#define EOFFSET_T1 0x20
#define EOFFSET_T2 0x24
#define EOFFSET_T3 0x28
#define EOFFSET_T4 0x2c
#define EOFFSET_T5 0x30
#define EOFFSET_T6 0x34
#define EOFFSET_T7 0x38
#define EOFFSET_S0 0x3c
#define EOFFSET_S1 0x40
#define EOFFSET_S2 0x44
#define EOFFSET_S3 0x48
#define EOFFSET_S4 0x4c
#define EOFFSET_S5 0x50
#define EOFFSET_S6 0x54
#define EOFFSET_S7 0x58
#define EOFFSET_T8 0x5c
#define EOFFSET_T9 0x60
#define EOFFSET_GP 0x64
#define EOFFSET_SP 0x68
#define EOFFSET_S8 0x6c
#define EOFFSET_RA 0x70
#define EOFFSET_LO 0x74
#define EOFFSET_HI 0x78
#define EOFFSET_STATUS 0x7c
#define EOFFSET_EPC 0x80
#define EOFFSET_K1 0x84
#define REGISTER_SPACE 136
/tags/0.2.0.3/kernel/arch/mips32/include/asm/regname.h
0,0 → 1,98
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 mips32
* @{
*/
/** @file
*/
 
#ifndef __mips32_REGNAME_H_
#define __mips32_REGNAME_H_
 
#define zero 0
#define at 1
#define v0 2
#define v1 3
#define a0 4
#define a1 5
#define a2 6
#define a3 7
#define t0 8
#define t1 9
#define t2 10
#define t3 11
#define t4 12
#define t5 13
#define t6 14
#define t7 15
#define s0 16
#define s1 17
#define s2 18
#define s3 19
#define s4 20
#define s5 21
#define s6 22
#define s7 23
#define t8 24
#define t9 25
#define k0 26
#define k1 27
#define gp 28
#define sp 29
#define s8 30
#define ra 31
 
#define rindex 0
#define rrandom 1
#define entrylo0 2
#define entrylo1 3
#define context 4
#define pagemask 5
#define wired 6
#define badvaddr 8
#define count 9
#define entryhi 10
#define compare 11
#define status 12
#define cause 13
#define epc 14
#define rconfig 16
#define lladdr 17
#define watchlo 18
#define watchhi 19
#define xcontext 20
#define rdebug 23
#define depc 24
#define eepc 30
 
 
#endif /* _REGNAME_H_ */
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/mips32/include/asm/boot.h
0,0 → 1,46
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 mips32
* @{
*/
/** @file
*/
 
#ifndef __mips32_BOOT_H_
#define __mips32_BOOT_H_
 
 
/* Temporary stack size for boot process */
#define TEMP_STACK_SIZE 0x100
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/mips32/include/interrupt.h
0,0 → 1,57
/*
* Copyright (C) 2003-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 mips32interrupt
* @{
*/
/** @file
*/
 
#ifndef __mips32_INTERRUPT_H__
#define __mips32_INTERRUPT_H__
 
#include <arch/exception.h>
 
#define IVT_ITEMS 40
#define INT_OFFSET 32
#define IRQ_COUNT 8
 
#define int_register(it, name, handler) exc_register(((it)+INT_OFFSET),name,handler)
 
#define IRQ2 2
#define IRQ3 3
#define IRQ7 7
 
#define TIMER_IRQ IRQ7
 
extern void interrupt_init(void);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/mips32/include/console.h
0,0 → 1,44
/*
* Copyright (C) 2005 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 mips32
* @{
*/
/** @file
*/
 
#ifndef __mips32_CONSOLE_H__
#define __mips32_CONSOLE_H__
 
 
void console_init(void);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/mips32/include/cache.h
0,0 → 1,45
/*
* Copyright (C) 2003-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 mips32
* @{
*/
/** @file
*/
 
#ifndef __mips32_CACHE_H__
#define __mips32_CACHE_H__
 
#include <typedefs.h>
 
extern void cache_error(istate_t *istate);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/mips32/include/stack.h
0,0 → 1,44
/*
* Copyright (C) 2006 Josef Cejka
* 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 mips32
* @{
*/
/** @file
*/
 
#ifndef __mips32_STACK_H__
#define __mips32_STACK_H__
 
#define STACK_ITEM_SIZE 4
#define STACK_ALIGNMENT 8
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/mips32/include/elf.h
0,0 → 1,51
/*
* Copyright (C) 2006 Sergey Bondari
* 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 mips32
* @{
*/
/** @file
*/
 
#ifndef __mips32_ELF_H__
#define __mips32_ELF_H__
 
#define ELF_MACHINE EM_MIPS
 
#ifdef BIG_ENDIAN
# define ELF_DATA_ENCODING ELFDATA2MSB
#else
# define ELF_DATA_ENCODING ELFDATA2LSB
#endif
 
#define ELF_CLASS ELFCLASS32
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/mips32/include/atomic.h
0,0 → 1,76
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 mips32
* @{
*/
/** @file
*/
 
#ifndef __mips32_ATOMIC_H__
#define __mips32_ATOMIC_H__
 
#define atomic_inc(x) ((void) atomic_add(x, 1))
#define atomic_dec(x) ((void) atomic_add(x, -1))
 
#define atomic_postinc(x) (atomic_add(x, 1) - 1)
#define atomic_postdec(x) (atomic_add(x, -1) + 1)
 
#define atomic_preinc(x) atomic_add(x, 1)
#define atomic_predec(x) atomic_add(x, -1)
 
/* Atomic addition of immediate value.
*
* @param val Memory location to which will be the immediate value added.
* @param i Signed immediate that will be added to *val.
*
* @return Value after addition.
*/
static inline long atomic_add(atomic_t *val, int i)
{
long tmp, v;
 
__asm__ volatile (
"1:\n"
" ll %0, %1\n"
" addiu %0, %0, %3\n" /* same as addi, but never traps on overflow */
" move %2, %0\n"
" sc %0, %1\n"
" beq %0, %4, 1b\n" /* if the atomic operation failed, try again */
" nop\n"
: "=r" (tmp), "=m" (val->count), "=r" (v)
: "i" (i), "i" (0)
);
 
return v;
}
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/mips32/include/arch.h
0,0 → 1,41
/*
* Copyright (C) 2005 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 mips32
* @{
*/
/** @file
*/
 
#ifndef __mips32_ARCH_H__
#define __mips32_ARCH_H__
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/mips32/include/debug.h
0,0 → 1,55
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 mips32debug
* @{
*/
/** @file
*/
 
#ifndef __mips32_DEBUG_H__
#define __mips23_DEBUG_H__
 
 
 
/** simulator enters the trace mode */
#define ___traceon() asm volatile ( "\t.word\t0x39\n");
/** simulator leaves the trace mode */
#define ___traceoff() asm volatile ( "\t.word\t0x3d\n");
/** register dump */
#define ___regview() asm volatile ( "\t.word\t0x37\n");
/** halt the simulator */
#define ___halt() asm volatile ( "\t.word\t0x28\n");
/** simulator enters interactive mode */
#define ___intmode() asm volatile ( "\t.word\t0x29\n");
 
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/mips32/include/barrier.h
0,0 → 1,52
/*
* 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 mips32
* @{
*/
/** @file
*/
 
#ifndef __mips32_BARRIER_H__
#define __mips32_BARRIER_H__
 
/*
* TODO: implement true MIPS memory barriers for macros below.
*/
#define CS_ENTER_BARRIER() __asm__ volatile ("" ::: "memory")
#define CS_LEAVE_BARRIER() __asm__ volatile ("" ::: "memory")
 
#define memory_barrier() __asm__ volatile ("" ::: "memory")
#define read_barrier() __asm__ volatile ("" ::: "memory")
#define write_barrier() __asm__ volatile ("" ::: "memory")
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/mips32/include/proc/task.h
0,0 → 1,48
/*
* 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 mips32proc
* @{
*/
/** @file
*/
 
#ifndef __mips32_TASK_H__
#define __mips32_TASK_H__
 
typedef struct {
} task_arch_t;
 
#define task_create_arch(t)
#define task_destroy_arch(t)
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/mips32/include/proc/thread.h
0,0 → 1,47
/*
* Copyright (C) 2003-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 mips32proc
* @{
*/
/** @file
*/
 
#ifndef __mips32_THREAD_H__
#define __mips32_THREAD_H__
 
typedef struct {
} thread_arch_t;
 
#define thread_create_arch(t)
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/mips32/_link.ld.in
0,0 → 1,60
/*
* MIPS32 linker script
*
* kernel text
* kernel data
*
*/
#undef mips
#define mips mips
 
OUTPUT_ARCH(mips)
 
ENTRY(kernel_image_start)
 
SECTIONS {
. = KERNEL_LOAD_ADDRESS;
.text : {
ktext_start = .;
*(.text);
ktext_end = .;
}
.data : {
kdata_start = .;
*(.data); /* initialized data */
hardcoded_ktext_size = .;
LONG(ktext_end - ktext_start);
hardcoded_kdata_size = .;
LONG(kdata_end - kdata_start);
hardcoded_load_address = .;
LONG(KERNEL_LOAD_ADDRESS);
*(.rodata*);
*(.sdata);
*(.reginfo);
/* Unfortunately IRIX does not allow us
* to include this as a last section :-(
* BSS/SBSS addresses will be wrong */
symbol_table = .;
*(symtab.*);
}
_gp = . + 0x8000;
.lit8 : { *(.lit8) }
.lit4 : { *(.lit4) }
.sbss : {
*(.sbss);
*(.scommon);
}
.bss : {
*(.bss); /* uninitialized static variables */
*(COMMON); /* global variables */
}
 
kdata_end = .;
 
/DISCARD/ : {
*(.mdebug*);
*(.pdr);
*(.comment);
*(.note);
}
}
/tags/0.2.0.3/kernel/arch/ia64/Makefile.inc
0,0 → 1,83
#
# Copyright (C) 2005 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 = elf64-little
BFD_ARCH = ia64-elf64
BFD = elf64-ia64-little
TARGET = ia64-pc-linux-gnu
TOOLCHAIN_DIR = /usr/local/ia64/bin
 
INIT0_ADDRESS = 0xe000000000400000
INIT0_SIZE = 0x100000
 
CFLAGS += -mconstant-gp -fno-unwind-tables -mfixed-range=f32-f127
LFLAGS += -EL
AFLAGS += -mconstant-gp
 
DEFS += -D__64_BITS__ -DINIT0_ADDRESS=$(INIT0_ADDRESS) -DINIT0_SIZE=$(INIT0_SIZE)
 
## Compile with page hash table support.
#
 
CONFIG_PAGE_HT = y
DEFS += -DCONFIG_PAGE_HT
 
## Compile with support for address space identifiers.
#
 
CONFIG_ASID = y
CONFIG_ASID_FIFO = y
 
 
## Compile with support for software integer division.
#
 
CONFIG_SOFTINT = y
 
ARCH_SOURCES = \
arch/$(ARCH)/src/start.S \
arch/$(ARCH)/src/asm.S \
arch/$(ARCH)/src/dummy.s \
arch/$(ARCH)/src/ia64.c \
arch/$(ARCH)/src/fpu_context.c \
arch/$(ARCH)/src/context.S \
arch/$(ARCH)/src/ski/ski.c \
arch/$(ARCH)/src/cpu/cpu.c \
arch/$(ARCH)/src/ivt.S \
arch/$(ARCH)/src/interrupt.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/mm/vhpt.c \
arch/$(ARCH)/src/proc/scheduler.c \
arch/$(ARCH)/src/ddi/ddi.c \
arch/$(ARCH)/src/drivers/it.c
/tags/0.2.0.3/kernel/arch/ia64/include/interrupt.h
0,0 → 1,148
/*
* 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 ia64interrupt
* @{
*/
/** @file
*/
 
#ifndef __ia64_INTERRUPT_H__
#define __ia64_INTERRUPT_H__
 
#include <typedefs.h>
#include <arch/types.h>
#include <arch/register.h>
 
#define IRQ_COUNT 257 /* 256 NOT suppotred IRQS*//* TODO */
#define IRQ_KBD 256 /* One simulated interrupt for ski simulator keyboard*/
 
/** External Interrupt vectors. */
#define INTERRUPT_TIMER 0
#define INTERRUPT_SPURIOUS 15
 
/** General Exception codes. */
#define GE_ILLEGALOP 0
#define GE_PRIVOP 1
#define GE_PRIVREG 2
#define GE_RESREGFLD 3
#define GE_DISBLDISTRAN 4
#define GE_ILLEGALDEP 8
 
#define EOI 0 /**< The actual value doesn't matter. */
 
struct istate {
__r128 f2;
__r128 f3;
__r128 f4;
__r128 f5;
__r128 f6;
__r128 f7;
__r128 f8;
__r128 f9;
__r128 f10;
__r128 f11;
__r128 f12;
__r128 f13;
__r128 f14;
__r128 f15;
__r128 f16;
__r128 f17;
__r128 f18;
__r128 f19;
__r128 f20;
__r128 f21;
__r128 f22;
__r128 f23;
__r128 f24;
__r128 f25;
__r128 f26;
__r128 f27;
__r128 f28;
__r128 f29;
__r128 f30;
__r128 f31;
uintptr_t ar_bsp;
uintptr_t ar_bspstore;
uintptr_t ar_bspstore_new;
uint64_t ar_rnat;
uint64_t ar_ifs;
uint64_t ar_pfs;
uint64_t ar_rsc;
uintptr_t cr_ifa;
cr_isr_t cr_isr;
uintptr_t cr_iipa;
psr_t cr_ipsr;
uintptr_t cr_iip;
uint64_t pr;
uintptr_t sp;
/*
* The following variables are defined only for break_instruction handler.
*/
uint64_t in0;
uint64_t in1;
uint64_t in2;
uint64_t in3;
uint64_t in4;
};
 
static inline void istate_set_retaddr(istate_t *istate, uintptr_t retaddr)
{
istate->cr_iip = retaddr;
istate->cr_ipsr.ri = 0; /* return to instruction slot #0 */
}
 
static inline unative_t istate_get_pc(istate_t *istate)
{
return istate->cr_iip;
}
#include <panic.h>
static inline int istate_from_uspace(istate_t *istate)
{
return (istate->cr_iip)<0xe000000000000000ULL;
}
 
extern void *ivt;
 
extern void general_exception(uint64_t vector, istate_t *istate);
extern int break_instruction(uint64_t vector, istate_t *istate);
extern void universal_handler(uint64_t vector, istate_t *istate);
extern void nop_handler(uint64_t vector, istate_t *istate);
extern void external_interrupt(uint64_t vector, istate_t *istate);
extern void virtual_interrupt(uint64_t irq, void *param);
extern void disabled_fp_register(uint64_t vector, istate_t *istate);
 
 
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/include/byteorder.h
0,0 → 1,46
/*
* 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 ia64
* @{
*/
/** @file
*/
 
#ifndef __ia64_BYTEORDER_H__
#define __ia64_BYTEORDER_H__
 
/* IA-64 is little-endian */
#define unative_t_le2host(n) (n)
#define uint64_t_le2host(n) (n)
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/include/types.h
0,0 → 1,73
/*
* 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 ia64
* @{
*/
/** @file
*/
 
#ifndef __TYPES_H__
#define __TYPES_H__
 
#define NULL 0
 
typedef signed char int8_t;
typedef signed short int int16_t;
typedef signed int int32_t;
typedef signed long int64_t;
 
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long uint64_t;
 
typedef unsigned char __r8; /* Reserve byte */
typedef unsigned short __r16;
typedef unsigned int __r32;
typedef unsigned long __r64;
typedef struct __r128 {
__r64 lo;
__r64 hi;
} __r128;
 
typedef uint64_t uintptr_t;
typedef uint64_t pfn_t;
 
typedef uint64_t ipl_t;
 
typedef uint64_t unative_t;
typedef int64_t native_t;
 
typedef struct pte pte_t;
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/include/memstr.h
0,0 → 1,49
/*
* Copyright (C) 2005 Sergey Bondari
* 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 ia64
* @{
*/
/** @file
*/
 
#ifndef __ia64_MEMSTR_H__
#define __ia64_MEMSTR_H__
 
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt))
 
extern void memsetw(uintptr_t dst, size_t cnt, uint16_t x);
extern void memsetb(uintptr_t dst, size_t cnt, uint8_t x);
 
extern int memcmp(uintptr_t src, uintptr_t dst, int cnt);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/include/faddr.h
0,0 → 1,53
/*
* 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 ia64
* @{
*/
/** @file
*/
 
#ifndef KERN_ia64_FADDR_H_
#define KERN_ia64_FADDR_H_
 
#include <arch/types.h>
 
/**
*
* Calculate absolute address of function
* referenced by fptr pointer.
*
* @param f Function pointer.
*
*/
#define FADDR(f) (*((uintptr_t *)(f)));
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ia64/include/asm.h
0,0 → 1,286
/*
* 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 ia64
* @{
*/
/** @file
*/
 
#ifndef __ia64_ASM_H__
#define __ia64_ASM_H__
 
#include <config.h>
#include <arch/types.h>
#include <arch/register.h>
 
/** Return base address of current stack
*
* Return the base address of the current stack.
* The stack is assumed to be STACK_SIZE long.
* The stack must start on page boundary.
*/
static inline uintptr_t get_stack_base(void)
{
uint64_t v;
 
__asm__ volatile ("and %0 = %1, r12" : "=r" (v) : "r" (~(STACK_SIZE-1)));
return v;
}
 
/** Return Processor State Register.
*
* @return PSR.
*/
static inline uint64_t psr_read(void)
{
uint64_t v;
__asm__ volatile ("mov %0 = psr\n" : "=r" (v));
return v;
}
 
/** Read IVA (Interruption Vector Address).
*
* @return Return location of interruption vector table.
*/
static inline uint64_t iva_read(void)
{
uint64_t v;
__asm__ volatile ("mov %0 = cr.iva\n" : "=r" (v));
return v;
}
 
/** Write IVA (Interruption Vector Address) register.
*
* @param v New location of interruption vector table.
*/
static inline void iva_write(uint64_t v)
{
__asm__ volatile ("mov cr.iva = %0\n" : : "r" (v));
}
 
 
/** Read IVR (External Interrupt Vector Register).
*
* @return Highest priority, pending, unmasked external interrupt vector.
*/
static inline uint64_t ivr_read(void)
{
uint64_t v;
__asm__ volatile ("mov %0 = cr.ivr\n" : "=r" (v));
return v;
}
 
/** Write ITC (Interval Timer Counter) register.
*
* @param v New counter value.
*/
static inline void itc_write(uint64_t v)
{
__asm__ volatile ("mov ar.itc = %0\n" : : "r" (v));
}
 
/** Read ITC (Interval Timer Counter) register.
*
* @return Current counter value.
*/
static inline uint64_t itc_read(void)
{
uint64_t v;
__asm__ volatile ("mov %0 = ar.itc\n" : "=r" (v));
return v;
}
 
/** Write ITM (Interval Timer Match) register.
*
* @param v New match value.
*/
static inline void itm_write(uint64_t v)
{
__asm__ volatile ("mov cr.itm = %0\n" : : "r" (v));
}
 
/** Read ITM (Interval Timer Match) register.
*
* @return Match value.
*/
static inline uint64_t itm_read(void)
{
uint64_t v;
__asm__ volatile ("mov %0 = cr.itm\n" : "=r" (v));
return v;
}
 
/** Read ITV (Interval Timer Vector) register.
*
* @return Current vector and mask bit.
*/
static inline uint64_t itv_read(void)
{
uint64_t v;
__asm__ volatile ("mov %0 = cr.itv\n" : "=r" (v));
return v;
}
 
/** Write ITV (Interval Timer Vector) register.
*
* @param v New vector and mask bit.
*/
static inline void itv_write(uint64_t v)
{
__asm__ volatile ("mov cr.itv = %0\n" : : "r" (v));
}
 
/** Write EOI (End Of Interrupt) register.
*
* @param v This value is ignored.
*/
static inline void eoi_write(uint64_t v)
{
__asm__ volatile ("mov cr.eoi = %0\n" : : "r" (v));
}
 
/** Read TPR (Task Priority Register).
*
* @return Current value of TPR.
*/
static inline uint64_t tpr_read(void)
{
uint64_t v;
 
__asm__ volatile ("mov %0 = cr.tpr\n" : "=r" (v));
return v;
}
 
/** Write TPR (Task Priority Register).
*
* @param v New value of TPR.
*/
static inline void tpr_write(uint64_t v)
{
__asm__ volatile ("mov cr.tpr = %0\n" : : "r" (v));
}
 
/** Disable interrupts.
*
* Disable interrupts and return previous
* value of PSR.
*
* @return Old interrupt priority level.
*/
static ipl_t interrupts_disable(void)
{
uint64_t v;
__asm__ volatile (
"mov %0 = psr\n"
"rsm %1\n"
: "=r" (v)
: "i" (PSR_I_MASK)
);
return (ipl_t) v;
}
 
/** Enable interrupts.
*
* Enable interrupts and return previous
* value of PSR.
*
* @return Old interrupt priority level.
*/
static ipl_t interrupts_enable(void)
{
uint64_t v;
__asm__ volatile (
"mov %0 = psr\n"
"ssm %1\n"
";;\n"
"srlz.d\n"
: "=r" (v)
: "i" (PSR_I_MASK)
);
return (ipl_t) v;
}
 
/** Restore interrupt priority level.
*
* Restore PSR.
*
* @param ipl Saved interrupt priority level.
*/
static inline void interrupts_restore(ipl_t ipl)
{
if (ipl & PSR_I_MASK)
(void) interrupts_enable();
else
(void) interrupts_disable();
}
 
/** Return interrupt priority level.
*
* @return PSR.
*/
static inline ipl_t interrupts_read(void)
{
return (ipl_t) psr_read();
}
 
/** Disable protection key checking. */
static inline void pk_disable(void)
{
__asm__ volatile ("rsm %0\n" : : "i" (PSR_PK_MASK));
}
 
extern void cpu_halt(void);
extern void cpu_sleep(void);
extern void asm_delay_loop(uint32_t t);
 
extern void switch_to_userspace(uintptr_t entry, uintptr_t sp, uintptr_t bsp, uintptr_t uspace_uarg, uint64_t ipsr, uint64_t rsc);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/include/mm/page.h
0,0 → 1,283
/*
* Copyright (C) 2005 - 2006 Jakub Jermar
* Copyright (C) 2006 Jakub Vana
* 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 ia64mm
* @{
*/
/** @file
*/
 
#ifndef __ia64_PAGE_H__
#define __ia64_PAGE_H__
 
#include <arch/mm/frame.h>
 
#define PAGE_SIZE FRAME_SIZE
#define PAGE_WIDTH FRAME_WIDTH
 
 
#ifdef KERNEL
 
/** Bit width of the TLB-locked portion of kernel address space. */
#define KERNEL_PAGE_WIDTH 28 /* 256M */
 
#define PPN_SHIFT 12
 
#define VRN_SHIFT 61
#define VRN_MASK (7LL << VRN_SHIFT)
#define VA2VRN(va) ((va)>>VRN_SHIFT)
 
#ifdef __ASM__
#define VRN_KERNEL 7
#else
#define VRN_KERNEL 7LL
#endif
 
#define REGION_REGISTERS 8
 
#define KA2PA(x) ((uintptr_t) (x-(VRN_KERNEL<<VRN_SHIFT)))
#define PA2KA(x) ((uintptr_t) (x+(VRN_KERNEL<<VRN_SHIFT)))
 
#define VHPT_WIDTH 20 /* 1M */
#define VHPT_SIZE (1 << VHPT_WIDTH)
 
#define PTA_BASE_SHIFT 15
 
/** Memory Attributes. */
#define MA_WRITEBACK 0x0
#define MA_UNCACHEABLE 0x4
 
/** Privilege Levels. Only the most and the least privileged ones are ever used. */
#define PL_KERNEL 0x0
#define PL_USER 0x3
 
/* Access Rigths. Only certain combinations are used by the kernel. */
#define AR_READ 0x0
#define AR_EXECUTE 0x1
#define AR_WRITE 0x2
 
#ifndef __ASM__
 
#include <arch/mm/frame.h>
#include <arch/barrier.h>
#include <genarch/mm/page_ht.h>
#include <arch/mm/asid.h>
#include <arch/types.h>
#include <typedefs.h>
#include <debug.h>
 
struct vhpt_tag_info {
unsigned long long tag : 63;
unsigned ti : 1;
} __attribute__ ((packed));
 
union vhpt_tag {
struct vhpt_tag_info tag_info;
unsigned tag_word;
};
 
struct vhpt_entry_present {
/* Word 0 */
unsigned p : 1;
unsigned : 1;
unsigned ma : 3;
unsigned a : 1;
unsigned d : 1;
unsigned pl : 2;
unsigned ar : 3;
unsigned long long ppn : 38;
unsigned : 2;
unsigned ed : 1;
unsigned ig1 : 11;
/* Word 1 */
unsigned : 2;
unsigned ps : 6;
unsigned key : 24;
unsigned : 32;
/* Word 2 */
union vhpt_tag tag;
/* Word 3 */
uint64_t ig3 : 64;
} __attribute__ ((packed));
 
struct vhpt_entry_not_present {
/* Word 0 */
unsigned p : 1;
unsigned long long ig0 : 52;
unsigned ig1 : 11;
/* Word 1 */
unsigned : 2;
unsigned ps : 6;
unsigned long long ig2 : 56;
 
/* Word 2 */
union vhpt_tag tag;
/* Word 3 */
uint64_t ig3 : 64;
} __attribute__ ((packed));
 
typedef union vhpt_entry {
struct vhpt_entry_present present;
struct vhpt_entry_not_present not_present;
uint64_t word[4];
} vhpt_entry_t;
 
struct region_register_map {
unsigned ve : 1;
unsigned : 1;
unsigned ps : 6;
unsigned rid : 24;
unsigned : 32;
} __attribute__ ((packed));
 
typedef union region_register {
struct region_register_map map;
unsigned long long word;
} region_register;
 
struct pta_register_map {
unsigned ve : 1;
unsigned : 1;
unsigned size : 6;
unsigned vf : 1;
unsigned : 6;
unsigned long long base : 49;
} __attribute__ ((packed));
 
typedef union pta_register {
struct pta_register_map map;
uint64_t word;
} pta_register;
 
/** Return Translation Hashed Entry Address.
*
* VRN bits are used to read RID (ASID) from one
* of the eight region registers registers.
*
* @param va Virtual address including VRN bits.
*
* @return Address of the head of VHPT collision chain.
*/
static inline uint64_t thash(uint64_t va)
{
uint64_t ret;
 
__asm__ volatile ("thash %0 = %1\n" : "=r" (ret) : "r" (va));
 
return ret;
}
 
/** Return Translation Hashed Entry Tag.
*
* VRN bits are used to read RID (ASID) from one
* of the eight region registers.
*
* @param va Virtual address including VRN bits.
*
* @return The unique tag for VPN and RID in the collision chain returned by thash().
*/
static inline uint64_t ttag(uint64_t va)
{
uint64_t ret;
 
__asm__ volatile ("ttag %0 = %1\n" : "=r" (ret) : "r" (va));
 
return ret;
}
 
/** Read Region Register.
*
* @param i Region register index.
*
* @return Current contents of rr[i].
*/
static inline uint64_t rr_read(index_t i)
{
uint64_t ret;
ASSERT(i < REGION_REGISTERS);
__asm__ volatile ("mov %0 = rr[%1]\n" : "=r" (ret) : "r" (i << VRN_SHIFT));
return ret;
}
 
/** Write Region Register.
*
* @param i Region register index.
* @param v Value to be written to rr[i].
*/
static inline void rr_write(index_t i, uint64_t v)
{
ASSERT(i < REGION_REGISTERS);
__asm__ volatile (
"mov rr[%0] = %1\n"
:
: "r" (i << VRN_SHIFT), "r" (v)
);
}
/** Read Page Table Register.
*
* @return Current value stored in PTA.
*/
static inline uint64_t pta_read(void)
{
uint64_t ret;
__asm__ volatile ("mov %0 = cr.pta\n" : "=r" (ret));
return ret;
}
 
/** Write Page Table Register.
*
* @param v New value to be stored in PTA.
*/
static inline void pta_write(uint64_t v)
{
__asm__ volatile ("mov cr.pta = %0\n" : : "r" (v));
}
 
extern void page_arch_init(void);
 
extern vhpt_entry_t *vhpt_hash(uintptr_t page, asid_t asid);
extern bool vhpt_compare(uintptr_t page, asid_t asid, vhpt_entry_t *v);
extern void vhpt_set_record(vhpt_entry_t *v, uintptr_t page, asid_t asid, uintptr_t frame, int flags);
 
#endif /* __ASM__ */
 
#endif /* KERNEL */
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ia64/include/mm/asid.h
0,0 → 1,67
/*
* 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 ia64mm
* @{
*/
/** @file
*/
 
#ifndef __ia64_ASID_H__
#define __ia64_ASID_H__
 
#ifndef __ASM__
 
#include <arch/types.h>
 
typedef uint16_t asid_t;
typedef uint32_t rid_t;
 
#endif /* __ASM__ */
 
/**
* Number of ia64 RIDs (Region Identifiers) per kernel ASID.
* Note that some architectures may support more bits,
* but those extra bits are not used by the kernel.
*/
#define RIDS_PER_ASID 7
 
#define RID_MAX 262143 /* 2^18 - 1 */
#define RID_KERNEL 0
#define RID_INVALID 1
 
#define ASID2RID(asid, vrn) (((asid)>RIDS_PER_ASID)?(((asid)*RIDS_PER_ASID)+(vrn)):(asid))
#define RID2ASID(rid) ((rid)/RIDS_PER_ASID)
 
#define ASID_MAX_ARCH (RID_MAX/RIDS_PER_ASID)
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/include/mm/tlb.h
0,0 → 1,105
/*
* 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 ia64mm
* @{
*/
/** @file
*/
 
#ifndef __ia64_TLB_H__
#define __ia64_TLB_H__
 
#define tlb_arch_init()
#define tlb_print()
 
#include <arch/mm/page.h>
#include <arch/mm/asid.h>
#include <arch/interrupt.h>
#include <arch/types.h>
#include <typedefs.h>
 
/** Data and instruction Translation Register indices. */
#define DTR_KERNEL 0
#define ITR_KERNEL 0
#define DTR_KSTACK1 1
#define DTR_KSTACK2 2
 
/** Portion of TLB insertion format data structure. */
union tlb_entry {
uint64_t word[2];
struct {
/* Word 0 */
unsigned p : 1; /**< Present. */
unsigned : 1;
unsigned ma : 3; /**< Memory attribute. */
unsigned a : 1; /**< Accessed. */
unsigned d : 1; /**< Dirty. */
unsigned pl : 2; /**< Privilege level. */
unsigned ar : 3; /**< Access rights. */
unsigned long long ppn : 38; /**< Physical Page Number, a.k.a. PFN. */
unsigned : 2;
unsigned ed : 1;
unsigned ig1 : 11;
 
/* Word 1 */
unsigned : 2;
unsigned ps : 6; /**< Page size will be 2^ps. */
unsigned key : 24; /**< Protection key, unused. */
unsigned : 32;
} __attribute__ ((packed));
} __attribute__ ((packed));
typedef union tlb_entry tlb_entry_t;
 
extern void tc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtc);
extern void dtc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry);
extern void itc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry);
 
extern void tr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtr, index_t tr);
extern void dtr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, index_t tr);
extern void itr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, index_t tr);
 
extern void dtlb_kernel_mapping_insert(uintptr_t page, uintptr_t frame, bool dtr, index_t tr);
extern void dtr_purge(uintptr_t page, count_t width);
 
extern void dtc_pte_copy(pte_t *t);
extern void itc_pte_copy(pte_t *t);
 
extern void alternate_instruction_tlb_fault(uint64_t vector, istate_t *istate);
extern void alternate_data_tlb_fault(uint64_t vector, istate_t *istate);
extern void data_nested_tlb_fault(uint64_t vector, istate_t *istate);
extern void data_dirty_bit_fault(uint64_t vector, istate_t *istate);
extern void instruction_access_bit_fault(uint64_t vector, istate_t *istate);
extern void data_access_bit_fault(uint64_t vector, istate_t *istate);
extern void page_not_present(uint64_t vector, istate_t *istate);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/include/mm/vhpt.h
0,0 → 1,64
/*
* Copyright (C) 2006 Jakub Vana
* 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 ia64mm
* @{
*/
/** @file
*/
 
#ifndef __ia64_VHPT_H__
#define __ia64_VHPT_H__
 
#include <arch/mm/tlb.h>
#include <arch/mm/page.h>
 
uintptr_t vhpt_set_up(void);
 
static inline vhpt_entry_t tlb_entry_t2vhpt_entry_t(tlb_entry_t tentry)
{
vhpt_entry_t ventry;
ventry.word[0]=tentry.word[0];
ventry.word[1]=tentry.word[1];
return ventry;
}
 
void vhpt_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry);
void vhpt_invalidate_all(void);
void vhpt_invalidate_asid(asid_t asid);
 
 
#endif
 
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/include/mm/frame.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 ia64mm
* @{
*/
/** @file
*/
 
#ifndef __ia64_FRAME_H__
#define __ia64_FRAME_H__
 
#define FRAME_WIDTH 14 /* 16K */
#define FRAME_SIZE (1<<FRAME_WIDTH)
 
#ifdef KERNEL
#ifndef __ASM__
 
extern void frame_arch_init(void);
 
#define ARCH_STACK_FRAMES TWO_FRAMES
 
#endif /* __ASM__ */
#endif /* KERNEL */
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/include/mm/memory_init.h
0,0 → 1,46
/*
* 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 ia64mm
* @{
*/
/** @file
*/
 
#ifndef __ia64_MEMORY_INIT_H__
#define __ia64_MEMORY_INIT_H__
 
#include <config.h>
 
#define get_memory_size() (512*1024*1024) /* 512M */
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/include/mm/as.h
0,0 → 1,53
/*
* 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 ia64mm
* @{
*/
/** @file
*/
 
#ifndef __ia64_AS_H__
#define __ia64_AS_H__
 
#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH 0
 
#define KERNEL_ADDRESS_SPACE_START_ARCH (unsigned long) 0xe000000000000000ULL
#define KERNEL_ADDRESS_SPACE_END_ARCH (unsigned long) 0xffffffffffffffffULL
#define USER_ADDRESS_SPACE_START_ARCH (unsigned long) 0x0000000000000000ULL
#define USER_ADDRESS_SPACE_END_ARCH (unsigned long) 0xdfffffffffffffffULL
 
#define USTACK_ADDRESS_ARCH 0x0000000ff0000000ULL
 
extern void as_arch_init(void);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/include/context.h
0,0 → 1,137
/*
* 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 ia64
* @{
*/
/** @file
*/
 
#ifndef __ia64_CONTEXT_H__
#define __ia64_CONTEXT_H__
 
#include <arch/types.h>
#include <arch/register.h>
#include <typedefs.h>
#include <align.h>
#include <arch/stack.h>
 
/*
* context_save_arch() and context_restore_arch() are both leaf procedures.
* No need to allocate scratch area.
*
* One item is put onto the stack to support get_stack_base().
*/
#define SP_DELTA (0+ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
 
#ifdef context_set
#undef context_set
#endif
 
/* RSE stack starts at the bottom of memory stack. */
#define context_set(c, _pc, stack, size) \
do { \
(c)->pc = (uintptr_t) _pc; \
(c)->bsp = ((uintptr_t) stack) + ALIGN_UP((size), REGISTER_STACK_ALIGNMENT); \
(c)->ar_pfs &= PFM_MASK; \
(c)->sp = ((uintptr_t) stack) + ALIGN_UP((size), STACK_ALIGNMENT) - SP_DELTA; \
} while (0);
 
/*
* Only save registers that must be preserved across
* function calls.
*/
struct context {
 
/*
* Application registers
*/
uint64_t ar_pfs;
uint64_t ar_unat_caller;
uint64_t ar_unat_callee;
uint64_t ar_rsc;
uintptr_t bsp; /* ar_bsp */
uint64_t ar_rnat;
uint64_t ar_lc;
 
/*
* General registers
*/
uint64_t r1;
uint64_t r4;
uint64_t r5;
uint64_t r6;
uint64_t r7;
uintptr_t sp; /* r12 */
uint64_t r13;
/*
* Branch registers
*/
uintptr_t pc; /* b0 */
uint64_t b1;
uint64_t b2;
uint64_t b3;
uint64_t b4;
uint64_t b5;
 
/*
* Predicate registers
*/
uint64_t pr;
 
__r128 f2 __attribute__ ((aligned(16)));
__r128 f3;
__r128 f4;
__r128 f5;
 
__r128 f16;
__r128 f17;
__r128 f18;
__r128 f19;
__r128 f20;
__r128 f21;
__r128 f22;
__r128 f23;
__r128 f24;
__r128 f25;
__r128 f26;
__r128 f27;
__r128 f28;
__r128 f29;
__r128 f30;
__r128 f31;
ipl_t ipl;
};
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/include/register.h
0,0 → 1,279
/*
* 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 ia64
* @{
*/
/** @file
*/
 
#ifndef __ia64_REGISTER_H__
#define __ia64_REGISTER_H__
 
#define CR_IVR_MASK 0xf
#define PSR_IC_MASK 0x2000
#define PSR_I_MASK 0x4000
#define PSR_PK_MASK 0x8000
 
#define PSR_DT_MASK (1<<17)
#define PSR_RT_MASK (1<<27)
 
#define PSR_DFL_MASK (1<<18)
#define PSR_DFH_MASK (1<<19)
 
#define PSR_IT_MASK 0x0000001000000000
 
#define PSR_CPL_SHIFT 32
#define PSR_CPL_MASK_SHIFTED 3
 
#define PFM_MASK (~0x3fffffffff)
 
#define RSC_MODE_MASK 3
#define RSC_PL_MASK 12
 
/** Application registers. */
#define AR_KR0 0
#define AR_KR1 1
#define AR_KR2 2
#define AR_KR3 3
#define AR_KR4 4
#define AR_KR5 5
#define AR_KR6 6
#define AR_KR7 7
/* AR 8-15 reserved */
#define AR_RSC 16
#define AR_BSP 17
#define AR_BSPSTORE 18
#define AR_RNAT 19
/* AR 20 reserved */
#define AR_FCR 21
/* AR 22-23 reserved */
#define AR_EFLAG 24
#define AR_CSD 25
#define AR_SSD 26
#define AR_CFLG 27
#define AR_FSR 28
#define AR_FIR 29
#define AR_FDR 30
/* AR 31 reserved */
#define AR_CCV 32
/* AR 33-35 reserved */
#define AR_UNAT 36
/* AR 37-39 reserved */
#define AR_FPSR 40
/* AR 41-43 reserved */
#define AR_ITC 44
/* AR 45-47 reserved */
/* AR 48-63 ignored */
#define AR_PFS 64
#define AR_LC 65
#define AR_EC 66
/* AR 67-111 reserved */
/* AR 112-127 ignored */
 
/** Control registers. */
#define CR_DCR 0
#define CR_ITM 1
#define CR_IVA 2
/* CR3-CR7 reserved */
#define CR_PTA 8
/* CR9-CR15 reserved */
#define CR_IPSR 16
#define CR_ISR 17
/* CR18 reserved */
#define CR_IIP 19
#define CR_IFA 20
#define CR_ITIR 21
#define CR_IIPA 22
#define CR_IFS 23
#define CR_IIM 24
#define CR_IHA 25
/* CR26-CR63 reserved */
#define CR_LID 64
#define CR_IVR 65
#define CR_TPR 66
#define CR_EOI 67
#define CR_IRR0 68
#define CR_IRR1 69
#define CR_IRR2 70
#define CR_IRR3 71
#define CR_ITV 72
#define CR_PMV 73
#define CR_CMCV 74
/* CR75-CR79 reserved */
#define CR_LRR0 80
#define CR_LRR1 81
/* CR82-CR127 reserved */
 
#ifndef __ASM__
 
#include <arch/types.h>
 
/** Processor Status Register. */
union psr {
uint64_t value;
struct {
unsigned : 1;
unsigned be : 1; /**< Big-Endian data accesses. */
unsigned up : 1; /**< User Performance monitor enable. */
unsigned ac : 1; /**< Alignment Check. */
unsigned mfl : 1; /**< Lower floating-point register written. */
unsigned mfh : 1; /**< Upper floating-point register written. */
unsigned : 7;
unsigned ic : 1; /**< Interruption Collection. */
unsigned i : 1; /**< Interrupt Bit. */
unsigned pk : 1; /**< Protection Key enable. */
unsigned : 1;
unsigned dt : 1; /**< Data address Translation. */
unsigned dfl : 1; /**< Disabled Floating-point Low register set. */
unsigned dfh : 1; /**< Disabled Floating-point High register set. */
unsigned sp : 1; /**< Secure Performance monitors. */
unsigned pp : 1; /**< Privileged Performance monitor enable. */
unsigned di : 1; /**< Disable Instruction set transition. */
unsigned si : 1; /**< Secure Interval timer. */
unsigned db : 1; /**< Debug Breakpoint fault. */
unsigned lp : 1; /**< Lower Privilege transfer trap. */
unsigned tb : 1; /**< Taken Branch trap. */
unsigned rt : 1; /**< Register Stack Translation. */
unsigned : 4;
unsigned cpl : 2; /**< Current Privilege Level. */
unsigned is : 1; /**< Instruction Set. */
unsigned mc : 1; /**< Machine Check abort mask. */
unsigned it : 1; /**< Instruction address Translation. */
unsigned id : 1; /**< Instruction Debug fault disable. */
unsigned da : 1; /**< Disable Data Access and Dirty-bit faults. */
unsigned dd : 1; /**< Data Debug fault disable. */
unsigned ss : 1; /**< Single Step enable. */
unsigned ri : 2; /**< Restart Instruction. */
unsigned ed : 1; /**< Exception Deferral. */
unsigned bn : 1; /**< Register Bank. */
unsigned ia : 1; /**< Disable Instruction Access-bit faults. */
} __attribute__ ((packed));
};
typedef union psr psr_t;
 
/** Register Stack Configuration Register */
union rsc {
uint64_t value;
struct {
unsigned mode : 2;
unsigned pl : 2; /**< Privilege Level. */
unsigned be : 1; /**< Big-endian. */
unsigned : 11;
unsigned loadrs : 14;
} __attribute__ ((packed));
};
typedef union rsc rsc_t;
 
/** External Interrupt Vector Register */
union cr_ivr {
uint8_t vector;
uint64_t value;
};
 
typedef union cr_ivr cr_ivr_t;
 
/** Task Priority Register */
union cr_tpr {
struct {
unsigned : 4;
unsigned mic: 4; /**< Mask Interrupt Class. */
unsigned : 8;
unsigned mmi: 1; /**< Mask Maskable Interrupts. */
} __attribute__ ((packed));
uint64_t value;
};
 
typedef union cr_tpr cr_tpr_t;
 
/** Interval Timer Vector */
union cr_itv {
struct {
unsigned vector : 8;
unsigned : 4;
unsigned : 1;
unsigned : 3;
unsigned m : 1; /**< Mask. */
} __attribute__ ((packed));
uint64_t value;
};
 
typedef union cr_itv cr_itv_t;
 
/** Interruption Status Register */
union cr_isr {
struct {
union {
/** General Exception code field structuring. */
struct {
unsigned ge_na : 4;
unsigned ge_code : 4;
} __attribute__ ((packed));
uint16_t code;
};
uint8_t vector;
unsigned : 8;
unsigned x : 1; /**< Execute exception. */
unsigned w : 1; /**< Write exception. */
unsigned r : 1; /**< Read exception. */
unsigned na : 1; /**< Non-access exception. */
unsigned sp : 1; /**< Speculative load exception. */
unsigned rs : 1; /**< Register stack. */
unsigned ir : 1; /**< Incomplete Register frame. */
unsigned ni : 1; /**< Nested Interruption. */
unsigned so : 1; /**< IA-32 Supervisor Override. */
unsigned ei : 2; /**< Excepting Instruction. */
unsigned ed : 1; /**< Exception Deferral. */
unsigned : 20;
} __attribute__ ((packed));
uint64_t value;
};
 
typedef union cr_isr cr_isr_t;
 
/** CPUID Register 3 */
union cpuid3 {
struct {
uint8_t number;
uint8_t revision;
uint8_t model;
uint8_t family;
uint8_t archrev;
} __attribute__ ((packed));
uint64_t value;
};
 
typedef union cpuid3 cpuid3_t;
 
#endif /* !__ASM__ */
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/include/cpu.h
0,0 → 1,69
/*
* 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 ia64
* @{
*/
/** @file
*/
 
#ifndef __ia64_CPU_H__
#define __ia64_CPU_H__
 
#include <arch/types.h>
#include <typedefs.h>
#include <arch/register.h>
 
#define FAMILY_ITANIUM 0x7
#define FAMILY_ITANIUM2 0x1f
 
struct cpu_arch {
uint64_t cpuid0;
uint64_t cpuid1;
cpuid3_t cpuid3;
};
 
/** Read CPUID register.
*
* @param n CPUID register number.
*
* @return Value of CPUID[n] register.
*/
static inline uint64_t cpuid_read(int n)
{
uint64_t v;
__asm__ volatile ("mov %0 = cpuid[%1]\n" : "=r" (v) : "r" (n));
return v;
}
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ia64/include/fpu_context.h
0,0 → 1,54
/*
* Copyright (C) 2005 Jakub Vana
* 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 ia64
* @{
*/
/** @file
*/
 
#ifndef __ia64_FPU_CONTEXT_H__
#define __ia64_FPU_CONTEXT_H__
 
#define ARCH_HAS_FPU 1
#define FPU_CONTEXT_ALIGN 16
 
#include <arch/types.h>
 
#define FRS 96
 
struct fpu_context {
__r128 fr[FRS];
};
 
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/include/ski/ski.h
0,0 → 1,56
/*
* 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 ia64
* @{
*/
/** @file
*/
 
#ifndef __SKI_H__
#define __SKI_H__
 
#include <arch/types.h>
#include <console/console.h>
 
#define SKI_INIT_CONSOLE 20
#define SKI_GETCHAR 21
#define SKI_PUTCHAR 31
 
extern void ski_init_console(void);
extern void ski_set_console_sysinfo(void);
extern void poll_keyboard(void);
 
extern chardev_t ski_uconsole;
extern int kbd_uspace;
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/include/stack.h
0,0 → 1,47
/*
* 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 ia64
* @{
*/
/** @file
*/
 
#ifndef __ia64_STACK_H__
#define __ia64_STACK_H__
 
#define STACK_ITEM_SIZE 8
#define STACK_ALIGNMENT 16
#define STACK_SCRATCH_AREA_SIZE 16
#define REGISTER_STACK_ALIGNMENT 8
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/include/elf.h
0,0 → 1,46
/*
* Copyright (C) 2006 Sergey Bondari
* 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 ia64
* @{
*/
/** @file
*/
 
#ifndef __ia64_ELF_H__
#define __ia64_ELF_H__
 
#define ELF_MACHINE EM_IA_64
#define ELF_DATA_ENCODING ELFDATA2LSB
#define ELF_CLASS ELFCLASS64
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/include/arg.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 ia64
* @{
*/
/** @file
*/
 
#ifndef __ia64_ARG_H__
#define __ia64_ARG_H__
 
#include <stdarg.h>
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/include/smp/atomic.h
0,0 → 1,4
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/include/atomic.h
0,0 → 1,67
/*
* 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 ia64
* @{
*/
/** @file
*/
 
#ifndef __ia64_ATOMIC_H__
#define __ia64_ATOMIC_H__
 
/** Atomic addition.
*
* @param val Atomic value.
* @param imm Value to add.
*
* @return Value before addition.
*/
static inline long atomic_add(atomic_t *val, int imm)
{
long v;
 
__asm__ volatile ("fetchadd8.rel %0 = %1, %2\n" : "=r" (v), "+m" (val->count) : "i" (imm));
return v;
}
 
static inline void atomic_inc(atomic_t *val) { atomic_add(val, 1); }
static inline void atomic_dec(atomic_t *val) { atomic_add(val, -1); }
 
static inline long atomic_preinc(atomic_t *val) { return atomic_add(val, 1) + 1; }
static inline long atomic_predec(atomic_t *val) { return atomic_add(val, -1) - 1; }
 
static inline long atomic_postinc(atomic_t *val) { return atomic_add(val, 1); }
static inline long atomic_postdec(atomic_t *val) { return atomic_add(val, -1); }
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/include/arch.h
0,0 → 1,46
/*
* Copyright (C) 2005 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 ia64
* @{
*/
/** @file
*/
 
#ifndef __ia64_ARCH_H__
#define __ia64_ARCH_H__
 
#define LOADED_PROG_STACK_PAGES_NO 2
 
#include <arch/ski/ski.h>
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/include/proc/task.h
0,0 → 1,48
/*
* 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 ia64proc
* @{
*/
/** @file
*/
 
#ifndef __ia64_TASK_H__
#define __ia64_TASK_H__
 
typedef struct {
} task_arch_t;
 
#define task_create_arch(t)
#define task_destroy_arch(t)
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/include/proc/thread.h
0,0 → 1,47
/*
* 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 ia64proc
* @{
*/
/** @file
*/
 
#ifndef __ia64_THREAD_H__
#define __ia64_THREAD_H__
 
typedef struct {
} thread_arch_t;
 
#define thread_create_arch(t)
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/include/debug.h
0,0 → 1,43
/*
* Copyright (C) 2005
* 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 ia64debug ia64
* @ingroup debug
* @{
*/
/** @file
*/
 
#ifndef __ia64_DEBUG_H__
#define __ia64_DEBUG_H__
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/include/barrier.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 ia64
* @{
*/
/** @file
*/
 
#ifndef __ia64_BARRIER_H__
#define __ia64_BARRIER_H__
 
/*
* TODO: Implement true IA-64 memory barriers for macros below.
*/
#define CS_ENTER_BARRIER() memory_barrier()
#define CS_LEAVE_BARRIER() memory_barrier()
 
#define memory_barrier() __asm__ volatile ("mf\n" ::: "memory")
#define read_barrier() memory_barrier()
#define write_barrier() memory_barrier()
 
#define srlz_i() __asm__ volatile (";; srlz.i ;;\n" ::: "memory")
#define srlz_d() __asm__ volatile (";; srlz.d\n" ::: "memory")
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/include/pal/pal.h
0,0 → 1,111
/*
* 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 ia64
* @{
*/
/** @file
*/
 
#ifndef __ia64_PAL_H__
#define __ia64_PAL_H__
 
#define PAL_OK 0 /**< Call completed without error. */
#define PAL_UNIMPL -1 /**< Unimplemented procedure. */
#define PAL_INVARG -2 /**< Invalid argument. */
#define PAL_ERR -3 /**< Can not compete call without error. */
 
/** These are the indices for PAL_PROC. */
#define PAL_CACHE_FLUSH 1
#define PAL_CACHE_INFO 2
#define PAL_CACHE_INIT 3
#define PAL_CACHE_PROT_INFO 38
#define PAL_CACHE_SHARED_INFO 43
#define PAL_CACHE_SUMMARY 4
 
#define PAL_MEM_ATTRIB 5
#define PAL_PREFETCH_VISIBILITY 41
#define PAL_PTCE_INFO 6
#define PAL_VM_INFO 7
#define PAL_VM_PAGE_SIZE 34
#define PAL_VM_SUMMARY 8
#define PAL_VM_TR_READ 261
 
#define PAL_BUS_GET_FEATURES 9
#define PAL_BUS_SET_FEATURES 10
#define PAL_DEBUG_INFO 11
#define PAL_FIXED_ADDR 12
#define PAL_FREQ_BASE 13
#define PAL_FREQ_RATIOS 14
#define PAL_LOGICAL_TO_PHYSICAL 42
#define PAL_PERF_MON_INFO 15
#define PAL_PLATFORM_ADDR 16
#define PAL_PROC_GET_FEATURES 17
#define PAL_PROC_SET_FEATURES 18
#define PAL_REGISTER_INFO 39
#define PAL_RSE_INFO 19
#define PAL_VERSION 20
 
#define PAL_MC_CLEAR_LOG 21
#define PAL_MC_DRAIN 22
#define PAL_MC_DYNAMIC_STATE 24
#define PAL_MC_ERROR_INFO 25
#define PAL_MC_EXPECTED 23
#define PAL_MC_REGISTER_MEM 27
#define PAL_MC_RESUME 26
 
#define PAL_HALT 28
#define PAL_HALT_INFO 257
#define PAL_HALT_LIGHT 29
 
#define PAL_CACHE_LINE_INIT 31
#define PAL_CACHE_READ 259
#define PAL_CACHE_WRITE 260
#define PAL_TEST_INFO 37
#define PAL_TEST_PROC 258
 
#define PAL_COPY_INFO 30
#define PAL_COPY_PAL 256
#define PAL_ENTER_IA_32_ENV 33
#define PAL_PMI_ENTRYPOINT 32
 
/*
Ski PTCE data
*/
#define PAL_PTCE_INFO_BASE() (0x100000000LL)
#define PAL_PTCE_INFO_COUNT1() (2)
#define PAL_PTCE_INFO_COUNT2() (3)
#define PAL_PTCE_INFO_STRIDE1() (0x10000000)
#define PAL_PTCE_INFO_STRIDE2() (0x2000)
 
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/include/drivers/it.h
0,0 → 1,53
/*
* 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 ia64
* @{
*/
/** @file
*/
 
#ifndef __ia64_IT_H__
#define __ia64_IT_H__
 
/*
* Unfortunately, Ski does not emulate PAL,
* so we can't read the real frequency ratios
* from firmware.
*
*/
#define IT_DELTA 100000
 
extern void it_init(void);
extern void it_interrupt(void);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/src/fpu_context.c
0,0 → 1,485
/*
* Copyright (C) 2005 Jakub Vana
* 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 ia64
* @{
*/
/** @file
*
*/
 
#include <fpu_context.h>
#include <arch/register.h>
#include <print.h>
 
 
void fpu_context_save(fpu_context_t *fctx){
 
asm volatile(
 
"stf.spill [%0]=f32,0x80\n"
"stf.spill [%1]=f33,0x80\n"
"stf.spill [%2]=f34,0x80\n"
"stf.spill [%3]=f35,0x80\n"
"stf.spill [%4]=f36,0x80\n"
"stf.spill [%5]=f37,0x80\n"
"stf.spill [%6]=f38,0x80\n"
"stf.spill [%7]=f39,0x80\n;;"
 
"stf.spill [%0]=f40,0x80\n"
"stf.spill [%1]=f41,0x80\n"
"stf.spill [%2]=f42,0x80\n"
"stf.spill [%3]=f43,0x80\n"
"stf.spill [%4]=f44,0x80\n"
"stf.spill [%5]=f45,0x80\n"
"stf.spill [%6]=f46,0x80\n"
"stf.spill [%7]=f47,0x80\n;;"
 
"stf.spill [%0]=f48,0x80\n"
"stf.spill [%1]=f49,0x80\n"
"stf.spill [%2]=f50,0x80\n"
"stf.spill [%3]=f51,0x80\n"
"stf.spill [%4]=f52,0x80\n"
"stf.spill [%5]=f53,0x80\n"
"stf.spill [%6]=f54,0x80\n"
"stf.spill [%7]=f55,0x80\n;;"
 
"stf.spill [%0]=f56,0x80\n"
"stf.spill [%1]=f57,0x80\n"
"stf.spill [%2]=f58,0x80\n"
"stf.spill [%3]=f59,0x80\n"
"stf.spill [%4]=f60,0x80\n"
"stf.spill [%5]=f61,0x80\n"
"stf.spill [%6]=f62,0x80\n"
"stf.spill [%7]=f63,0x80\n;;"
 
"stf.spill [%0]=f64,0x80\n"
"stf.spill [%1]=f65,0x80\n"
"stf.spill [%2]=f66,0x80\n"
"stf.spill [%3]=f67,0x80\n"
"stf.spill [%4]=f68,0x80\n"
"stf.spill [%5]=f69,0x80\n"
"stf.spill [%6]=f70,0x80\n"
"stf.spill [%7]=f71,0x80\n;;"
 
"stf.spill [%0]=f72,0x80\n"
"stf.spill [%1]=f73,0x80\n"
"stf.spill [%2]=f74,0x80\n"
"stf.spill [%3]=f75,0x80\n"
"stf.spill [%4]=f76,0x80\n"
"stf.spill [%5]=f77,0x80\n"
"stf.spill [%6]=f78,0x80\n"
"stf.spill [%7]=f79,0x80\n;;"
 
"stf.spill [%0]=f80,0x80\n"
"stf.spill [%1]=f81,0x80\n"
"stf.spill [%2]=f82,0x80\n"
"stf.spill [%3]=f83,0x80\n"
"stf.spill [%4]=f84,0x80\n"
"stf.spill [%5]=f85,0x80\n"
"stf.spill [%6]=f86,0x80\n"
"stf.spill [%7]=f87,0x80\n;;"
 
"stf.spill [%0]=f88,0x80\n"
"stf.spill [%1]=f89,0x80\n"
"stf.spill [%2]=f90,0x80\n"
"stf.spill [%3]=f91,0x80\n"
"stf.spill [%4]=f92,0x80\n"
"stf.spill [%5]=f93,0x80\n"
"stf.spill [%6]=f94,0x80\n"
"stf.spill [%7]=f95,0x80\n;;"
 
 
"stf.spill [%0]=f96,0x80\n"
"stf.spill [%1]=f97,0x80\n"
"stf.spill [%2]=f98,0x80\n"
"stf.spill [%3]=f99,0x80\n"
"stf.spill [%4]=f100,0x80\n"
"stf.spill [%5]=f101,0x80\n"
"stf.spill [%6]=f102,0x80\n"
"stf.spill [%7]=f103,0x80\n;;"
 
"stf.spill [%0]=f104,0x80\n"
"stf.spill [%1]=f105,0x80\n"
"stf.spill [%2]=f106,0x80\n"
"stf.spill [%3]=f107,0x80\n"
"stf.spill [%4]=f108,0x80\n"
"stf.spill [%5]=f109,0x80\n"
"stf.spill [%6]=f110,0x80\n"
"stf.spill [%7]=f111,0x80\n;;"
 
"stf.spill [%0]=f112,0x80\n"
"stf.spill [%1]=f113,0x80\n"
"stf.spill [%2]=f114,0x80\n"
"stf.spill [%3]=f115,0x80\n"
"stf.spill [%4]=f116,0x80\n"
"stf.spill [%5]=f117,0x80\n"
"stf.spill [%6]=f118,0x80\n"
"stf.spill [%7]=f119,0x80\n;;"
 
"stf.spill [%0]=f120,0x80\n"
"stf.spill [%1]=f121,0x80\n"
"stf.spill [%2]=f122,0x80\n"
"stf.spill [%3]=f123,0x80\n"
"stf.spill [%4]=f124,0x80\n"
"stf.spill [%5]=f125,0x80\n"
"stf.spill [%6]=f126,0x80\n"
"stf.spill [%7]=f127,0x80\n;;"
 
 
:
:"r" (&((fctx->fr)[0])),"r" (&((fctx->fr)[1])),"r" (&((fctx->fr)[2])),"r" (&((fctx->fr)[3])),
"r" (&((fctx->fr)[4])),"r" (&((fctx->fr)[5])),"r" (&((fctx->fr)[6])),"r" (&((fctx->fr)[7]))
);
}
 
 
void fpu_context_restore(fpu_context_t *fctx)
{
 
asm volatile(
"ldf.fill f32=[%0],0x80\n"
"ldf.fill f33=[%1],0x80\n"
"ldf.fill f34=[%2],0x80\n"
"ldf.fill f35=[%3],0x80\n"
"ldf.fill f36=[%4],0x80\n"
"ldf.fill f37=[%5],0x80\n"
"ldf.fill f38=[%6],0x80\n"
"ldf.fill f39=[%7],0x80\n;;"
 
"ldf.fill f40=[%0],0x80\n"
"ldf.fill f41=[%1],0x80\n"
"ldf.fill f42=[%2],0x80\n"
"ldf.fill f43=[%3],0x80\n"
"ldf.fill f44=[%4],0x80\n"
"ldf.fill f45=[%5],0x80\n"
"ldf.fill f46=[%6],0x80\n"
"ldf.fill f47=[%7],0x80\n;;"
 
"ldf.fill f48=[%0],0x80\n"
"ldf.fill f49=[%1],0x80\n"
"ldf.fill f50=[%2],0x80\n"
"ldf.fill f51=[%3],0x80\n"
"ldf.fill f52=[%4],0x80\n"
"ldf.fill f53=[%5],0x80\n"
"ldf.fill f54=[%6],0x80\n"
"ldf.fill f55=[%7],0x80\n;;"
 
"ldf.fill f56=[%0],0x80\n"
"ldf.fill f57=[%1],0x80\n"
"ldf.fill f58=[%2],0x80\n"
"ldf.fill f59=[%3],0x80\n"
"ldf.fill f60=[%4],0x80\n"
"ldf.fill f61=[%5],0x80\n"
"ldf.fill f62=[%6],0x80\n"
"ldf.fill f63=[%7],0x80\n;;"
 
"ldf.fill f64=[%0],0x80\n"
"ldf.fill f65=[%1],0x80\n"
"ldf.fill f66=[%2],0x80\n"
"ldf.fill f67=[%3],0x80\n"
"ldf.fill f68=[%4],0x80\n"
"ldf.fill f69=[%5],0x80\n"
"ldf.fill f70=[%6],0x80\n"
"ldf.fill f71=[%7],0x80\n;;"
 
"ldf.fill f72=[%0],0x80\n"
"ldf.fill f73=[%1],0x80\n"
"ldf.fill f74=[%2],0x80\n"
"ldf.fill f75=[%3],0x80\n"
"ldf.fill f76=[%4],0x80\n"
"ldf.fill f77=[%5],0x80\n"
"ldf.fill f78=[%6],0x80\n"
"ldf.fill f79=[%7],0x80\n;;"
 
"ldf.fill f80=[%0],0x80\n"
"ldf.fill f81=[%1],0x80\n"
"ldf.fill f82=[%2],0x80\n"
"ldf.fill f83=[%3],0x80\n"
"ldf.fill f84=[%4],0x80\n"
"ldf.fill f85=[%5],0x80\n"
"ldf.fill f86=[%6],0x80\n"
"ldf.fill f87=[%7],0x80\n;;"
 
"ldf.fill f88=[%0],0x80\n"
"ldf.fill f89=[%1],0x80\n"
"ldf.fill f90=[%2],0x80\n"
"ldf.fill f91=[%3],0x80\n"
"ldf.fill f92=[%4],0x80\n"
"ldf.fill f93=[%5],0x80\n"
"ldf.fill f94=[%6],0x80\n"
"ldf.fill f95=[%7],0x80\n;;"
 
 
"ldf.fill f96=[%0],0x80\n"
"ldf.fill f97=[%1],0x80\n"
"ldf.fill f98=[%2],0x80\n"
"ldf.fill f99=[%3],0x80\n"
"ldf.fill f100=[%4],0x80\n"
"ldf.fill f101=[%5],0x80\n"
"ldf.fill f102=[%6],0x80\n"
"ldf.fill f103=[%7],0x80\n;;"
 
"ldf.fill f104=[%0],0x80\n"
"ldf.fill f105=[%1],0x80\n"
"ldf.fill f106=[%2],0x80\n"
"ldf.fill f107=[%3],0x80\n"
"ldf.fill f108=[%4],0x80\n"
"ldf.fill f109=[%5],0x80\n"
"ldf.fill f110=[%6],0x80\n"
"ldf.fill f111=[%7],0x80\n;;"
 
"ldf.fill f112=[%0],0x80\n"
"ldf.fill f113=[%1],0x80\n"
"ldf.fill f114=[%2],0x80\n"
"ldf.fill f115=[%3],0x80\n"
"ldf.fill f116=[%4],0x80\n"
"ldf.fill f117=[%5],0x80\n"
"ldf.fill f118=[%6],0x80\n"
"ldf.fill f119=[%7],0x80\n;;"
 
"ldf.fill f120=[%0],0x80\n"
"ldf.fill f121=[%1],0x80\n"
"ldf.fill f122=[%2],0x80\n"
"ldf.fill f123=[%3],0x80\n"
"ldf.fill f124=[%4],0x80\n"
"ldf.fill f125=[%5],0x80\n"
"ldf.fill f126=[%6],0x80\n"
"ldf.fill f127=[%7],0x80\n;;"
 
 
:
:"r" (&((fctx->fr)[0])),"r" (&((fctx->fr)[1])),"r" (&((fctx->fr)[2])),"r" (&((fctx->fr)[3])),
"r" (&((fctx->fr)[4])),"r" (&((fctx->fr)[5])),"r" (&((fctx->fr)[6])),"r" (&((fctx->fr)[7]))
);
}
 
void fpu_enable(void)
{
uint64_t a = 0 ;
asm volatile(
"rsm %0;;"
"srlz.i\n"
"srlz.d;;\n"
:
:"i" (PSR_DFH_MASK)
);
asm volatile
(
"mov %0=ar.fpsr;;\n"
"or %0=%0,%1;;\n"
"mov ar.fpsr=%0;;\n"
: "+r" (a)
: "r" (0x38)
);
 
}
 
void fpu_disable(void)
{
 
uint64_t a = 0 ;
asm volatile(
"ssm %0;;\n"
"srlz.i\n"
"srlz.d;;\n"
:
:"i" (PSR_DFH_MASK)
);
asm volatile
(
"mov %0=ar.fpsr;;\n"
"or %0=%0,%1;;\n"
"mov ar.fpsr=%0;;\n"
: "+r" (a)
: "r" (0x38)
);
 
}
 
void fpu_init(void)
{
uint64_t a = 0 ;
asm volatile
(
"mov %0=ar.fpsr;;\n"
"or %0=%0,%1;;\n"
"mov ar.fpsr=%0;;\n"
: "+r" (a)
: "r" (0x38)
);
 
asm volatile(
"mov f2=f0\n"
"mov f3=f0\n"
"mov f4=f0\n"
"mov f5=f0\n"
"mov f6=f0\n"
"mov f7=f0\n"
"mov f8=f0\n"
"mov f9=f0\n"
 
"mov f10=f0\n"
"mov f11=f0\n"
"mov f12=f0\n"
"mov f13=f0\n"
"mov f14=f0\n"
"mov f15=f0\n"
"mov f16=f0\n"
"mov f17=f0\n"
"mov f18=f0\n"
"mov f19=f0\n"
 
"mov f20=f0\n"
"mov f21=f0\n"
"mov f22=f0\n"
"mov f23=f0\n"
"mov f24=f0\n"
"mov f25=f0\n"
"mov f26=f0\n"
"mov f27=f0\n"
"mov f28=f0\n"
"mov f29=f0\n"
 
"mov f30=f0\n"
"mov f31=f0\n"
"mov f32=f0\n"
"mov f33=f0\n"
"mov f34=f0\n"
"mov f35=f0\n"
"mov f36=f0\n"
"mov f37=f0\n"
"mov f38=f0\n"
"mov f39=f0\n"
 
"mov f40=f0\n"
"mov f41=f0\n"
"mov f42=f0\n"
"mov f43=f0\n"
"mov f44=f0\n"
"mov f45=f0\n"
"mov f46=f0\n"
"mov f47=f0\n"
"mov f48=f0\n"
"mov f49=f0\n"
 
"mov f50=f0\n"
"mov f51=f0\n"
"mov f52=f0\n"
"mov f53=f0\n"
"mov f54=f0\n"
"mov f55=f0\n"
"mov f56=f0\n"
"mov f57=f0\n"
"mov f58=f0\n"
"mov f59=f0\n"
 
"mov f60=f0\n"
"mov f61=f0\n"
"mov f62=f0\n"
"mov f63=f0\n"
"mov f64=f0\n"
"mov f65=f0\n"
"mov f66=f0\n"
"mov f67=f0\n"
"mov f68=f0\n"
"mov f69=f0\n"
 
"mov f70=f0\n"
"mov f71=f0\n"
"mov f72=f0\n"
"mov f73=f0\n"
"mov f74=f0\n"
"mov f75=f0\n"
"mov f76=f0\n"
"mov f77=f0\n"
"mov f78=f0\n"
"mov f79=f0\n"
 
"mov f80=f0\n"
"mov f81=f0\n"
"mov f82=f0\n"
"mov f83=f0\n"
"mov f84=f0\n"
"mov f85=f0\n"
"mov f86=f0\n"
"mov f87=f0\n"
"mov f88=f0\n"
"mov f89=f0\n"
 
"mov f90=f0\n"
"mov f91=f0\n"
"mov f92=f0\n"
"mov f93=f0\n"
"mov f94=f0\n"
"mov f95=f0\n"
"mov f96=f0\n"
"mov f97=f0\n"
"mov f98=f0\n"
"mov f99=f0\n"
 
"mov f100=f0\n"
"mov f101=f0\n"
"mov f102=f0\n"
"mov f103=f0\n"
"mov f104=f0\n"
"mov f105=f0\n"
"mov f106=f0\n"
"mov f107=f0\n"
"mov f108=f0\n"
"mov f109=f0\n"
 
"mov f110=f0\n"
"mov f111=f0\n"
"mov f112=f0\n"
"mov f113=f0\n"
"mov f114=f0\n"
"mov f115=f0\n"
"mov f116=f0\n"
"mov f117=f0\n"
"mov f118=f0\n"
"mov f119=f0\n"
 
"mov f120=f0\n"
"mov f121=f0\n"
"mov f122=f0\n"
"mov f123=f0\n"
"mov f124=f0\n"
"mov f125=f0\n"
"mov f126=f0\n"
"mov f127=f0\n"
 
);
 
}
 
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/src/ddi/ddi.c
0,0 → 1,56
/*
* 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 ia64ddi
* @{
*/
/** @file
*/
 
#include <ddi/ddi.h>
#include <proc/task.h>
#include <arch/types.h>
#include <typedefs.h>
 
/** Enable I/O space range for task.
*
* Interrupts are disabled and task is locked.
*
* @param task Task.
* @param ioaddr Startign I/O space address.
* @param size Size of the enabled I/O range.
*
* @return 0 on success or an error code from errno.h.
*/
int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
{
return 0;
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ia64/src/proc/scheduler.c
0,0 → 1,93
/*
* 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 ia64proc
* @{
*/
/** @file
*/
 
#include <proc/scheduler.h>
#include <proc/thread.h>
#include <arch.h>
#include <arch/register.h>
#include <arch/context.h>
#include <arch/stack.h>
#include <arch/mm/tlb.h>
#include <config.h>
#include <align.h>
 
/** Perform ia64 specific tasks needed before the new task is run. */
void before_task_runs_arch(void)
{
}
 
/** Prepare kernel stack pointers in bank 0 r22 and r23 and make sure the stack is mapped in DTR. */
void before_thread_runs_arch(void)
{
uintptr_t base;
base = ALIGN_DOWN(config.base, 1<<KERNEL_PAGE_WIDTH);
 
if ((uintptr_t) THREAD->kstack < base || (uintptr_t) THREAD->kstack > base + (1<<(KERNEL_PAGE_WIDTH))) {
/*
* Kernel stack of this thread is not mapped by DTR[TR_KERNEL].
* Use DTR[TR_KSTACK1] and DTR[TR_KSTACK2] to map it.
*/
/* purge DTR[TR_STACK1] and DTR[TR_STACK2] */
dtr_purge((uintptr_t) THREAD->kstack, PAGE_WIDTH+1);
/* insert DTR[TR_STACK1] and DTR[TR_STACK2] */
dtlb_kernel_mapping_insert((uintptr_t) THREAD->kstack, KA2PA(THREAD->kstack), true, DTR_KSTACK1);
dtlb_kernel_mapping_insert((uintptr_t) THREAD->kstack + PAGE_SIZE, KA2PA(THREAD->kstack) + FRAME_SIZE, true, DTR_KSTACK2);
}
/*
* Record address of kernel backing store to bank 0 r22.
* Record address of kernel stack to bank 0 r23.
* These values will be found there after switch from userspace.
*/
__asm__ volatile (
"bsw.0\n"
"mov r22 = %0\n"
"mov r23 = %1\n"
"bsw.1\n"
:
: "r" (&THREAD->kstack[THREAD_STACK_SIZE]),
"r" (&THREAD->kstack[THREAD_STACK_SIZE - SP_DELTA])
);
}
 
void after_thread_ran_arch(void)
{
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/src/ia64.c
0,0 → 1,157
/*
* 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 ia64
* @{
*/
/** @file
*/
 
#include <arch.h>
#include <arch/ski/ski.h>
#include <arch/drivers/it.h>
#include <arch/interrupt.h>
#include <arch/barrier.h>
#include <arch/asm.h>
#include <arch/register.h>
#include <arch/types.h>
#include <arch/context.h>
#include <arch/stack.h>
#include <arch/mm/page.h>
#include <mm/as.h>
#include <config.h>
#include <userspace.h>
#include <console/console.h>
#include <proc/uarg.h>
#include <syscall/syscall.h>
 
static int kbd_release=0;
 
void arch_pre_main(void)
{
/* Setup usermode init tasks. */
init.cnt = 8;
init.tasks[0].addr = INIT0_ADDRESS;
init.tasks[0].size = INIT0_SIZE;
init.tasks[1].addr = INIT0_ADDRESS + 0x400000;
init.tasks[1].size = INIT0_SIZE;
init.tasks[2].addr = INIT0_ADDRESS + 0x800000;
init.tasks[2].size = INIT0_SIZE;
init.tasks[3].addr = INIT0_ADDRESS + 0xc00000;
init.tasks[3].size = INIT0_SIZE;
init.tasks[4].addr = INIT0_ADDRESS + 0x1000000;
init.tasks[4].size = INIT0_SIZE;
init.tasks[5].addr = INIT0_ADDRESS + 0x1400000;
init.tasks[5].size = INIT0_SIZE;
init.tasks[6].addr = INIT0_ADDRESS + 0x1800000;
init.tasks[6].size = INIT0_SIZE;
init.tasks[7].addr = INIT0_ADDRESS + 0x1c00000;
init.tasks[7].size = INIT0_SIZE;
}
 
void arch_pre_mm_init(void)
{
/* Set Interruption Vector Address (i.e. location of interruption vector table). */
iva_write((uintptr_t) &ivt);
srlz_d();
ski_init_console();
it_init();
}
 
void arch_post_mm_init(void)
{
ski_set_console_sysinfo();
}
 
void arch_pre_smp_init(void)
{
}
 
void arch_post_smp_init(void)
{
}
 
/** Enter userspace and never return. */
void userspace(uspace_arg_t *kernel_uarg)
{
psr_t psr;
rsc_t rsc;
 
psr.value = psr_read();
psr.cpl = PL_USER;
psr.i = true; /* start with interrupts enabled */
psr.ic = true;
psr.ri = 0; /* start with instruction #0 */
psr.bn = 1; /* start in bank 0 */
 
__asm__ volatile ("mov %0 = ar.rsc\n" : "=r" (rsc.value));
rsc.loadrs = 0;
rsc.be = false;
rsc.pl = PL_USER;
rsc.mode = 3; /* eager mode */
 
switch_to_userspace((uintptr_t) kernel_uarg->uspace_entry,
((uintptr_t) kernel_uarg->uspace_stack)+PAGE_SIZE-ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT),
((uintptr_t) kernel_uarg->uspace_stack)+PAGE_SIZE,
(uintptr_t) kernel_uarg->uspace_uarg,
psr.value, rsc.value);
 
while (1) {
;
}
}
 
/** Set thread-local-storage pointer.
*
* We use r13 (a.k.a. tp) for this purpose.
*/
unative_t sys_tls_set(unative_t addr)
{
return 0;
}
 
/** Acquire console back for kernel
*
*/
void arch_grab_console(void)
{
kbd_release=kbd_uspace;
kbd_uspace=0;
}
/** Return console to userspace
*
*/
void arch_release_console(void)
{
kbd_uspace=kbd_release;
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/src/ski/ski.c
0,0 → 1,205
/*
* 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 ia64
* @{
*/
/** @file
*/
 
#include <arch/ski/ski.h>
#include <console/console.h>
#include <console/chardev.h>
#include <arch/interrupt.h>
#include <sysinfo/sysinfo.h>
 
chardev_t ski_console;
chardev_t ski_uconsole;
static bool kb_disable;
int kbd_uspace=0;
 
static void ski_putchar(chardev_t *d, const char ch);
static int32_t ski_getchar(void);
 
/** Display character on debug console
*
* Use SSC (Simulator System Call) to
* display character on debug console.
*
* @param d Character device.
* @param ch Character to be printed.
*/
void ski_putchar(chardev_t *d, const char ch)
{
__asm__ volatile (
"mov r15=%0\n"
"mov r32=%1\n" /* r32 is in0 */
"break 0x80000\n" /* modifies r8 */
:
: "i" (SKI_PUTCHAR), "r" (ch)
: "r15", "in0", "r8"
);
if (ch == '\n')
ski_putchar(d, '\r');
}
 
/** Ask debug console if a key was pressed.
*
* Use SSC (Simulator System Call) to
* get character from debug console.
*
* This call is non-blocking.
*
* @return ASCII code of pressed key or 0 if no key pressed.
*/
int32_t ski_getchar(void)
{
uint64_t ch;
__asm__ volatile (
"mov r15=%1\n"
"break 0x80000;;\n" /* modifies r8 */
"mov %0=r8;;\n"
 
: "=r" (ch)
: "i" (SKI_GETCHAR)
: "r15", "r8"
);
 
return (int32_t) ch;
}
 
/**
* This is a blocking wrapper for ski_getchar().
* To be used when the kernel crashes.
*/
static char ski_getchar_blocking(chardev_t *d)
{
int ch;
 
while(!(ch=ski_getchar()))
;
if(ch == '\r')
ch = '\n';
return (char) ch;
}
 
/** Ask keyboard if a key was pressed. */
void poll_keyboard(void)
{
char ch;
static char last;
 
if (kb_disable)
return;
 
ch = ski_getchar();
if(ch == '\r')
ch = '\n';
if (ch){
if(kbd_uspace){
chardev_push_character(&ski_uconsole, ch);
virtual_interrupt(IRQ_KBD,NULL);
}
else {
chardev_push_character(&ski_console, ch);
}
last = ch;
return;
}
 
if (last){
if(kbd_uspace){
chardev_push_character(&ski_uconsole, 0);
virtual_interrupt(IRQ_KBD,NULL);
}
else {
}
last = 0;
}
 
}
 
/* Called from getc(). */
static void ski_kb_enable(chardev_t *d)
{
kb_disable = false;
}
 
/* Called from getc(). */
static void ski_kb_disable(chardev_t *d)
{
kb_disable = true;
}
 
 
static chardev_operations_t ski_ops = {
.resume = ski_kb_enable,
.suspend = ski_kb_disable,
.write = ski_putchar,
.read = ski_getchar_blocking
};
 
 
/** Initialize debug console
*
* Issue SSC (Simulator System Call) to
* to open debug console.
*/
void ski_init_console(void)
{
__asm__ volatile (
"mov r15=%0\n"
"break 0x80000\n"
:
: "i" (SKI_INIT_CONSOLE)
: "r15", "r8"
);
 
chardev_initialize("ski_console", &ski_console, &ski_ops);
chardev_initialize("ski_uconsole", &ski_uconsole, &ski_ops);
stdin = &ski_console;
stdout = &ski_console;
 
}
/** Setup console sysinfo (i.e. Keyboard IRQ)
*
* Because sysinfo neads memory allocation/dealocation
* this functions should be called separetely from init.
*
*/
void ski_set_console_sysinfo(void)
{
sysinfo_set_item_val("kbd",NULL,true);
sysinfo_set_item_val("kbd.irq",NULL,IRQ_KBD);
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/src/cpu/cpu.c
0,0 → 1,76
/*
* 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 ia64
* @{
*/
/** @file
*/
 
#include <cpu.h>
#include <arch.h>
#include <arch/register.h>
#include <print.h>
 
void cpu_arch_init(void)
{
}
 
void cpu_identify(void)
{
CPU->arch.cpuid0 = cpuid_read(0);
CPU->arch.cpuid1 = cpuid_read(1);
CPU->arch.cpuid3.value = cpuid_read(3);
}
 
void cpu_print_report(cpu_t *m)
{
char *family_str;
char vendor[2*sizeof(uint64_t)+1];
*((uint64_t *) &vendor[0*sizeof(uint64_t)]) = CPU->arch.cpuid0;
*((uint64_t *) &vendor[1*sizeof(uint64_t)]) = CPU->arch.cpuid1;
vendor[sizeof(vendor)-1] = '\0';
switch(m->arch.cpuid3.family) {
case FAMILY_ITANIUM:
family_str = "Itanium";
break;
case FAMILY_ITANIUM2:
family_str = "Itanium 2";
break;
default:
family_str = "Unknown";
break;
}
printf("cpu%d: %s (%s), archrev=%d, model=%d, revision=%d\n", CPU->id, family_str, vendor, CPU->arch.cpuid3.archrev, CPU->arch.cpuid3.model, CPU->arch.cpuid3.revision);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ia64/src/mm/tlb.c
0,0 → 1,690
/*
* 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 ia64mm
* @{
*/
/** @file
*/
 
/*
* TLB management.
*/
 
#include <mm/tlb.h>
#include <mm/asid.h>
#include <mm/page.h>
#include <mm/as.h>
#include <arch/mm/tlb.h>
#include <arch/mm/page.h>
#include <arch/mm/vhpt.h>
#include <arch/barrier.h>
#include <arch/interrupt.h>
#include <arch/pal/pal.h>
#include <arch/asm.h>
#include <typedefs.h>
#include <panic.h>
#include <print.h>
#include <arch.h>
#include <interrupt.h>
 
/** Invalidate all TLB entries. */
void tlb_invalidate_all(void)
{
ipl_t ipl;
uintptr_t adr;
uint32_t count1, count2, stride1, stride2;
int i,j;
adr = PAL_PTCE_INFO_BASE();
count1 = PAL_PTCE_INFO_COUNT1();
count2 = PAL_PTCE_INFO_COUNT2();
stride1 = PAL_PTCE_INFO_STRIDE1();
stride2 = PAL_PTCE_INFO_STRIDE2();
ipl = interrupts_disable();
 
for(i = 0; i < count1; i++) {
for(j = 0; j < count2; j++) {
__asm__ volatile (
"ptc.e %0 ;;"
:
: "r" (adr)
);
adr += stride2;
}
adr += stride1;
}
 
interrupts_restore(ipl);
 
srlz_d();
srlz_i();
#ifdef CONFIG_VHPT
vhpt_invalidate_all();
#endif
}
 
/** Invalidate entries belonging to an address space.
*
* @param asid Address space identifier.
*/
void tlb_invalidate_asid(asid_t asid)
{
tlb_invalidate_all();
}
 
 
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt)
{
region_register rr;
bool restore_rr = false;
int b = 0;
int c = cnt;
 
uintptr_t va;
va = page;
 
rr.word = rr_read(VA2VRN(va));
if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA2VRN(va))))) {
/*
* The selected region register does not contain required RID.
* Save the old content of the register and replace the RID.
*/
region_register rr0;
 
rr0 = rr;
rr0.map.rid = ASID2RID(asid, VA2VRN(va));
rr_write(VA2VRN(va), rr0.word);
srlz_d();
srlz_i();
}
while(c >>= 1)
b++;
b >>= 1;
uint64_t ps;
switch (b) {
case 0: /*cnt 1-3*/
ps = PAGE_WIDTH;
break;
case 1: /*cnt 4-15*/
/*cnt=((cnt-1)/4)+1;*/
ps = PAGE_WIDTH+2;
va &= ~((1<<ps)-1);
break;
case 2: /*cnt 16-63*/
/*cnt=((cnt-1)/16)+1;*/
ps = PAGE_WIDTH+4;
va &= ~((1<<ps)-1);
break;
case 3: /*cnt 64-255*/
/*cnt=((cnt-1)/64)+1;*/
ps = PAGE_WIDTH+6;
va &= ~((1<<ps)-1);
break;
case 4: /*cnt 256-1023*/
/*cnt=((cnt-1)/256)+1;*/
ps = PAGE_WIDTH+8;
va &= ~((1<<ps)-1);
break;
case 5: /*cnt 1024-4095*/
/*cnt=((cnt-1)/1024)+1;*/
ps = PAGE_WIDTH+10;
va &= ~((1<<ps)-1);
break;
case 6: /*cnt 4096-16383*/
/*cnt=((cnt-1)/4096)+1;*/
ps = PAGE_WIDTH+12;
va &= ~((1<<ps)-1);
break;
case 7: /*cnt 16384-65535*/
case 8: /*cnt 65536-(256K-1)*/
/*cnt=((cnt-1)/16384)+1;*/
ps = PAGE_WIDTH+14;
va &= ~((1<<ps)-1);
break;
default:
/*cnt=((cnt-1)/(16384*16))+1;*/
ps=PAGE_WIDTH+18;
va&=~((1<<ps)-1);
break;
}
/*cnt+=(page!=va);*/
for(; va<(page+cnt*(PAGE_SIZE)); va += (1<<ps)) {
__asm__ volatile (
"ptc.l %0,%1;;"
:
: "r" (va), "r" (ps<<2)
);
}
srlz_d();
srlz_i();
if (restore_rr) {
rr_write(VA2VRN(va), rr.word);
srlz_d();
srlz_i();
}
}
 
/** Insert data into data translation cache.
*
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion format.
*/
void dtc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry)
{
tc_mapping_insert(va, asid, entry, true);
}
 
/** Insert data into instruction translation cache.
*
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion format.
*/
void itc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry)
{
tc_mapping_insert(va, asid, entry, false);
}
 
/** Insert data into instruction or data translation cache.
*
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion format.
* @param dtc If true, insert into data translation cache, use instruction translation cache otherwise.
*/
void tc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtc)
{
region_register rr;
bool restore_rr = false;
 
rr.word = rr_read(VA2VRN(va));
if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA2VRN(va))))) {
/*
* The selected region register does not contain required RID.
* Save the old content of the register and replace the RID.
*/
region_register rr0;
 
rr0 = rr;
rr0.map.rid = ASID2RID(asid, VA2VRN(va));
rr_write(VA2VRN(va), rr0.word);
srlz_d();
srlz_i();
}
__asm__ volatile (
"mov r8=psr;;\n"
"rsm %0;;\n" /* PSR_IC_MASK */
"srlz.d;;\n"
"srlz.i;;\n"
"mov cr.ifa=%1\n" /* va */
"mov cr.itir=%2;;\n" /* entry.word[1] */
"cmp.eq p6,p7 = %4,r0;;\n" /* decide between itc and dtc */
"(p6) itc.i %3;;\n"
"(p7) itc.d %3;;\n"
"mov psr.l=r8;;\n"
"srlz.d;;\n"
:
: "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]), "r" (entry.word[0]), "r" (dtc)
: "p6", "p7", "r8"
);
if (restore_rr) {
rr_write(VA2VRN(va), rr.word);
srlz_d();
srlz_i();
}
}
 
/** Insert data into instruction translation register.
*
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion format.
* @param tr Translation register.
*/
void itr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, index_t tr)
{
tr_mapping_insert(va, asid, entry, false, tr);
}
 
/** Insert data into data translation register.
*
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion format.
* @param tr Translation register.
*/
void dtr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, index_t tr)
{
tr_mapping_insert(va, asid, entry, true, tr);
}
 
/** Insert data into instruction or data translation register.
*
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion format.
* @param dtr If true, insert into data translation register, use instruction translation register otherwise.
* @param tr Translation register.
*/
void tr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtr, index_t tr)
{
region_register rr;
bool restore_rr = false;
 
rr.word = rr_read(VA2VRN(va));
if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA2VRN(va))))) {
/*
* The selected region register does not contain required RID.
* Save the old content of the register and replace the RID.
*/
region_register rr0;
 
rr0 = rr;
rr0.map.rid = ASID2RID(asid, VA2VRN(va));
rr_write(VA2VRN(va), rr0.word);
srlz_d();
srlz_i();
}
 
__asm__ volatile (
"mov r8=psr;;\n"
"rsm %0;;\n" /* PSR_IC_MASK */
"srlz.d;;\n"
"srlz.i;;\n"
"mov cr.ifa=%1\n" /* va */
"mov cr.itir=%2;;\n" /* entry.word[1] */
"cmp.eq p6,p7=%5,r0;;\n" /* decide between itr and dtr */
"(p6) itr.i itr[%4]=%3;;\n"
"(p7) itr.d dtr[%4]=%3;;\n"
"mov psr.l=r8;;\n"
"srlz.d;;\n"
:
: "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]), "r" (entry.word[0]), "r" (tr), "r" (dtr)
: "p6", "p7", "r8"
);
if (restore_rr) {
rr_write(VA2VRN(va), rr.word);
srlz_d();
srlz_i();
}
}
 
/** Insert data into DTLB.
*
* @param page Virtual page address including VRN bits.
* @param frame Physical frame address.
* @param dtr If true, insert into data translation register, use data translation cache otherwise.
* @param tr Translation register if dtr is true, ignored otherwise.
*/
void dtlb_kernel_mapping_insert(uintptr_t page, uintptr_t frame, bool dtr, index_t tr)
{
tlb_entry_t entry;
entry.word[0] = 0;
entry.word[1] = 0;
entry.p = true; /* present */
entry.ma = MA_WRITEBACK;
entry.a = true; /* already accessed */
entry.d = true; /* already dirty */
entry.pl = PL_KERNEL;
entry.ar = AR_READ | AR_WRITE;
entry.ppn = frame >> PPN_SHIFT;
entry.ps = PAGE_WIDTH;
if (dtr)
dtr_mapping_insert(page, ASID_KERNEL, entry, tr);
else
dtc_mapping_insert(page, ASID_KERNEL, entry);
}
 
/** Purge kernel entries from DTR.
*
* Purge DTR entries used by the kernel.
*
* @param page Virtual page address including VRN bits.
* @param width Width of the purge in bits.
*/
void dtr_purge(uintptr_t page, count_t width)
{
__asm__ volatile ("ptr.d %0, %1\n" : : "r" (page), "r" (width<<2));
}
 
 
/** Copy content of PTE into data translation cache.
*
* @param t PTE.
*/
void dtc_pte_copy(pte_t *t)
{
tlb_entry_t entry;
 
entry.word[0] = 0;
entry.word[1] = 0;
entry.p = t->p;
entry.ma = t->c ? MA_WRITEBACK : MA_UNCACHEABLE;
entry.a = t->a;
entry.d = t->d;
entry.pl = t->k ? PL_KERNEL : PL_USER;
entry.ar = t->w ? AR_WRITE : AR_READ;
entry.ppn = t->frame >> PPN_SHIFT;
entry.ps = PAGE_WIDTH;
dtc_mapping_insert(t->page, t->as->asid, entry);
#ifdef CONFIG_VHPT
vhpt_mapping_insert(t->page, t->as->asid, entry);
#endif
}
 
/** Copy content of PTE into instruction translation cache.
*
* @param t PTE.
*/
void itc_pte_copy(pte_t *t)
{
tlb_entry_t entry;
 
entry.word[0] = 0;
entry.word[1] = 0;
ASSERT(t->x);
entry.p = t->p;
entry.ma = t->c ? MA_WRITEBACK : MA_UNCACHEABLE;
entry.a = t->a;
entry.pl = t->k ? PL_KERNEL : PL_USER;
entry.ar = t->x ? (AR_EXECUTE | AR_READ) : AR_READ;
entry.ppn = t->frame >> PPN_SHIFT;
entry.ps = PAGE_WIDTH;
itc_mapping_insert(t->page, t->as->asid, entry);
#ifdef CONFIG_VHPT
vhpt_mapping_insert(t->page, t->as->asid, entry);
#endif
}
 
/** Instruction TLB fault handler for faults with VHPT turned off.
*
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
*/
void alternate_instruction_tlb_fault(uint64_t vector, istate_t *istate)
{
region_register rr;
rid_t rid;
uintptr_t va;
pte_t *t;
va = istate->cr_ifa; /* faulting address */
rr.word = rr_read(VA2VRN(va));
rid = rr.map.rid;
 
page_table_lock(AS, true);
t = page_mapping_find(AS, va);
if (t) {
/*
* The mapping was found in software page hash table.
* Insert it into data translation cache.
*/
itc_pte_copy(t);
page_table_unlock(AS, true);
} else {
/*
* Forward the page fault to address space page fault handler.
*/
page_table_unlock(AS, true);
if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate,"Page fault at %p",va);
panic("%s: va=%p, rid=%d, iip=%p\n", __FUNCTION__, va, rid, istate->cr_iip);
}
}
}
 
/** Data TLB fault handler for faults with VHPT turned off.
*
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
*/
void alternate_data_tlb_fault(uint64_t vector, istate_t *istate)
{
region_register rr;
rid_t rid;
uintptr_t va;
pte_t *t;
va = istate->cr_ifa; /* faulting address */
rr.word = rr_read(VA2VRN(va));
rid = rr.map.rid;
if (RID2ASID(rid) == ASID_KERNEL) {
if (VA2VRN(va) == VRN_KERNEL) {
/*
* Provide KA2PA(identity) mapping for faulting piece of
* kernel address space.
*/
dtlb_kernel_mapping_insert(va, KA2PA(va), false, 0);
return;
}
}
 
page_table_lock(AS, true);
t = page_mapping_find(AS, va);
if (t) {
/*
* The mapping was found in software page hash table.
* Insert it into data translation cache.
*/
dtc_pte_copy(t);
page_table_unlock(AS, true);
} else {
/*
* Forward the page fault to address space page fault handler.
*/
page_table_unlock(AS, true);
if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate,"Page fault at %p",va);
panic("%s: va=%p, rid=%d, iip=%p\n", __FUNCTION__, va, rid, istate->cr_iip);
}
}
}
 
/** Data nested TLB fault handler.
*
* This fault should not occur.
*
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
*/
void data_nested_tlb_fault(uint64_t vector, istate_t *istate)
{
panic("%s\n", __FUNCTION__);
}
 
/** Data Dirty bit fault handler.
*
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
*/
void data_dirty_bit_fault(uint64_t vector, istate_t *istate)
{
region_register rr;
rid_t rid;
uintptr_t va;
pte_t *t;
va = istate->cr_ifa; /* faulting address */
rr.word = rr_read(VA2VRN(va));
rid = rr.map.rid;
 
page_table_lock(AS, true);
t = page_mapping_find(AS, va);
ASSERT(t && t->p);
if (t && t->p && t->w) {
/*
* Update the Dirty bit in page tables and reinsert
* the mapping into DTC.
*/
t->d = true;
dtc_pte_copy(t);
} else {
if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate,"Page fault at %p",va);
panic("%s: va=%p, rid=%d, iip=%p\n", __FUNCTION__, va, rid, istate->cr_iip);
t->d = true;
dtc_pte_copy(t);
}
}
page_table_unlock(AS, true);
}
 
/** Instruction access bit fault handler.
*
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
*/
void instruction_access_bit_fault(uint64_t vector, istate_t *istate)
{
region_register rr;
rid_t rid;
uintptr_t va;
pte_t *t;
 
va = istate->cr_ifa; /* faulting address */
rr.word = rr_read(VA2VRN(va));
rid = rr.map.rid;
 
page_table_lock(AS, true);
t = page_mapping_find(AS, va);
ASSERT(t && t->p);
if (t && t->p && t->x) {
/*
* Update the Accessed bit in page tables and reinsert
* the mapping into ITC.
*/
t->a = true;
itc_pte_copy(t);
} else {
if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate,"Page fault at %p",va);
panic("%s: va=%p, rid=%d, iip=%p\n", __FUNCTION__, va, rid, istate->cr_iip);
t->a = true;
itc_pte_copy(t);
}
}
page_table_unlock(AS, true);
}
 
/** Data access bit fault handler.
*
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
*/
void data_access_bit_fault(uint64_t vector, istate_t *istate)
{
region_register rr;
rid_t rid;
uintptr_t va;
pte_t *t;
 
va = istate->cr_ifa; /* faulting address */
rr.word = rr_read(VA2VRN(va));
rid = rr.map.rid;
 
page_table_lock(AS, true);
t = page_mapping_find(AS, va);
ASSERT(t && t->p);
if (t && t->p) {
/*
* Update the Accessed bit in page tables and reinsert
* the mapping into DTC.
*/
t->a = true;
dtc_pte_copy(t);
} else {
if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate,"Page fault at %p",va);
panic("%s: va=%p, rid=%d, iip=%p\n", __FUNCTION__, va, rid, istate->cr_iip);
t->a = true;
itc_pte_copy(t);
}
}
page_table_unlock(AS, true);
}
 
/** Page not present fault handler.
*
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
*/
void page_not_present(uint64_t vector, istate_t *istate)
{
region_register rr;
rid_t rid;
uintptr_t va;
pte_t *t;
va = istate->cr_ifa; /* faulting address */
rr.word = rr_read(VA2VRN(va));
rid = rr.map.rid;
 
page_table_lock(AS, true);
t = page_mapping_find(AS, va);
ASSERT(t);
if (t->p) {
/*
* If the Present bit is set in page hash table, just copy it
* and update ITC/DTC.
*/
if (t->x)
itc_pte_copy(t);
else
dtc_pte_copy(t);
page_table_unlock(AS, true);
} else {
page_table_unlock(AS, true);
if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate,"Page fault at %p",va);
panic("%s: va=%p, rid=%d\n", __FUNCTION__, va, rid);
}
}
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/src/mm/vhpt.c
0,0 → 1,99
/*
* Copyright (C) 2006 Jakub Vana
* 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 ia64mm
* @{
*/
/** @file
*/
 
#include <arch/mm/vhpt.h>
#include <mm/frame.h>
#include <print.h>
 
 
static vhpt_entry_t* vhpt_base;
 
uintptr_t vhpt_set_up(void)
{
vhpt_base = frame_alloc(VHPT_WIDTH-FRAME_WIDTH,FRAME_KA | FRAME_ATOMIC);
if(!vhpt_base)
panic("Kernel configured with VHPT but no memory for table.");
vhpt_invalidate_all();
return (uintptr_t) vhpt_base;
}
 
 
void vhpt_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry)
{
region_register rr_save, rr;
index_t vrn;
rid_t rid;
uint64_t tag;
 
vhpt_entry_t *ventry;
 
 
vrn = va >> VRN_SHIFT;
rid = ASID2RID(asid, vrn);
rr_save.word = rr_read(vrn);
rr.word = rr_save.word;
rr.map.rid = rid;
rr_write(vrn, rr.word);
srlz_i();
ventry = (vhpt_entry_t *) thash(va);
tag = ttag(va);
rr_write(vrn, rr_save.word);
srlz_i();
srlz_d();
 
ventry->word[0]=entry.word[0];
ventry->word[1]=entry.word[1];
ventry->present.tag.tag_word = tag;
 
}
 
void vhpt_invalidate_all()
{
memsetb((uintptr_t)vhpt_base,1<<VHPT_WIDTH,0);
}
 
void vhpt_invalidate_asid(asid_t asid)
{
vhpt_invalidate_all();
}
 
 
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/src/mm/page.c
0,0 → 1,268
/*
* Copyright (C) 2006 Jakub Jermar
* Copyright (C) 2006 Jakub Vana
* 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 ia64mm
* @{
*/
/** @file
*/
 
#include <arch/mm/page.h>
#include <genarch/mm/page_ht.h>
#include <mm/asid.h>
#include <arch/mm/asid.h>
#include <arch/mm/vhpt.h>
#include <arch/types.h>
#include <typedefs.h>
#include <print.h>
#include <mm/page.h>
#include <mm/frame.h>
#include <config.h>
#include <panic.h>
#include <arch/asm.h>
#include <arch/barrier.h>
#include <memstr.h>
 
static void set_environment(void);
 
/** Initialize ia64 virtual address translation subsystem. */
void page_arch_init(void)
{
page_mapping_operations = &ht_mapping_operations;
pk_disable();
set_environment();
}
 
/** Initialize VHPT and region registers. */
void set_environment(void)
{
region_register rr;
pta_register pta;
int i;
#ifdef CONFIG_VHPT
uintptr_t vhpt_base;
#endif
 
/*
* First set up kernel region register.
* This is redundant (see start.S) but we keep it here just for sure.
*/
rr.word = rr_read(VRN_KERNEL);
rr.map.ve = 0; /* disable VHPT walker */
rr.map.ps = PAGE_WIDTH;
rr.map.rid = ASID2RID(ASID_KERNEL, VRN_KERNEL);
rr_write(VRN_KERNEL, rr.word);
srlz_i();
srlz_d();
 
/*
* And setup the rest of region register.
*/
for(i = 0; i < REGION_REGISTERS; i++) {
/* skip kernel rr */
if (i == VRN_KERNEL)
continue;
rr.word = rr_read(i);
rr.map.ve = 0; /* disable VHPT walker */
rr.map.rid = RID_KERNEL;
rr.map.ps = PAGE_WIDTH;
rr_write(i, rr.word);
srlz_i();
srlz_d();
}
 
#ifdef CONFIG_VHPT
vhpt_base = vhpt_set_up();
#endif
/*
* Set up PTA register.
*/
pta.word = pta_read();
#ifndef CONFIG_VHPT
pta.map.ve = 0; /* disable VHPT walker */
pta.map.base = 0 >> PTA_BASE_SHIFT;
#else
pta.map.ve = 1; /* enable VHPT walker */
pta.map.base = vhpt_base >> PTA_BASE_SHIFT;
#endif
pta.map.vf = 1; /* large entry format */
pta.map.size = VHPT_WIDTH;
pta_write(pta.word);
srlz_i();
srlz_d();
}
 
/** Calculate address of collision chain from VPN and ASID.
*
* Interrupts must be disabled.
*
* @param page Address of virtual page including VRN bits.
* @param asid Address space identifier.
*
* @return VHPT entry address.
*/
vhpt_entry_t *vhpt_hash(uintptr_t page, asid_t asid)
{
region_register rr_save, rr;
index_t vrn;
rid_t rid;
vhpt_entry_t *v;
 
vrn = page >> VRN_SHIFT;
rid = ASID2RID(asid, vrn);
rr_save.word = rr_read(vrn);
if (rr_save.map.rid == rid) {
/*
* The RID is already in place, compute thash and return.
*/
v = (vhpt_entry_t *) thash(page);
return v;
}
/*
* The RID must be written to some region register.
* To speed things up, register indexed by vrn is used.
*/
rr.word = rr_save.word;
rr.map.rid = rid;
rr_write(vrn, rr.word);
srlz_i();
v = (vhpt_entry_t *) thash(page);
rr_write(vrn, rr_save.word);
srlz_i();
srlz_d();
 
return v;
}
 
/** Compare ASID and VPN against PTE.
*
* Interrupts must be disabled.
*
* @param page Address of virtual page including VRN bits.
* @param asid Address space identifier.
*
* @return True if page and asid match the page and asid of t, false otherwise.
*/
bool vhpt_compare(uintptr_t page, asid_t asid, vhpt_entry_t *v)
{
region_register rr_save, rr;
index_t vrn;
rid_t rid;
bool match;
 
ASSERT(v);
 
vrn = page >> VRN_SHIFT;
rid = ASID2RID(asid, vrn);
rr_save.word = rr_read(vrn);
if (rr_save.map.rid == rid) {
/*
* The RID is already in place, compare ttag with t and return.
*/
return ttag(page) == v->present.tag.tag_word;
}
/*
* The RID must be written to some region register.
* To speed things up, register indexed by vrn is used.
*/
rr.word = rr_save.word;
rr.map.rid = rid;
rr_write(vrn, rr.word);
srlz_i();
match = (ttag(page) == v->present.tag.tag_word);
rr_write(vrn, rr_save.word);
srlz_i();
srlz_d();
 
return match;
}
 
/** Set up one VHPT entry.
*
* @param v VHPT entry to be set up.
* @param page Virtual address of the page mapped by the entry.
* @param asid Address space identifier of the address space to which page belongs.
* @param frame Physical address of the frame to wich page is mapped.
* @param flags Different flags for the mapping.
*/
void vhpt_set_record(vhpt_entry_t *v, uintptr_t page, asid_t asid, uintptr_t frame, int flags)
{
region_register rr_save, rr;
index_t vrn;
rid_t rid;
uint64_t tag;
 
ASSERT(v);
 
vrn = page >> VRN_SHIFT;
rid = ASID2RID(asid, vrn);
/*
* Compute ttag.
*/
rr_save.word = rr_read(vrn);
rr.word = rr_save.word;
rr.map.rid = rid;
rr_write(vrn, rr.word);
srlz_i();
tag = ttag(page);
rr_write(vrn, rr_save.word);
srlz_i();
srlz_d();
/*
* Clear the entry.
*/
v->word[0] = 0;
v->word[1] = 0;
v->word[2] = 0;
v->word[3] = 0;
v->present.p = true;
v->present.ma = (flags & PAGE_CACHEABLE) ? MA_WRITEBACK : MA_UNCACHEABLE;
v->present.a = false; /* not accessed */
v->present.d = false; /* not dirty */
v->present.pl = (flags & PAGE_USER) ? PL_USER : PL_KERNEL;
v->present.ar = (flags & PAGE_WRITE) ? AR_WRITE : AR_READ;
v->present.ar |= (flags & PAGE_EXEC) ? AR_EXECUTE : 0;
v->present.ppn = frame >> PPN_SHIFT;
v->present.ed = false; /* exception not deffered */
v->present.ps = PAGE_WIDTH;
v->present.key = 0;
v->present.tag.tag_word = tag;
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/src/mm/as.c
0,0 → 1,90
/*
* 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 ia64mm
* @{
*/
/** @file
*/
 
#include <arch/mm/as.h>
#include <arch/mm/asid.h>
#include <arch/mm/page.h>
#include <genarch/mm/as_ht.h>
#include <genarch/mm/asid_fifo.h>
#include <mm/asid.h>
#include <arch.h>
#include <arch/barrier.h>
#include <synch/spinlock.h>
 
/** Architecture dependent address space init. */
void as_arch_init(void)
{
as_operations = &as_ht_operations;
asid_fifo_init();
}
 
/** Prepare registers for switching to another address space.
*
* @param as Address space.
*/
void as_install_arch(as_t *as)
{
ipl_t ipl;
region_register rr;
int i;
ipl = interrupts_disable();
spinlock_lock(&as->lock);
ASSERT(as->asid != ASID_INVALID);
/*
* Load respective ASID (7 consecutive RIDs) to
* region registers.
*/
for (i = 0; i < REGION_REGISTERS; i++) {
if (i == VRN_KERNEL)
continue;
rr.word = rr_read(i);
rr.map.ve = false; /* disable VHPT walker */
rr.map.rid = ASID2RID(as->asid, i);
rr.map.ps = PAGE_WIDTH;
rr_write(i, rr.word);
}
srlz_d();
srlz_i();
spinlock_unlock(&as->lock);
interrupts_restore(ipl);
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/src/mm/frame.c
0,0 → 1,59
/*
* 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 ia64mm
* @{
*/
/** @file
*/
 
#include <arch/mm/frame.h>
#include <mm/frame.h>
#include <config.h>
#include <panic.h>
 
/*
* This is Ski-specific and certainly not sufficient
* for real ia64 systems that provide memory map.
*/
#define ROM_BASE 0xa0000
#define ROM_SIZE (384*1024)
 
void frame_arch_init(void)
{
zone_create(0, config.memory_size >> FRAME_WIDTH, 1, 0);
/*
* Blacklist ROM regions.
*/
frame_mark_unavailable(ADDR2PFN(ROM_BASE), ROM_SIZE >> FRAME_WIDTH);
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/src/interrupt.c
0,0 → 1,283
/*
* Copyright (C) 2005 Jakub Jermar
* Copyright (C) 2005 Jakub Vana
* 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 ia64interrupt
* @{
*/
/** @file
*/
 
#include <arch/interrupt.h>
#include <panic.h>
#include <print.h>
#include <console/console.h>
#include <arch/types.h>
#include <arch/asm.h>
#include <arch/barrier.h>
#include <arch/register.h>
#include <arch/drivers/it.h>
#include <arch.h>
#include <symtab.h>
#include <debug.h>
#include <syscall/syscall.h>
#include <print.h>
#include <proc/scheduler.h>
#include <ipc/sysipc.h>
#include <ipc/irq.h>
#include <ipc/ipc.h>
#include <interrupt.h>
 
 
#define VECTORS_64_BUNDLE 20
#define VECTORS_16_BUNDLE 48
#define VECTORS_16_BUNDLE_START 0x5000
#define VECTOR_MAX 0x7f00
 
#define BUNDLE_SIZE 16
 
 
char *vector_names_64_bundle[VECTORS_64_BUNDLE] = {
"VHPT Translation vector",
"Instruction TLB vector",
"Data TLB vector",
"Alternate Instruction TLB vector",
"Alternate Data TLB vector",
"Data Nested TLB vector",
"Instruction Key Miss vector",
"Data Key Miss vector",
"Dirty-Bit vector",
"Instruction Access-Bit vector",
"Data Access-Bit vector"
"Break Instruction vector",
"External Interrupt vector"
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved"
};
 
char *vector_names_16_bundle[VECTORS_16_BUNDLE] = {
"Page Not Present vector",
"Key Permission vector",
"Instruction Access rights vector",
"Data Access Rights vector",
"General Exception vector",
"Disabled FP-Register vector",
"NaT Consumption vector",
"Speculation vector",
"Reserved",
"Debug vector",
"Unaligned Reference vector",
"Unsupported Data Reference vector",
"Floating-point Fault vector",
"Floating-point Trap vector",
"Lower-Privilege Transfer Trap vector",
"Taken Branch Trap vector",
"Single STep Trap vector",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"IA-32 Exception vector",
"IA-32 Intercept vector",
"IA-32 Interrupt vector",
"Reserved",
"Reserved",
"Reserved"
};
 
static char *vector_to_string(uint16_t vector);
static void dump_interrupted_context(istate_t *istate);
 
char *vector_to_string(uint16_t vector)
{
ASSERT(vector <= VECTOR_MAX);
if (vector >= VECTORS_16_BUNDLE_START)
return vector_names_16_bundle[(vector-VECTORS_16_BUNDLE_START)/(16*BUNDLE_SIZE)];
else
return vector_names_64_bundle[vector/(64*BUNDLE_SIZE)];
}
 
void dump_interrupted_context(istate_t *istate)
{
char *ifa, *iipa, *iip;
 
ifa = get_symtab_entry(istate->cr_ifa);
iipa = get_symtab_entry(istate->cr_iipa);
iip = get_symtab_entry(istate->cr_iip);
 
putchar('\n');
printf("Interrupted context dump:\n");
printf("ar.bsp=%p\tar.bspstore=%p\n", istate->ar_bsp, istate->ar_bspstore);
printf("ar.rnat=%#018llx\tar.rsc=%#018llx\n", istate->ar_rnat, istate->ar_rsc);
printf("ar.ifs=%#018llx\tar.pfs=%#018llx\n", istate->ar_ifs, istate->ar_pfs);
printf("cr.isr=%#018llx\tcr.ipsr=%#018llx\t\n", istate->cr_isr.value, istate->cr_ipsr);
printf("cr.iip=%#018llx, #%d\t(%s)\n", istate->cr_iip, istate->cr_isr.ei, iip);
printf("cr.iipa=%#018llx\t(%s)\n", istate->cr_iipa, iipa);
printf("cr.ifa=%#018llx\t(%s)\n", istate->cr_ifa, ifa);
}
 
void general_exception(uint64_t vector, istate_t *istate)
{
char *desc = "";
 
switch (istate->cr_isr.ge_code) {
case GE_ILLEGALOP:
desc = "Illegal Operation fault";
break;
case GE_PRIVOP:
desc = "Privileged Operation fault";
break;
case GE_PRIVREG:
desc = "Privileged Register fault";
break;
case GE_RESREGFLD:
desc = "Reserved Register/Field fault";
break;
case GE_DISBLDISTRAN:
desc = "Disabled Instruction Set Transition fault";
break;
case GE_ILLEGALDEP:
desc = "Illegal Dependency fault";
break;
default:
desc = "unknown";
break;
}
 
fault_if_from_uspace(istate, "General Exception (%s)", desc);
 
dump_interrupted_context(istate);
panic("General Exception (%s)\n", desc);
}
 
void fpu_enable(void);
 
void disabled_fp_register(uint64_t vector, istate_t *istate)
{
#ifdef CONFIG_FPU_LAZY
scheduler_fpu_lazy_request();
#else
fault_if_from_uspace(istate, "Interruption: %#hx (%s)", (uint16_t) vector, vector_to_string(vector));
dump_interrupted_context(istate);
panic("Interruption: %#hx (%s)\n", (uint16_t) vector, vector_to_string(vector));
#endif
}
 
 
void nop_handler(uint64_t vector, istate_t *istate)
{
}
 
 
 
/** Handle syscall. */
int break_instruction(uint64_t vector, istate_t *istate)
{
/*
* Move to next instruction after BREAK.
*/
if (istate->cr_ipsr.ri == 2) {
istate->cr_ipsr.ri = 0;
istate->cr_iip += 16;
} else {
istate->cr_ipsr.ri++;
}
 
if (istate->in4 < SYSCALL_END)
return syscall_table[istate->in4](istate->in0, istate->in1, istate->in2, istate->in3);
else
panic("Undefined syscall %d", istate->in4);
return -1;
}
 
void universal_handler(uint64_t vector, istate_t *istate)
{
fault_if_from_uspace(istate,"Interruption: %#hx (%s)\n",(uint16_t) vector, vector_to_string(vector));
dump_interrupted_context(istate);
panic("Interruption: %#hx (%s)\n", (uint16_t) vector, vector_to_string(vector));
}
 
void external_interrupt(uint64_t vector, istate_t *istate)
{
cr_ivr_t ivr;
ivr.value = ivr_read();
srlz_d();
 
switch(ivr.vector) {
case INTERRUPT_TIMER:
it_interrupt();
break;
case INTERRUPT_SPURIOUS:
printf("cpu%d: spurious interrupt\n", CPU->id);
break;
default:
panic("\nUnhandled External Interrupt Vector %d\n", ivr.vector);
break;
}
}
 
void virtual_interrupt(uint64_t irq,void *param)
{
switch(irq) {
case IRQ_KBD:
if(kbd_uspace) ipc_irq_send_notif(irq);
break;
default:
panic("\nUnhandled Virtual Interrupt request %d\n", irq);
break;
}
}
 
/* Reregister irq to be IPC-ready */
void irq_ipc_bind_arch(unative_t irq)
{
if(irq==IRQ_KBD) {
kbd_uspace=1;
return;
}
return;
panic("not implemented\n");
/* TODO */
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/src/drivers/it.c
0,0 → 1,106
/*
* 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 ia64
* @{
*/
/** @file
*/
 
/** Interval Timer driver. */
#include <arch/drivers/it.h>
#include <arch/ski/ski.h>
#include <arch/interrupt.h>
#include <arch/register.h>
#include <arch/asm.h>
#include <arch/barrier.h>
#include <time/clock.h>
#include <arch.h>
 
 
#define IT_SERVICE_CLOCKS 64
 
/** Initialize Interval Timer. */
void it_init(void)
{
cr_itv_t itv;
 
/* initialize Interval Timer external interrupt vector */
itv.value = itv_read();
itv.vector = INTERRUPT_TIMER;
itv.m = 0;
itv_write(itv.value);
 
/* set Interval Timer Counter to zero */
itc_write(0);
/* generate first Interval Timer interrupt in IT_DELTA ticks */
itm_write(IT_DELTA);
 
/* propagate changes */
srlz_d();
}
 
 
/** Process Interval Timer interrupt. */
void it_interrupt(void)
{
int64_t c;
int64_t m;
eoi_write(EOI);
m=itm_read();
while(1)
{
c=itc_read();
c+=IT_SERVICE_CLOCKS;
 
m+=IT_DELTA;
if(m-c<0)
{
CPU->missed_clock_ticks++;
}
else break;
}
itm_write(m);
srlz_d(); /* propagate changes */
clock();
poll_keyboard();
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/src/putchar.c
0,0 → 1,45
/*
* 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 ia64
* @{
*/
/** @file
*/
 
#include <putchar.h>
#include <arch/ski/ski.h>
 
void putchar(const char ch)
{
ski_write(ch);
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ia64/src/asm.S
0,0 → 1,184
#
# 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.
#
 
#include <arch/register.h>
 
.text
 
/** Copy memory from/to userspace.
*
* This memcpy() has been taken from the assembler output of
* the generic _memcpy() and modified to have the failover part.
*
* @param in0 Destination address.
* @param in1 Source address.
* @param in2 Number of byte to copy.
*/
.global memcpy
.global memcpy_from_uspace
.global memcpy_to_uspace
.global memcpy_from_uspace_failover_address
.global memcpy_to_uspace_failover_address
memcpy:
memcpy_from_uspace:
memcpy_to_uspace:
alloc loc0 = ar.pfs, 3, 1, 0, 0
 
adds r14 = 7, in1
mov r2 = ar.lc
mov r8 = in1 ;;
and r14 = -8, r14 ;;
cmp.ne p6, p7 = r14, in1
(p7) br.cond.dpnt 3f ;;
0:
cmp.ne p6, p7 = 0, in2
(p7) br.cond.dpnt 2f ;;
(p6) adds r14 = -1, in2
(p6) mov r16 = r0
(p6) mov r17 = r0 ;;
(p6) mov ar.lc = r14
1:
add r14 = r16, r8
add r15 = r16, in0
adds r17 = 1, r17 ;;
ld1 r14 = [r14]
mov r16 = r17 ;;
st1 [r15] = r14
br.cloop.sptk.few 1b ;;
2:
mov ar.lc = r2
 
mov ar.pfs = loc0
br.ret.sptk.many rp
3:
adds r14 = 7, in0 ;;
and r14 = -8, r14 ;;
cmp.eq p6, p7 = r14, in0
(p7) br.cond.dptk 0b
shr.u r18 = in2, 3 ;;
cmp.ne p6, p7 = 0, r18
(p7) br.cond.dpnt 5f ;;
(p6) adds r14 = -1, r18
(p6) mov r16 = r0
(p6) mov r17 = r0 ;;
(p6) mov ar.lc = r14
4:
shladd r14 = r16, 3, r0
adds r16 = 1, r17 ;;
add r15 = r8, r14
add r14 = in0, r14
mov r17 = r16 ;;
ld8 r15 = [r15] ;;
st8 [r14] = r15
br.cloop.sptk.few 4b
5:
and r15 = 7, in2
shladd r14 = r18, 3, r0
mov r16 = r0
mov r18 = r0 ;;
cmp.eq p6, p7 = 0, r15
add in0 = r14, in0
adds r15 = -1, r15
add r17 = r14, r8
(p6) br.cond.dpnt 2b ;;
mov ar.lc = r15
6:
add r14 = r16, r17
add r15 = r16, in0
adds r16 = 1, r18 ;;
ld1 r14 = [r14]
mov r18 = r16 ;;
st1 [r15] = r14
br.cloop.sptk.few 6b ;;
mov ar.lc = r2
 
mov ar.pfs = loc0
br.ret.sptk.many rp
memcpy_from_uspace_failover_address:
memcpy_to_uspace_failover_address:
mov r8 = r0 /* return 0 on failure */
mov ar.pfs = loc0
br.ret.sptk.many rp
 
.global memsetb
memsetb:
br _memsetb
 
.global cpu_halt
cpu_halt:
br cpu_halt
 
.global panic_printf
panic_printf:
{
br.call.sptk.many b0=printf
}
br halt
 
/** Switch to userspace - low level code.
*
* @param in0 Userspace entry point address.
* @param in1 Userspace stack pointer address.
* @param in2 Userspace register stack pointer address.
* @param in3 Userspace address of thread uspace_arg_t structure.
* @param in4 Value to be stored in IPSR.
* @param in5 Value to be stored in RSC.
*/
.global switch_to_userspace
switch_to_userspace:
alloc loc0 = ar.pfs, 6, 3, 0, 0
rsm (PSR_IC_MASK | PSR_I_MASK) /* disable interruption collection and interrupts */
srlz.d ;;
srlz.i ;;
mov cr.ipsr = in4
mov cr.iip = in0
mov r12 = in1
 
xor r1 = r1, r1
mov loc1 = cr.ifs
movl loc2 = PFM_MASK ;;
and loc1 = loc2, loc1 ;;
mov cr.ifs = loc1 ;; /* prevent decrementing BSP by rfi */
 
invala
mov loc1 = ar.rsc ;;
and loc1 = ~3, loc1 ;;
mov ar.rsc = loc1 ;; /* put RSE into enforced lazy mode */
 
flushrs ;;
mov ar.bspstore = in2 ;;
mov ar.rsc = in5 ;;
mov r8 = in3
rfi ;;
/tags/0.2.0.3/kernel/arch/ia64/src/start.S
0,0 → 1,139
#
# 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.
#
 
#include <arch/register.h>
#include <arch/mm/page.h>
#include <arch/mm/asid.h>
#include <mm/asid.h>
 
#define RR_MASK (0xFFFFFFFF00000002)
#define RID_SHIFT 8
#define PS_SHIFT 2
 
#define KERNEL_TRANSLATION_I 0x0010000000000661
#define KERNEL_TRANSLATION_D 0x0010000000000661
 
.section K_TEXT_START, "ax"
 
.global kernel_image_start
 
stack0:
kernel_image_start:
.auto
 
# Fill TR.i and TR.d using Region Register #VRN_KERNEL
 
movl r8=(VRN_KERNEL<<VRN_SHIFT)
mov r9=rr[r8]
movl r10=(RR_MASK)
and r9=r10,r9
movl r10=((RID_KERNEL<<RID_SHIFT)|(KERNEL_PAGE_WIDTH<<PS_SHIFT))
or r9=r10,r9
mov rr[r8]=r9
 
movl r8=(VRN_KERNEL<<VRN_SHIFT)
mov cr.ifa=r8
movl r10=(KERNEL_PAGE_WIDTH<<PS_SHIFT)
mov cr.itir=r10
movl r10=(KERNEL_TRANSLATION_I)
itr.i itr[r0]=r10
movl r10=(KERNEL_TRANSLATION_D)
itr.d dtr[r0]=r10
 
# initialize PSR
mov psr.l = r0
srlz.i
srlz.d
movl r10=(PSR_DT_MASK|PSR_RT_MASK|PSR_IT_MASK|PSR_IC_MASK) /* Enable paging */
mov r9=psr
or r10=r10,r9
mov cr.ipsr=r10
mov cr.ifs=r0
movl r8=paging_start
mov cr.iip=r8
srlz.d
srlz.i
 
.explicit
/*
* Return From Interupt is the only the way to fill upper half word of PSR.
*/
rfi;;
 
.global paging_start
paging_start:
 
/*
* Now we are paging.
*/
 
# switch to register bank 1
bsw.1
# initialize register stack
mov ar.rsc = r0
movl r8=(VRN_KERNEL<<VRN_SHIFT) ;;
mov ar.bspstore = r8
loadrs
 
# initialize memory stack to some sane value
movl r12 = stack0;;
add r12 = - 16, r12 /* allocate a scratch area on the stack */
 
# initialize gp (Global Pointer) register
movl r1 = _hardcoded_load_address
 
/*
* Initialize hardcoded_* variables.
*/
movl r14 = _hardcoded_ktext_size
movl r15 = _hardcoded_kdata_size
movl r16 = _hardcoded_load_address ;;
addl r17 = @gprel(hardcoded_ktext_size), gp
addl r18 = @gprel(hardcoded_kdata_size), gp
addl r19 = @gprel(hardcoded_load_address), gp
;;
st8 [r17] = r14
st8 [r18] = r15
st8 [r19] = r16
 
 
ssm (1<<19);; /*Disable f32 - f127*/
srlz.i;
srlz.d;;
 
br.call.sptk.many b0 = arch_pre_main
 
movl r18=main_bsp ;;
mov b1=r18 ;;
br.call.sptk.many b0=b1
 
 
0:
br 0b
/tags/0.2.0.3/kernel/arch/ia64/src/ivt.S
0,0 → 1,582
#
# Copyright (C) 2005 Jakub Vana
# 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.
#
 
#include <arch/stack.h>
#include <arch/register.h>
#include <arch/mm/page.h>
#include <align.h>
 
#define FRS_TO_SAVE 30
#define STACK_ITEMS (19 + FRS_TO_SAVE*2)
#define STACK_FRAME_SIZE ALIGN_UP((STACK_ITEMS*STACK_ITEM_SIZE) + STACK_SCRATCH_AREA_SIZE, STACK_ALIGNMENT)
 
#if (STACK_ITEMS % 2 == 0)
# define STACK_FRAME_BIAS 8
#else
# define STACK_FRAME_BIAS 16
#endif
 
/** Partitioning of bank 0 registers. */
#define R_OFFS r16
#define R_HANDLER r17
#define R_RET r18
#define R_TMP r19
#define R_KSTACK_BSP r22 /* keep in sync with before_thread_runs_arch() */
#define R_KSTACK r23 /* keep in sync with before_thread_runs_arch() */
 
/** Heavyweight interrupt handler
*
* This macro roughly follows steps from 1 to 19 described in
* Intel Itanium Architecture Software Developer's Manual, Chapter 3.4.2.
*
* HEAVYWEIGHT_HANDLER macro must cram into 16 bundles (48 instructions).
* This goal is achieved by using procedure calls after RSE becomes operational.
*
* Some steps are skipped (enabling and disabling interrupts).
*
* @param offs Offset from the beginning of IVT.
* @param handler Interrupt handler address.
*/
.macro HEAVYWEIGHT_HANDLER offs, handler=universal_handler
.org ivt + \offs
mov R_OFFS = \offs
movl R_HANDLER = \handler ;;
br heavyweight_handler
.endm
 
.global heavyweight_handler
heavyweight_handler:
/* 1. copy interrupt registers into bank 0 */
/*
* Note that r24-r31 from bank 0 can be used only as long as PSR.ic = 0.
*/
/* Set up FPU as in interrupted context. */
mov r24 = psr
mov r25 = cr.ipsr
mov r26 = PSR_DFH_MASK
mov r27 = ~PSR_DFH_MASK ;;
and r26 = r25, r26
and r24 = r24, r27;;
or r24 = r24, r26;;
mov psr.l = r24;;
srlz.i
srlz.d;;
 
mov r24 = cr.iip
mov r25 = cr.ipsr
mov r26 = cr.iipa
mov r27 = cr.isr
mov r28 = cr.ifa
/* 2. preserve predicate register into bank 0 */
mov r29 = pr ;;
/* 3. switch to kernel memory stack */
mov r30 = cr.ipsr
shr.u r31 = r12, VRN_SHIFT ;;
 
shr.u r30 = r30, PSR_CPL_SHIFT ;;
and r30 = PSR_CPL_MASK_SHIFTED, r30 ;;
 
/*
* Set p3 to true if the interrupted context executed in kernel mode.
* Set p4 to false if the interrupted context didn't execute in kernel mode.
*/
cmp.eq p3, p4 = r30, r0 ;;
cmp.eq p1, p2 = r30, r0 ;; /* remember IPSR setting in p1 and p2 */
 
/*
* Set p3 to true if the stack register references kernel address space.
* Set p4 to false if the stack register doesn't reference kernel address space.
*/
(p3) cmp.eq p3, p4 = VRN_KERNEL, r31 ;;
/*
* Now, p4 is true iff the stack needs to be switched to kernel stack.
*/
mov r30 = r12
(p4) mov r12 = R_KSTACK ;;
add r31 = -STACK_FRAME_BIAS, r12 ;;
add r12 = -STACK_FRAME_SIZE, r12
 
/* 4. save registers in bank 0 into memory stack */
 
/*
* If this is break_instruction handler,
* copy input parameters to stack.
*/
mov R_TMP = 0x2c00 ;;
cmp.eq p6,p5 = R_OFFS, R_TMP ;;
/*
* From now on, if this is break_instruction handler, p6 is true and p5 is false.
* Otherwise p6 is false and p5 is true.
* Note that p5 is a preserved predicate register and we make use of it.
*/
 
(p6) st8 [r31] = r36, -8 ;; /* save in4 */
(p6) st8 [r31] = r35, -8 ;; /* save in3 */
(p6) st8 [r31] = r34, -8 ;; /* save in2 */
(p6) st8 [r31] = r33, -8 ;; /* save in1 */
(p6) st8 [r31] = r32, -8 ;; /* save in0 */
(p5) add r31 = -40, r31 ;;
st8 [r31] = r30, -8 ;; /* save old stack pointer */
st8 [r31] = r29, -8 ;; /* save predicate registers */
 
st8 [r31] = r24, -8 ;; /* save cr.iip */
st8 [r31] = r25, -8 ;; /* save cr.ipsr */
st8 [r31] = r26, -8 ;; /* save cr.iipa */
st8 [r31] = r27, -8 ;; /* save cr.isr */
st8 [r31] = r28, -8 ;; /* save cr.ifa */
 
/* 5. RSE switch from interrupted context */
mov r24 = ar.rsc
mov r25 = ar.pfs
cover
mov r26 = cr.ifs
st8 [r31] = r24, -8 ;; /* save ar.rsc */
st8 [r31] = r25, -8 ;; /* save ar.pfs */
st8 [r31] = r26, -8 /* save ar.ifs */
and r24 = ~(RSC_PL_MASK), r24 ;;
and r30 = ~(RSC_MODE_MASK), r24 ;;
mov ar.rsc = r30 ;; /* update RSE state */
mov r27 = ar.rnat
mov r28 = ar.bspstore ;;
/*
* Inspect BSPSTORE to figure out whether it is necessary to switch to kernel BSPSTORE.
*/
(p1) shr.u r30 = r28, VRN_SHIFT ;;
(p1) cmp.eq p1, p2 = VRN_KERNEL, r30 ;;
/*
* If BSPSTORE needs to be switched, p1 is false and p2 is true.
*/
(p1) mov r30 = r28
(p2) mov r30 = R_KSTACK_BSP ;;
(p2) mov ar.bspstore = r30 ;;
mov r29 = ar.bsp
st8 [r31] = r27, -8 ;; /* save ar.rnat */
st8 [r31] = r30, -8 ;; /* save new value written to ar.bspstore */
st8 [r31] = r28, -8 ;; /* save ar.bspstore */
st8 [r31] = r29, -8 /* save ar.bsp */
mov ar.rsc = r24 /* restore RSE's setting + kernel privileges */
/* steps 6 - 15 are done by heavyweight_handler_inner() */
mov R_RET = b0 /* save b0 belonging to interrupted context */
br.call.sptk.many b0 = heavyweight_handler_inner
0: mov b0 = R_RET /* restore b0 belonging to the interrupted context */
 
/* 16. RSE switch to interrupted context */
cover /* allocate zerro size frame (step 1 (from Intel Docs)) */
 
add r31 = (STACK_SCRATCH_AREA_SIZE+(FRS_TO_SAVE*2*8)), r12 ;;
 
ld8 r30 = [r31], +8 ;; /* load ar.bsp */
ld8 r29 = [r31], +8 ;; /* load ar.bspstore */
ld8 r28 = [r31], +8 ;; /* load ar.bspstore_new */
sub r27 = r30 , r28 ;; /* calculate loadrs (step 2) */
shl r27 = r27, 16
 
mov r24 = ar.rsc ;;
and r30 = ~3, r24 ;;
or r24 = r30 , r27 ;;
mov ar.rsc = r24 ;; /* place RSE in enforced lazy mode */
 
loadrs /* (step 3) */
 
ld8 r27 = [r31], +8 ;; /* load ar.rnat */
ld8 r26 = [r31], +8 ;; /* load cr.ifs */
ld8 r25 = [r31], +8 ;; /* load ar.pfs */
ld8 r24 = [r31], +8 ;; /* load ar.rsc */
 
mov ar.bspstore = r29 ;; /* (step 4) */
mov ar.rnat = r27 /* (step 5) */
 
mov ar.pfs = r25 /* (step 6) */
mov cr.ifs = r26
 
mov ar.rsc = r24 /* (step 7) */
 
/* 17. restore interruption state from memory stack */
ld8 r28 = [r31], +8 ;; /* load cr.ifa */
ld8 r27 = [r31], +8 ;; /* load cr.isr */
ld8 r26 = [r31], +8 ;; /* load cr.iipa */
ld8 r25 = [r31], +8 ;; /* load cr.ipsr */
ld8 r24 = [r31], +8 ;; /* load cr.iip */
 
mov cr.iip = r24;;
mov cr.iipa = r26
mov cr.isr = r27
mov cr.ifa = r28
 
/* Set up FPU as in exception. */
mov r24 = psr
mov r26 = PSR_DFH_MASK
mov r27 = ~PSR_DFH_MASK ;;
and r25 = r25, r27
and r24 = r24, r26 ;;
or r25 = r25, r24;;
mov cr.ipsr = r25
 
/* 18. restore predicate registers from memory stack */
ld8 r29 = [r31], +8 ;; /* load predicate registers */
mov pr = r29
/* 19. return from interruption */
ld8 r12 = [r31] /* load stack pointer */
rfi ;;
 
.global heavyweight_handler_inner
heavyweight_handler_inner:
/*
* From this point, the rest of the interrupted context
* will be preserved in stacked registers and backing store.
*/
alloc loc0 = ar.pfs, 0, 48, 2, 0 ;;
/* bank 0 is going to be shadowed, copy essential data from there */
mov loc1 = R_RET /* b0 belonging to interrupted context */
mov loc2 = R_HANDLER
mov out0 = R_OFFS
add out1 = STACK_SCRATCH_AREA_SIZE, r12
 
/* 6. switch to bank 1 and reenable PSR.ic */
ssm PSR_IC_MASK
bsw.1 ;;
srlz.d
/* 7. preserve branch and application registers */
mov loc3 = ar.unat
mov loc4 = ar.lc
mov loc5 = ar.ec
mov loc6 = ar.ccv
mov loc7 = ar.csd
mov loc8 = ar.ssd
mov loc9 = b0
mov loc10 = b1
mov loc11 = b2
mov loc12 = b3
mov loc13 = b4
mov loc14 = b5
mov loc15 = b6
mov loc16 = b7
/* 8. preserve general and floating-point registers */
mov loc17 = r1
mov loc18 = r2
mov loc19 = r3
mov loc20 = r4
mov loc21 = r5
mov loc22 = r6
mov loc23 = r7
(p5) mov loc24 = r8 /* only if not in break_instruction handler */
mov loc25 = r9
mov loc26 = r10
mov loc27 = r11
/* skip r12 (stack pointer) */
mov loc28 = r13
mov loc29 = r14
mov loc30 = r15
mov loc31 = r16
mov loc32 = r17
mov loc33 = r18
mov loc34 = r19
mov loc35 = r20
mov loc36 = r21
mov loc37 = r22
mov loc38 = r23
mov loc39 = r24
mov loc40 = r25
mov loc41 = r26
mov loc42 = r27
mov loc43 = r28
mov loc44 = r29
mov loc45 = r30
mov loc46 = r31
 
add r24 = 96 + STACK_SCRATCH_AREA_SIZE, r12
add r25 = 112 + STACK_SCRATCH_AREA_SIZE, r12
add r26 = 0 + STACK_SCRATCH_AREA_SIZE, r12
add r27 = 16 + STACK_SCRATCH_AREA_SIZE, r12
add r28 = 32 + STACK_SCRATCH_AREA_SIZE, r12
add r29 = 48 + STACK_SCRATCH_AREA_SIZE, r12
add r30 = 64 + STACK_SCRATCH_AREA_SIZE, r12
add r31 = 80 + STACK_SCRATCH_AREA_SIZE, r12 ;;
stf.spill [r26] = f2, 0x80
stf.spill [r27] = f3, 0x80
stf.spill [r28] = f4, 0x80
stf.spill [r29] = f5, 0x80
stf.spill [r30] = f6, 0x80
stf.spill [r31] = f7, 0x80 ;;
 
stf.spill [r24] = f8, 0x80
stf.spill [r25] = f9, 0x80
stf.spill [r26] = f10, 0x80
stf.spill [r27] = f11, 0x80
stf.spill [r28] = f12, 0x80
stf.spill [r29] = f13, 0x80
stf.spill [r30] = f14, 0x80
stf.spill [r31] = f15, 0x80 ;;
 
stf.spill [r24] = f16, 0x80
stf.spill [r25] = f17, 0x80
stf.spill [r26] = f18, 0x80
stf.spill [r27] = f19, 0x80
stf.spill [r28] = f20, 0x80
stf.spill [r29] = f21, 0x80
stf.spill [r30] = f22, 0x80
stf.spill [r31] = f23, 0x80 ;;
 
stf.spill [r24] = f24, 0x80
stf.spill [r25] = f25, 0x80
stf.spill [r26] = f26, 0x80
stf.spill [r27] = f27, 0x80
stf.spill [r28] = f28, 0x80
stf.spill [r29] = f29, 0x80
stf.spill [r30] = f30, 0x80
stf.spill [r31] = f31, 0x80 ;;
 
mov loc47 = ar.fpsr /* preserve floating point status register */
/* 9. skipped (will not enable interrupts) */
/*
* ssm PSR_I_MASK
* ;;
* srlz.d
*/
 
/* 10. call handler */
movl r1 = _hardcoded_load_address
mov b1 = loc2
br.call.sptk.many b0 = b1
 
/* 11. return from handler */
0:
/* 12. skipped (will not disable interrupts) */
/*
* rsm PSR_I_MASK
* ;;
* srlz.d
*/
 
/* 13. restore general and floating-point registers */
add r24 = 96 + STACK_SCRATCH_AREA_SIZE, r12
add r25 = 112 + STACK_SCRATCH_AREA_SIZE, r12
add r26 = 0 + STACK_SCRATCH_AREA_SIZE, r12
add r27 = 16 + STACK_SCRATCH_AREA_SIZE, r12
add r28 = 32 + STACK_SCRATCH_AREA_SIZE, r12
add r29 = 48 + STACK_SCRATCH_AREA_SIZE, r12
add r30 = 64 + STACK_SCRATCH_AREA_SIZE, r12
add r31 = 80 + STACK_SCRATCH_AREA_SIZE, r12 ;;
 
ldf.fill f2 = [r26], 0x80
ldf.fill f3 = [r27], 0x80
ldf.fill f4 = [r28], 0x80
ldf.fill f5 = [r29], 0x80
ldf.fill f6 = [r30], 0x80
ldf.fill f7 = [r31], 0x80 ;;
 
ldf.fill f8 = [r24], 0x80
ldf.fill f9 = [r25], 0x80
ldf.fill f10 = [r26], 0x80
ldf.fill f11 = [r27], 0x80
ldf.fill f12 = [r28], 0x80
ldf.fill f13 = [r29], 0x80
ldf.fill f14 = [r30], 0x80
ldf.fill f15 = [r31], 0x80 ;;
 
ldf.fill f16 = [r24], 0x80
ldf.fill f17 = [r25], 0x80
ldf.fill f18 = [r26], 0x80
ldf.fill f19 = [r27], 0x80
ldf.fill f20 = [r28], 0x80
ldf.fill f21 = [r29], 0x80
ldf.fill f22 = [r30], 0x80
ldf.fill f23 = [r31], 0x80 ;;
 
ldf.fill f24 = [r24], 0x80
ldf.fill f25 = [r25], 0x80
ldf.fill f26 = [r26], 0x80
ldf.fill f27 = [r27], 0x80
ldf.fill f28 = [r28], 0x80
ldf.fill f29 = [r29], 0x80
ldf.fill f30 = [r30], 0x80
ldf.fill f31 = [r31], 0x80 ;;
mov r1 = loc17
mov r2 = loc18
mov r3 = loc19
mov r4 = loc20
mov r5 = loc21
mov r6 = loc22
mov r7 = loc23
(p5) mov r8 = loc24 /* only if not in break_instruction handler */
mov r9 = loc25
mov r10 = loc26
mov r11 = loc27
/* skip r12 (stack pointer) */
mov r13 = loc28
mov r14 = loc29
mov r15 = loc30
mov r16 = loc31
mov r17 = loc32
mov r18 = loc33
mov r19 = loc34
mov r20 = loc35
mov r21 = loc36
mov r22 = loc37
mov r23 = loc38
mov r24 = loc39
mov r25 = loc40
mov r26 = loc41
mov r27 = loc42
mov r28 = loc43
mov r29 = loc44
mov r30 = loc45
mov r31 = loc46
 
mov ar.fpsr = loc47 /* restore floating point status register */
/* 14. restore branch and application registers */
mov ar.unat = loc3
mov ar.lc = loc4
mov ar.ec = loc5
mov ar.ccv = loc6
mov ar.csd = loc7
mov ar.ssd = loc8
mov b0 = loc9
mov b1 = loc10
mov b2 = loc11
mov b3 = loc12
mov b4 = loc13
mov b5 = loc14
mov b6 = loc15
mov b7 = loc16
/* 15. disable PSR.ic and switch to bank 0 */
rsm PSR_IC_MASK
bsw.0 ;;
srlz.d
 
mov R_RET = loc1
mov ar.pfs = loc0
br.ret.sptk.many b0
 
.global ivt
.align 32768
ivt:
HEAVYWEIGHT_HANDLER 0x0000
HEAVYWEIGHT_HANDLER 0x0400
HEAVYWEIGHT_HANDLER 0x0800
HEAVYWEIGHT_HANDLER 0x0c00 alternate_instruction_tlb_fault
HEAVYWEIGHT_HANDLER 0x1000 alternate_data_tlb_fault
HEAVYWEIGHT_HANDLER 0x1400 data_nested_tlb_fault
HEAVYWEIGHT_HANDLER 0x1800
HEAVYWEIGHT_HANDLER 0x1c00
HEAVYWEIGHT_HANDLER 0x2000 data_dirty_bit_fault
HEAVYWEIGHT_HANDLER 0x2400 instruction_access_bit_fault
HEAVYWEIGHT_HANDLER 0x2800 data_access_bit_fault
HEAVYWEIGHT_HANDLER 0x2c00 break_instruction
HEAVYWEIGHT_HANDLER 0x3000 external_interrupt /* For external interrupt, heavyweight handler is used. */
HEAVYWEIGHT_HANDLER 0x3400
HEAVYWEIGHT_HANDLER 0x3800
HEAVYWEIGHT_HANDLER 0x3c00
HEAVYWEIGHT_HANDLER 0x4000
HEAVYWEIGHT_HANDLER 0x4400
HEAVYWEIGHT_HANDLER 0x4800
HEAVYWEIGHT_HANDLER 0x4c00
 
HEAVYWEIGHT_HANDLER 0x5000 page_not_present
HEAVYWEIGHT_HANDLER 0x5100
HEAVYWEIGHT_HANDLER 0x5200
HEAVYWEIGHT_HANDLER 0x5300
HEAVYWEIGHT_HANDLER 0x5400 general_exception
HEAVYWEIGHT_HANDLER 0x5500 disabled_fp_register
HEAVYWEIGHT_HANDLER 0x5600
HEAVYWEIGHT_HANDLER 0x5700
HEAVYWEIGHT_HANDLER 0x5800
HEAVYWEIGHT_HANDLER 0x5900
HEAVYWEIGHT_HANDLER 0x5a00
HEAVYWEIGHT_HANDLER 0x5b00
HEAVYWEIGHT_HANDLER 0x5c00
HEAVYWEIGHT_HANDLER 0x5d00
HEAVYWEIGHT_HANDLER 0x5e00
HEAVYWEIGHT_HANDLER 0x5f00
HEAVYWEIGHT_HANDLER 0x6000
HEAVYWEIGHT_HANDLER 0x6100
HEAVYWEIGHT_HANDLER 0x6200
HEAVYWEIGHT_HANDLER 0x6300
HEAVYWEIGHT_HANDLER 0x6400
HEAVYWEIGHT_HANDLER 0x6500
HEAVYWEIGHT_HANDLER 0x6600
HEAVYWEIGHT_HANDLER 0x6700
HEAVYWEIGHT_HANDLER 0x6800
HEAVYWEIGHT_HANDLER 0x6900
HEAVYWEIGHT_HANDLER 0x6a00
HEAVYWEIGHT_HANDLER 0x6b00
HEAVYWEIGHT_HANDLER 0x6c00
HEAVYWEIGHT_HANDLER 0x6d00
HEAVYWEIGHT_HANDLER 0x6e00
HEAVYWEIGHT_HANDLER 0x6f00
 
HEAVYWEIGHT_HANDLER 0x7000
HEAVYWEIGHT_HANDLER 0x7100
HEAVYWEIGHT_HANDLER 0x7200
HEAVYWEIGHT_HANDLER 0x7300
HEAVYWEIGHT_HANDLER 0x7400
HEAVYWEIGHT_HANDLER 0x7500
HEAVYWEIGHT_HANDLER 0x7600
HEAVYWEIGHT_HANDLER 0x7700
HEAVYWEIGHT_HANDLER 0x7800
HEAVYWEIGHT_HANDLER 0x7900
HEAVYWEIGHT_HANDLER 0x7a00
HEAVYWEIGHT_HANDLER 0x7b00
HEAVYWEIGHT_HANDLER 0x7c00
HEAVYWEIGHT_HANDLER 0x7d00
HEAVYWEIGHT_HANDLER 0x7e00
HEAVYWEIGHT_HANDLER 0x7f00
/tags/0.2.0.3/kernel/arch/ia64/src/context.S
0,0 → 1,246
#
# 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.
#
 
.text
 
.global context_save_arch
.global context_restore_arch
 
context_save_arch:
alloc loc0 = ar.pfs, 1, 8, 0, 0
mov loc1 = ar.unat ;;
/* loc2 */
mov loc3 = ar.rsc
 
.auto
 
/*
* Flush dirty registers to backing store.
* After this ar.bsp and ar.bspstore are equal.
*/
flushrs
mov loc4 = ar.bsp
/*
* Put RSE to enforced lazy mode.
* So that ar.rnat can be read.
*/
and loc5 = ~3, loc3
mov ar.rsc = loc5
mov loc5 = ar.rnat
 
.explicit
 
mov loc6 = ar.lc
/*
* Save application registers
*/
st8 [in0] = loc0, 8 ;; /* save ar.pfs */
st8 [in0] = loc1, 8 ;; /* save ar.unat (caller) */
mov loc2 = in0 ;;
add in0 = 8, in0 ;; /* skip ar.unat (callee) */
st8 [in0] = loc3, 8 ;; /* save ar.rsc */
st8 [in0] = loc4, 8 ;; /* save ar.bsp */
st8 [in0] = loc5, 8 ;; /* save ar.rnat */
st8 [in0] = loc6, 8 ;; /* save ar.lc */
/*
* Save general registers including NaT bits
*/
st8.spill [in0] = r1, 8 ;;
st8.spill [in0] = r4, 8 ;;
st8.spill [in0] = r5, 8 ;;
st8.spill [in0] = r6, 8 ;;
st8.spill [in0] = r7, 8 ;;
st8.spill [in0] = r12, 8 ;; /* save sp */
st8.spill [in0] = r13, 8 ;;
 
mov loc3 = ar.unat ;;
st8 [loc2] = loc3 /* save ar.unat (callee) */
 
/*
* Save branch registers
*/
mov loc2 = b0 ;;
st8 [in0] = loc2, 8 /* save pc */
mov loc3 = b1 ;;
st8 [in0] = loc3, 8
mov loc4 = b2 ;;
st8 [in0] = loc4, 8
mov loc5 = b3 ;;
st8 [in0] = loc5, 8
mov loc6 = b4 ;;
st8 [in0] = loc6, 8
mov loc7 = b5 ;;
st8 [in0] = loc7, 8
 
/*
* Save predicate registers
*/
mov loc2 = pr ;;
st8 [in0] = loc2, 16;; /* Next fpu registers should be spilled to 16B aligned address */
 
/*
* Save floating-point registers.
*/
stf.spill [in0] = f2, 16 ;;
stf.spill [in0] = f3, 16 ;;
stf.spill [in0] = f4, 16 ;;
stf.spill [in0] = f5, 16 ;;
 
stf.spill [in0] = f16, 16 ;;
stf.spill [in0] = f17, 16 ;;
stf.spill [in0] = f18, 16 ;;
stf.spill [in0] = f19, 16 ;;
stf.spill [in0] = f20, 16 ;;
stf.spill [in0] = f21, 16 ;;
stf.spill [in0] = f22, 16 ;;
stf.spill [in0] = f23, 16 ;;
stf.spill [in0] = f24, 16 ;;
stf.spill [in0] = f25, 16 ;;
stf.spill [in0] = f26, 16 ;;
stf.spill [in0] = f27, 16 ;;
stf.spill [in0] = f28, 16 ;;
stf.spill [in0] = f29, 16 ;;
stf.spill [in0] = f30, 16 ;;
stf.spill [in0] = f31, 16 ;;
 
mov ar.unat = loc1
add r8 = r0, r0, 1 /* context_save returns 1 */
br.ret.sptk.many b0
 
context_restore_arch:
alloc loc0 = ar.pfs, 1, 9, 0, 0 ;;
 
ld8 loc0 = [in0], 8 ;; /* load ar.pfs */
ld8 loc1 = [in0], 8 ;; /* load ar.unat (caller) */
ld8 loc2 = [in0], 8 ;; /* load ar.unat (callee) */
ld8 loc3 = [in0], 8 ;; /* load ar.rsc */
ld8 loc4 = [in0], 8 ;; /* load ar.bsp */
ld8 loc5 = [in0], 8 ;; /* load ar.rnat */
ld8 loc6 = [in0], 8 ;; /* load ar.lc */
.auto
 
/*
* Invalidate the ALAT
*/
invala
 
/*
* Put RSE to enforced lazy mode.
* So that ar.bspstore and ar.rnat can be written.
*/
movl loc8 = ~3
and loc8 = loc3, loc8
mov ar.rsc = loc8
 
/*
* Flush dirty registers to backing store.
* We do this because we want the following move
* to ar.bspstore to assign the same value to ar.bsp.
*/
flushrs
 
/*
* Restore application registers
*/
mov ar.bspstore = loc4 /* rse.bspload = ar.bsp = ar.bspstore = loc4 */
mov ar.rnat = loc5
mov ar.pfs = loc0
mov ar.rsc = loc3
 
.explicit
 
mov ar.unat = loc2 ;;
mov ar.lc = loc6
/*
* Restore general registers including NaT bits
*/
ld8.fill r1 = [in0], 8 ;;
ld8.fill r4 = [in0], 8 ;;
ld8.fill r5 = [in0], 8 ;;
ld8.fill r6 = [in0], 8 ;;
ld8.fill r7 = [in0], 8 ;;
ld8.fill r12 = [in0], 8 ;; /* restore sp */
ld8.fill r13 = [in0], 8 ;;
 
/*
* Restore branch registers
*/
ld8 loc2 = [in0], 8 ;; /* restore pc */
mov b0 = loc2
ld8 loc3 = [in0], 8 ;;
mov b1 = loc3
ld8 loc4 = [in0], 8 ;;
mov b2 = loc4
ld8 loc5 = [in0], 8 ;;
mov b3 = loc5
ld8 loc6 = [in0], 8 ;;
mov b4 = loc6
ld8 loc7 = [in0], 8 ;;
mov b5 = loc7
 
/*
* Restore predicate registers
*/
ld8 loc2 = [in0], 16 ;;
mov pr = loc2, ~0
/*
* Restore floating-point registers.
*/
ldf.fill f2 = [in0], 16 ;;
ldf.fill f3 = [in0], 16 ;;
ldf.fill f4 = [in0], 16 ;;
ldf.fill f5 = [in0], 16 ;;
 
ldf.fill f16 = [in0], 16 ;;
ldf.fill f17 = [in0], 16 ;;
ldf.fill f18 = [in0], 16 ;;
ldf.fill f19 = [in0], 16 ;;
ldf.fill f20 = [in0], 16 ;;
ldf.fill f21 = [in0], 16 ;;
ldf.fill f22 = [in0], 16 ;;
ldf.fill f23 = [in0], 16 ;;
ldf.fill f24 = [in0], 16 ;;
ldf.fill f25 = [in0], 16 ;;
ldf.fill f26 = [in0], 16 ;;
ldf.fill f27 = [in0], 16 ;;
ldf.fill f28 = [in0], 16 ;;
ldf.fill f29 = [in0], 16 ;;
ldf.fill f30 = [in0], 16 ;;
ldf.fill f31 = [in0], 16 ;;
mov ar.unat = loc1
mov r8 = r0 /* context_restore returns 0 */
br.ret.sptk.many b0
/tags/0.2.0.3/kernel/arch/ia64/src/dummy.s
0,0 → 1,42
#
# 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.
#
 
.text
 
.global calibrate_delay_loop
.global asm_delay_loop
.global cpu_sleep
.global dummy
 
calibrate_delay_loop:
asm_delay_loop:
cpu_sleep:
 
dummy:
br.ret.sptk.many b0
 
/tags/0.2.0.3/kernel/arch/ia64/_link.ld.in
0,0 → 1,46
/** IA-64 linker script
*
* It is ELF format, but its only section looks like this:
* kernel text
* kernel data
*
*/
 
#define __ASM__
 
ENTRY(kernel_image_start)
 
SECTIONS {
.image 0xe000000000100000: AT (0x0000000000100000) {
ktext_start = .;
*(K_TEXT_START);
*(.text)
ktext_end = .;
kdata_start = .;
*(K_DATA_START)
*(.rodata .rodata.*)
*(.opd)
*(.data .data.*)
*(.got .got.*)
*(.sdata)
*(.sbss)
*(.scommon)
*(.bss)
*(COMMON);
 
symbol_table = .;
*(symtab.*); /* Symbol table, must be LAST symbol!*/
 
kdata_end = .;
}
 
/DISCARD/ : {
*(*);
}
 
_hardcoded_ktext_size = ktext_end - ktext_start;
_hardcoded_kdata_size = kdata_end - kdata_start;
_hardcoded_load_address = 0xe000000000100000;
 
}
/tags/0.2.0.3/kernel/arch/ppc32/Makefile.inc
0,0 → 1,85
#
# Copyright (C) 2005 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-powerpc
BFD_ARCH = powerpc:common
BFD = binary
TARGET = ppc-linux-gnu
TOOLCHAIN_DIR = /usr/local/ppc/bin
 
CFLAGS += -mcpu=powerpc -msoft-float -m32
AFLAGS += -a32
LFLAGS += -no-check-sections -N
 
DEFS += -D__32_BITS__
 
## Own configuration directives
#
 
CONFIG_FB = y
 
## Compile with hierarchical page tables support.
#
 
CONFIG_PAGE_PT = y
DEFS += -DCONFIG_PAGE_PT
 
## Compile with support for address space identifiers.
#
 
CONFIG_ASID = y
CONFIG_ASID_FIFO = y
 
## 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/fpu_context.S \
arch/$(ARCH)/src/boot/boot.S \
arch/$(ARCH)/src/ppc32.c \
arch/$(ARCH)/src/dummy.s \
arch/$(ARCH)/src/exception.S \
arch/$(ARCH)/src/interrupt.c \
arch/$(ARCH)/src/asm.S \
arch/$(ARCH)/src/cpu/cpu.c \
arch/$(ARCH)/src/proc/scheduler.c \
arch/$(ARCH)/src/ddi/ddi.c \
arch/$(ARCH)/src/drivers/cuda.c \
arch/$(ARCH)/src/mm/as.c \
arch/$(ARCH)/src/mm/frame.c \
arch/$(ARCH)/src/mm/memory_init.c \
arch/$(ARCH)/src/mm/page.c \
arch/$(ARCH)/src/mm/tlb.c \
arch/$(ARCH)/src/drivers/pic.c
/tags/0.2.0.3/kernel/arch/ppc32/src/ppc32.c
0,0 → 1,124
/*
* Copyright (C) 2005 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 ppc32
* @{
*/
/** @file
*/
 
#include <arch.h>
#include <arch/boot/boot.h>
#include <arch/drivers/cuda.h>
#include <arch/mm/memory_init.h>
#include <arch/interrupt.h>
#include <genarch/fb/fb.h>
#include <userspace.h>
#include <proc/uarg.h>
#include <console/console.h>
#include <arch/drivers/pic.h>
 
bootinfo_t bootinfo;
 
void arch_pre_main(void)
{
/* Setup usermode */
init.cnt = bootinfo.taskmap.count;
uint32_t i;
for (i = 0; i < bootinfo.taskmap.count; i++) {
init.tasks[i].addr = PA2KA(bootinfo.taskmap.tasks[i].addr);
init.tasks[i].size = bootinfo.taskmap.tasks[i].size;
}
}
 
void arch_pre_mm_init(void)
{
/* Initialize dispatch table */
interrupt_init();
 
/* Start decrementer */
start_decrementer();
}
 
void arch_post_mm_init(void)
{
if (config.cpu_active == 1) {
fb_init(bootinfo.screen.addr, bootinfo.screen.width, bootinfo.screen.height, bootinfo.screen.bpp, bootinfo.screen.scanline);
/* Initialize PIC */
pic_init(bootinfo.keyboard.addr, PAGE_SIZE);
cuda_init(bootinfo.keyboard.addr + 0x16000, 2 * PAGE_SIZE);
/* Merge all zones to 1 big zone */
zone_merge_all();
}
}
 
void arch_pre_smp_init(void)
{
memory_print_map();
}
 
void arch_post_smp_init(void)
{
}
 
void calibrate_delay_loop(void)
{
}
 
void userspace(uspace_arg_t *kernel_uarg)
{
userspace_asm((uintptr_t) kernel_uarg->uspace_uarg, (uintptr_t) kernel_uarg->uspace_stack + THREAD_STACK_SIZE - SP_DELTA, (uintptr_t) kernel_uarg->uspace_entry);
/* Unreachable */
for (;;)
;
}
 
/** Acquire console back for kernel
*
*/
void arch_grab_console(void)
{
cuda_grab();
}
 
/** Return console to userspace
*
*/
void arch_release_console(void)
{
cuda_release();
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ppc32/src/ddi/ddi.c
0,0 → 1,57
/*
* 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 ppc32ddi
* @{
*/
/** @file
*/
 
#include <ddi/ddi.h>
#include <proc/task.h>
#include <arch/types.h>
#include <typedefs.h>
 
/** Enable I/O space range for task.
*
* Interrupts are disabled and task is locked.
*
* @param task Task.
* @param ioaddr Startign I/O space address.
* @param size Size of the enabled I/O range.
*
* @return 0 on success or an error code from errno.h.
*/
int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
{
return 0;
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc32/src/mm/tlb.c
0,0 → 1,444
/*
* 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 ppc32mm
* @{
*/
/** @file
*/
 
#include <mm/tlb.h>
#include <arch/mm/tlb.h>
#include <arch/interrupt.h>
#include <mm/as.h>
#include <arch.h>
#include <print.h>
#include <symtab.h>
 
 
/** Try to find PTE for faulting address
*
* Try to find PTE for faulting address.
* The as->lock must be held on entry to this function
* if lock is true.
*
* @param as Address space.
* @param lock Lock/unlock the address space.
* @param badvaddr Faulting virtual address.
* @param access Access mode that caused the fault.
* @param istate Pointer to interrupted state.
* @param pfrc Pointer to variable where as_page_fault() return code will be stored.
* @return PTE on success, NULL otherwise.
*
*/
static pte_t *find_mapping_and_check(as_t *as, bool lock, uintptr_t badvaddr, int access, istate_t *istate, int *pfrc)
{
/*
* Check if the mapping exists in page tables.
*/
pte_t *pte = page_mapping_find(as, badvaddr);
if ((pte) && (pte->p)) {
/*
* Mapping found in page tables.
* Immediately succeed.
*/
return pte;
} else {
int rc;
/*
* Mapping not found in page tables.
* Resort to higher-level page fault handler.
*/
page_table_unlock(as, lock);
switch (rc = as_page_fault(badvaddr, access, istate)) {
case AS_PF_OK:
/*
* The higher-level page fault handler succeeded,
* The mapping ought to be in place.
*/
page_table_lock(as, lock);
pte = page_mapping_find(as, badvaddr);
ASSERT((pte) && (pte->p));
*pfrc = 0;
return pte;
case AS_PF_DEFER:
page_table_lock(as, lock);
*pfrc = rc;
return NULL;
case AS_PF_FAULT:
page_table_lock(as, lock);
printf("Page fault.\n");
*pfrc = rc;
return NULL;
default:
panic("unexpected rc (%d)\n", rc);
}
}
}
 
 
static void pht_refill_fail(uintptr_t badvaddr, istate_t *istate)
{
char *symbol = "";
char *sym2 = "";
 
char *s = get_symtab_entry(istate->pc);
if (s)
symbol = s;
s = get_symtab_entry(istate->lr);
if (s)
sym2 = s;
panic("%p: PHT Refill Exception at %p (%s<-%s)\n", badvaddr, istate->pc, symbol, sym2);
}
 
 
static void pht_insert(const uintptr_t vaddr, const pfn_t pfn)
{
uint32_t page = (vaddr >> 12) & 0xffff;
uint32_t api = (vaddr >> 22) & 0x3f;
uint32_t vsid;
asm volatile (
"mfsrin %0, %1\n"
: "=r" (vsid)
: "r" (vaddr)
);
uint32_t sdr1;
asm volatile (
"mfsdr1 %0\n"
: "=r" (sdr1)
);
phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000);
/* Primary hash (xor) */
uint32_t h = 0;
uint32_t hash = vsid ^ page;
uint32_t base = (hash & 0x3ff) << 3;
uint32_t i;
bool found = false;
/* Find unused or colliding
PTE in PTEG */
for (i = 0; i < 8; i++) {
if ((!phte[base + i].v) || ((phte[base + i].vsid == vsid) && (phte[base + i].api == api))) {
found = true;
break;
}
}
if (!found) {
/* Secondary hash (not) */
uint32_t base2 = (~hash & 0x3ff) << 3;
/* Find unused or colliding
PTE in PTEG */
for (i = 0; i < 8; i++) {
if ((!phte[base2 + i].v) || ((phte[base2 + i].vsid == vsid) && (phte[base2 + i].api == api))) {
found = true;
base = base2;
h = 1;
break;
}
}
if (!found) {
// TODO: A/C precedence groups
i = page % 8;
}
}
phte[base + i].v = 1;
phte[base + i].vsid = vsid;
phte[base + i].h = h;
phte[base + i].api = api;
phte[base + i].rpn = pfn;
phte[base + i].r = 0;
phte[base + i].c = 0;
phte[base + i].pp = 2; // FIXME
}
 
 
static void pht_real_insert(const uintptr_t vaddr, const pfn_t pfn)
{
uint32_t page = (vaddr >> 12) & 0xffff;
uint32_t api = (vaddr >> 22) & 0x3f;
uint32_t vsid;
asm volatile (
"mfsrin %0, %1\n"
: "=r" (vsid)
: "r" (vaddr)
);
uint32_t sdr1;
asm volatile (
"mfsdr1 %0\n"
: "=r" (sdr1)
);
phte_t *phte_physical = (phte_t *) (sdr1 & 0xffff0000);
/* Primary hash (xor) */
uint32_t h = 0;
uint32_t hash = vsid ^ page;
uint32_t base = (hash & 0x3ff) << 3;
uint32_t i;
bool found = false;
/* Find unused or colliding
PTE in PTEG */
for (i = 0; i < 8; i++) {
if ((!phte_physical[base + i].v) || ((phte_physical[base + i].vsid == vsid) && (phte_physical[base + i].api == api))) {
found = true;
break;
}
}
if (!found) {
/* Secondary hash (not) */
uint32_t base2 = (~hash & 0x3ff) << 3;
/* Find unused or colliding
PTE in PTEG */
for (i = 0; i < 8; i++) {
if ((!phte_physical[base2 + i].v) || ((phte_physical[base2 + i].vsid == vsid) && (phte_physical[base2 + i].api == api))) {
found = true;
base = base2;
h = 1;
break;
}
}
if (!found) {
// TODO: A/C precedence groups
i = page % 8;
}
}
phte_physical[base + i].v = 1;
phte_physical[base + i].vsid = vsid;
phte_physical[base + i].h = h;
phte_physical[base + i].api = api;
phte_physical[base + i].rpn = pfn;
phte_physical[base + i].r = 0;
phte_physical[base + i].c = 0;
phte_physical[base + i].pp = 2; // FIXME
}
 
 
/** Process Instruction/Data Storage Interrupt
*
* @param n Interrupt vector number.
* @param istate Interrupted register context.
*
*/
void pht_refill(int n, istate_t *istate)
{
uintptr_t badvaddr;
pte_t *pte;
int pfrc;
as_t *as;
bool lock;
if (AS == NULL) {
as = AS_KERNEL;
lock = false;
} else {
as = AS;
lock = true;
}
if (n == VECTOR_DATA_STORAGE) {
asm volatile (
"mfdar %0\n"
: "=r" (badvaddr)
);
} else
badvaddr = istate->pc;
page_table_lock(as, lock);
pte = find_mapping_and_check(as, lock, badvaddr, PF_ACCESS_READ /* FIXME */, istate, &pfrc);
if (!pte) {
switch (pfrc) {
case AS_PF_FAULT:
goto fail;
break;
case AS_PF_DEFER:
/*
* The page fault came during copy_from_uspace()
* or copy_to_uspace().
*/
page_table_unlock(as, lock);
return;
default:
panic("Unexpected pfrc (%d)\n", pfrc);
}
}
pte->a = 1; /* Record access to PTE */
pht_insert(badvaddr, pte->pfn);
page_table_unlock(as, lock);
return;
fail:
page_table_unlock(as, lock);
pht_refill_fail(badvaddr, istate);
}
 
 
/** Process Instruction/Data Storage Interrupt in Real Mode
*
* @param n Interrupt vector number.
* @param istate Interrupted register context.
*
*/
bool pht_real_refill(int n, istate_t *istate)
{
uintptr_t badvaddr;
if (n == VECTOR_DATA_STORAGE) {
asm volatile (
"mfdar %0\n"
: "=r" (badvaddr)
);
} else
badvaddr = istate->pc;
uint32_t physmem;
asm volatile (
"mfsprg3 %0\n"
: "=r" (physmem)
);
if ((badvaddr >= PA2KA(0)) && (badvaddr < PA2KA(physmem))) {
pht_real_insert(badvaddr, KA2PA(badvaddr) >> 12);
return true;
}
return false;
}
 
 
void tlb_arch_init(void)
{
tlb_invalidate_all();
}
 
 
void tlb_invalidate_all(void)
{
asm volatile (
"tlbia\n"
"tlbsync\n"
);
}
 
 
void tlb_invalidate_asid(asid_t asid)
{
uint32_t sdr1;
asm volatile (
"mfsdr1 %0\n"
: "=r" (sdr1)
);
phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000);
uint32_t i;
for (i = 0; i < 8192; i++) {
if ((phte[i].v) && (phte[i].vsid >= (asid << 4)) && (phte[i].vsid < ((asid << 4) + 16)))
phte[i].v = 0;
}
tlb_invalidate_all();
}
 
 
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt)
{
// TODO
tlb_invalidate_all();
}
 
 
#define PRINT_BAT(name, ureg, lreg) \
asm volatile ( \
"mfspr %0," #ureg "\n" \
"mfspr %1," #lreg "\n" \
: "=r" (upper), "=r" (lower) \
); \
mask = (upper & 0x1ffc) >> 2; \
if (upper & 3) { \
uint32_t tmp = mask; \
length = 128; \
while (tmp) { \
if ((tmp & 1) == 0) { \
printf("ibat[0]: error in mask\n"); \
break; \
} \
length <<= 1; \
tmp >>= 1; \
} \
} else \
length = 0; \
printf(name ": page=%.*p frame=%.*p length=%d KB (mask=%#x)%s%s\n", sizeof(upper) * 2, upper & 0xffff0000, sizeof(lower) * 2, lower & 0xffff0000, length, mask, ((upper >> 1) & 1) ? " supervisor" : "", (upper & 1) ? " user" : "");
 
 
void tlb_print(void)
{
uint32_t sr;
for (sr = 0; sr < 16; sr++) {
uint32_t vsid;
asm volatile (
"mfsrin %0, %1\n"
: "=r" (vsid)
: "r" (sr << 28)
);
printf("vsid[%d]: VSID=%.*p (ASID=%d)%s%s\n", sr, sizeof(vsid) * 2, vsid & 0xffffff, (vsid & 0xffffff) >> 4, ((vsid >> 30) & 1) ? " supervisor" : "", ((vsid >> 29) & 1) ? " user" : "");
}
uint32_t upper;
uint32_t lower;
uint32_t mask;
uint32_t length;
PRINT_BAT("ibat[0]", 528, 529);
PRINT_BAT("ibat[1]", 530, 531);
PRINT_BAT("ibat[2]", 532, 533);
PRINT_BAT("ibat[3]", 534, 535);
PRINT_BAT("dbat[0]", 536, 537);
PRINT_BAT("dbat[1]", 538, 539);
PRINT_BAT("dbat[2]", 540, 541);
PRINT_BAT("dbat[3]", 542, 543);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ppc32/src/mm/as.c
0,0 → 1,88
/*
* 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 ppc32mm
* @{
*/
/** @file
*/
 
#include <arch/mm/as.h>
#include <genarch/mm/as_pt.h>
#include <genarch/mm/asid_fifo.h>
#include <arch.h>
 
/** Architecture dependent address space init. */
void as_arch_init(void)
{
as_operations = &as_pt_operations;
asid_fifo_init();
}
 
/** Install address space.
*
* Install ASID.
*
* @param as Address space structure.
*
*/
void as_install_arch(as_t *as)
{
asid_t asid;
ipl_t ipl;
uint32_t sr;
 
ipl = interrupts_disable();
spinlock_lock(&as->lock);
asid = as->asid;
/* Lower 2 GB, user and supervisor access */
for (sr = 0; sr < 8; sr++) {
asm volatile (
"mtsrin %0, %1\n"
:
: "r" ((0x6000 << 16) + (asid << 4) + sr), "r" (sr << 28)
);
}
/* Upper 2 GB, only supervisor access */
for (sr = 8; sr < 16; sr++) {
asm volatile (
"mtsrin %0, %1\n"
:
: "r" ((0x4000 << 16) + (asid << 4) + sr), "r" (sr << 28)
);
}
spinlock_unlock(&as->lock);
interrupts_restore(ipl);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ppc32/src/mm/frame.c
0,0 → 1,79
/*
* Copyright (C) 2005 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 ppc32mm
* @{
*/
/** @file
*/
 
#include <arch/boot/boot.h>
#include <arch/mm/frame.h>
#include <arch/mm/memory_init.h>
#include <mm/frame.h>
#include <align.h>
#include <macros.h>
 
uintptr_t last_frame = 0;
 
void frame_arch_init(void)
{
pfn_t minconf = 2;
count_t i;
pfn_t start, conf;
size_t size;
for (i = 0; i < bootinfo.memmap.count; i++) {
start = ADDR2PFN(ALIGN_UP(bootinfo.memmap.zones[i].start, FRAME_SIZE));
size = SIZE2FRAMES(ALIGN_DOWN(bootinfo.memmap.zones[i].size, FRAME_SIZE));
if ((minconf < start) || (minconf >= start + size))
conf = start;
else
conf = minconf;
zone_create(start, size, conf, 0);
if (last_frame < ALIGN_UP(bootinfo.memmap.zones[i].start + bootinfo.memmap.zones[i].size, FRAME_SIZE))
last_frame = ALIGN_UP(bootinfo.memmap.zones[i].start + bootinfo.memmap.zones[i].size, FRAME_SIZE);
}
 
/* First is exception vector, second is 'implementation specific',
third and fourth is reserved, other contain real mode code */
frame_mark_unavailable(0, 8);
/* Mark the Page Hash Table frames as unavailable */
uint32_t sdr1;
asm volatile (
"mfsdr1 %0\n"
: "=r" (sdr1)
);
frame_mark_unavailable(ADDR2PFN(sdr1 & 0xffff000), 16); // FIXME
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ppc32/src/mm/page.c
0,0 → 1,64
/*
* Copyright (C) 2005 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 ppc32mm
* @{
*/
/** @file
*/
 
#include <genarch/mm/page_pt.h>
#include <mm/frame.h>
#include <mm/as.h>
#include <align.h>
#include <config.h>
 
void page_arch_init(void)
{
if (config.cpu_active == 1)
page_mapping_operations = &pt_mapping_operations;
}
 
 
uintptr_t hw_map(uintptr_t physaddr, size_t size)
{
if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH))
panic("Unable to map physical memory %p (%d bytes)", physaddr, size)
uintptr_t virtaddr = PA2KA(last_frame);
pfn_t i;
for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++)
page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE);
last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE);
return virtaddr;
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ppc32/src/mm/memory_init.c
0,0 → 1,56
/*
* Copyright (C) 2005 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 ppc32mm
* @{
*/
/** @file
*/
 
#include <arch/boot/boot.h>
#include <arch/mm/memory_init.h>
#include <typedefs.h>
#include <print.h>
 
 
size_t get_memory_size(void)
{
return bootinfo.memmap.total;
}
 
 
void memory_print_map(void)
{
count_t i;
for (i = 0; i < bootinfo.memmap.count; i++)
printf("base: %.*p size: %#x\n", sizeof(bootinfo.memmap.zones[i].start) * 2, bootinfo.memmap.zones[i].start, bootinfo.memmap.zones[i].size);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ppc32/src/interrupt.c
0,0 → 1,97
/*
* 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 ppc32interrupt
* @{
*/
/** @file
*/
 
#include <interrupt.h>
#include <arch/interrupt.h>
#include <arch/types.h>
#include <arch.h>
#include <time/clock.h>
#include <ipc/sysipc.h>
#include <arch/drivers/pic.h>
#include <arch/mm/tlb.h>
 
 
void start_decrementer(void)
{
asm volatile (
"mtdec %0\n"
:
: "r" (1000)
);
}
 
 
/** Handler of external interrupts */
static void exception_external(int n, istate_t *istate)
{
int inum;
 
while ((inum = pic_get_pending()) != -1) {
exc_dispatch(inum + INT_OFFSET, istate);
pic_ack_interrupt(inum);
}
}
 
 
static void exception_decrementer(int n, istate_t *istate)
{
clock();
start_decrementer();
}
 
 
/* Initialize basic tables for exception dispatching */
void interrupt_init(void)
{
exc_register(VECTOR_DATA_STORAGE, "data_storage", pht_refill);
exc_register(VECTOR_INSTRUCTION_STORAGE, "instruction_storage", pht_refill);
exc_register(VECTOR_EXTERNAL, "external", exception_external);
exc_register(VECTOR_DECREMENTER, "timer", exception_decrementer);
}
 
 
static void ipc_int(int n, istate_t *istate)
{
ipc_irq_send_notif(n - INT_OFFSET);
}
 
 
/* Reregister irq to be IPC-ready */
void irq_ipc_bind_arch(unative_t irq)
{
int_register(irq, "ipc_int", ipc_int);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ppc32/src/drivers/pic.c
0,0 → 1,95
/*
* Copyright (C) 2006 Ondrej Palkovsky
* 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 ppc32
* @{
*/
/** @file
*/
 
 
#include <arch/asm.h>
#include <arch/drivers/pic.h>
#include <byteorder.h>
#include <bitops.h>
 
static volatile uint32_t *pic;
 
void pic_init(uintptr_t base, size_t size)
{
pic = (uint32_t *) hw_map(base, size);
}
 
 
 
void pic_enable_interrupt(int intnum)
{
if (intnum < 32) {
pic[PIC_MASK_LOW] = pic[PIC_MASK_LOW] | (1 << intnum);
} else {
pic[PIC_MASK_HIGH] = pic[PIC_MASK_HIGH] | (1 << (intnum - 32));
}
}
 
void pic_disable_interrupt(int intnum)
{
if (intnum < 32) {
pic[PIC_MASK_LOW] = pic[PIC_MASK_LOW] & (~(1 << intnum));
} else {
pic[PIC_MASK_HIGH] = pic[PIC_MASK_HIGH] & (~(1 << (intnum - 32)));
}
}
 
void pic_ack_interrupt(int intnum)
{
if (intnum < 32)
pic[PIC_ACK_LOW] = 1 << intnum;
else
pic[PIC_ACK_HIGH] = 1 << (intnum - 32);
}
 
/** Return number of pending interrupt */
int pic_get_pending(void)
{
int pending;
 
pending = pic[PIC_PENDING_LOW];
if (pending) {
return fnzb32(pending);
}
pending = pic[PIC_PENDING_HIGH];
if (pending) {
return fnzb32(pending) + 32;
}
return -1;
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc32/src/drivers/cuda.c
0,0 → 1,327
/*
* 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 ppc32
* @{
*/
/** @file
*/
 
#include <arch/drivers/cuda.h>
#include <arch/asm.h>
#include <console/console.h>
#include <console/chardev.h>
#include <arch/drivers/pic.h>
#include <sysinfo/sysinfo.h>
#include <interrupt.h>
#include <stdarg.h>
 
#define SPECIAL '?'
 
#define PACKET_ADB 0x00
#define PACKET_CUDA 0x01
 
#define CUDA_POWERDOWN 0x0a
 
#define RS 0x200
#define B (0 * RS)
#define A (1 * RS)
#define SR (10 * RS)
#define ACR (11 * RS)
 
#define SR_OUT 0x10
#define TACK 0x10
#define TIP 0x20
 
 
static volatile uint8_t *cuda = NULL;
static iroutine vector;
 
 
static char lchars[0x80] = {
'a',
's',
'd',
'f',
'h',
'g',
'z',
'x',
'c',
'v',
SPECIAL,
'b',
'q',
'w',
'e',
'r',
'y',
't',
'1',
'2',
'3',
'4',
'6',
'5',
'=',
'9',
'7',
'-',
'8',
'0',
']',
'o',
'u',
'[',
'i',
'p',
'\n', /* Enter */
'l',
'j',
'\'',
'k',
';',
'\\',
',',
'/',
'n',
'm',
'.',
'\t', /* Tab */
' ',
'`',
'\b', /* Backspace */
SPECIAL,
SPECIAL, /* Escape */
SPECIAL, /* Ctrl */
SPECIAL, /* Alt */
SPECIAL, /* Shift */
SPECIAL, /* Caps-Lock */
SPECIAL, /* RAlt */
SPECIAL, /* Left */
SPECIAL, /* Right */
SPECIAL, /* Down */
SPECIAL, /* Up */
SPECIAL,
SPECIAL,
'.', /* Keypad . */
SPECIAL,
'*', /* Keypad * */
SPECIAL,
'+', /* Keypad + */
SPECIAL,
SPECIAL, /* NumLock */
SPECIAL,
SPECIAL,
SPECIAL,
'/', /* Keypad / */
'\n', /* Keypad Enter */
SPECIAL,
'-', /* Keypad - */
SPECIAL,
SPECIAL,
SPECIAL,
'0', /* Keypad 0 */
'1', /* Keypad 1 */
'2', /* Keypad 2 */
'3', /* Keypad 3 */
'4', /* Keypad 4 */
'5', /* Keypad 5 */
'6', /* Keypad 6 */
'7', /* Keypad 7 */
SPECIAL,
'8', /* Keypad 8 */
'9', /* Keypad 9 */
SPECIAL,
SPECIAL,
SPECIAL,
SPECIAL, /* F5 */
SPECIAL, /* F6 */
SPECIAL, /* F7 */
SPECIAL, /* F3 */
SPECIAL, /* F8 */
SPECIAL, /* F9 */
SPECIAL,
SPECIAL, /* F11 */
SPECIAL,
SPECIAL, /* F13 */
SPECIAL,
SPECIAL, /* ScrollLock */
SPECIAL,
SPECIAL, /* F10 */
SPECIAL,
SPECIAL, /* F12 */
SPECIAL,
SPECIAL, /* Pause */
SPECIAL, /* Insert */
SPECIAL, /* Home */
SPECIAL, /* PageUp */
SPECIAL, /* Delete */
SPECIAL, /* F4 */
SPECIAL, /* End */
SPECIAL, /* F2 */
SPECIAL, /* PageDown */
SPECIAL /* F1 */
};
 
 
void send_packet(const uint8_t kind, index_t count, ...);
 
 
static void receive_packet(uint8_t *kind, index_t count, uint8_t data[])
{
cuda[B] = cuda[B] & ~TIP;
*kind = cuda[SR];
index_t i;
for (i = 0; i < count; i++)
data[i] = cuda[SR];
cuda[B] = cuda[B] | TIP;
}
 
 
/* Called from getc(). */
static void cuda_resume(chardev_t *d)
{
}
 
 
/* Called from getc(). */
static void cuda_suspend(chardev_t *d)
{
}
 
 
static char key_read(chardev_t *d)
{
char ch;
ch = 0;
return ch;
}
 
 
static chardev_t kbrd;
static chardev_operations_t ops = {
.suspend = cuda_suspend,
.resume = cuda_resume,
.read = key_read
};
 
 
int cuda_get_scancode(void)
{
uint8_t kind;
uint8_t data[4];
receive_packet(&kind, 4, data);
if ((kind == PACKET_ADB) && (data[0] == 0x40) && (data[1] == 0x2c))
return data[2];
return -1;
}
 
static void cuda_irq(int n, istate_t *istate)
{
int scan_code = cuda_get_scancode();
if (scan_code != -1) {
uint8_t scancode = (uint8_t) scan_code;
if ((scancode & 0x80) != 0x80)
chardev_push_character(&kbrd, lchars[scancode & 0x7f]);
}
}
 
 
/** Initialize keyboard and service interrupts using kernel routine */
void cuda_grab(void)
{
vector = int_register(CUDA_IRQ, "cuda", cuda_irq);
}
 
 
/** Resume the former interrupt vector */
void cuda_release(void)
{
if (vector)
int_register(CUDA_IRQ, "user_interrupt", vector);
}
 
 
void cuda_init(uintptr_t base, size_t size)
{
cuda = (uint8_t *) hw_map(base, size);
int_register(CUDA_IRQ, "cuda", cuda_irq);
pic_enable_interrupt(CUDA_IRQ);
chardev_initialize("cuda_kbd", &kbrd, &ops);
stdin = &kbrd;
sysinfo_set_item_val("cuda", NULL, true);
sysinfo_set_item_val("cuda.irq", NULL, CUDA_IRQ);
}
 
 
void send_packet(const uint8_t kind, index_t count, ...)
{
index_t i;
va_list va;
cuda[B] = cuda[B] | TIP;
cuda[ACR] = cuda[ACR] | SR_OUT;
cuda[SR] = kind;
cuda[B] = cuda[B] & ~TIP;
va_start(va, count);
for (i = 0; i < count; i++) {
cuda[ACR] = cuda[ACR] | SR_OUT;
cuda[SR] = va_arg(va, int);
cuda[B] = cuda[B] | TACK;
}
va_end(va);
cuda[B] = cuda[B] | TIP;
}
 
 
void cpu_halt(void) {
#ifdef CONFIG_POWEROFF
send_packet(PACKET_CUDA, 1, CUDA_POWERDOWN);
#endif
asm volatile (
"b 0\n"
);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ppc32/src/cpu/cpu.c
0,0 → 1,82
/*
* Copyright (C) 2005 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 ppc32
* @{
*/
/** @file
*/
 
#include <arch/cpu.h>
#include <arch/cpuid.h>
#include <cpu.h>
 
#include <arch.h>
 
#include <typedefs.h>
#include <print.h>
 
void cpu_arch_init(void)
{
}
 
void cpu_identify(void)
{
cpu_info_t info;
cpu_version(&info);
CPU->arch.version = info.version;
CPU->arch.revision = info.revision;
}
 
void cpu_print_report(cpu_t *m)
{
char *name;
switch (m->arch.version) {
case 8:
name = " (PowerPC 750)";
break;
case 9:
name = " (PowerPC 604e)";
break;
case 0x81:
name = " (PowerPC 8260)";
break;
case 0x8081:
name = " (PowerPC 826xA)";
break;
default:
name = "";
}
printf("cpu%d: version=%d%s, revision=%d\n", m->id, m->arch.version, name, m->arch.revision);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ppc32/src/exception.S
0,0 → 1,328
#
# 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/asm/regname.h>
#include <arch/mm/page.h>
 
.section K_UNMAPPED_TEXT_START, "ax"
 
.macro CONTEXT_STORE
# save R12 in SPRG1, backup CR in R12
# save SP in SPRG2
 
mtsprg1 r12
mfcr r12
mtsprg2 sp
# check whether SP is in kernel
andis. sp, sp, 0x8000
bne 1f
# stack is in user-space
mfsprg0 sp
b 2f
1:
# stack is in kernel
mfsprg2 sp
subis sp, sp, 0x8000
2:
subi sp, sp, 160
stw r0, 8(sp)
stw r2, 12(sp)
stw r3, 16(sp)
stw r4, 20(sp)
stw r5, 24(sp)
stw r6, 28(sp)
stw r7, 32(sp)
stw r8, 36(sp)
stw r9, 40(sp)
stw r10, 44(sp)
stw r11, 48(sp)
stw r13, 52(sp)
stw r14, 56(sp)
stw r15, 60(sp)
stw r16, 64(sp)
stw r17, 68(sp)
stw r18, 72(sp)
stw r19, 76(sp)
stw r20, 80(sp)
stw r21, 84(sp)
stw r22, 88(sp)
stw r23, 92(sp)
stw r24, 96(sp)
stw r25, 100(sp)
stw r26, 104(sp)
stw r27, 108(sp)
stw r28, 112(sp)
stw r29, 116(sp)
stw r30, 120(sp)
stw r31, 124(sp)
stw r12, 128(sp)
mfsrr0 r12
stw r12, 132(sp)
mfsrr1 r12
stw r12, 136(sp)
mflr r12
stw r12, 140(sp)
mfctr r12
stw r12, 144(sp)
mfxer r12
stw r12, 148(sp)
mfsprg1 r12
stw r12, 152(sp)
mfsprg2 r12
stw r12, 156(sp)
.endm
 
.org 0x100
.global exc_system_reset
exc_system_reset:
CONTEXT_STORE
li r3, 0
b jump_to_kernel
 
.org 0x200
.global exc_machine_check
exc_machine_check:
CONTEXT_STORE
li r3, 1
b jump_to_kernel
 
.org 0x300
.global exc_data_storage
exc_data_storage:
CONTEXT_STORE
li r3, 2
mr r4, sp
addi r4, r4, 8
bl pht_real_refill
cmpwi r3, 0
bne iret_real
li r3, 2
b jump_to_kernel
 
.org 0x400
.global exc_instruction_storage
exc_instruction_storage:
CONTEXT_STORE
li r3, 3
mr r4, sp
addi r4, r4, 8
bl pht_real_refill
cmpwi r3, 0
bne iret_real
 
li r3, 3
b jump_to_kernel
 
.org 0x500
.global exc_external
exc_external:
CONTEXT_STORE
li r3, 4
b jump_to_kernel
 
.org 0x600
.global exc_alignment
exc_alignment:
CONTEXT_STORE
li r3, 5
b jump_to_kernel
 
.org 0x700
.global exc_program
exc_program:
CONTEXT_STORE
li r3, 6
b jump_to_kernel
 
.org 0x800
.global exc_fp_unavailable
exc_fp_unavailable:
CONTEXT_STORE
li r3, 7
b jump_to_kernel
 
.org 0x900
.global exc_decrementer
exc_decrementer:
CONTEXT_STORE
li r3, 8
b jump_to_kernel
 
.org 0xa00
.global exc_reserved0
exc_reserved0:
CONTEXT_STORE
li r3, 9
b jump_to_kernel
 
.org 0xb00
.global exc_reserved1
exc_reserved1:
CONTEXT_STORE
li r3, 10
b jump_to_kernel
 
.org 0xc00
.global exc_syscall
exc_syscall:
CONTEXT_STORE
b jump_to_kernel_syscall
 
.org 0xd00
.global exc_trace
exc_trace:
CONTEXT_STORE
li r3, 12
b jump_to_kernel
 
.org 0x4000
jump_to_kernel:
lis r12, iret@ha
addi r12, r12, iret@l
mtlr r12
lis r12, exc_dispatch@ha
addi r12, r12, exc_dispatch@l
mtsrr0 r12
mfmsr r12
ori r12, r12, (msr_ir | msr_dr)@l
mtsrr1 r12
addis sp, sp, 0x8000
mr r4, sp
addi r4, r4, 8
rfi
 
jump_to_kernel_syscall:
lis r12, syscall_handler@ha
addi r12, r12, syscall_handler@l
mtsrr0 r12
lis r12, iret_syscall@ha
addi r12, r12, iret_syscall@l
mtlr r12
mfmsr r12
ori r12, r12, (msr_ir | msr_dr)@l
mtsrr1 r12
addis sp, sp, 0x8000
rfi
 
iret_real:
lwz r0, 8(sp)
lwz r2, 12(sp)
lwz r3, 16(sp)
lwz r4, 20(sp)
lwz r5, 24(sp)
lwz r6, 28(sp)
lwz r7, 32(sp)
lwz r8, 36(sp)
lwz r9, 40(sp)
lwz r10, 44(sp)
lwz r11, 48(sp)
lwz r13, 52(sp)
lwz r14, 56(sp)
lwz r15, 60(sp)
lwz r16, 64(sp)
lwz r17, 68(sp)
lwz r18, 72(sp)
lwz r19, 76(sp)
lwz r20, 80(sp)
lwz r21, 84(sp)
lwz r22, 88(sp)
lwz r23, 92(sp)
lwz r24, 96(sp)
lwz r25, 100(sp)
lwz r26, 104(sp)
lwz r27, 108(sp)
lwz r28, 112(sp)
lwz r29, 116(sp)
lwz r30, 120(sp)
lwz r31, 124(sp)
lwz r12, 128(sp)
mtcr r12
lwz r12, 132(sp)
mtsrr0 r12
lwz r12, 136(sp)
mtsrr1 r12
lwz r12, 140(sp)
mtlr r12
lwz r12, 144(sp)
mtctr r12
lwz r12, 148(sp)
mtxer r12
lwz r12, 152(sp)
lwz sp, 156(sp)
rfi
/tags/0.2.0.3/kernel/arch/ppc32/src/proc/scheduler.c
0,0 → 1,62
/*
* 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 ppc32proc
* @{
*/
/** @file
*/
 
#include <arch/mm/page.h>
#include <arch/boot/boot.h>
#include <proc/scheduler.h>
#include <proc/thread.h>
#include <arch.h>
 
/** Perform ppc32 specific tasks needed before the new task is run. */
void before_task_runs_arch(void)
{
}
 
/** Perform ppc32 specific tasks needed before the new thread is scheduled. */
void before_thread_runs_arch(void)
{
tlb_invalidate_all();
asm volatile (
"mtsprg0 %0\n"
:
: "r" (KA2PA(&THREAD->kstack[THREAD_STACK_SIZE - SP_DELTA]))
);
}
 
void after_thread_ran_arch(void)
{
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ppc32/src/boot/boot.S
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.
#
 
#include <arch/asm/regname.h>
#include <arch/boot/boot.h>
 
.section K_TEXT_START, "ax"
 
.global kernel_image_start
kernel_image_start:
 
# load temporal kernel stack
lis sp, kernel_stack@ha
addi sp, sp, kernel_stack@l
# set kernel stack for interrupt handling
mr r31, sp
subis r31, r31, 0x8000
mtsprg0 r31
# r3 contains physical address of bootinfo_t
# r4 contains size of bootinfo_t
cmpwi r4, 0
beq bootinfo_end
addis r3, r3, 0x8000
 
lis r31, bootinfo@ha
addi r31, r31, bootinfo@l # r31 = bootinfo
bootinfo_loop:
lwz r30, 0(r3)
stw r30, 0(r31)
addi r3, r3, 4
addi r31, r31, 4
subi r4, r4, 4
cmpwi r4, 0
bgt bootinfo_loop
bootinfo_end:
bl arch_pre_main
b main_bsp
 
.section K_DATA_START, "aw", @progbits
 
.align 12
kernel_stack_bottom:
.space TEMP_STACK_SIZE
kernel_stack:
/tags/0.2.0.3/kernel/arch/ppc32/src/asm.S
0,0 → 1,311
#
# Copyright (C) 2005 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/asm/regname.h>
 
.text
 
.global userspace_asm
.global iret
.global iret_syscall
.global memsetb
.global memcpy
.global memcpy_from_uspace
.global memcpy_to_uspace
.global memcpy_from_uspace_failover_address
.global memcpy_to_uspace_failover_address
 
userspace_asm:
 
# r3 = uspace_uarg
# r4 = stack
# r5 = entry
# disable interrupts
 
mfmsr r31
rlwinm r31, r31, 0, 17, 15
mtmsr r31
# set entry point
mtsrr0 r5
# set problem state, enable interrupts
ori r31, r31, msr_pr
ori r31, r31, msr_ee
mtsrr1 r31
# set stack
mr sp, r4
# jump to userspace
rfi
 
iret:
# disable interrupts
mfmsr r31
rlwinm r31, r31, 0, 17, 15
mtmsr r31
lwz r0, 8(sp)
lwz r2, 12(sp)
lwz r3, 16(sp)
lwz r4, 20(sp)
lwz r5, 24(sp)
lwz r6, 28(sp)
lwz r7, 32(sp)
lwz r8, 36(sp)
lwz r9, 40(sp)
lwz r10, 44(sp)
lwz r11, 48(sp)
lwz r13, 52(sp)
lwz r14, 56(sp)
lwz r15, 60(sp)
lwz r16, 64(sp)
lwz r17, 68(sp)
lwz r18, 72(sp)
lwz r19, 76(sp)
lwz r20, 80(sp)
lwz r21, 84(sp)
lwz r22, 88(sp)
lwz r23, 92(sp)
lwz r24, 96(sp)
lwz r25, 100(sp)
lwz r26, 104(sp)
lwz r27, 108(sp)
lwz r28, 112(sp)
lwz r29, 116(sp)
lwz r30, 120(sp)
lwz r31, 124(sp)
lwz r12, 128(sp)
mtcr r12
lwz r12, 132(sp)
mtsrr0 r12
lwz r12, 136(sp)
mtsrr1 r12
lwz r12, 140(sp)
mtlr r12
lwz r12, 144(sp)
mtctr r12
lwz r12, 148(sp)
mtxer r12
lwz r12, 152(sp)
lwz sp, 156(sp)
rfi
 
iret_syscall:
# reset decrementer
 
li r31, 1000
mtdec r31
# disable interrupts
mfmsr r31
rlwinm r31, r31, 0, 17, 15
mtmsr r31
lwz r0, 8(sp)
lwz r2, 12(sp)
lwz r4, 20(sp)
lwz r5, 24(sp)
lwz r6, 28(sp)
lwz r7, 32(sp)
lwz r8, 36(sp)
lwz r9, 40(sp)
lwz r10, 44(sp)
lwz r11, 48(sp)
lwz r13, 52(sp)
lwz r14, 56(sp)
lwz r15, 60(sp)
lwz r16, 64(sp)
lwz r17, 68(sp)
lwz r18, 72(sp)
lwz r19, 76(sp)
lwz r20, 80(sp)
lwz r21, 84(sp)
lwz r22, 88(sp)
lwz r23, 92(sp)
lwz r24, 96(sp)
lwz r25, 100(sp)
lwz r26, 104(sp)
lwz r27, 108(sp)
lwz r28, 112(sp)
lwz r29, 116(sp)
lwz r30, 120(sp)
lwz r31, 124(sp)
lwz r12, 128(sp)
mtcr r12
lwz r12, 132(sp)
mtsrr0 r12
lwz r12, 136(sp)
mtsrr1 r12
lwz r12, 140(sp)
mtlr r12
lwz r12, 144(sp)
mtctr r12
lwz r12, 148(sp)
mtxer r12
lwz r12, 152(sp)
lwz sp, 156(sp)
 
rfi
memsetb:
rlwimi r5, r5, 8, 16, 23
rlwimi r5, r5, 16, 0, 15
addi r14, r3, -4
cmplwi 0, r4, 4
blt 7f
stwu r5, 4(r14)
beqlr
andi. r15, r14, 3
add r4, r15, r4
subf r14, r15, r14
srwi r15, r4, 2
mtctr r15
bdz 6f
1:
stwu r5, 4(r14)
bdnz 1b
6:
andi. r4, r4, 3
7:
cmpwi 0, r4, 0
beqlr
mtctr r4
addi r6, r6, 3
8:
stbu r5, 1(r14)
bdnz 8b
blr
 
memcpy:
memcpy_from_uspace:
memcpy_to_uspace:
 
srwi. r7, r5, 3
addi r6, r3, -4
addi r4, r4, -4
beq 2f
andi. r0, r6, 3
mtctr r7
bne 5f
1:
lwz r7, 4(r4)
lwzu r8, 8(r4)
stw r7, 4(r6)
stwu r8, 8(r6)
bdnz 1b
andi. r5, r5, 7
2:
cmplwi 0, r5, 4
blt 3f
lwzu r0, 4(r4)
addi r5, r5, -4
stwu r0, 4(r6)
3:
cmpwi 0, r5, 0
beqlr
mtctr r5
addi r4, r4, 3
addi r6, r6, 3
4:
lbzu r0, 1(r4)
stbu r0, 1(r6)
bdnz 4b
blr
5:
subfic r0, r0, 4
mtctr r0
6:
lbz r7, 4(r4)
addi r4, r4, 1
stb r7, 4(r6)
addi r6, r6, 1
bdnz 6b
subf r5, r0, r5
rlwinm. r7, r5, 32-3, 3, 31
beq 2b
mtctr r7
b 1b
 
memcpy_from_uspace_failover_address:
memcpy_to_uspace_failover_address:
b memcpy_from_uspace_failover_address
/tags/0.2.0.3/kernel/arch/ppc32/src/dummy.s
0,0 → 1,38
#
# 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.
#
 
.text
 
.global asm_delay_loop
.global sys_tls_set
 
sys_tls_set:
b sys_tls_set
 
asm_delay_loop:
blr
/tags/0.2.0.3/kernel/arch/ppc32/src/fpu_context.S
0,0 → 1,105
#
# 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/asm/regname.h>
#include <arch/context_offset.h>
 
.text
 
.global fpu_context_save
.global fpu_context_restore
.global fpu_init
.global fpu_enable
.global fpu_disable
 
.macro FPU_CONTEXT_STORE r
stfd fr14, OFFSET_FR14(\r)
stfd fr15, OFFSET_FR15(\r)
stfd fr16, OFFSET_FR16(\r)
stfd fr17, OFFSET_FR17(\r)
stfd fr18, OFFSET_FR18(\r)
stfd fr19, OFFSET_FR19(\r)
stfd fr20, OFFSET_FR20(\r)
stfd fr21, OFFSET_FR21(\r)
stfd fr22, OFFSET_FR22(\r)
stfd fr23, OFFSET_FR23(\r)
stfd fr24, OFFSET_FR24(\r)
stfd fr25, OFFSET_FR25(\r)
stfd fr26, OFFSET_FR26(\r)
stfd fr27, OFFSET_FR27(\r)
stfd fr28, OFFSET_FR28(\r)
stfd fr29, OFFSET_FR29(\r)
stfd fr30, OFFSET_FR30(\r)
stfd fr31, OFFSET_FR31(\r)
.endm
 
.macro FPU_CONTEXT_LOAD r
lfd fr14, OFFSET_FR14(\r)
lfd fr15, OFFSET_FR15(\r)
lfd fr16, OFFSET_FR16(\r)
lfd fr17, OFFSET_FR17(\r)
lfd fr18, OFFSET_FR18(\r)
lfd fr19, OFFSET_FR19(\r)
lfd fr20, OFFSET_FR20(\r)
lfd fr21, OFFSET_FR21(\r)
lfd fr22, OFFSET_FR22(\r)
lfd fr23, OFFSET_FR23(\r)
lfd fr24, OFFSET_FR24(\r)
lfd fr25, OFFSET_FR25(\r)
lfd fr26, OFFSET_FR26(\r)
lfd fr27, OFFSET_FR27(\r)
lfd fr28, OFFSET_FR28(\r)
lfd fr29, OFFSET_FR29(\r)
lfd fr30, OFFSET_FR30(\r)
lfd fr31, OFFSET_FR31(\r)
.endm
 
fpu_context_save:
// FPU_CONTEXT_STORE r3
//
// mffs fr0
// stfd fr0, OFFSET_FPSCR(r3)
blr
fpu_context_restore:
// FPU_CONTEXT_LOAD r3
//
// lfd fr0, OFFSET_FPSCR(r3)
// mtfsf 7, fr0
blr
 
fpu_init:
blr
 
fpu_enable:
blr
 
fpu_disable:
blr
/tags/0.2.0.3/kernel/arch/ppc32/src/context.S
0,0 → 1,109
#
# Copyright (C) 2005 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/asm/regname.h>
#include <arch/context_offset.h>
 
.text
 
.global context_save_arch
.global context_restore_arch
 
.macro CONTEXT_STORE r
stw sp, OFFSET_SP(\r)
stw r2, OFFSET_R2(\r)
stw r13, OFFSET_R13(\r)
stw r14, OFFSET_R14(\r)
stw r15, OFFSET_R15(\r)
stw r16, OFFSET_R16(\r)
stw r17, OFFSET_R17(\r)
stw r18, OFFSET_R18(\r)
stw r19, OFFSET_R19(\r)
stw r20, OFFSET_R20(\r)
stw r21, OFFSET_R21(\r)
stw r22, OFFSET_R22(\r)
stw r23, OFFSET_R23(\r)
stw r24, OFFSET_R24(\r)
stw r25, OFFSET_R25(\r)
stw r26, OFFSET_R26(\r)
stw r27, OFFSET_R27(\r)
stw r28, OFFSET_R28(\r)
stw r29, OFFSET_R29(\r)
stw r30, OFFSET_R30(\r)
stw r31, OFFSET_R31(\r)
.endm
 
.macro CONTEXT_LOAD r
lwz sp, OFFSET_SP(\r)
lwz r2, OFFSET_R2(\r)
lwz r13, OFFSET_R13(\r)
lwz r14, OFFSET_R14(\r)
lwz r15, OFFSET_R15(\r)
lwz r16, OFFSET_R16(\r)
lwz r17, OFFSET_R17(\r)
lwz r18, OFFSET_R18(\r)
lwz r19, OFFSET_R19(\r)
lwz r20, OFFSET_R20(\r)
lwz r21, OFFSET_R21(\r)
lwz r22, OFFSET_R22(\r)
lwz r23, OFFSET_R23(\r)
lwz r24, OFFSET_R24(\r)
lwz r25, OFFSET_R25(\r)
lwz r26, OFFSET_R26(\r)
lwz r27, OFFSET_R27(\r)
lwz r28, OFFSET_R28(\r)
lwz r29, OFFSET_R29(\r)
lwz r30, OFFSET_R30(\r)
lwz r31, OFFSET_R31(\r)
.endm
 
context_save_arch:
CONTEXT_STORE r3
mflr r4
stw r4, OFFSET_PC(r3)
mfcr r4
stw r4, OFFSET_CR(r3)
# context_save returns 1
li r3, 1
blr
context_restore_arch:
CONTEXT_LOAD r3
lwz r4, OFFSET_CR(r3)
mtcr r4
lwz r4, OFFSET_PC(r3)
mtlr r4
# context_restore returns 0
li r3, 0
blr
/tags/0.2.0.3/kernel/arch/ppc32/src/debug/panic.s
0,0 → 1,38
#
# Copyright (C) 2005 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/asm/macro.h>
 
.text
.global panic_printf
 
panic_printf:
lis %r14, halt@ha
addi %r14, %r14, halt@l
mtlr %r14 # fake stack to make printf return to halt
b printf
/tags/0.2.0.3/kernel/arch/ppc32/include/exception.h
0,0 → 1,104
/*
* 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 ppc32
* @{
*/
/** @file
*/
 
#ifndef __ppc32_EXCEPTION_H__
#define __ppc32_EXCEPTION_H__
 
#ifndef __ppc32_TYPES_H__
# include <arch/types.h>
#endif
 
#include <typedefs.h>
 
struct istate {
uint32_t r0;
uint32_t r2;
uint32_t r3;
uint32_t r4;
uint32_t r5;
uint32_t r6;
uint32_t r7;
uint32_t r8;
uint32_t r9;
uint32_t r10;
uint32_t r11;
uint32_t r13;
uint32_t r14;
uint32_t r15;
uint32_t r16;
uint32_t r17;
uint32_t r18;
uint32_t r19;
uint32_t r20;
uint32_t r21;
uint32_t r22;
uint32_t r23;
uint32_t r24;
uint32_t r25;
uint32_t r26;
uint32_t r27;
uint32_t r28;
uint32_t r29;
uint32_t r30;
uint32_t r31;
uint32_t cr;
uint32_t pc;
uint32_t srr1;
uint32_t lr;
uint32_t ctr;
uint32_t xer;
uint32_t r12;
uint32_t sp;
};
 
static inline void istate_set_retaddr(istate_t *istate, uintptr_t retaddr)
{
istate->pc = retaddr;
}
/** Return true if exception happened while in userspace */
#include <panic.h>
static inline int istate_from_uspace(istate_t *istate)
{
panic("istate_from_uspace not yet implemented");
return 0;
}
static inline unative_t istate_get_pc(istate_t *istate)
{
return istate->pc;
}
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ppc32/include/fpu_context.h
0,0 → 1,68
/*
* Copyright (C) 2005 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 ppc32
* @{
*/
/** @file
*/
 
#ifndef __ppc32_FPU_CONTEXT_H__
#define __ppc32_FPU_CONTEXT_H__
 
#ifndef __ppc32_TYPES_H__
# include <arch/types.h>
#endif
 
struct fpu_context {
uint64_t fr14;
uint64_t fr15;
uint64_t fr16;
uint64_t fr17;
uint64_t fr18;
uint64_t fr19;
uint64_t fr20;
uint64_t fr21;
uint64_t fr22;
uint64_t fr23;
uint64_t fr24;
uint64_t fr25;
uint64_t fr26;
uint64_t fr27;
uint64_t fr28;
uint64_t fr29;
uint64_t fr30;
uint64_t fr31;
uint32_t fpscr;
} __attribute__ ((packed));
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc32/include/byteorder.h
0,0 → 1,74
/*
* 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 ppc32
* @{
*/
/** @file
*/
 
#ifndef __ppc32_BYTEORDER_H__
#define __ppc32_BYTEORDER_H__
 
#include <arch/types.h>
#include <byteorder.h>
 
#define BIG_ENDIAN
 
static inline uint64_t uint64_t_le2host(uint64_t n)
{
return uint64_t_byteorder_swap(n);
}
 
 
/** Convert little-endian unative_t to host unative_t
*
* Convert little-endian unative_t parameter to host endianess.
*
* @param n Little-endian unative_t argument.
*
* @return Result in host endianess.
*
*/
static inline unative_t unative_t_le2host(unative_t n)
{
uintptr_t v;
asm volatile (
"lwbrx %0, %1, %2\n"
: "=r" (v)
: "i" (0), "r" (&n)
);
return v;
}
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc32/include/cpuid.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 ppc32
* @{
*/
/** @file
*/
 
#ifndef __ppc32_CPUID_H__
#define __ppc32_CPUID_H__
 
#include <arch/types.h>
 
struct cpu_info {
uint16_t version;
uint16_t revision;
} __attribute__ ((packed));
 
static inline void cpu_version(struct cpu_info *info)
{
asm volatile (
"mfpvr %0\n"
: "=r" (*info)
);
}
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ppc32/include/types.h
0,0 → 1,69
/*
* Copyright (C) 2005 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 ppc32
* @{
*/
/** @file
*/
 
#ifndef __ppc32_TYPES_H__
#define __ppc32_TYPES_H__
 
#define NULL 0
 
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef signed long long int64_t;
 
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
 
typedef uint32_t uintptr_t;
typedef uint32_t pfn_t;
 
typedef uint32_t ipl_t;
 
typedef uint32_t unative_t;
 
/** Page Table Entry. */
typedef struct {
unsigned p : 1; /**< Present bit. */
unsigned a : 1; /**< Accessed bit. */
unsigned g : 1; /**< Global bit. */
unsigned valid : 1; /**< Valid content even if not present. */
unsigned pfn : 20; /**< Physical frame number. */
} pte_t;
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ppc32/include/memstr.h
0,0 → 1,49
/*
* Copyright (C) 2005 Sergey Bondari
* 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 ppc32
* @{
*/
/** @file
*/
 
#ifndef __ppc32_MEMSTR_H__
#define __ppc32_MEMSTR_H__
 
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt))
 
extern void memsetw(uintptr_t dst, size_t cnt, uint16_t x);
extern void memsetb(uintptr_t dst, size_t cnt, uint8_t x);
 
extern int memcmp(uintptr_t src, uintptr_t dst, int cnt);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc32/include/boot/boot.h
0,0 → 1,98
/*
* 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 ppc32
* @{
*/
/** @file
*/
 
#ifndef __ppc32_BOOT_H__
#define __ppc32_BOOT_H__
 
#define BOOT_OFFSET 0x8000
 
/* Temporary stack size for boot process */
#define TEMP_STACK_SIZE 0x100
 
#define TASKMAP_MAX_RECORDS 32
#define MEMMAP_MAX_RECORDS 32
 
#ifndef __ASM__
 
#include <arch/types.h>
 
typedef struct {
uintptr_t addr;
uint32_t size;
} utask_t;
 
typedef struct {
uint32_t count;
utask_t tasks[TASKMAP_MAX_RECORDS];
} taskmap_t;
 
typedef struct {
uintptr_t start;
uint32_t size;
} memzone_t;
 
typedef struct {
uint32_t total;
uint32_t count;
memzone_t zones[MEMMAP_MAX_RECORDS];
} memmap_t;
 
typedef struct {
uintptr_t addr;
unsigned int width;
unsigned int height;
unsigned int bpp;
unsigned int scanline;
} screen_t;
 
typedef struct {
uintptr_t addr;
unsigned int size;
} keyboard_t;
 
typedef struct {
memmap_t memmap;
taskmap_t taskmap;
screen_t screen;
keyboard_t keyboard;
} bootinfo_t;
 
extern bootinfo_t bootinfo;
 
#endif
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ppc32/include/asm.h
0,0 → 1,156
/*
* Copyright (C) 2005 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 ppc32
* @{
*/
/** @file
*/
 
#ifndef __ppc32_ASM_H__
#define __ppc32_ASM_H__
 
#include <arch/types.h>
#include <config.h>
 
/** Enable interrupts.
*
* Enable interrupts and return previous
* value of EE.
*
* @return Old interrupt priority level.
*/
static inline ipl_t interrupts_enable(void)
{
ipl_t v;
ipl_t tmp;
asm volatile (
"mfmsr %0\n"
"mfmsr %1\n"
"ori %1, %1, 1 << 15\n"
"mtmsr %1\n"
: "=r" (v), "=r" (tmp)
);
return v;
}
 
/** Disable interrupts.
*
* Disable interrupts and return previous
* value of EE.
*
* @return Old interrupt priority level.
*/
static inline ipl_t interrupts_disable(void)
{
ipl_t v;
ipl_t tmp;
asm volatile (
"mfmsr %0\n"
"mfmsr %1\n"
"rlwinm %1, %1, 0, 17, 15\n"
"mtmsr %1\n"
: "=r" (v), "=r" (tmp)
);
return v;
}
 
/** Restore interrupt priority level.
*
* Restore EE.
*
* @param ipl Saved interrupt priority level.
*/
static inline void interrupts_restore(ipl_t ipl)
{
ipl_t tmp;
asm volatile (
"mfmsr %1\n"
"rlwimi %0, %1, 0, 17, 15\n"
"cmpw 0, %0, %1\n"
"beq 0f\n"
"mtmsr %0\n"
"0:\n"
: "=r" (ipl), "=r" (tmp)
: "0" (ipl)
: "cr0"
);
}
 
/** Return interrupt priority level.
*
* Return EE.
*
* @return Current interrupt priority level.
*/
static inline ipl_t interrupts_read(void)
{
ipl_t v;
asm volatile (
"mfmsr %0\n"
: "=r" (v)
);
return v;
}
 
/** 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 (
"and %0, %%sp, %1\n"
: "=r" (v)
: "r" (~(STACK_SIZE - 1))
);
return v;
}
 
static inline void cpu_sleep(void)
{
}
 
void cpu_halt(void);
void asm_delay_loop(uint32_t t);
 
extern void userspace_asm(uintptr_t uspace_uarg, uintptr_t stack, uintptr_t entry);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc32/include/faddr.h
0,0 → 1,46
/*
* Copyright (C) 2005 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 ppc32
* @{
*/
/** @file
*/
 
#ifndef __ppc32_FADDR_H__
#define __ppc32_FADDR_H__
 
#include <arch/types.h>
 
#define FADDR(fptr) ((uintptr_t) (fptr))
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc32/include/mm/frame.h
0,0 → 1,56
/*
* Copyright (C) 2005 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 ppc32mm
* @{
*/
/** @file
*/
 
#ifndef __ppc32_FRAME_H__
#define __ppc32_FRAME_H__
 
#define FRAME_WIDTH 12 /* 4K */
#define FRAME_SIZE (1 << FRAME_WIDTH)
 
#ifdef KERNEL
#ifndef __ASM__
 
#include <arch/types.h>
 
extern uintptr_t last_frame;
 
extern void frame_arch_init(void);
 
#endif /* __ASM__ */
#endif /* KERNEL */
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ppc32/include/mm/page.h
0,0 → 1,142
/*
* Copyright (C) 2005 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 ppc32mm
* @{
*/
/** @file
*/
 
#ifndef __ppc32_PAGE_H__
#define __ppc32_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,
* the hardware Page Hash Table is used as cache.
*
* Page table layout:
* - 32-bit virtual addressess
* - Offset is 12 bits => pages are 4K long
* - PTL0 has 1024 entries (10 bits)
* - PTL1 is not used
* - PTL2 is not used
* - PLT3 has 1024 entries (10 bits)
*/
 
#define PTL0_ENTRIES_ARCH 1024
#define PTL1_ENTRIES_ARCH 0
#define PTL2_ENTRIES_ARCH 0
#define PTL3_ENTRIES_ARCH 1024
 
#define PTL0_INDEX_ARCH(vaddr) (((vaddr) >> 22) & 0x3ff)
#define PTL1_INDEX_ARCH(vaddr) 0
#define PTL2_INDEX_ARCH(vaddr) 0
#define PTL3_INDEX_ARCH(vaddr) (((vaddr) >> 12) & 0x3ff)
 
#define GET_PTL1_ADDRESS_ARCH(ptl0, i) (((pte_t *) (ptl0))[(i)].pfn << 12)
#define GET_PTL2_ADDRESS_ARCH(ptl1, i) (ptl1)
#define GET_PTL3_ADDRESS_ARCH(ptl2, i) (ptl2)
#define GET_FRAME_ADDRESS_ARCH(ptl3, i) (((pte_t *) (ptl3))[(i)].pfn << 12)
 
#define SET_PTL0_ADDRESS_ARCH(ptl0)
#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) (((pte_t *) (ptl0))[(i)].pfn = (a) >> 12)
#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) (((pte_t *) (ptl3))[(i)].pfn = (a) >> 12)
 
#define GET_PTL1_FLAGS_ARCH(ptl0, i) get_pt_flags((pte_t *) (ptl0), (index_t) (i))
#define GET_PTL2_FLAGS_ARCH(ptl1, i) PAGE_PRESENT
#define GET_PTL3_FLAGS_ARCH(ptl2, i) PAGE_PRESENT
#define GET_FRAME_FLAGS_ARCH(ptl3, i) get_pt_flags((pte_t *) (ptl3), (index_t) (i))
 
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) set_pt_flags((pte_t *) (ptl0), (index_t) (i), (x))
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x)
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) set_pt_flags((pte_t *) (ptl3), (index_t) (i), (x))
 
#define PTE_VALID_ARCH(pte) (*((uint32_t *) (pte)) != 0)
#define PTE_PRESENT_ARCH(pte) ((pte)->p != 0)
#define PTE_GET_FRAME_ARCH(pte) ((pte)->pfn << 12)
#define PTE_WRITABLE_ARCH(pte) 1
#define PTE_EXECUTABLE_ARCH(pte) 1
 
#ifndef __ASM__
 
#include <mm/page.h>
#include <arch/mm/frame.h>
#include <arch/types.h>
 
static inline int get_pt_flags(pte_t *pt, index_t i)
{
pte_t *p = &pt[i];
return (
(1 << PAGE_CACHEABLE_SHIFT) |
((!p->p) << PAGE_PRESENT_SHIFT) |
(1 << PAGE_USER_SHIFT) |
(1 << PAGE_READ_SHIFT) |
(1 << PAGE_WRITE_SHIFT) |
(1 << PAGE_EXEC_SHIFT) |
(p->g << PAGE_GLOBAL_SHIFT)
);
}
 
static inline void set_pt_flags(pte_t *pt, index_t i, int flags)
{
pte_t *p = &pt[i];
p->p = !(flags & PAGE_NOT_PRESENT);
p->g = (flags & PAGE_GLOBAL) != 0;
p->valid = 1;
}
 
extern void page_arch_init(void);
 
#endif /* __ASM__ */
 
#endif /* KERNEL */
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ppc32/include/mm/asid.h
0,0 → 1,47
/*
* 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 ppc32mm
* @{
*/
/** @file
*/
 
#ifndef __ppc32_ASID_H__
#define __ppc32_ASID_H__
 
#include <arch/types.h>
 
#define ASID_MAX_ARCH 4096
 
typedef uint32_t asid_t;
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ppc32/include/mm/memory_init.h
0,0 → 1,47
/*
* Copyright (C) 2005 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 ppc32mm
* @{
*/
/** @file
*/
 
#ifndef __ppc32_MEMORY_INIT_H__
#define __ppc32_MEMORY_INIT_H__
 
#include <typedefs.h>
 
size_t get_memory_size(void);
 
void memory_print_map(void);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ppc32/include/mm/tlb.h
0,0 → 1,59
/*
* Copyright (C) 2006 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ppc32mm
* @{
*/
/** @file
*/
 
#ifndef __ppc32_TLB_H__
#define __ppc32_TLB_H__
 
typedef struct {
unsigned v : 1; /**< Valid */
unsigned vsid : 24; /**< Virtual Segment ID */
unsigned h : 1; /**< Primary/secondary hash */
unsigned api : 6; /**< Abbreviated Page Index */
unsigned rpn : 20; /**< Real Page Number */
unsigned reserved0 : 3;
unsigned r : 1; /**< Reference */
unsigned c : 1; /**< Change */
unsigned wimg : 4; /**< Access control */
unsigned reserved1 : 1;
unsigned pp : 2; /**< Page protection */
} phte_t;
 
extern void pht_refill(int n, istate_t *istate);
extern bool pht_real_refill(int n, istate_t *istate) __attribute__ ((section("K_UNMAPPED_TEXT_START")));
extern void pht_init(void);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ppc32/include/mm/as.h
0,0 → 1,52
/*
* Copyright (C) 2005 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 ppc32mm
* @{
*/
/** @file
*/
 
#ifndef __ppc32_AS_H__
#define __ppc32_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 (0x7fffffff-(PAGE_SIZE-1))
 
extern void as_arch_init(void);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ppc32/include/context.h
0,0 → 1,78
/*
* Copyright (C) 2005 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 ppc32
* @{
*/
/** @file
*/
 
#ifndef __ppc32_CONTEXT_H__
#define __ppc32_CONTEXT_H__
 
#ifndef __ppc32_TYPES_H__
# include <arch/types.h>
#endif
 
#define SP_DELTA 16
 
struct context {
uintptr_t sp;
uintptr_t pc;
uint32_t r2;
uint32_t r13;
uint32_t r14;
uint32_t r15;
uint32_t r16;
uint32_t r17;
uint32_t r18;
uint32_t r19;
uint32_t r20;
uint32_t r21;
uint32_t r22;
uint32_t r23;
uint32_t r24;
uint32_t r25;
uint32_t r26;
uint32_t r27;
uint32_t r28;
uint32_t r29;
uint32_t r30;
uint32_t r31;
uint32_t cr;
ipl_t ipl;
} __attribute__ ((packed));
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc32/include/drivers/pic.h
0,0 → 1,54
/*
* Copyright (C) 2006 Ondrej Palkovsky
* 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 ppc32
* @{
*/
/** @file
*/
 
#ifndef __PIC_H_
#define __PIC_H_
 
#define PIC_PENDING_LOW 8
#define PIC_PENDING_HIGH 4
#define PIC_MASK_LOW 9
#define PIC_MASK_HIGH 5
#define PIC_ACK_LOW 10
#define PIC_ACK_HIGH 6
 
void pic_init(uintptr_t base, size_t size);
void pic_enable_interrupt(int intnum);
void pic_disable_interrupt(int intnum);
void pic_ack_interrupt(int intnum);
int pic_get_pending(void);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ppc32/include/drivers/cuda.h
0,0 → 1,51
/*
* 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 ppc32
* @{
*/
/** @file
*/
 
#ifndef __CUDA_H__
#define __CUDA_H__
 
#include <arch/types.h>
#include <typedefs.h>
 
#define CUDA_IRQ 10
 
extern void cuda_init(uintptr_t base, size_t size);
extern int cuda_get_scancode(void);
extern void cuda_grab(void);
extern void cuda_release(void);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ppc32/include/asm/regname.h
0,0 → 1,231
/*
* Copyright (C) 2005 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 ppc32
* @{
*/
/** @file
*/
 
#ifndef __ppc32_REGNAME_H__
#define __ppc32_REGNAME_H__
 
/* Condition Register Bit Fields */
#define cr0 0
#define cr1 1
#define cr2 2
#define cr3 3
#define cr4 4
#define cr5 5
#define cr6 6
#define cr7 7
 
/* General Purpose Registers (GPRs) */
#define r0 0
#define r1 1
#define r2 2
#define r3 3
#define r4 4
#define r5 5
#define r6 6
#define r7 7
#define r8 8
#define r9 9
#define r10 10
#define r11 11
#define r12 12
#define r13 13
#define r14 14
#define r15 15
#define r16 16
#define r17 17
#define r18 18
#define r19 19
#define r20 20
#define r21 21
#define r22 22
#define r23 23
#define r24 24
#define r25 25
#define r26 26
#define r27 27
#define r28 28
#define r29 29
#define r30 30
#define r31 31
 
/* GPR Aliases */
#define sp 1
 
/* Floating Point Registers (FPRs) */
#define fr0 0
#define fr1 1
#define fr2 2
#define fr3 3
#define fr4 4
#define fr5 5
#define fr6 6
#define fr7 7
#define fr8 8
#define fr9 9
#define fr10 10
#define fr11 11
#define fr12 12
#define fr13 13
#define fr14 14
#define fr15 15
#define fr16 16
#define fr17 17
#define fr18 18
#define fr19 19
#define fr20 20
#define fr21 21
#define fr22 22
#define fr23 23
#define fr24 24
#define fr25 25
#define fr26 26
#define fr27 27
#define fr28 28
#define fr29 29
#define fr30 30
#define fr31 31
 
#define vr0 0
#define vr1 1
#define vr2 2
#define vr3 3
#define vr4 4
#define vr5 5
#define vr6 6
#define vr7 7
#define vr8 8
#define vr9 9
#define vr10 10
#define vr11 11
#define vr12 12
#define vr13 13
#define vr14 14
#define vr15 15
#define vr16 16
#define vr17 17
#define vr18 18
#define vr19 19
#define vr20 20
#define vr21 21
#define vr22 22
#define vr23 23
#define vr24 24
#define vr25 25
#define vr26 26
#define vr27 27
#define vr28 28
#define vr29 29
#define vr30 30
#define vr31 31
 
#define evr0 0
#define evr1 1
#define evr2 2
#define evr3 3
#define evr4 4
#define evr5 5
#define evr6 6
#define evr7 7
#define evr8 8
#define evr9 9
#define evr10 10
#define evr11 11
#define evr12 12
#define evr13 13
#define evr14 14
#define evr15 15
#define evr16 16
#define evr17 17
#define evr18 18
#define evr19 19
#define evr20 20
#define evr21 21
#define evr22 22
#define evr23 23
#define evr24 24
#define evr25 25
#define evr26 26
#define evr27 27
#define evr28 28
#define evr29 29
#define evr30 30
#define evr31 31
 
/* Special Purpose Registers (SPRs) */
#define xer 1
#define lr 8
#define ctr 9
#define dec 22
#define sdr1 25
#define srr0 26
#define srr1 27
#define sprg0 272
#define sprg1 273
#define sprg2 274
#define sprg3 275
#define prv 287
#define ibat0u 528
#define ibat0l 529
#define ibat1u 530
#define ibat1l 531
#define ibat2u 532
#define ibat2l 533
#define ibat3u 534
#define ibat3l 535
#define dbat0u 536
#define dbat0l 537
#define dbat1u 538
#define dbat1l 539
#define dbat2u 540
#define dbat2l 541
#define dbat3u 542
#define dbat3l 543
#define hid0 1008
 
/* MSR bits */
#define msr_ir (1 << 4)
#define msr_dr (1 << 5)
#define msr_pr (1 << 14)
#define msr_ee (1 << 15)
 
/* HID0 bits */
#define hid0_ice (1 << 15)
#define hid0_dce (1 << 14)
#define hid0_icfi (1 << 11)
#define hid0_dci (1 << 10)
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ppc32/include/cpu.h
0,0 → 1,48
/*
* Copyright (C) 2005 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 ppc32
* @{
*/
/** @file
*/
 
#ifndef __ppc32_CPU_H__
#define __ppc32_CPU_H__
 
#include <typedefs.h>
 
struct cpu_arch {
int version;
int revision;
};
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ppc32/include/interrupt.h
0,0 → 1,60
/*
* Copyright (C) 2005 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 ppc32interrupt
* @{
*/
/** @file
*/
 
#ifndef __ppc32_INTERRUPT_H__
#define __ppc32_INTERRUPT_H__
 
#include <arch/exception.h>
 
#define IRQ_COUNT 64
 
 
#define IVT_ITEMS (16 + IRQ_COUNT)
#define INT_OFFSET 16
 
#define int_register(it, name, handler) exc_register(((it) + INT_OFFSET), name, handler)
 
#define VECTOR_DATA_STORAGE 2
#define VECTOR_INSTRUCTION_STORAGE 3
#define VECTOR_EXTERNAL 4
#define VECTOR_DECREMENTER 8
 
extern void start_decrementer(void);
extern void interrupt_init(void);
extern void extint_handler(int n, istate_t *istate);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ppc32/include/arch.h
0,0 → 1,43
/*
* Copyright (C) 2005 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 ppc32
* @{
*/
/** @file
*/
 
#ifndef __ppc32_ARCH_H__
#define __ppc32_ARCH_H__
 
#include <arch/drivers/cuda.h>
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ppc32/include/debug.h
0,0 → 1,42
/*
* Copyright (C) 2005
* 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 ppc32debug
* @{
*/
/** @file
*/
 
#ifndef __ppc32_DEBUG_H__
#define __ppc32_DEBUG_H__
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc32/include/context_offset.h
0,0 → 1,49
/* This file is automatically generated by gencontext.c. */
/* struct context */
#define OFFSET_SP 0x0
#define OFFSET_PC 0x4
#define OFFSET_R2 0x8
#define OFFSET_R13 0xc
#define OFFSET_R14 0x10
#define OFFSET_R15 0x14
#define OFFSET_R16 0x18
#define OFFSET_R17 0x1c
#define OFFSET_R18 0x20
#define OFFSET_R19 0x24
#define OFFSET_R20 0x28
#define OFFSET_R21 0x2c
#define OFFSET_R22 0x30
#define OFFSET_R23 0x34
#define OFFSET_R24 0x38
#define OFFSET_R25 0x3c
#define OFFSET_R26 0x40
#define OFFSET_R27 0x44
#define OFFSET_R28 0x48
#define OFFSET_R29 0x4c
#define OFFSET_R30 0x50
#define OFFSET_R31 0x54
#define OFFSET_CR 0x58
 
#define OFFSET_FR14 0x0
#define OFFSET_FR15 0x8
#define OFFSET_FR16 0x10
#define OFFSET_FR17 0x18
#define OFFSET_FR18 0x20
#define OFFSET_FR19 0x28
#define OFFSET_FR20 0x30
#define OFFSET_FR21 0x38
#define OFFSET_FR22 0x40
#define OFFSET_FR23 0x48
#define OFFSET_FR24 0x50
#define OFFSET_FR25 0x58
#define OFFSET_FR26 0x60
#define OFFSET_FR27 0x68
#define OFFSET_FR28 0x70
#define OFFSET_FR29 0x78
#define OFFSET_FR30 0x80
#define OFFSET_FR31 0x88
#define OFFSET_FPSCR 0x90
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc32/include/elf.h
0,0 → 1,46
/*
* Copyright (C) 2006 Sergey Bondari
* 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 ppc32
* @{
*/
/** @file
*/
 
#ifndef __ppc32_ELF_H__
#define __ppc32_ELF_H__
 
#define ELF_MACHINE EM_PPC
#define ELF_DATA_ENCODING ELFDATA2MSB
#define ELF_CLASS ELFCLASS32
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc32/include/arg.h
0,0 → 1,44
/*
* Copyright (C) 2005 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 ppc32
* @{
*/
/** @file
*/
 
#ifndef __ppc32_ARG_H__
#define __ppc32_ARG_H__
 
#include <stdarg.h>
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc32/include/atomic.h
0,0 → 1,98
/*
* Copyright (C) 2005 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 ppc32
* @{
*/
/** @file
*/
 
#ifndef __ppc32_ATOMIC_H__
#define __ppc32_ATOMIC_H__
 
static inline void atomic_inc(atomic_t *val)
{
long tmp;
 
asm volatile (
"1:\n"
"lwarx %0, 0, %2\n"
"addic %0, %0, 1\n"
"stwcx. %0, 0, %2\n"
"bne- 1b"
: "=&r" (tmp), "=m" (val->count)
: "r" (&val->count), "m" (val->count)
: "cc"
);
}
 
static inline void atomic_dec(atomic_t *val)
{
long tmp;
 
asm volatile (
"1:\n"
"lwarx %0, 0, %2\n"
"addic %0, %0, -1\n"
"stwcx. %0, 0, %2\n"
"bne- 1b"
: "=&r" (tmp), "=m" (val->count)
: "r" (&val->count), "m" (val->count)
: "cc"
);
}
 
static inline long atomic_postinc(atomic_t *val)
{
atomic_inc(val);
return val->count - 1;
}
 
static inline long atomic_postdec(atomic_t *val)
{
atomic_dec(val);
return val->count + 1;
}
 
static inline long atomic_preinc(atomic_t *val)
{
atomic_inc(val);
return val->count;
}
 
static inline long atomic_predec(atomic_t *val)
{
atomic_dec(val);
return val->count;
}
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc32/include/proc/task.h
0,0 → 1,48
/*
* 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 ppc32proc
* @{
*/
/** @file
*/
 
#ifndef __ppc32_TASK_H__
#define __ppc32_TASK_H__
 
typedef struct {
} task_arch_t;
 
#define task_create_arch(t)
#define task_destroy_arch(t)
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc32/include/proc/thread.h
0,0 → 1,47
/*
* Copyright (C) 2005 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 ppc32proc
* @{
*/
/** @file
*/
 
#ifndef __ppc32_THREAD_H__
#define __ppc32_THREAD_H__
 
typedef struct {
} thread_arch_t;
 
#define thread_create_arch(t)
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc32/include/barrier.h
0,0 → 1,49
/*
* Copyright (C) 2005 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 ppc32
* @{
*/
/** @file
*/
 
#ifndef __ppc32_BARRIER_H__
#define __ppc32_BARRIER_H__
 
#define CS_ENTER_BARRIER() asm volatile ("" ::: "memory")
#define CS_LEAVE_BARRIER() asm volatile ("" ::: "memory")
 
#define memory_barrier() asm volatile ("sync" ::: "memory")
#define read_barrier() asm volatile ("sync" ::: "memory")
#define write_barrier() asm volatile ("eieio" ::: "memory")
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc32/_link.ld.in
0,0 → 1,59
/** PPC32 linker script
*
* umapped section:
* kernel text
* kernel data
* mapped section:
* kernel text
* kernel data
*
*/
 
#define __ASM__
#include <arch/boot/boot.h>
#include <arch/mm/page.h>
 
ENTRY(kernel_image_start)
OUTPUT_FORMAT("elf32-powerpc")
OUTPUT_ARCH("powerpc:common")
 
SECTIONS {
.unmapped 0: AT (0) {
unmapped_ktext_start = .;
*(K_UNMAPPED_TEXT_START);
unmapped_ktext_end = .;
unmapped_kdata_start = .;
*(K_UNMAPPED_DATA_START);
unmapped_kdata_start = .;
}
.mapped PA2KA(BOOT_OFFSET): AT (BOOT_OFFSET) {
ktext_start = .;
*(K_TEXT_START);
*(.text);
ktext_end = .;
kdata_start = .;
*(K_DATA_START);
*(.rodata);
*(.rodata.*);
*(.data); /* initialized data */
*(.sdata);
*(.sdata2);
*(.sbss);
hardcoded_ktext_size = .;
LONG(ktext_end - ktext_start);
hardcoded_kdata_size = .;
LONG(kdata_end - kdata_start);
hardcoded_load_address = .;
LONG(PA2KA(BOOT_OFFSET));
*(.bss); /* uninitialized static variables */
*(COMMON); /* global variables */
 
symbol_table = .;
*(symtab.*); /* Symbol table, must be LAST symbol!*/
 
kdata_end = .;
}
}
/tags/0.2.0.3/kernel/arch/ppc64/Makefile.inc
0,0 → 1,72
#
# 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 = elf64-powerpc
BFD_ARCH = powerpc:common64
BFD = binary
TARGET = ppc64-linux-gnu
TOOLCHAIN_DIR = /usr/local/ppc64/bin
 
CFLAGS += -mcpu=powerpc64 -msoft-float -m64
AFLAGS += -a64
LFLAGS += -no-check-sections -N
 
DEFS += -D__64_BITS__
 
## Own configuration directives
#
 
CONFIG_FB = y
 
## Compile with hierarchical page tables support.
#
 
CONFIG_PAGE_PT = y
DEFS += -DCONFIG_PAGE_PT
 
ARCH_SOURCES = \
arch/$(ARCH)/src/context.S \
arch/$(ARCH)/src/debug/panic.s \
arch/$(ARCH)/src/fpu_context.S \
arch/$(ARCH)/src/boot/boot.S \
arch/$(ARCH)/src/ppc64.c \
arch/$(ARCH)/src/dummy.s \
arch/$(ARCH)/src/exception.S \
arch/$(ARCH)/src/interrupt.c \
arch/$(ARCH)/src/asm.S \
arch/$(ARCH)/src/cpu/cpu.c \
arch/$(ARCH)/src/proc/scheduler.c \
arch/$(ARCH)/src/ddi/ddi.c \
arch/$(ARCH)/src/mm/as.c \
arch/$(ARCH)/src/mm/frame.c \
arch/$(ARCH)/src/mm/memory_init.c \
arch/$(ARCH)/src/mm/page.c \
arch/$(ARCH)/src/mm/tlb.c
/tags/0.2.0.3/kernel/arch/ppc64/include/exception.h
0,0 → 1,105
/*
* 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 ppc64
* @{
*/
/** @file
*/
 
#ifndef __ppc64_EXCEPTION_H__
#define __ppc64_EXCEPTION_H__
 
#ifndef __ppc64_TYPES_H__
# include <arch/types.h>
#endif
 
#include <typedefs.h>
 
struct istate {
uint64_t r0;
uint64_t r2;
uint64_t r3;
uint64_t r4;
uint64_t r5;
uint64_t r6;
uint64_t r7;
uint64_t r8;
uint64_t r9;
uint64_t r10;
uint64_t r11;
uint64_t r13;
uint64_t r14;
uint64_t r15;
uint64_t r16;
uint64_t r17;
uint64_t r18;
uint64_t r19;
uint64_t r20;
uint64_t r21;
uint64_t r22;
uint64_t r23;
uint64_t r24;
uint64_t r25;
uint64_t r26;
uint64_t r27;
uint64_t r28;
uint64_t r29;
uint64_t r30;
uint64_t r31;
uint64_t cr;
uint64_t pc;
uint64_t srr1;
uint64_t lr;
uint64_t ctr;
uint64_t xer;
uint64_t r12;
uint64_t sp;
};
 
static inline void istate_set_retaddr(istate_t *istate, uintptr_t retaddr)
{
istate->pc = retaddr;
}
/** Return true if exception happened while in userspace */
#include <panic.h>
static inline int istate_from_uspace(istate_t *istate)
{
panic("istate_from_uspace not yet implemented");
return 0;
}
static inline unative_t istate_get_pc(istate_t *istate)
{
return istate->pc;
}
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/include/fpu_context.h
0,0 → 1,68
/*
* Copyright (C) 2005 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 ppc64
* @{
*/
/** @file
*/
 
#ifndef __ppc64_FPU_CONTEXT_H__
#define __ppc64_FPU_CONTEXT_H__
 
#ifndef __ppc64_TYPES_H__
# include <arch/types.h>
#endif
 
struct fpu_context {
uint64_t fr14;
uint64_t fr15;
uint64_t fr16;
uint64_t fr17;
uint64_t fr18;
uint64_t fr19;
uint64_t fr20;
uint64_t fr21;
uint64_t fr22;
uint64_t fr23;
uint64_t fr24;
uint64_t fr25;
uint64_t fr26;
uint64_t fr27;
uint64_t fr28;
uint64_t fr29;
uint64_t fr30;
uint64_t fr31;
uint32_t fpscr;
} __attribute__ ((packed));
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/include/byteorder.h
0,0 → 1,74
/*
* 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 ppc64
* @{
*/
/** @file
*/
 
#ifndef __ppc64_BYTEORDER_H__
#define __ppc64_BYTEORDER_H__
 
#include <arch/types.h>
#include <byteorder.h>
 
#define BIG_ENDIAN
 
static inline uint64_t uint64_t_le2host(uint64_t n)
{
return uint64_t_byteorder_swap(n);
}
 
 
/** Convert little-endian unative_t to host unative_t
*
* Convert little-endian unative_t parameter to host endianess.
*
* @param n Little-endian unative_t argument.
*
* @return Result in host endianess.
*
*/
static inline unative_t unative_t_le2host(unative_t n)
{
uintptr_t v;
asm volatile (
"lwbrx %0, %1, %2\n"
: "=r" (v)
: "i" (0), "r" (&n)
);
return v;
}
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/include/cpuid.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 ppc64
* @{
*/
/** @file
*/
 
#ifndef __ppc64_CPUID_H__
#define __ppc64_CPUID_H__
 
#include <arch/types.h>
 
struct cpu_info {
uint16_t version;
uint16_t revision;
} __attribute__ ((packed));
 
static inline void cpu_version(struct cpu_info *info)
{
asm volatile (
"mfpvr %0\n"
: "=r" (*info)
);
}
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ppc64/include/types.h
0,0 → 1,70
/*
* 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 ppc64
* @{
*/
/** @file
*/
 
#ifndef __ppc64_TYPES_H__
#define __ppc64_TYPES_H__
 
#define NULL 0
 
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef signed long int64_t;
 
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long uint64_t;
 
typedef uint64_t uintptr_t;
typedef uint64_t pfn_t;
 
typedef uint64_t ipl_t;
 
typedef uint64_t unative_t;
 
/** Page Table Entry. */
typedef struct {
unsigned p : 1; /**< Present bit. */
unsigned a : 1; /**< Accessed bit. */
unsigned g : 1; /**< Global bit. */
unsigned valid : 1; /**< Valid content even if not present. */
unsigned pfn : 20; /**< Physical frame number. */
} pte_t;
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/include/memstr.h
0,0 → 1,49
/*
* Copyright (C) 2005 Sergey Bondari
* 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 ppc64
* @{
*/
/** @file
*/
 
#ifndef __ppc64_MEMSTR_H__
#define __ppc64_MEMSTR_H__
 
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt))
 
extern void memsetw(uintptr_t dst, size_t cnt, uint16_t x);
extern void memsetb(uintptr_t dst, size_t cnt, uint8_t x);
 
extern int memcmp(uintptr_t src, uintptr_t dst, int cnt);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/include/boot/boot.h
0,0 → 1,93
/*
* 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 ppc64
* @{
*/
/** @file
*/
 
#ifndef __ppc64_BOOT_H__
#define __ppc64_BOOT_H__
 
#define BOOT_OFFSET 0x4000
 
/* Temporary stack size for boot process */
#define TEMP_STACK_SIZE 0x100
 
#define TASKMAP_MAX_RECORDS 32
#define MEMMAP_MAX_RECORDS 32
 
#ifndef __ASM__
 
#include <arch/types.h>
 
typedef struct {
uintptr_t addr;
uint64_t size;
} utask_t;
 
typedef struct {
uint32_t count;
utask_t tasks[TASKMAP_MAX_RECORDS];
} taskmap_t;
 
typedef struct {
uintptr_t start;
uint64_t size;
} memzone_t;
 
typedef struct {
uint64_t total;
uint32_t count;
memzone_t zones[MEMMAP_MAX_RECORDS];
} memmap_t;
 
typedef struct {
uintptr_t addr;
unsigned int width;
unsigned int height;
unsigned int bpp;
unsigned int scanline;
} screen_t;
 
typedef struct {
taskmap_t taskmap;
memmap_t memmap;
screen_t screen;
} bootinfo_t;
 
extern bootinfo_t bootinfo;
 
#endif
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/include/faddr.h
0,0 → 1,46
/*
* Copyright (C) 2005 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 ppc64
* @{
*/
/** @file
*/
 
#ifndef __ppc64_FADDR_H__
#define __ppc64_FADDR_H__
 
#include <arch/types.h>
 
#define FADDR(fptr) ((uintptr_t) (fptr))
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/include/asm.h
0,0 → 1,162
/*
* Copyright (C) 2005 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 ppc64
* @{
*/
/** @file
*/
 
#ifndef __ppc64_ASM_H__
#define __ppc64_ASM_H__
 
#include <arch/types.h>
#include <config.h>
 
/** Enable interrupts.
*
* Enable interrupts and return previous
* value of EE.
*
* @return Old interrupt priority level.
*/
static inline ipl_t interrupts_enable(void)
{
ipl_t v;
ipl_t tmp;
asm volatile (
"mfmsr %0\n"
"mfmsr %1\n"
"ori %1, %1, 1 << 15\n"
"mtmsr %1\n"
: "=r" (v), "=r" (tmp)
);
return v;
}
 
/** Disable interrupts.
*
* Disable interrupts and return previous
* value of EE.
*
* @return Old interrupt priority level.
*/
static inline ipl_t interrupts_disable(void)
{
ipl_t v;
ipl_t tmp;
asm volatile (
"mfmsr %0\n"
"mfmsr %1\n"
"rlwinm %1, %1, 0, 17, 15\n"
"mtmsr %1\n"
: "=r" (v), "=r" (tmp)
);
return v;
}
 
/** Restore interrupt priority level.
*
* Restore EE.
*
* @param ipl Saved interrupt priority level.
*/
static inline void interrupts_restore(ipl_t ipl)
{
ipl_t tmp;
asm volatile (
"mfmsr %1\n"
"rlwimi %0, %1, 0, 17, 15\n"
"cmpw 0, %0, %1\n"
"beq 0f\n"
"mtmsr %0\n"
"0:\n"
: "=r" (ipl), "=r" (tmp)
: "0" (ipl)
: "cr0"
);
}
 
/** Return interrupt priority level.
*
* Return EE.
*
* @return Current interrupt priority level.
*/
static inline ipl_t interrupts_read(void)
{
ipl_t v;
asm volatile (
"mfmsr %0\n"
: "=r" (v)
);
return v;
}
 
/** 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 (
"and %0, %%sp, %1\n"
: "=r" (v)
: "r" (~(STACK_SIZE - 1))
);
return v;
}
 
static inline void cpu_sleep(void)
{
}
 
static inline void cpu_halt(void)
{
asm volatile (
"b 0\n"
);
}
 
void asm_delay_loop(uint32_t t);
 
extern void userspace_asm(uintptr_t uspace_uarg, uintptr_t stack, uintptr_t entry);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/include/mm/frame.h
0,0 → 1,57
/*
* Copyright (C) 2005 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 ppc64mm
* @{
*/
/** @file
*/
 
#ifndef __ppc64_FRAME_H__
#define __ppc64_FRAME_H__
 
#define FRAME_WIDTH 12 /* 4K */
#define FRAME_SIZE (1 << FRAME_WIDTH)
 
#ifdef KERNEL
#ifndef __ASM__
 
#include <arch/types.h>
 
extern uintptr_t last_frame;
 
extern void frame_arch_init(void);
 
#endif /* __ASM__ */
#endif /* KERNEL */
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/include/mm/page.h
0,0 → 1,163
/*
* Copyright (C) 2005 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 ppc64mm
* @{
*/
/** @file
*/
 
#ifndef __ppc64_PAGE_H__
#define __ppc64_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,
* the hardware Page Hash Table is used as cache.
*
* Page table layout:
* - 32-bit virtual addressess
* - Offset is 12 bits => pages are 4K long
* - PTL0 has 1024 entries (10 bits)
* - PTL1 is not used
* - PTL2 is not used
* - PLT3 has 1024 entries (10 bits)
*/
 
#define PTL0_ENTRIES_ARCH 1024
#define PTL1_ENTRIES_ARCH 0
#define PTL2_ENTRIES_ARCH 0
#define PTL3_ENTRIES_ARCH 1024
 
#define PTL0_INDEX_ARCH(vaddr) (((vaddr) >> 22) & 0x3ff)
#define PTL1_INDEX_ARCH(vaddr) 0
#define PTL2_INDEX_ARCH(vaddr) 0
#define PTL3_INDEX_ARCH(vaddr) (((vaddr) >> 12) & 0x3ff)
 
#define GET_PTL1_ADDRESS_ARCH(ptl0, i) (((pte_t *) (ptl0))[(i)].pfn << 12)
#define GET_PTL2_ADDRESS_ARCH(ptl1, i) (ptl1)
#define GET_PTL3_ADDRESS_ARCH(ptl2, i) (ptl2)
#define GET_FRAME_ADDRESS_ARCH(ptl3, i) (((pte_t *) (ptl3))[(i)].pfn << 12)
 
#define SET_PTL0_ADDRESS_ARCH(ptl0)
#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) (((pte_t *) (ptl0))[(i)].pfn = (a) >> 12)
#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) (((pte_t *) (ptl3))[(i)].pfn = (a) >> 12)
 
#define GET_PTL1_FLAGS_ARCH(ptl0, i) get_pt_flags((pte_t *) (ptl0), (index_t) (i))
#define GET_PTL2_FLAGS_ARCH(ptl1, i) PAGE_PRESENT
#define GET_PTL3_FLAGS_ARCH(ptl2, i) PAGE_PRESENT
#define GET_FRAME_FLAGS_ARCH(ptl3, i) get_pt_flags((pte_t *) (ptl3), (index_t) (i))
 
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) set_pt_flags((pte_t *) (ptl0), (index_t) (i), (x))
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x)
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) set_pt_flags((pte_t *) (ptl3), (index_t) (i), (x))
 
#define PTE_VALID_ARCH(pte) (*((uint32_t *) (pte)) != 0)
#define PTE_PRESENT_ARCH(pte) ((pte)->p != 0)
#define PTE_GET_FRAME_ARCH(pte) ((uintptr_t) ((pte)->pfn << 12))
#define PTE_WRITABLE_ARCH(pte) 1
#define PTE_EXECUTABLE_ARCH(pte) 1
 
#ifndef __ASM__
 
#include <mm/page.h>
#include <arch/mm/frame.h>
#include <arch/types.h>
 
static inline int get_pt_flags(pte_t *pt, index_t i)
{
pte_t *p = &pt[i];
return (
(1 << PAGE_CACHEABLE_SHIFT) |
((!p->p) << PAGE_PRESENT_SHIFT) |
(1 << PAGE_USER_SHIFT) |
(1 << PAGE_READ_SHIFT) |
(1 << PAGE_WRITE_SHIFT) |
(1 << PAGE_EXEC_SHIFT) |
(p->g << PAGE_GLOBAL_SHIFT)
);
}
 
static inline void set_pt_flags(pte_t *pt, index_t i, int flags)
{
pte_t *p = &pt[i];
p->p = !(flags & PAGE_NOT_PRESENT);
p->g = (flags & PAGE_GLOBAL) != 0;
p->valid = 1;
}
 
extern void page_arch_init(void);
 
#define PHT_BITS 16
#define PHT_ORDER 4
 
typedef struct {
unsigned v : 1; /**< Valid */
unsigned vsid : 24; /**< Virtual Segment ID */
unsigned h : 1; /**< Primary/secondary hash */
unsigned api : 6; /**< Abbreviated Page Index */
unsigned rpn : 20; /**< Real Page Number */
unsigned reserved0 : 3;
unsigned r : 1; /**< Reference */
unsigned c : 1; /**< Change */
unsigned wimg : 4; /**< Access control */
unsigned reserved1 : 1;
unsigned pp : 2; /**< Page protection */
} phte_t;
 
extern void pht_refill(bool data, istate_t *istate);
extern void pht_init(void);
 
#endif /* __ASM__ */
 
#endif /* KERNEL */
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/include/mm/memory_init.h
0,0 → 1,48
/*
* Copyright (C) 2005 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 ppc64mm
* @{
*/
/** @file
*/
 
#ifndef __ppc64_MEMORY_INIT_H__
#define __ppc64_MEMORY_INIT_H__
 
#include <typedefs.h>
 
size_t get_memory_size(void);
 
void memory_print_map(void);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/include/mm/asid.h
0,0 → 1,49
/*
* 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 ppc64mm
* @{
*/
/** @file
*/
 
#ifndef __ppc64_ASID_H__
#define __ppc64_ASID_H__
 
typedef int asid_t;
 
#define ASID_MAX_ARCH 3
 
#define asid_get() (ASID_START+1)
#define asid_put(asid)
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/include/mm/tlb.h
0,0 → 1,43
/*
* 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 ppc64mm
* @{
*/
/** @file
*/
 
#ifndef __ppc64_TLB_H__
#define __ppc64_TLB_H__
 
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/include/mm/as.h
0,0 → 1,55
/*
* Copyright (C) 2005 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 ppc64mm
* @{
*/
/** @file
*/
 
#ifndef __ppc64_AS_H__
#define __ppc64_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 (0x7fffffff-(PAGE_SIZE-1))
 
#define as_install_arch(as)
 
extern void as_arch_init(void);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/include/context.h
0,0 → 1,78
/*
* Copyright (C) 2005 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 ppc64
* @{
*/
/** @file
*/
 
#ifndef __ppc64_CONTEXT_H__
#define __ppc64_CONTEXT_H__
 
#ifndef __ppc64_TYPES_H__
# include <arch/types.h>
#endif
 
#define SP_DELTA 16
 
struct context {
uintptr_t sp;
uintptr_t pc;
uint64_t r2;
uint64_t r13;
uint64_t r14;
uint64_t r15;
uint64_t r16;
uint64_t r17;
uint64_t r18;
uint64_t r19;
uint64_t r20;
uint64_t r21;
uint64_t r22;
uint64_t r23;
uint64_t r24;
uint64_t r25;
uint64_t r26;
uint64_t r27;
uint64_t r28;
uint64_t r29;
uint64_t r30;
uint64_t r31;
uint64_t cr;
ipl_t ipl;
} __attribute__ ((packed));
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/include/cpu.h
0,0 → 1,48
/*
* Copyright (C) 2006 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ppc64
* @{
*/
/** @file
*/
 
#ifndef __ppc64_CPU_H__
#define __ppc64_CPU_H__
 
#include <typedefs.h>
 
struct cpu_arch {
int version;
int revision;
};
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ppc64/include/debug.h
0,0 → 1,42
/*
* Copyright (C) 2005
* 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 ppc64debug
* @{
*/
/** @file
*/
 
#ifndef __ppc64_DEBUG_H__
#define __ppc64_DEBUG_H__
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/include/context_offset.h
0,0 → 1,49
/* This file is automatically generated by gencontext.c. */
/* struct context */
#define OFFSET_SP 0x0
#define OFFSET_PC 0x8
#define OFFSET_R2 0x10
#define OFFSET_R13 0x18
#define OFFSET_R14 0x20
#define OFFSET_R15 0x28
#define OFFSET_R16 0x30
#define OFFSET_R17 0x38
#define OFFSET_R18 0x40
#define OFFSET_R19 0x48
#define OFFSET_R20 0x50
#define OFFSET_R21 0x58
#define OFFSET_R22 0x60
#define OFFSET_R23 0x68
#define OFFSET_R24 0x70
#define OFFSET_R25 0x78
#define OFFSET_R26 0x80
#define OFFSET_R27 0x88
#define OFFSET_R28 0x90
#define OFFSET_R29 0x98
#define OFFSET_R30 0xa0
#define OFFSET_R31 0xa8
#define OFFSET_CR 0xb0
 
#define OFFSET_FR14 0x0
#define OFFSET_FR15 0x8
#define OFFSET_FR16 0x10
#define OFFSET_FR17 0x18
#define OFFSET_FR18 0x20
#define OFFSET_FR19 0x28
#define OFFSET_FR20 0x30
#define OFFSET_FR21 0x38
#define OFFSET_FR22 0x40
#define OFFSET_FR23 0x48
#define OFFSET_FR24 0x50
#define OFFSET_FR25 0x58
#define OFFSET_FR26 0x60
#define OFFSET_FR27 0x68
#define OFFSET_FR28 0x70
#define OFFSET_FR29 0x78
#define OFFSET_FR30 0x80
#define OFFSET_FR31 0x88
#define OFFSET_FPSCR 0x90
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/include/asm/regname.h
0,0 → 1,216
/*
* Copyright (C) 2005 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 ppc64
* @{
*/
/** @file
*/
 
#ifndef __ppc64_REGNAME_H__
#define __ppc64_REGNAME_H__
 
/* Condition Register Bit Fields */
#define cr0 0
#define cr1 1
#define cr2 2
#define cr3 3
#define cr4 4
#define cr5 5
#define cr6 6
#define cr7 7
 
/* General Purpose Registers (GPRs) */
#define r0 0
#define r1 1
#define r2 2
#define r3 3
#define r4 4
#define r5 5
#define r6 6
#define r7 7
#define r8 8
#define r9 9
#define r10 10
#define r11 11
#define r12 12
#define r13 13
#define r14 14
#define r15 15
#define r16 16
#define r17 17
#define r18 18
#define r19 19
#define r20 20
#define r21 21
#define r22 22
#define r23 23
#define r24 24
#define r25 25
#define r26 26
#define r27 27
#define r28 28
#define r29 29
#define r30 30
#define r31 31
 
/* GPR Aliases */
#define sp 1
 
/* Floating Point Registers (FPRs) */
#define fr0 0
#define fr1 1
#define fr2 2
#define fr3 3
#define fr4 4
#define fr5 5
#define fr6 6
#define fr7 7
#define fr8 8
#define fr9 9
#define fr10 10
#define fr11 11
#define fr12 12
#define fr13 13
#define fr14 14
#define fr15 15
#define fr16 16
#define fr17 17
#define fr18 18
#define fr19 19
#define fr20 20
#define fr21 21
#define fr22 22
#define fr23 23
#define fr24 24
#define fr25 25
#define fr26 26
#define fr27 27
#define fr28 28
#define fr29 29
#define fr30 30
#define fr31 31
 
#define vr0 0
#define vr1 1
#define vr2 2
#define vr3 3
#define vr4 4
#define vr5 5
#define vr6 6
#define vr7 7
#define vr8 8
#define vr9 9
#define vr10 10
#define vr11 11
#define vr12 12
#define vr13 13
#define vr14 14
#define vr15 15
#define vr16 16
#define vr17 17
#define vr18 18
#define vr19 19
#define vr20 20
#define vr21 21
#define vr22 22
#define vr23 23
#define vr24 24
#define vr25 25
#define vr26 26
#define vr27 27
#define vr28 28
#define vr29 29
#define vr30 30
#define vr31 31
 
#define evr0 0
#define evr1 1
#define evr2 2
#define evr3 3
#define evr4 4
#define evr5 5
#define evr6 6
#define evr7 7
#define evr8 8
#define evr9 9
#define evr10 10
#define evr11 11
#define evr12 12
#define evr13 13
#define evr14 14
#define evr15 15
#define evr16 16
#define evr17 17
#define evr18 18
#define evr19 19
#define evr20 20
#define evr21 21
#define evr22 22
#define evr23 23
#define evr24 24
#define evr25 25
#define evr26 26
#define evr27 27
#define evr28 28
#define evr29 29
#define evr30 30
#define evr31 31
 
/* Special Purpose Registers (SPRs) */
#define xer 1
#define lr 8
#define ctr 9
#define dec 22
#define sdr1 25
#define srr0 26
#define srr1 27
#define sprg0 272
#define sprg1 273
#define sprg2 274
#define sprg3 275
#define prv 287
#define hid0 1008
 
/* MSR bits */
#define msr_ir (1 << 4)
#define msr_dr (1 << 5)
#define msr_pr (1 << 14)
#define msr_ee (1 << 15)
 
/* HID0 bits */
#define hid0_ice (1 << 15)
#define hid0_dce (1 << 14)
#define hid0_icfi (1 << 11)
#define hid0_dci (1 << 10)
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/include/interrupt.h
0,0 → 1,53
/*
* 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 ppc64interrupt
* @{
*/
/** @file
*/
 
#ifndef __ppc64_INTERRUPT_H__
#define __ppc64_INTERRUPT_H__
 
#include <arch/exception.h>
 
#define IRQ_COUNT 1
#define IVT_ITEMS 15
#define INT_OFFSET 0
 
#define VECTOR_DECREMENTER 10
 
extern void start_decrementer(void);
extern void interrupt_init(void);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/include/elf.h
0,0 → 1,46
/*
* Copyright (C) 2006 Sergey Bondari
* 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 ppc64
* @{
*/
/** @file
*/
 
#ifndef __ppc64_ELF_H__
#define __ppc64_ELF_H__
 
#define ELF_MACHINE EM_PPC64
#define ELF_DATA_ENCODING ELFDATA2MSB
#define ELF_CLASS ELFCLASS32
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/include/arg.h
0,0 → 1,44
/*
* Copyright (C) 2005 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 ppc64
* @{
*/
/** @file
*/
 
#ifndef __ppc64_ARG_H__
#define __ppc64_ARG_H__
 
#include <stdarg.h>
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/include/atomic.h
0,0 → 1,98
/*
* Copyright (C) 2005 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 ppc64
* @{
*/
/** @file
*/
 
#ifndef __ppc64_ATOMIC_H__
#define __ppc64_ATOMIC_H__
 
static inline void atomic_inc(atomic_t *val)
{
long tmp;
 
asm volatile (
"1:\n"
"lwarx %0, 0, %2\n"
"addic %0, %0, 1\n"
"stwcx. %0, 0, %2\n"
"bne- 1b"
: "=&r" (tmp), "=m" (val->count)
: "r" (&val->count), "m" (val->count)
: "cc"
);
}
 
static inline void atomic_dec(atomic_t *val)
{
long tmp;
 
asm volatile (
"1:\n"
"lwarx %0, 0, %2\n"
"addic %0, %0, -1\n"
"stwcx. %0, 0, %2\n"
"bne- 1b"
: "=&r" (tmp), "=m" (val->count)
: "r" (&val->count), "m" (val->count)
: "cc"
);
}
 
static inline long atomic_postinc(atomic_t *val)
{
atomic_inc(val);
return val->count - 1;
}
 
static inline long atomic_postdec(atomic_t *val)
{
atomic_dec(val);
return val->count + 1;
}
 
static inline long atomic_preinc(atomic_t *val)
{
atomic_inc(val);
return val->count;
}
 
static inline long atomic_predec(atomic_t *val)
{
atomic_dec(val);
return val->count;
}
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/include/arch.h
0,0 → 1,42
/*
* Copyright (C) 2005 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 ppc64
* @{
*/
/** @file
*/
 
#ifndef __ppc64_ARCH_H__
#define __ppc64_ARCH_H__
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/include/proc/task.h
0,0 → 1,48
/*
* 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 ppc64proc
* @{
*/
/** @file
*/
 
#ifndef __ppc64_TASK_H__
#define __ppc64_TASK_H__
 
typedef struct {
} task_arch_t;
 
#define task_create_arch(t)
#define task_destroy_arch(t)
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/include/proc/thread.h
0,0 → 1,47
/*
* Copyright (C) 2005 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 ppc64proc
* @{
*/
/** @file
*/
 
#ifndef __ppc64_THREAD_H__
#define __ppc64_THREAD_H__
 
typedef struct {
} thread_arch_t;
 
#define thread_create_arch(t)
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/include/barrier.h
0,0 → 1,49
/*
* Copyright (C) 2005 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 ppc64
* @{
*/
/** @file
*/
 
#ifndef __ppc64_BARRIER_H__
#define __ppc64_BARRIER_H__
 
#define CS_ENTER_BARRIER() asm volatile ("" ::: "memory")
#define CS_LEAVE_BARRIER() asm volatile ("" ::: "memory")
 
#define memory_barrier() asm volatile ("sync" ::: "memory")
#define read_barrier() asm volatile ("sync" ::: "memory")
#define write_barrier() asm volatile ("eieio" ::: "memory")
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/src/ddi/ddi.c
0,0 → 1,57
/*
* 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 ppc64ddi
* @{
*/
/** @file
*/
 
#include <ddi/ddi.h>
#include <proc/task.h>
#include <arch/types.h>
#include <typedefs.h>
 
/** Enable I/O space range for task.
*
* Interrupts are disabled and task is locked.
*
* @param task Task.
* @param ioaddr Startign I/O space address.
* @param size Size of the enabled I/O range.
*
* @return 0 on success or an error code from errno.h.
*/
int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
{
return 0;
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/src/mm/tlb.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 ppc64mm
* @{
*/
/** @file
*/
 
#include <mm/tlb.h>
 
 
/** Initialize Page Hash Table.
*
* Setup the Page Hash Table with no entries.
*
*/
void tlb_arch_init(void)
{
tlb_invalidate_all();
}
 
 
void tlb_invalidate_all(void)
{
asm volatile (
"tlbia\n"
"tlbsync\n"
);
}
 
 
/** 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)
{
tlb_invalidate_all();
}
 
 
 
/** Print contents of Page Hash Table. */
void tlb_print(void)
{
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ppc64/src/mm/frame.c
0,0 → 1,72
/*
* Copyright (C) 2005 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 ppc64mm
* @{
*/
/** @file
*/
 
#include <arch/boot/boot.h>
#include <arch/mm/frame.h>
#include <arch/mm/memory_init.h>
#include <mm/frame.h>
#include <align.h>
#include <macros.h>
 
uintptr_t last_frame = 0;
 
void frame_arch_init(void)
{
pfn_t minconf = 2;
count_t i;
pfn_t start, conf;
size_t size;
for (i = 0; i < bootinfo.memmap.count; i++) {
start = ADDR2PFN(ALIGN_UP(bootinfo.memmap.zones[i].start, FRAME_SIZE));
size = SIZE2FRAMES(ALIGN_DOWN(bootinfo.memmap.zones[i].size, FRAME_SIZE));
if ((minconf < start) || (minconf >= start + size))
conf = start;
else
conf = minconf;
zone_create(start, size, conf, 0);
if (last_frame < ALIGN_UP(bootinfo.memmap.zones[i].start + bootinfo.memmap.zones[i].size, FRAME_SIZE))
last_frame = ALIGN_UP(bootinfo.memmap.zones[i].start + bootinfo.memmap.zones[i].size, FRAME_SIZE);
}
 
/* First is exception vector, second is 'implementation specific', third and fourth is reserved */
frame_mark_unavailable(0, 4);
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/src/mm/page.c
0,0 → 1,308
/*
* Copyright (C) 2005 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 ppc64mm
* @{
*/
/** @file
*/
 
#include <arch/mm/page.h>
#include <genarch/mm/page_pt.h>
#include <arch/mm/frame.h>
#include <arch/asm.h>
#include <mm/frame.h>
#include <mm/page.h>
#include <mm/as.h>
#include <arch.h>
#include <arch/types.h>
#include <arch/exception.h>
#include <align.h>
#include <config.h>
#include <print.h>
#include <symtab.h>
 
static phte_t *phte;
 
 
/** Try to find PTE for faulting address
*
* Try to find PTE for faulting address.
* The as->lock must be held on entry to this function
* if lock is true.
*
* @param as Address space.
* @param lock Lock/unlock the address space.
* @param badvaddr Faulting virtual address.
* @param access Access mode that caused the fault.
* @param istate Pointer to interrupted state.
* @param pfrc Pointer to variable where as_page_fault() return code will be stored.
* @return PTE on success, NULL otherwise.
*
*/
static pte_t *find_mapping_and_check(as_t *as, bool lock, uintptr_t badvaddr, int access,
istate_t *istate, int *pfrc)
{
/*
* Check if the mapping exists in page tables.
*/
pte_t *pte = page_mapping_find(as, badvaddr);
if ((pte) && (pte->p)) {
/*
* Mapping found in page tables.
* Immediately succeed.
*/
return pte;
} else {
int rc;
/*
* Mapping not found in page tables.
* Resort to higher-level page fault handler.
*/
page_table_unlock(as, lock);
switch (rc = as_page_fault(badvaddr, access, istate)) {
case AS_PF_OK:
/*
* The higher-level page fault handler succeeded,
* The mapping ought to be in place.
*/
page_table_lock(as, lock);
pte = page_mapping_find(as, badvaddr);
ASSERT((pte) && (pte->p));
*pfrc = 0;
return pte;
case AS_PF_DEFER:
page_table_lock(as, lock);
*pfrc = rc;
return NULL;
case AS_PF_FAULT:
page_table_lock(as, lock);
printf("Page fault.\n");
*pfrc = rc;
return NULL;
default:
panic("unexpected rc (%d)\n", rc);
}
}
}
 
 
static void pht_refill_fail(uintptr_t badvaddr, istate_t *istate)
{
char *symbol = "";
char *sym2 = "";
 
char *s = get_symtab_entry(istate->pc);
if (s)
symbol = s;
s = get_symtab_entry(istate->lr);
if (s)
sym2 = s;
panic("%p: PHT Refill Exception at %p (%s<-%s)\n", badvaddr, istate->pc, symbol, sym2);
}
 
 
static void pht_insert(const uintptr_t vaddr, const pfn_t pfn)
{
uint32_t page = (vaddr >> 12) & 0xffff;
uint32_t api = (vaddr >> 22) & 0x3f;
uint32_t vsid;
asm volatile (
"mfsrin %0, %1\n"
: "=r" (vsid)
: "r" (vaddr)
);
/* Primary hash (xor) */
uint32_t h = 0;
uint32_t hash = vsid ^ page;
uint32_t base = (hash & 0x3ff) << 3;
uint32_t i;
bool found = false;
/* Find unused or colliding
PTE in PTEG */
for (i = 0; i < 8; i++) {
if ((!phte[base + i].v) || ((phte[base + i].vsid == vsid) && (phte[base + i].api == api))) {
found = true;
break;
}
}
if (!found) {
/* Secondary hash (not) */
uint32_t base2 = (~hash & 0x3ff) << 3;
/* Find unused or colliding
PTE in PTEG */
for (i = 0; i < 8; i++) {
if ((!phte[base2 + i].v) || ((phte[base2 + i].vsid == vsid) && (phte[base2 + i].api == api))) {
found = true;
base = base2;
h = 1;
break;
}
}
if (!found) {
// TODO: A/C precedence groups
i = page % 8;
}
}
phte[base + i].v = 1;
phte[base + i].vsid = vsid;
phte[base + i].h = h;
phte[base + i].api = api;
phte[base + i].rpn = pfn;
phte[base + i].r = 0;
phte[base + i].c = 0;
phte[base + i].pp = 2; // FIXME
}
 
 
/** Process Instruction/Data Storage Interrupt
*
* @param data True if Data Storage Interrupt.
* @param istate Interrupted register context.
*
*/
void pht_refill(bool data, istate_t *istate)
{
uintptr_t badvaddr;
pte_t *pte;
int pfrc;
as_t *as;
bool lock;
if (AS == NULL) {
as = AS_KERNEL;
lock = false;
} else {
as = AS;
lock = true;
}
if (data) {
asm volatile (
"mfdar %0\n"
: "=r" (badvaddr)
);
} else
badvaddr = istate->pc;
page_table_lock(as, lock);
pte = find_mapping_and_check(as, lock, badvaddr, PF_ACCESS_READ /* FIXME */, istate, &pfrc);
if (!pte) {
switch (pfrc) {
case AS_PF_FAULT:
goto fail;
break;
case AS_PF_DEFER:
/*
* The page fault came during copy_from_uspace()
* or copy_to_uspace().
*/
page_table_unlock(as, lock);
return;
default:
panic("Unexpected pfrc (%d)\n", pfrc);
}
}
pte->a = 1; /* Record access to PTE */
pht_insert(badvaddr, pte->pfn);
page_table_unlock(as, lock);
return;
fail:
page_table_unlock(as, lock);
pht_refill_fail(badvaddr, istate);
}
 
 
void pht_init(void)
{
memsetb((uintptr_t) phte, 1 << PHT_BITS, 0);
}
 
 
void page_arch_init(void)
{
if (config.cpu_active == 1) {
page_mapping_operations = &pt_mapping_operations;
uintptr_t cur;
int flags;
/* Frames below 128 MB are mapped using BAT,
map rest of the physical memory */
for (cur = 128 << 20; cur < last_frame; cur += FRAME_SIZE) {
flags = PAGE_CACHEABLE;
if ((PA2KA(cur) >= config.base) && (PA2KA(cur) < config.base + config.kernel_size))
flags |= PAGE_GLOBAL;
page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags);
}
/* Allocate page hash table */
phte_t *physical_phte = (phte_t *) frame_alloc(PHT_ORDER, FRAME_KA | FRAME_ATOMIC);
ASSERT((uintptr_t) physical_phte % (1 << PHT_BITS) == 0);
pht_init();
asm volatile (
"mtsdr1 %0\n"
:
: "r" ((uintptr_t) physical_phte)
);
}
}
 
 
uintptr_t hw_map(uintptr_t physaddr, size_t size)
{
if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH))
panic("Unable to map physical memory %p (%d bytes)", physaddr, size)
uintptr_t virtaddr = PA2KA(last_frame);
pfn_t i;
for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++)
page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE);
last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE);
return virtaddr;
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/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 ppc64mm
* @{
*/
/** @file
*/
 
#include <arch/mm/as.h>
#include <genarch/mm/as_pt.h>
 
/** Architecture dependent address space init. */
void as_arch_init(void)
{
as_operations = &as_pt_operations;
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/src/mm/memory_init.c
0,0 → 1,57
/*
* Copyright (C) 2005 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 ppc64mm
* @{
*/
/** @file
*/
 
#include <arch/boot/boot.h>
#include <arch/mm/memory_init.h>
#include <typedefs.h>
#include <print.h>
 
 
size_t get_memory_size(void)
{
return bootinfo.memmap.total;
}
 
 
void memory_print_map(void)
{
count_t i;
for (i = 0; i < bootinfo.memmap.count; i++)
printf("base: %#x size: %#x\n", bootinfo.memmap.zones[i].start, bootinfo.memmap.zones[i].size);
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/src/interrupt.c
0,0 → 1,76
/*
* 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 ppc64interrupt
* @{
*/
/** @file
*/
 
#include <interrupt.h>
#include <arch/interrupt.h>
#include <arch/types.h>
#include <arch.h>
#include <time/clock.h>
#include <ipc/sysipc.h>
 
 
void start_decrementer(void)
{
asm volatile (
"mtdec %0\n"
:
: "r" (1000)
);
}
 
 
static void exception_decrementer(int n, istate_t *istate)
{
clock();
start_decrementer();
}
 
 
/* Initialize basic tables for exception dispatching */
void interrupt_init(void)
{
exc_register(VECTOR_DECREMENTER, "timer", exception_decrementer);
}
 
 
/* Reregister irq to be IPC-ready */
void irq_ipc_bind_arch(unative_t irq)
{
panic("not implemented\n");
/* TODO */
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/src/ppc64.c
0,0 → 1,115
/*
* 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 ppc64
* @{
*/
/** @file
*/
 
#include <arch.h>
#include <arch/boot/boot.h>
#include <arch/mm/memory_init.h>
#include <arch/interrupt.h>
#include <genarch/fb/fb.h>
#include <userspace.h>
#include <proc/uarg.h>
#include <console/console.h>
 
bootinfo_t bootinfo;
 
void arch_pre_main(void)
{
/* Setup usermode */
init.cnt = bootinfo.taskmap.count;
uint32_t i;
for (i = 0; i < bootinfo.taskmap.count; i++) {
init.tasks[i].addr = PA2KA(bootinfo.taskmap.tasks[i].addr);
init.tasks[i].size = bootinfo.taskmap.tasks[i].size;
}
}
 
void arch_pre_mm_init(void)
{
/* Initialize dispatch table */
interrupt_init();
/* Start decrementer */
start_decrementer();
}
 
void arch_post_mm_init(void)
{
if (config.cpu_active == 1) {
fb_init(bootinfo.screen.addr, bootinfo.screen.width, bootinfo.screen.height, bootinfo.screen.bpp, bootinfo.screen.scanline);
/* Merge all zones to 1 big zone */
zone_merge_all();
}
}
 
void arch_pre_smp_init(void)
{
memory_print_map();
}
 
void arch_post_smp_init(void)
{
}
 
void calibrate_delay_loop(void)
{
}
 
void userspace(uspace_arg_t *kernel_uarg)
{
userspace_asm((uintptr_t) kernel_uarg->uspace_uarg, (uintptr_t) kernel_uarg->uspace_stack + THREAD_STACK_SIZE - SP_DELTA, (uintptr_t) kernel_uarg->uspace_entry);
/* Unreachable */
for (;;)
;
}
 
/** Acquire console back for kernel
*
*/
void arch_grab_console(void)
{
}
/** Return console to userspace
*
*/
void arch_release_console(void)
{
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/src/cpu/cpu.c
0,0 → 1,63
/*
* Copyright (C) 2005 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 ppc64
* @{
*/
/** @file
*/
 
#include <arch/cpu.h>
#include <arch/cpuid.h>
#include <cpu.h>
 
#include <arch.h>
 
#include <typedefs.h>
#include <print.h>
 
void cpu_arch_init(void)
{
}
 
void cpu_identify(void)
{
cpu_info_t info;
cpu_version(&info);
CPU->arch.version = info.version;
CPU->arch.revision = info.revision;
}
 
void cpu_print_report(cpu_t *m)
{
printf("cpu%d: version=%d, revision=%d\n", m->id, m->arch.version, m->arch.revision);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/arch/ppc64/src/proc/scheduler.c
0,0 → 1,64
/*
* 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 ppc64proc
* @{
*/
/** @file
*/
 
#include <arch/mm/page.h>
#include <arch/boot/boot.h>
#include <proc/scheduler.h>
#include <proc/thread.h>
#include <arch.h>
 
/** Perform ppc64 specific tasks needed before the new task is run. */
void before_task_runs_arch(void)
{
}
 
/** Perform ppc64 specific tasks needed before the new thread is scheduled. */
void before_thread_runs_arch(void)
{
pht_init();
tlb_invalidate_all();
asm volatile (
"mtsprg0 %0\n"
:
: "r" (KA2PA(&THREAD->kstack[THREAD_STACK_SIZE - SP_DELTA]))
);
}
 
void after_thread_ran_arch(void)
{
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/arch/ppc64/src/exception.S
0,0 → 1,237
#
# 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/asm/regname.h>
#include <arch/mm/page.h>
 
.section K_UNMAPPED_TEXT_START, "ax"
 
.macro CONTEXT_STORE
# save R12 in SPRG1, backup CR in R12
# save SP in SPRG2
 
mtsprg1 r12
mfcr r12
mtsprg2 sp
# check whether SP is in kernel
andis. sp, sp, 0x8000
bne 1f
# stack is in user-space
mfsprg0 sp
b 2f
1:
# stack is in kernel
mfsprg2 sp
subis sp, sp, 0x8000
2:
subi sp, sp, 160
stw r0, 8(sp)
stw r2, 12(sp)
stw r3, 16(sp)
stw r4, 20(sp)
stw r5, 24(sp)
stw r6, 28(sp)
stw r7, 32(sp)
stw r8, 36(sp)
stw r9, 40(sp)
stw r10, 44(sp)
stw r11, 48(sp)
stw r13, 52(sp)
stw r14, 56(sp)
stw r15, 60(sp)
stw r16, 64(sp)
stw r17, 68(sp)
stw r18, 72(sp)
stw r19, 76(sp)
stw r20, 80(sp)
stw r21, 84(sp)
stw r22, 88(sp)
stw r23, 92(sp)
stw r24, 96(sp)
stw r25, 100(sp)
stw r26, 104(sp)
stw r27, 108(sp)
stw r28, 112(sp)
stw r29, 116(sp)
stw r30, 120(sp)
stw r31, 124(sp)
stw r12, 128(sp)
mfsrr0 r12
stw r12, 132(sp)
mfsrr1 r12
stw r12, 136(sp)
mflr r12
stw r12, 140(sp)
mfctr r12
stw r12, 144(sp)
mfxer r12
stw r12, 148(sp)
mfsprg1 r12
stw r12, 152(sp)
mfsprg2 r12
stw r12, 156(sp)
.endm
 
.org 0x060
jump_to_kernel:
lis r12, iret@ha
addi r12, r12, iret@l
mtlr r12
 
mfmsr r12
ori r12, r12, (msr_ir | msr_dr)@l
mtsrr1 r12
addis sp, sp, 0x8000
mr r4, sp
addi r4, r4, 8
rfi
 
jump_to_kernel_syscall:
lis r12, syscall_handler@ha
addi r12, r12, syscall_handler@l
mtsrr0 r12
lis r12, iret_syscall@ha
addi r12, r12, iret_syscall@l
mtlr r12
 
mfmsr r12
ori r12, r12, (msr_ir | msr_dr)@l
mtsrr1 r12
addis sp, sp, 0x8000
rfi
 
.org 0x100
.global exc_system_reset
exc_system_reset:
b exc_system_reset
 
.org 0x200
.global exc_machine_check
exc_machine_check:
b exc_machine_check
 
.org 0x300
.global exc_data_storage
exc_data_storage:
CONTEXT_STORE
lis r12, pht_refill@ha
addi r12, r12, pht_refill@l
mtsrr0 r12
li r3, 1
b jump_to_kernel
 
.org 0x400
.global exc_instruction_storage
exc_instruction_storage:
CONTEXT_STORE
lis r12, pht_refill@ha
addi r12, r12, pht_refill@l
mtsrr0 r12
li r3, 0
b jump_to_kernel
 
.org 0x500
.global exc_external
exc_external:
b exc_external
 
.org 0x600
.global exc_alignment
exc_alignment:
b exc_alignment
 
.org 0x700
.global exc_program
exc_program:
b exc_program
 
.org 0x800
.global exc_fp_unavailable
exc_fp_unavailable:
b exc_fp_unavailable
 
.org 0x900
.global exc_decrementer
exc_decrementer:
CONTEXT_STORE
 
lis r12, exc_dispatch@ha
addi r12, r12, exc_dispatch@l
mtsrr0 r12
li r3, 10
b jump_to_kernel
 
.org 0xa00
.global exc_reserved0
exc_reserved0:
b exc_reserved0
 
.org 0xb00
.global exc_reserved1
exc_reserved1:
b exc_reserved1
 
.org 0xc00
.global exc_syscall
exc_syscall:
CONTEXT_STORE
b jump_to_kernel_syscall
 
.org 0xd00
.global exc_trace
exc_trace:
b exc_trace
/tags/0.2.0.3/kernel/arch/ppc64/src/asm.S
0,0 → 1,311
#
# 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/asm/regname.h>
 
.text
 
.global userspace_asm
.global iret
.global iret_syscall
.global memsetb
.global memcpy
.global memcpy_from_uspace
.global memcpy_to_uspace
.global memcpy_from_uspace_failover_address
.global memcpy_to_uspace_failover_address
 
userspace_asm:
 
# r3 = uspace_uarg
# r4 = stack
# r5 = entry
# disable interrupts
 
mfmsr r31
rlwinm r31, r31, 0, 17, 15
mtmsr r31
# set entry point
mtsrr0 r5
# set problem state, enable interrupts
ori r31, r31, msr_pr
ori r31, r31, msr_ee
mtsrr1 r31
# set stack
mr sp, r4
# jump to userspace
rfi
 
iret:
# disable interrupts
mfmsr r31
rlwinm r31, r31, 0, 17, 15
mtmsr r31
lwz r0, 8(sp)
lwz r2, 12(sp)
lwz r3, 16(sp)
lwz r4, 20(sp)
lwz r5, 24(sp)
lwz r6, 28(sp)
lwz r7, 32(sp)
lwz r8, 36(sp)
lwz r9, 40(sp)
lwz r10, 44(sp)
lwz r11, 48(sp)
lwz r13, 52(sp)
lwz r14, 56(sp)
lwz r15, 60(sp)
lwz r16, 64(sp)
lwz r17, 68(sp)
lwz r18, 72(sp)
lwz r19, 76(sp)
lwz r20, 80(sp)
lwz r21, 84(sp)
lwz r22, 88(sp)
lwz r23, 92(sp)
lwz r24, 96(sp)
lwz r25, 100(sp)
lwz r26, 104(sp)
lwz r27, 108(sp)
lwz r28, 112(sp)
lwz r29, 116(sp)
lwz r30, 120(sp)
lwz r31, 124(sp)
lwz r12, 128(sp)
mtcr r12
lwz r12, 132(sp)
mtsrr0 r12
lwz r12, 136(sp)
mtsrr1 r12
lwz r12, 140(sp)
mtlr r12
lwz r12, 144(sp)
mtctr r12
lwz r12, 148(sp)
mtxer r12
lwz r12, 152(sp)
lwz sp, 156(sp)
rfi
 
iret_syscall:
# reset decrementer
 
li r31, 1000
mtdec r31
# disable interrupts
mfmsr r31
rlwinm r31, r31, 0, 17, 15
mtmsr r31
lwz r0, 8(sp)
lwz r2, 12(sp)
lwz r4, 20(sp)
lwz r5, 24(sp)
lwz r6, 28(sp)
lwz r7, 32(sp)
lwz r8, 36(sp)
lwz r9, 40(sp)
lwz r10, 44(sp)
lwz r11, 48(sp)
lwz r13, 52(sp)
lwz r14, 56(sp)
lwz r15, 60(sp)
lwz r16, 64(sp)
lwz r17, 68(sp)
lwz r18, 72(sp)
lwz r19, 76(sp)
lwz r20, 80(sp)
lwz r21, 84(sp)
lwz r22, 88(sp)
lwz r23, 92(sp)
lwz r24, 96(sp)
lwz r25, 100(sp)
lwz r26, 104(sp)
lwz r27, 108(sp)
lwz r28, 112(sp)
lwz r29, 116(sp)
lwz r30, 120(sp)
lwz r31, 124(sp)
lwz r12, 128(sp)
mtcr r12
lwz r12, 132(sp)
mtsrr0 r12
lwz r12, 136(sp)
mtsrr1 r12
lwz r12, 140(sp)
mtlr r12
lwz r12, 144(sp)
mtctr r12
lwz r12, 148(sp)
mtxer r12
lwz r12, 152(sp)
lwz sp, 156(sp)
 
rfi
memsetb:
rlwimi r5, r5, 8, 16, 23
rlwimi r5, r5, 16, 0, 15
addi r14, r3, -4
cmplwi 0, r4, 4
blt 7f
stwu r5, 4(r14)
beqlr
andi. r15, r14, 3
add r4, r15, r4
subf r14, r15, r14
srwi r15, r4, 2
mtctr r15
bdz 6f
1:
stwu r5, 4(r14)
bdnz 1b
6:
andi. r4, r4, 3
7:
cmpwi 0, r4, 0
beqlr
mtctr r4
addi r6, r6, 3
8:
stbu r5, 1(r14)
bdnz 8b
blr
 
memcpy:
memcpy_from_uspace:
memcpy_to_uspace:
 
srwi. r7, r5, 3
addi r6, r3, -4
addi r4, r4, -4
beq 2f
andi. r0, r6, 3
mtctr r7
bne 5f
1:
lwz r7, 4(r4)
lwzu r8, 8(r4)
stw r7, 4(r6)
stwu r8, 8(r6)
bdnz 1b
andi. r5, r5, 7
2:
cmplwi 0, r5, 4
blt 3f
lwzu r0, 4(r4)
addi r5, r5, -4
stwu r0, 4(r6)
3:
cmpwi 0, r5, 0
beqlr
mtctr r5
addi r4, r4, 3
addi r6, r6, 3
4:
lbzu r0, 1(r4)
stbu r0, 1(r6)
bdnz 4b
blr
5:
subfic r0, r0, 4
mtctr r0
6:
lbz r7, 4(r4)
addi r4, r4, 1
stb r7, 4(r6)
addi r6, r6, 1
bdnz 6b
subf r5, r0, r5
rlwinm. r7, r5, 32-3, 3, 31
beq 2b
mtctr r7
b 1b
 
memcpy_from_uspace_failover_address:
memcpy_to_uspace_failover_address:
b memcpy_from_uspace_failover_address
/tags/0.2.0.3/kernel/arch/ppc64/src/boot/boot.S
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.
#
 
#include <arch/asm/regname.h>
#include <arch/boot/boot.h>
 
.section K_TEXT_START, "ax"
 
.global kernel_image_start
kernel_image_start:
 
# load temporal kernel stack
lis sp, kernel_stack@ha
addi sp, sp, kernel_stack@l
# set kernel stack for interrupt handling
mr r31, sp
subis r31, r31, 0x8000
mtsprg0 r31
# r3 contains physical address of bootinfo_t
# r4 contains size of bootinfo_t
addis r3, r3, 0x8000
 
lis r31, bootinfo@ha
addi r31, r31, bootinfo@l # r31 = bootinfo
cmpwi r4, 0
beq bootinfo_end
bootinfo_loop:
lwz r30, 0(r3)
stw r30, 0(r31)
addi r3, r3, 4
addi r31, r31, 4
subi r4, r4, 4
cmpwi r4, 0
bgt bootinfo_loop
bootinfo_end:
bl arch_pre_main
b main_bsp
 
.section K_DATA_START, "aw", @progbits
 
.align 12
kernel_stack_bottom:
.space TEMP_STACK_SIZE
kernel_stack:
/tags/0.2.0.3/kernel/arch/ppc64/src/dummy.s
0,0 → 1,38
#
# 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.
#
 
.text
 
.global asm_delay_loop
.global sys_tls_set
 
sys_tls_set:
b sys_tls_set
 
asm_delay_loop:
blr
/tags/0.2.0.3/kernel/arch/ppc64/src/fpu_context.S
0,0 → 1,105
#
# 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/asm/regname.h>
#include <arch/context_offset.h>
 
.text
 
.global fpu_context_save
.global fpu_context_restore
.global fpu_init
.global fpu_enable
.global fpu_disable
 
.macro FPU_CONTEXT_STORE r
stfd fr14, OFFSET_FR14(\r)
stfd fr15, OFFSET_FR15(\r)
stfd fr16, OFFSET_FR16(\r)
stfd fr17, OFFSET_FR17(\r)
stfd fr18, OFFSET_FR18(\r)
stfd fr19, OFFSET_FR19(\r)
stfd fr20, OFFSET_FR20(\r)
stfd fr21, OFFSET_FR21(\r)
stfd fr22, OFFSET_FR22(\r)
stfd fr23, OFFSET_FR23(\r)
stfd fr24, OFFSET_FR24(\r)
stfd fr25, OFFSET_FR25(\r)
stfd fr26, OFFSET_FR26(\r)
stfd fr27, OFFSET_FR27(\r)
stfd fr28, OFFSET_FR28(\r)
stfd fr29, OFFSET_FR29(\r)
stfd fr30, OFFSET_FR30(\r)
stfd fr31, OFFSET_FR31(\r)
.endm
 
.macro FPU_CONTEXT_LOAD r
lfd fr14, OFFSET_FR14(\r)
lfd fr15, OFFSET_FR15(\r)
lfd fr16, OFFSET_FR16(\r)
lfd fr17, OFFSET_FR17(\r)
lfd fr18, OFFSET_FR18(\r)
lfd fr19, OFFSET_FR19(\r)
lfd fr20, OFFSET_FR20(\r)
lfd fr21, OFFSET_FR21(\r)
lfd fr22, OFFSET_FR22(\r)
lfd fr23, OFFSET_FR23(\r)
lfd fr24, OFFSET_FR24(\r)
lfd fr25, OFFSET_FR25(\r)
lfd fr26, OFFSET_FR26(\r)
lfd fr27, OFFSET_FR27(\r)
lfd fr28, OFFSET_FR28(\r)
lfd fr29, OFFSET_FR29(\r)
lfd fr30, OFFSET_FR30(\r)
lfd fr31, OFFSET_FR31(\r)
.endm
 
fpu_context_save:
// FPU_CONTEXT_STORE r3
//
// mffs fr0
// stfd fr0, OFFSET_FPSCR(r3)
blr
fpu_context_restore:
// FPU_CONTEXT_LOAD r3
//
// lfd fr0, OFFSET_FPSCR(r3)
// mtfsf 7, fr0
blr
 
fpu_init:
blr
 
fpu_enable:
blr
 
fpu_disable:
blr
/tags/0.2.0.3/kernel/arch/ppc64/src/context.S
0,0 → 1,109
#
# Copyright (C) 2005 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/asm/regname.h>
#include <arch/context_offset.h>
 
.text
 
.global context_save_arch
.global context_restore_arch
 
.macro CONTEXT_STORE r
stw sp, OFFSET_SP(\r)
stw r2, OFFSET_R2(\r)
stw r13, OFFSET_R13(\r)
stw r14, OFFSET_R14(\r)
stw r15, OFFSET_R15(\r)
stw r16, OFFSET_R16(\r)
stw r17, OFFSET_R17(\r)
stw r18, OFFSET_R18(\r)
stw r19, OFFSET_R19(\r)
stw r20, OFFSET_R20(\r)
stw r21, OFFSET_R21(\r)
stw r22, OFFSET_R22(\r)
stw r23, OFFSET_R23(\r)
stw r24, OFFSET_R24(\r)
stw r25, OFFSET_R25(\r)
stw r26, OFFSET_R26(\r)
stw r27, OFFSET_R27(\r)
stw r28, OFFSET_R28(\r)
stw r29, OFFSET_R29(\r)
stw r30, OFFSET_R30(\r)
stw r31, OFFSET_R31(\r)
.endm
 
.macro CONTEXT_LOAD r
lwz sp, OFFSET_SP(\r)
lwz r2, OFFSET_R2(\r)
lwz r13, OFFSET_R13(\r)
lwz r14, OFFSET_R14(\r)
lwz r15, OFFSET_R15(\r)
lwz r16, OFFSET_R16(\r)
lwz r17, OFFSET_R17(\r)
lwz r18, OFFSET_R18(\r)
lwz r19, OFFSET_R19(\r)
lwz r20, OFFSET_R20(\r)
lwz r21, OFFSET_R21(\r)
lwz r22, OFFSET_R22(\r)
lwz r23, OFFSET_R23(\r)
lwz r24, OFFSET_R24(\r)
lwz r25, OFFSET_R25(\r)
lwz r26, OFFSET_R26(\r)
lwz r27, OFFSET_R27(\r)
lwz r28, OFFSET_R28(\r)
lwz r29, OFFSET_R29(\r)
lwz r30, OFFSET_R30(\r)
lwz r31, OFFSET_R31(\r)
.endm
 
context_save_arch:
CONTEXT_STORE r3
mflr r4
stw r4, OFFSET_PC(r3)
mfcr r4
stw r4, OFFSET_CR(r3)
# context_save returns 1
li r3, 1
blr
context_restore_arch:
CONTEXT_LOAD r3
lwz r4, OFFSET_CR(r3)
mtcr r4
lwz r4, OFFSET_PC(r3)
mtlr r4
# context_restore returns 0
li r3, 0
blr
/tags/0.2.0.3/kernel/arch/ppc64/src/debug/panic.s
0,0 → 1,38
#
# Copyright (C) 2005 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/asm/macro.h>
 
.text
.global panic_printf
 
panic_printf:
lis %r14, halt@ha
addi %r14, %r14, halt@l
mtlr %r14 # fake stack to make printf return to halt
b printf
/tags/0.2.0.3/kernel/arch/ppc64/_link.ld.in
0,0 → 1,59
/** PPC64 linker script
*
* umapped section:
* kernel text
* kernel data
* mapped section:
* kernel text
* kernel data
*
*/
 
#define __ASM__
#include <arch/boot/boot.h>
#include <arch/mm/page.h>
 
ENTRY(kernel_image_start)
OUTPUT_FORMAT("elf64-powerpc")
OUTPUT_ARCH(powerpc:common64)
 
SECTIONS {
.unmapped 0: AT (0) {
unmapped_ktext_start = .;
*(K_UNMAPPED_TEXT_START);
unmapped_ktext_end = .;
unmapped_kdata_start = .;
*(K_UNMAPPED_DATA_START);
unmapped_kdata_start = .;
}
.mapped PA2KA(BOOT_OFFSET): AT (BOOT_OFFSET) {
ktext_start = .;
*(K_TEXT_START);
*(.text);
ktext_end = .;
kdata_start = .;
*(K_DATA_START);
*(.rodata);
*(.rodata.*);
*(.data); /* initialized data */
*(.sdata);
*(.sdata2);
*(.sbss);
hardcoded_ktext_size = .;
LONG(ktext_end - ktext_start);
hardcoded_kdata_size = .;
LONG(kdata_end - kdata_start);
hardcoded_load_address = .;
LONG(PA2KA(BOOT_OFFSET));
*(.bss); /* uninitialized static variables */
*(COMMON); /* global variables */
 
symbol_table = .;
*(symtab.*); /* Symbol table, must be LAST symbol!*/
 
kdata_end = .;
}
}
/tags/0.2.0.3/kernel/generic/include/config.h
0,0 → 1,76
/*
* 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 generic
* @{
*/
/** @file
*/
 
#ifndef __CONFIG_H__
#define __CONFIG_H__
 
#include <arch/types.h>
#include <typedefs.h>
#include <arch/mm/page.h>
 
#define STACK_SIZE PAGE_SIZE
 
#define CONFIG_MEMORY_SIZE (8 * 1024 * 1024)
 
#define CONFIG_INIT_TASKS 32
 
typedef struct {
uintptr_t addr;
size_t size;
} init_task_t;
 
typedef struct {
count_t cnt;
init_task_t tasks[CONFIG_INIT_TASKS];
} init_t;
 
typedef struct {
count_t cpu_count; /**< Number of processors detected. */
volatile count_t cpu_active; /**< Number of processors that are up and running. */
 
uintptr_t base;
size_t memory_size; /**< Size of detected memory in bytes. */
size_t kernel_size; /**< Size of memory in bytes taken by kernel and stack */
uintptr_t stack_base; /**< Base adddress of initial stack */
size_t stack_size; /**< Size of initial stack */
} config_t;
 
extern config_t config;
extern init_t init;
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/main/main.h
0,0 → 1,45
/*
* 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 main
* @{
*/
/** @file
*/
#ifndef __MAIN_H__
#define __MAIN_H__
 
#include <typedefs.h>
 
extern uintptr_t stack_safe;
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/main/kinit.h
0,0 → 1,44
/*
* 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 main
* @{
*/
/** @file
*/
 
#ifndef __KINIT_H__
#define __KINIT_H__
 
extern void kinit(void *arg);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/main/version.h
0,0 → 1,44
/*
* 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 main
* @{
*/
/** @file
*/
 
#ifndef __VERSION_H__
#define __VERSION_H__
 
extern void version_print(void);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/main/uinit.h
0,0 → 1,46
/*
* 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 main
* @{
*/
/** @file
*/
 
#ifndef __UINIT_H__
#define __UINIT_H__
 
#include <arch/types.h>
 
extern void uinit(void *arg);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/proc/scheduler.h
0,0 → 1,73
/*
* 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 genericproc
* @{
*/
/** @file
*/
 
#ifndef __SCHEDULER_H__
#define __SCHEDULER_H__
 
#include <synch/spinlock.h>
#include <time/clock.h> /* HZ */
#include <typedefs.h>
#include <atomic.h>
#include <adt/list.h>
 
#define RQ_COUNT 16
#define NEEDS_RELINK_MAX (HZ)
 
/** Scheduler run queue structure. */
struct runq {
SPINLOCK_DECLARE(lock);
link_t rq_head; /**< List of ready threads. */
count_t n; /**< Number of threads in rq_ready. */
};
 
extern atomic_t nrdy;
extern void scheduler_init(void);
 
extern void scheduler_fpu_lazy_request(void);
extern void scheduler(void);
extern void kcpulb(void *arg);
 
extern void sched_print_list(void);
 
/*
* To be defined by architectures:
*/
extern void before_task_runs_arch(void);
extern void before_thread_runs_arch(void);
extern void after_thread_ran_arch(void);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/proc/uarg.h
0,0 → 1,52
/*
* 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 genericproc
* @{
*/
/** @file
*/
 
#ifndef __UARG_H__
#define __UARG_H__
 
/** Structure passed to uinit kernel thread as argument. */
typedef struct uspace_arg {
void *uspace_entry;
void *uspace_stack;
 
void (* uspace_thread_function)();
void *uspace_thread_arg;
struct uspace_arg *uspace_uarg;
} uspace_arg_t;
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/proc/task.h
0,0 → 1,112
/*
* 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 genericproc
* @{
*/
/** @file
*/
 
#ifndef __TASK_H__
#define __TASK_H__
 
#include <typedefs.h>
#include <synch/spinlock.h>
#include <synch/mutex.h>
#include <synch/futex.h>
#include <adt/btree.h>
#include <adt/list.h>
#include <ipc/ipc.h>
#include <security/cap.h>
#include <arch/proc/task.h>
 
/** Task structure. */
struct task {
/** Task lock.
*
* Must be acquired before threads_lock and thread lock of any of its threads.
*/
SPINLOCK_DECLARE(lock);
char *name;
thread_t *main_thread; /**< Pointer to the main thread. */
link_t th_head; /**< List of threads contained in this task. */
as_t *as; /**< Address space. */
task_id_t taskid; /**< Unique identity of task */
context_id_t context; /**< Task security context */
 
/** If this is true, new threads can become part of the task. */
bool accept_new_threads;
 
count_t refcount; /**< Number of references (i.e. threads). */
 
cap_t capabilities; /**< Task capabilities. */
 
/* IPC stuff */
answerbox_t answerbox; /**< Communication endpoint */
phone_t phones[IPC_MAX_PHONES];
atomic_t active_calls; /**< Active asynchronous messages.
* It is used for limiting uspace to
* certain extent. */
task_arch_t arch; /**< Architecture specific task data. */
/**
* Serializes access to the B+tree of task's futexes. This mutex is
* independent on the task spinlock.
*/
mutex_t futexes_lock;
btree_t futexes; /**< B+tree of futexes referenced by this task. */
};
 
extern spinlock_t tasks_lock;
extern btree_t tasks_btree;
 
extern void task_init(void);
extern task_t *task_create(as_t *as, char *name);
extern void task_destroy(task_t *t);
extern task_t *task_run_program(void *program_addr, char *name);
extern task_t *task_find_by_id(task_id_t id);
extern int task_kill(task_id_t id);
 
 
#ifndef task_create_arch
extern void task_create_arch(task_t *t);
#endif
 
#ifndef task_destroy_arch
extern void task_destroy_arch(task_t *t);
#endif
 
extern unative_t sys_task_get_id(task_id_t *uspace_task_id);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/proc/thread.h
0,0 → 1,197
/*
* 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 genericproc
* @{
*/
/** @file
*/
 
#ifndef __THREAD_H__
#define __THREAD_H__
 
#include <arch/proc/thread.h>
#include <synch/spinlock.h>
#include <arch/context.h>
#include <fpu_context.h>
#include <arch/types.h>
#include <typedefs.h>
#include <time/timeout.h>
#include <synch/rwlock.h>
#include <synch/synch.h>
#include <config.h>
#include <adt/btree.h>
#include <adt/list.h>
#include <mm/slab.h>
#include <proc/uarg.h>
 
#define THREAD_STACK_SIZE STACK_SIZE
 
/**< Thread states. */
enum state {
Invalid, /**< It is an error, if thread is found in this state. */
Running, /**< State of a thread that is currently executing on some CPU. */
Sleeping, /**< Thread in this state is waiting for an event. */
Ready, /**< State of threads in a run queue. */
Entering, /**< Threads are in this state before they are first readied. */
Exiting, /**< After a thread calls thread_exit(), it is put into Exiting state. */
Undead /**< Threads that were not detached but exited are in the Undead state. */
};
 
extern char *thread_states[];
 
/**< Join types. */
typedef enum {
None,
TaskClnp, /**< The thread will be joined by ktaskclnp thread. */
TaskGC /**< The thread will be joined by ktaskgc thread. */
} thread_join_type_t;
 
#define X_WIRED (1<<0)
#define X_STOLEN (1<<1)
 
#define THREAD_NAME_BUFLEN 20
 
/** Thread structure. There is one per thread. */
struct thread {
link_t rq_link; /**< Run queue link. */
link_t wq_link; /**< Wait queue link. */
link_t th_link; /**< Links to threads within containing task. */
/** Lock protecting thread structure.
*
* Protects the whole thread structure except list links above.
*/
SPINLOCK_DECLARE(lock);
 
char name[THREAD_NAME_BUFLEN];
 
void (* thread_code)(void *); /**< Function implementing the thread. */
void *thread_arg; /**< Argument passed to thread_code() function. */
 
/** From here, the stored context is restored when the thread is scheduled. */
context_t saved_context;
/** From here, the stored timeout context is restored when sleep times out. */
context_t sleep_timeout_context;
/** From here, the stored interruption context is restored when sleep is interrupted. */
context_t sleep_interruption_context;
 
bool sleep_interruptible; /**< If true, the thread can be interrupted from sleep. */
waitq_t *sleep_queue; /**< Wait queue in which this thread sleeps. */
timeout_t sleep_timeout; /**< Timeout used for timeoutable sleeping. */
volatile int timeout_pending; /**< Flag signalling sleep timeout in progress. */
 
/** True if this thread is executing copy_from_uspace(). False otherwise. */
bool in_copy_from_uspace;
/** True if this thread is executing copy_to_uspace(). False otherwise. */
bool in_copy_to_uspace;
/**
* If true, the thread will not go to sleep at all and will
* call thread_exit() before returning to userspace.
*/
bool interrupted;
thread_join_type_t join_type; /**< Who joinins the thread. */
bool detached; /**< If true, thread_join_timeout() cannot be used on this thread. */
waitq_t join_wq; /**< Waitq for thread_join_timeout(). */
 
fpu_context_t *saved_fpu_context;
int fpu_context_exists;
 
/*
* Defined only if thread doesn't run.
* It means that fpu context is in CPU that last time executes this thread.
* This disables migration
*/
int fpu_context_engaged;
 
rwlock_type_t rwlock_holder_type;
 
void (* call_me)(void *); /**< Funtion to be called in scheduler before the thread is put asleep. */
void *call_me_with; /**< Argument passed to call_me(). */
 
state_t state; /**< Thread's state. */
int flags; /**< Thread's flags. */
cpu_t *cpu; /**< Thread's CPU. */
task_t *task; /**< Containing task. */
 
uint64_t ticks; /**< Ticks before preemption. */
 
int priority; /**< Thread's priority. Implemented as index to CPU->rq */
uint32_t tid; /**< Thread ID. */
context_id_t context; /**< Thread security context */
thread_arch_t arch; /**< Architecture-specific data. */
 
uint8_t *kstack; /**< Thread's kernel stack. */
};
 
/** Thread list lock.
*
* This lock protects all link_t structures chained in threads_head.
* Must be acquired before T.lock for each T of type thread_t.
*
*/
extern spinlock_t threads_lock;
 
extern btree_t threads_btree; /**< B+tree containing all threads. */
 
extern void thread_init(void);
extern thread_t *thread_create(void (* func)(void *), void *arg, task_t *task, int flags, char *name);
extern void thread_ready(thread_t *t);
extern void thread_exit(void) __attribute__((noreturn));
 
#ifndef thread_create_arch
extern void thread_create_arch(thread_t *t);
#endif
 
extern void thread_sleep(uint32_t sec);
extern void thread_usleep(uint32_t usec);
 
#define thread_join(t) thread_join_timeout((t), SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE)
extern int thread_join_timeout(thread_t *t, uint32_t usec, int flags);
extern void thread_detach(thread_t *t);
 
extern void thread_register_call_me(void (* call_me)(void *), void *call_me_with);
extern void thread_print_list(void);
extern void thread_destroy(thread_t *t);
extern bool thread_exists(thread_t *t);
 
/* Fpu context slab cache */
extern slab_cache_t *fpu_context_slab;
 
/** Thread syscall prototypes. */
unative_t sys_thread_create(uspace_arg_t *uspace_uarg, char *uspace_name);
unative_t sys_thread_exit(int uspace_status);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/arch.h
0,0 → 1,86
/*
* 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 generic
* @{
*/
/** @file
*/
 
#ifndef __ARCH_H__
#define __ARCH_H__
 
#include <arch/types.h>
#include <arch/arch.h>
#include <typedefs.h>
 
#include <cpu.h>
#include <arch/cpu.h>
#include <arch/asm.h>
 
#define CPU THE->cpu
#define THREAD THE->thread
#define TASK THE->task
#define AS THE->as
#define PREEMPTION_DISABLED THE->preemption_disabled
 
/**
* For each possible kernel stack, structure
* of the following type will be placed at
* the base address of the stack.
*/
struct the {
count_t preemption_disabled; /**< Preemption disabled counter. */
thread_t *thread; /**< Current thread. */
task_t *task; /**< Current task. */
cpu_t *cpu; /**< Executing cpu. */
as_t *as; /**< Current address space. */
context_id_t context; /**< Current security context. */
};
 
#define THE ((the_t *)(get_stack_base()))
 
extern void the_initialize(the_t *the);
extern void the_copy(the_t *src, the_t *dst);
 
extern void arch_pre_main(void);
extern void arch_pre_mm_init(void);
extern void arch_post_mm_init(void);
extern void arch_pre_smp_init(void);
extern void arch_post_smp_init(void);
extern void calibrate_delay_loop(void);
 
extern ipl_t interrupts_disable(void);
extern ipl_t interrupts_enable(void);
extern void interrupts_restore(ipl_t ipl);
extern ipl_t interrupts_read(void);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/typedefs.h
0,0 → 1,101
/*
* 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 generic
* @{
*/
/** @file
*/
 
#ifndef __TYPEDEFS_H__
#define __TYPEDEFS_H__
 
#define false 0
#define true 1
 
typedef short bool;
 
typedef unsigned long size_t;
typedef unsigned long count_t;
typedef unsigned long index_t;
 
typedef unsigned long long task_id_t;
typedef unsigned long context_id_t;
 
typedef struct cpu_info cpu_info_t;
 
typedef struct cpu cpu_t;
typedef struct cpu_arch cpu_arch_t;
typedef struct task task_t;
typedef enum state state_t;
typedef struct thread thread_t;
typedef struct context context_t;
typedef struct fpu_context fpu_context_t;
 
typedef struct timeout timeout_t;
 
typedef struct runq runq_t;
 
typedef struct spinlock spinlock_t;
typedef struct mutex mutex_t;
typedef struct semaphore semaphore_t;
typedef struct rwlock rwlock_t;
typedef enum rwlock_type rwlock_type_t;
typedef struct condvar condvar_t;
typedef struct waitq waitq_t;
typedef struct futex futex_t;
 
typedef struct buddy_system buddy_system_t;
typedef struct buddy_system_operations buddy_system_operations_t;
 
typedef struct as_area as_area_t;
typedef struct as as_t;
 
typedef struct link link_t;
 
typedef struct the the_t;
 
typedef struct chardev chardev_t;
 
typedef enum cmd_arg_type cmd_arg_type_t;
typedef struct cmd_arg cmd_arg_t;
typedef struct cmd_info cmd_info_t;
 
typedef struct istate istate_t;
typedef void (* iroutine)(int n, istate_t *istate);
 
typedef struct hash_table hash_table_t;
typedef struct hash_table_operations hash_table_operations_t;
 
typedef struct btree_node btree_node_t;
typedef struct btree btree_t;
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/align.h
0,0 → 1,58
/*
* 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 generic
* @ingroup others
* @{
*/
/** @file
*/
 
#ifndef __ALIGN_H__
#define __ALIGN_H__
 
/** Align to the nearest lower address.
*
* @param s Address or size to be aligned.
* @param a Size of alignment, must be power of 2.
*/
#define ALIGN_DOWN(s, a) ((s) & ~((a) - 1))
 
 
/** Align to the nearest higher address.
*
* @param s Address or size to be aligned.
* @param a Size of alignment, must be power of 2.
*/
#define ALIGN_UP(s, a) (((s) + ((a) - 1)) & ~((a) - 1))
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/func.h
0,0 → 1,54
/*
* 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 generic
* @{
*/
/** @file
*/
 
#ifndef __FUNC_H__
#define __FUNC_H__
 
#include <arch/types.h>
#include <typedefs.h>
#include <atomic.h>
 
extern atomic_t haltstate;
 
extern void halt(void);
 
extern size_t strlen(const char *str);
extern int strncmp(const char *src, const char *dst, size_t len);
extern void strncpy(char *dest, const char *src, size_t len);
extern unative_t atoi(const char *text);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/print.h
0,0 → 1,58
/*
* 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 generic
* @{
*/
/** @file
*/
 
#ifndef __PRINT_H__
#define __PRINT_H__
 
#include <arch/types.h>
#include <synch/spinlock.h>
#include <arch/arg.h>
 
/* We need this address in spinlock to avoid deadlock in deadlock detection */
extern spinlock_t printflock;
 
#define EOF (-1)
 
extern int printf(const char *fmt, ...);
extern int sprintf(char *str, const char *fmt, ...);
extern int snprintf(char *str, size_t size, const char *fmt, ...);
 
extern int vprintf(const char *fmt, va_list ap);
extern int vsprintf(char *str, const char *fmt, va_list ap);
extern int vsnprintf(char *str, size_t size, const char *fmt, va_list ap);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/fpu_context.h
0,0 → 1,57
/*
* Copyright (C) 2005 Jakub Vana
* 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 generic
* @{
*/
/** @file
*/
 
#ifndef __FPU_CONTEXT_H__
#define __FPU_CONTEXT_H__
 
 
#include <arch/fpu_context.h>
#include <typedefs.h>
 
#if defined(CONFIG_FPU_LAZY) && !defined(ARCH_HAS_FPU)
# error "CONFIG_FPU_LAZY defined, but no ARCH_HAS_FPU"
#endif
 
extern void fpu_context_save(fpu_context_t *);
extern void fpu_context_restore(fpu_context_t *);
extern void fpu_init(void);
extern void fpu_enable(void);
extern void fpu_disable(void);
 
 
#endif /* __FPU_CONTEXT_H__ */
 
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/stackarg.h
0,0 → 1,65
/*
* 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 generic
* @{
*/
/** @file
*/
 
 
/*
* Variable argument list manipulation macros
* for architectures using stack to pass arguments.
*/
#ifndef __STACKARG_H__
#define __STACKARG_H__
 
#include <arch/types.h>
 
typedef struct va_list {
int pos;
uint8_t *last;
} va_list;
 
#define va_start(ap, lst) \
(ap).pos = sizeof(lst); \
(ap).last = (uint8_t *) &(lst)
 
#define va_arg(ap, type) \
(*((type *)((ap).last + ((ap).pos += sizeof(type) ) - sizeof(type))))
 
#define va_copy(dst,src) dst=src
#define va_end(ap)
 
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/byteorder.h
0,0 → 1,61
/*
* 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 generic
* @{
*/
/** @file
*/
 
#ifndef __BYTEORDER_H__
#define __BYTEORDER_H__
 
static inline uint64_t uint64_t_byteorder_swap(uint64_t n)
{
return ((n & 0xff) << 56) |
((n & 0xff00) << 40) |
((n & 0xff0000) << 24) |
((n & 0xff000000LL) << 8) |
((n & 0xff00000000LL) >>8) |
((n & 0xff0000000000LL) >> 24) |
((n & 0xff000000000000LL) >> 40) |
((n & 0xff00000000000000LL) >> 56);
}
 
static inline uint32_t uint32_t_byteorder_swap(uint32_t n)
{
return ((n & 0xff) << 24) |
((n & 0xff00) << 8) |
((n & 0xff0000) >> 8) |
((n & 0xff000000) >> 24);
}
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/symtab.h
0,0 → 1,58
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 generic
* @{
*/
/** @file
*/
 
#ifndef __SYMTAB_H__
#define __SYMTAB_H__
 
#include <arch/types.h>
 
#define MAX_SYMBOL_NAME 64
 
struct symtab_entry {
uint64_t address_le;
char symbol_name[MAX_SYMBOL_NAME];
};
 
extern char * get_symtab_entry(unative_t addr);
extern uintptr_t get_symbol_addr(const char *name);
extern void symtab_print_search(const char *name);
extern int symtab_compl(char *name);
 
/* Symtable linked together by build process */
extern struct symtab_entry symbol_table[];
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/sysinfo/sysinfo.h
0,0 → 1,87
/*
* Copyright (C) 2006 Jakub Vana
* 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 generic
* @{
*/
/** @file
*/
 
#include <arch/types.h>
 
typedef union sysinfo_item_val {
unative_t val;
void *fn;
} sysinfo_item_val_t;
 
typedef struct sysinfo_item {
char *name;
union {
unative_t val;
void *fn;
} val;
 
union {
struct sysinfo_item *table;
void *fn;
} subinfo;
 
struct sysinfo_item *next;
int val_type;
int subinfo_type;
} sysinfo_item_t;
 
#define SYSINFO_VAL_VAL 0
#define SYSINFO_VAL_FUNCTION 1
#define SYSINFO_VAL_UNDEFINED '?'
 
#define SYSINFO_SUBINFO_NONE 0
#define SYSINFO_SUBINFO_TABLE 1
#define SYSINFO_SUBINFO_FUNCTION 2
 
 
typedef unative_t (*sysinfo_val_fn_t)(sysinfo_item_t *root);
typedef unative_t (*sysinfo_subinfo_fn_t)(const char *subname);
 
typedef struct sysinfo_rettype {
unative_t val;
unative_t valid;
} sysinfo_rettype_t;
 
void sysinfo_set_item_val(const char *name,sysinfo_item_t **root,unative_t val);
void sysinfo_dump(sysinfo_item_t **root,int depth);
void sysinfo_set_item_function(const char *name,sysinfo_item_t **root,sysinfo_val_fn_t fn);
void sysinfo_set_item_undefined(const char *name,sysinfo_item_t **root);
 
sysinfo_rettype_t sysinfo_get_val(const char *name,sysinfo_item_t **root);
 
unative_t sys_sysinfo_valid(unative_t ptr,unative_t len);
unative_t sys_sysinfo_value(unative_t ptr,unative_t len);
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/elf.h
0,0 → 1,344
/*
* Copyright (C) 2006 Sergey Bondari
* 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 generic
* @{
*/
/** @file
*/
 
#ifndef __ELF_H__
#define __ELF_H__
 
#include <arch/elf.h>
#include <arch/types.h>
#include <typedefs.h>
 
/**
* current ELF version
*/
#define EV_CURRENT 1
 
/**
* ELF types
*/
#define ET_NONE 0 /* No type */
#define ET_REL 1 /* Relocatable file */
#define ET_EXEC 2 /* Executable */
#define ET_DYN 3 /* Shared object */
#define ET_CORE 4 /* Core */
#define ET_LOPROC 0xff00 /* Processor specific */
#define ET_HIPROC 0xffff /* Processor specific */
 
/**
* ELF machine types
*/
#define EM_NO 0 /* No machine */
#define EM_SPARC 2 /* SPARC */
#define EM_386 3 /* i386 */
#define EM_MIPS 8 /* MIPS RS3000 */
#define EM_MIPS_RS3_LE 10 /* MIPS RS3000 LE */
#define EM_PPC 20 /* PPC32 */
#define EM_PPC64 21 /* PPC64 */
#define EM_SPARCV9 43 /* SPARC64 */
#define EM_IA_64 50 /* IA-64 */
#define EM_X86_64 62 /* AMD64/EMT64 */
 
/**
* ELF identification indexes
*/
#define EI_MAG0 0
#define EI_MAG1 1
#define EI_MAG2 2
#define EI_MAG3 3
#define EI_CLASS 4 /* File class */
#define EI_DATA 5 /* Data encoding */
#define EI_VERSION 6 /* File version */
#define EI_OSABI 7
#define EI_ABIVERSION 8
#define EI_PAD 9 /* Start of padding bytes */
#define EI_NIDENT 16 /* ELF identification table size */
 
/**
* ELF magic number
*/
#define ELFMAG0 0x7f
#define ELFMAG1 'E'
#define ELFMAG2 'L'
#define ELFMAG3 'F'
 
/**
* ELF file classes
*/
#define ELFCLASSNONE 0
#define ELFCLASS32 1
#define ELFCLASS64 2
 
/**
* ELF data encoding types
*/
#define ELFDATANONE 0
#define ELFDATA2LSB 1 /* Least significant byte first (little endian) */
#define ELFDATA2MSB 2 /* Most signigicant byte first (big endian) */
 
/**
* ELF error return codes
*/
#define EE_OK 0 /* No error */
#define EE_INVALID 1 /* Invalid ELF image */
#define EE_MEMORY 2 /* Cannot allocate address space */
#define EE_INCOMPATIBLE 3 /* ELF image is not compatible with current architecture */
#define EE_UNSUPPORTED 4 /* Non-supported ELF (e.g. dynamic ELFs) */
#define EE_IRRECOVERABLE 5
 
/**
* ELF section types
*/
#define SHT_NULL 0
#define SHT_PROGBITS 1
#define SHT_SYMTAB 2
#define SHT_STRTAB 3
#define SHT_RELA 4
#define SHT_HASH 5
#define SHT_DYNAMIC 6
#define SHT_NOTE 7
#define SHT_NOBITS 8
#define SHT_REL 9
#define SHT_SHLIB 10
#define SHT_DYNSYM 11
#define SHT_LOOS 0x60000000
#define SHT_HIOS 0x6fffffff
#define SHT_LOPROC 0x70000000
#define SHT_HIPROC 0x7fffffff
#define SHT_LOUSER 0x80000000
#define SHT_HIUSER 0xffffffff
 
/**
* ELF section flags
*/
#define SHF_WRITE 0x1
#define SHF_ALLOC 0x2
#define SHF_EXECINSTR 0x4
#define SHF_MASKPROC 0xf0000000
 
/**
* Symbol binding
*/
#define STB_LOCAL 0
#define STB_GLOBAL 1
#define STB_WEAK 2
#define STB_LOPROC 13
#define STB_HIPROC 15
 
/**
* Symbol types
*/
#define STT_NOTYPE 0
#define STT_OBJECT 1
#define STT_FUNC 2
#define STT_SECTION 3
#define STT_FILE 4
#define STT_LOPROC 13
#define STT_HIPROC 15
 
/**
* Program segment types
*/
#define PT_NULL 0
#define PT_LOAD 1
#define PT_DYNAMIC 2
#define PT_INTERP 3
#define PT_NOTE 4
#define PT_SHLIB 5
#define PT_PHDR 6
#define PT_LOPROC 0x70000000
#define PT_HIPROC 0x7fffffff
 
/**
* Program segment attributes.
*/
#define PF_X 1
#define PF_W 2
#define PF_R 4
 
/**
* ELF data types
*
* These types are found to be identical in both 32-bit and 64-bit
* ELF object file specifications. They are the only types used
* in ELF header.
*/
typedef uint64_t elf_xword;
typedef int64_t elf_sxword;
typedef uint32_t elf_word;
typedef int32_t elf_sword;
typedef uint16_t elf_half;
 
/**
* 32-bit ELF data types.
*
* These types are specific for 32-bit format.
*/
typedef uint32_t elf32_addr;
typedef uint32_t elf32_off;
 
/**
* 64-bit ELF data types.
*
* These types are specific for 64-bit format.
*/
typedef uint64_t elf64_addr;
typedef uint64_t elf64_off;
 
/** ELF header */
struct elf32_header {
uint8_t e_ident[EI_NIDENT];
elf_half e_type;
elf_half e_machine;
elf_word e_version;
elf32_addr e_entry;
elf32_off e_phoff;
elf32_off e_shoff;
elf_word e_flags;
elf_half e_ehsize;
elf_half e_phentsize;
elf_half e_phnum;
elf_half e_shentsize;
elf_half e_shnum;
elf_half e_shstrndx;
};
struct elf64_header {
uint8_t e_ident[EI_NIDENT];
elf_half e_type;
elf_half e_machine;
elf_word e_version;
elf64_addr e_entry;
elf64_off e_phoff;
elf64_off e_shoff;
elf_word e_flags;
elf_half e_ehsize;
elf_half e_phentsize;
elf_half e_phnum;
elf_half e_shentsize;
elf_half e_shnum;
elf_half e_shstrndx;
};
 
/*
* ELF segment header.
* Segments headers are also known as program headers.
*/
struct elf32_segment_header {
elf_word p_type;
elf32_off p_offset;
elf32_addr p_vaddr;
elf32_addr p_paddr;
elf_word p_filesz;
elf_word p_memsz;
elf_word p_flags;
elf_word p_align;
};
struct elf64_segment_header {
elf_word p_type;
elf_word p_flags;
elf64_off p_offset;
elf64_addr p_vaddr;
elf64_addr p_paddr;
elf_xword p_filesz;
elf_xword p_memsz;
elf_xword p_align;
};
 
/*
* ELF section header
*/
struct elf32_section_header {
elf_word sh_name;
elf_word sh_type;
elf_word sh_flags;
elf32_addr sh_addr;
elf32_off sh_offset;
elf_word sh_size;
elf_word sh_link;
elf_word sh_info;
elf_word sh_addralign;
elf_word sh_entsize;
};
struct elf64_section_header {
elf_word sh_name;
elf_word sh_type;
elf_xword sh_flags;
elf64_addr sh_addr;
elf64_off sh_offset;
elf_xword sh_size;
elf_word sh_link;
elf_word sh_info;
elf_xword sh_addralign;
elf_xword sh_entsize;
};
 
/*
* ELF symbol table entry
*/
struct elf32_symbol {
elf_word st_name;
elf32_addr st_value;
elf_word st_size;
uint8_t st_info;
uint8_t st_other;
elf_half st_shndx;
};
struct elf64_symbol {
elf_word st_name;
uint8_t st_info;
uint8_t st_other;
elf_half st_shndx;
elf64_addr st_value;
elf_xword st_size;
};
 
#ifdef __32_BITS__
typedef struct elf32_header elf_header_t;
typedef struct elf32_segment_header elf_segment_header_t;
typedef struct elf32_section_header elf_section_header_t;
typedef struct elf32_symbol elf_symbol_t;
#endif
#ifdef __64_BITS__
typedef struct elf64_header elf_header_t;
typedef struct elf64_segment_header elf_segment_header_t;
typedef struct elf64_section_header elf_section_header_t;
typedef struct elf64_symbol elf_symbol_t;
#endif
 
extern int elf_load(elf_header_t *header, as_t * as);
extern char *elf_error(int rc);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/panic.h
0,0 → 1,49
/*
* 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 generic
* @{
*/
/** @file
*/
 
#ifndef __PANIC_H__
#define __PANIC_H__
 
#ifdef CONFIG_DEBUG
# define panic(format, ...) panic_printf("Kernel panic in %s() at %s on line %d: " format, __FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__);
#else
# define panic(format, ...) panic_printf("Kernel panic: " format, ##__VA_ARGS__);
#endif
 
extern void panic_printf(char *fmt, ...) __attribute__((noreturn)) ;
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/userspace.h
0,0 → 1,47
/*
* 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 generic
* @{
*/
/** @file
*/
 
#ifndef __USERSPACE_H__
#define __USERSPACE_H__
 
#include <proc/thread.h>
#include <arch/types.h>
 
/** Switch to user-space (CPU user priviledge level) */
extern void userspace(uspace_arg_t *uarg) __attribute__ ((noreturn));
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/interrupt.h
0,0 → 1,73
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 genericinterrupt
* @{
*/
/** @file
*/
 
#ifndef __INTERRUPT_H__
#define __INTERRUPT_H__
 
#include <arch/interrupt.h>
#include <typedefs.h>
#include <arch/types.h>
#include <proc/task.h>
#include <proc/thread.h>
#include <arch.h>
#include <console/klog.h>
#include <ipc/irq.h>
 
#ifndef IVT_ITEMS
# define IVT_ITEMS 0
#endif
 
#ifndef IVT_FIRST
# define IVT_FIRST 0
#endif
 
#define fault_if_from_uspace(istate, cmd, ...) \
{ \
if (istate_from_uspace(istate)) { \
klog_printf(cmd, ##__VA_ARGS__); \
klog_printf("Task %lld got exception at PC:%p. Task killed.", TASK->taskid, istate_get_pc(istate)); \
task_kill(TASK->taskid); \
thread_exit(); \
} \
}
 
 
extern iroutine exc_register(int n, const char *name, iroutine f);
extern void exc_dispatch(int n, istate_t *t);
void exc_init(void);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/bitops.h
0,0 → 1,70
/*
* Copyright (C) 2006 Ondrej Palkovsky
* 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 generic
* @{
*/
/** @file
*/
 
#ifndef _BITOPS_H_
#define _BITOPS_H_
 
#include <typedefs.h>
 
 
/** Return position of first non-zero bit from left (i.e. [log_2(arg)]).
*
* If number is zero, it returns 0
*/
static inline int fnzb32(uint32_t arg)
{
int n = 0;
 
if (arg >> 16) { arg >>= 16;n += 16;}
if (arg >> 8) { arg >>= 8; n += 8;}
if (arg >> 4) { arg >>= 4; n += 4;}
if (arg >> 2) { arg >>= 2; n+=2;}
if (arg >> 1) { arg >>= 1; n+=1;}
return n;
}
 
static inline int fnzb64(uint64_t arg)
{
int n = 0;
 
if (arg >> 32) { arg >>= 32;n += 32;}
return n + fnzb32((uint32_t) arg);
}
 
#define fnzb(x) fnzb32(x)
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/putchar.h
0,0 → 1,43
/*
* 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 generic
* @{
*/
/** @file
*/
 
#ifndef __PUTCHAR_H__
#define __PUTCHAR_H__
 
extern void putchar(const char ch);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/memstr.h
0,0 → 1,52
/*
* 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 generic
* @{
*/
/** @file
*/
 
#ifndef __MEMSTR_H__
#define __MEMSTR_H__
 
#include <typedefs.h>
#include <arch/types.h>
#include <arch/memstr.h>
 
/*
* Architecture independent variants.
*/
extern void *_memcpy(void *dst, const void *src, size_t cnt);
extern void _memsetb(uintptr_t dst, size_t cnt, uint8_t x);
extern void _memsetw(uintptr_t dst, size_t cnt, uint16_t x);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/atomic.h
0,0 → 1,57
/*
* 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 generic
* @{
*/
/** @file
*/
 
#ifndef __ATOMIC_H__
#define __ATOMIC_H__
 
typedef struct atomic {
volatile long count;
} atomic_t;
 
#include <arch/atomic.h>
 
static inline void atomic_set(atomic_t *val, long i)
{
val->count = i;
}
 
static inline long atomic_get(atomic_t *val)
{
return val->count;
}
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/test.h
0,0 → 1,43
/*
* 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 generic
* @{
*/
/** @file
*/
 
#ifndef __TEST_H__
#define __TEST_H__
 
extern void test(void);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/preemption.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 generic
* @{
*/
/** @file
*/
 
#ifndef __PREEMPTION_H__
#define __PREEMPTION_H__
 
extern void preemption_disable(void);
extern void preemption_enable(void);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/context.h
0,0 → 1,94
/*
* 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 generic
* @{
*/
/** @file
*/
 
#ifndef __CONTEXT_H__
#define __CONTEXT_H__
 
#include <arch/types.h>
#include <typedefs.h>
#include <arch/context.h>
 
 
#ifndef context_set
#define context_set(c, _pc, stack, size) \
(c)->pc = (uintptr_t) (_pc); \
(c)->sp = ((uintptr_t) (stack)) + (size) - SP_DELTA;
#endif /* context_set */
 
extern int context_save_arch(context_t *c);
extern void context_restore_arch(context_t *c) __attribute__ ((noreturn));
 
/** Save register context.
*
* Save current register context (including stack pointers)
* to context structure.
*
* Note that call to context_restore() will return at the same
* address as the corresponding call to context_save().
*
* This MUST be a macro, gcc -O0 does not inline functions even
* if they are marked inline and context_save_arch must be called
* from level <= that when context_restore is called.
*
* @param c Context structure.
*
* @return context_save() returns 1, context_restore() returns 0.
*/
#define context_save(c) context_save_arch(c)
 
/** Restore register context.
*
* Restore previously saved register context (including stack pointers)
* from context structure.
*
* Note that this function does not normally return.
* Instead, it returns at the same address as the
* corresponding call to context_save(), the only
* difference being return value.
*
* Note that content of any local variable defined by
* the caller of context_save() is undefined after
* context_restore().
*
* @param c Context structure.
*/
static inline void context_restore(context_t *c)
{
context_restore_arch(c);
}
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/stdarg.h
0,0 → 1,54
/*
* 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 generic
* @{
*/
/** @file
*/
 
 
/*
* Variable argument list manipulation macros
* for all architectures with compiler support for __builtin_va_*.
*/
#ifndef __STDARG_H__
#define __STDARG_H__
 
typedef __builtin_va_list va_list;
 
#define va_start(ap, last) __builtin_va_start(ap, last)
#define va_arg(ap, type) __builtin_va_arg(ap, type)
#define va_end(ap) __builtin_va_end(ap)
#define va_copy(dst,src) __builtin_va_copy(dst,src)
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/syscall/copy.h
0,0 → 1,58
/*
* 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 generic
* @{
*/
/** @file
*/
 
#ifndef __COPY_H__
#define __COPY_H__
 
#include <typedefs.h>
 
/** Label within memcpy_from_uspace() that contains return -1. */
extern char memcpy_from_uspace_failover_address;
 
/** Label within memcpy_to_uspace() that contains return -1. */
extern char memcpy_to_uspace_failover_address;
 
extern int copy_from_uspace(void *dst, const void *uspace_src, size_t size);
extern int copy_to_uspace(void *dst_uspace, const void *src, size_t size);
 
/*
* This interface must be implemented by each architecture.
*/
extern int memcpy_from_uspace(void *dst, const void *uspace_src, size_t size);
extern int memcpy_to_uspace(void *uspace_dst, const void *src, size_t size);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/syscall/syscall.h
0,0 → 1,89
/*
* Copyright (C) 2005 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 generic
* @{
*/
/** @file
*/
 
#ifndef __SYSCALL_H__
#define __SYSCALL_H__
 
typedef enum {
SYS_IO = 0,
SYS_TLS_SET = 1, /* Hardcoded in AMD64, IA32 uspace - psthread.S */
SYS_THREAD_CREATE,
SYS_THREAD_EXIT,
SYS_TASK_GET_ID,
SYS_FUTEX_SLEEP,
SYS_FUTEX_WAKEUP,
SYS_AS_AREA_CREATE,
SYS_AS_AREA_RESIZE,
SYS_AS_AREA_DESTROY,
SYS_IPC_CALL_SYNC_FAST,
SYS_IPC_CALL_SYNC,
SYS_IPC_CALL_ASYNC_FAST,
SYS_IPC_CALL_ASYNC,
SYS_IPC_ANSWER_FAST,
SYS_IPC_ANSWER,
SYS_IPC_FORWARD_FAST,
SYS_IPC_WAIT,
SYS_IPC_HANGUP,
SYS_IPC_REGISTER_IRQ,
SYS_IPC_UNREGISTER_IRQ,
SYS_CAP_GRANT,
SYS_CAP_REVOKE,
SYS_MAP_PHYSMEM,
SYS_IOSPACE_ENABLE,
SYS_PREEMPT_CONTROL,
SYS_SYSINFO_VALID,
SYS_SYSINFO_VALUE,
SYS_DEBUG_ENABLE_CONSOLE,
SYSCALL_END
} syscall_t;
 
#ifdef KERNEL
 
#include <arch/types.h>
#include <typedefs.h>
 
typedef unative_t (*syshandler_t)();
 
extern syshandler_t syscall_table[SYSCALL_END];
extern unative_t syscall_handler(unative_t a1, unative_t a2, unative_t a3,
unative_t a4, unative_t id);
extern unative_t sys_tls_set(unative_t addr);
 
 
#endif
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/syscall/sysarg64.h
0,0 → 1,48
/*
* 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 generic
* @{
*/
 
/**
* @file
* @brief Wrapper for explicit 64-bit arguments passed to syscalls.
*/
 
#ifndef __SYSARG64_H__
#define __SYSARG64_H__
 
typedef struct {
unsigned long long value;
} sysarg64_t;
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/errno.h
0,0 → 1,60
/*
* Copyright (C) 2005 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 generic
* @{
*/
/** @file
*/
 
#ifndef __ERRNO_H__
#define __ERRNO_H__
 
/* 1-255 are kernel error codes, 256-512 are user error codes */
 
#define ENOENT -1 /* No such entry */
#define ENOMEM -2 /* Not enough memory */
#define ELIMIT -3 /* Limit exceeded */
#define EREFUSED -4 /* Connection refused */
#define EFORWARD -5 /* Forward error */
#define EPERM -6 /* Permission denied */
#define EHANGUP -7 /* Answerbox closed connection, call sys_ipc_hangup
* to close the connection. Used by answerbox
* to close the connection. */
#define EEXISTS -8 /* Entry already exists */
#define EBADMEM -9 /* Bad memory pointer */
#define ENOTSUP -10 /* Not supported */
#define EADDRNOTAVAIL -11 /* Address not available. */
#define ETIMEOUT -12 /* Timeout expired */
#define EINVAL -13 /* Invalid value */
#define EBUSY -14 /* Resource is busy */
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/sort.h
0,0 → 1,57
/*
* Copyright (C) 2005 Sergey Bondari
* 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 generic
* @{
*/
/** @file
*/
 
#ifndef __SORT_H__
#define __SORT_H__
 
#include <arch/types.h>
 
/*
* sorting routines
*/
extern void bubblesort(void * data, count_t n, size_t e_size, int (* cmp) (void * a, void * b));
extern void qsort(void * data, count_t n, size_t e_size, int (* cmp) (void * a, void * b));
 
/*
* default sorting comparators
*/
extern int int_cmp(void * a, void * b);
extern int uint32_t_cmp(void * a, void * b);
extern int uint16_t_cmp(void * a, void * b);
extern int uint8_t_cmp(void * a, void * b);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/debug.h
0,0 → 1,66
/*
* Copyright (C) 2005 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 genericdebug
* @{
*/
/** @file
*/
 
#ifndef __DEBUG_H__
#define __DEBUG_H__
 
#include <panic.h>
#include <arch/debug.h>
 
#define CALLER ((uintptr_t)__builtin_return_address(0))
 
#ifndef HERE
/** Current Instruction Pointer address */
# define HERE ((uintptr_t *)0)
#endif
 
/** Debugging ASSERT macro
*
* If CONFIG_DEBUG is set, the ASSERT() macro
* evaluates expr and if it is false raises
* kernel panic.
*
* @param expr Expression which is expected to be true.
*
*/
#ifdef CONFIG_DEBUG
# define ASSERT(expr) if (!(expr)) { panic("assertion failed (%s), caller=%.*p\n", #expr, sizeof(uintptr_t) * 2, CALLER); }
#else
# define ASSERT(expr)
#endif
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/macros.h
0,0 → 1,68
/*
* 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 generic
* @{
*/
/** @file
*/
 
#ifndef __MACROS_H__
#define __MACROS_H__
 
#include <arch/types.h>
#include <typedefs.h>
 
#define is_digit(d) (((d) >= '0') && ((d) <= '9'))
#define is_lower(c) (((c) >= 'a') && ((c) <= 'z'))
#define is_upper(c) (((c) >= 'A') && ((c) <= 'Z'))
#define is_alpha(c) (is_lower(c) || is_upper(c))
#define is_alphanum(c) (is_alpha(c) || is_digit(c))
#define is_white(c) (((c) == ' ') || ((c) == '\t') || ((c) == '\n') || ((c) == '\r'))
 
#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))
 
/** Return true if the interlvals overlap. */
static inline int overlaps(uintptr_t s1, size_t sz1, uintptr_t s2, size_t sz2)
{
uintptr_t e1 = s1 + sz1;
uintptr_t e2 = s2 + sz2;
 
return (s1 < e2) && (s2 < e1);
}
/* Compute overlapping of physical addresses */
#define PA_overlaps(x, szx, y, szy) overlaps(KA2PA(x), szx, KA2PA(y), szy)
 
#define STRING(arg) STRING_ARG(arg)
#define STRING_ARG(arg) #arg
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/time/delay.h
0,0 → 1,45
/*
* 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 time
* @{
*/
/** @file
*/
 
#ifndef __DELAY_H__
#define __DELAY_H__
 
#include <arch/types.h>
 
extern void delay(uint32_t microseconds);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/time/timeout.h
0,0 → 1,69
/*
* 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 time
* @{
*/
/** @file
*/
 
#ifndef __TIMEOUT_H__
#define __TIMEOUT_H__
 
#include <arch/types.h>
#include <typedefs.h>
#include <synch/spinlock.h>
#include <adt/list.h>
 
#define us2ticks(us) ((uint64_t)(((uint32_t) (us)/(1000000/HZ))))
 
typedef void (* timeout_handler_t)(void *arg);
 
struct timeout {
SPINLOCK_DECLARE(lock);
 
link_t link; /**< Link to the list of active timeouts on THE->cpu */
uint64_t ticks; /**< Timeout will be activated in this amount of clock() ticks. */
 
timeout_handler_t handler; /**< Function that will be called on timeout activation. */
void *arg; /**< Argument to be passed to handler() function. */
cpu_t *cpu; /**< On which processor is this timeout registered. */
};
 
extern void timeout_init(void);
extern void timeout_initialize(timeout_t *t);
extern void timeout_reinitialize(timeout_t *t);
extern void timeout_register(timeout_t *t, uint64_t usec, timeout_handler_t f, void *arg);
extern bool timeout_unregister(timeout_t *t);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/time/clock.h
0,0 → 1,46
/*
* 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 time
* @{
*/
/** @file
*/
 
#ifndef __CLOCK_H__
#define __CLOCK_H__
 
#define HZ 100
 
extern void clock(void);
extern void clock_counter_init(void);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/cpu.h
0,0 → 1,108
/*
* 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 generic
* @{
*/
/** @file
*/
 
#ifndef __CPU_H__
#define __CPU_H__
 
#include <arch/cpu.h>
#include <proc/scheduler.h>
#include <synch/spinlock.h>
#include <synch/waitq.h>
#include <arch/types.h>
#include <typedefs.h>
#include <arch/context.h>
#include <config.h>
#include <adt/list.h>
#include <mm/tlb.h>
 
#define CPU_STACK_SIZE STACK_SIZE
 
/** CPU structure.
*
* There is one structure like this for every processor.
*/
struct cpu {
SPINLOCK_DECLARE(lock);
 
tlb_shootdown_msg_t tlb_messages[TLB_MESSAGE_QUEUE_LEN];
count_t tlb_messages_count;
context_t saved_context;
 
atomic_t nrdy;
runq_t rq[RQ_COUNT];
volatile count_t needs_relink;
 
SPINLOCK_DECLARE(timeoutlock);
link_t timeout_active_head;
 
count_t missed_clock_ticks; /**< When system clock loses a tick, it is recorded here
so that clock() can react. This variable is
CPU-local and can be only accessed when interrupts
are disabled. */
 
/**
* Processor ID assigned by kernel.
*/
int id;
int active;
int tlb_active;
 
uint16_t frequency_mhz;
uint32_t delay_loop_const;
 
cpu_arch_t arch;
 
thread_t *fpu_owner;
/**
* Stack used by scheduler when there is no running thread.
*/
uint8_t *stack;
};
 
extern cpu_t *cpus;
 
extern void cpu_init(void);
extern void cpu_list(void);
 
extern void cpu_arch_init(void);
extern void cpu_identify(void);
extern void cpu_print_report(cpu_t *m);
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/include/synch/futex.h
0,0 → 1,62
/*
* 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 sync
* @{
*/
/** @file
*/
 
#ifndef __FUTEX_H__
#define __FUTEX_H__
 
#include <arch/types.h>
#include <typedefs.h>
#include <synch/waitq.h>
#include <genarch/mm/page_ht.h>
#include <genarch/mm/page_pt.h>
 
/** Kernel-side futex structure. */
struct futex {
uintptr_t paddr; /**< Physical address of the status variable. */
waitq_t wq; /**< Wait queue for threads waiting for futex availability. */
link_t ht_link; /**< Futex hash table link. */
count_t refcount; /**< Number of tasks that reference this futex. */
};
 
extern void futex_init(void);
extern unative_t sys_futex_sleep_timeout(uintptr_t uaddr, uint32_t usec, int flags);
extern unative_t sys_futex_wakeup(uintptr_t uaddr);
 
extern void futex_cleanup(void);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/synch/condvar.h
0,0 → 1,61
/*
* 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 sync
* @{
*/
/** @file
*/
 
#ifndef __CONDVAR_H__
#define __CONDVAR_H__
 
#include <arch/types.h>
#include <synch/waitq.h>
#include <typedefs.h>
#include <synch/synch.h>
 
struct condvar {
waitq_t wq;
};
 
#define condvar_wait(cv,mtx) \
_condvar_wait_timeout((cv),(mtx),SYNCH_NO_TIMEOUT,SYNCH_FLAGS_NONE)
#define condvar_wait_timeout(cv,mtx,usec) \
_condvar_wait_timeout((cv),(mtx),(usec),SYNCH_FLAGS_NONE)
 
extern void condvar_initialize(condvar_t *cv);
extern void condvar_signal(condvar_t *cv);
extern void condvar_broadcast(condvar_t *cv);
extern int _condvar_wait_timeout(condvar_t *cv, mutex_t *mtx, uint32_t usec, int flags);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/synch/rwlock.h
0,0 → 1,80
/*
* 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 sync
* @{
*/
/** @file
*/
 
#ifndef __RWLOCK_H__
#define __RWLOCK_H__
 
#include <arch/types.h>
#include <typedefs.h>
#include <synch/mutex.h>
#include <synch/synch.h>
#include <synch/spinlock.h>
 
enum rwlock_type {
RWLOCK_NONE,
RWLOCK_READER,
RWLOCK_WRITER
};
 
struct rwlock {
SPINLOCK_DECLARE(lock);
mutex_t exclusive; /**< Mutex for writers, readers can bypass it if readers_in is positive. */
count_t readers_in; /**< Number of readers in critical section. */
};
 
#define rwlock_write_lock(rwl) \
_rwlock_write_lock_timeout((rwl),SYNCH_NO_TIMEOUT,SYNCH_FLAGS_NONE)
#define rwlock_read_lock(rwl) \
_rwlock_read_lock_timeout((rwl),SYNCH_NO_TIMEOUT,SYNCH_FLAGS_NONE)
#define rwlock_write_trylock(rwl) \
_rwlock_write_lock_timeout((rwl),SYNCH_NO_TIMEOUT,SYNCH_FLAGS_NON_BLOCKING)
#define rwlock_read_trylock(rwl) \
_rwlock_read_lock_timeout((rwl),SYNCH_NO_TIMEOUT,SYNCH_FLAGS_NON_BLOCKING)
#define rwlock_write_lock_timeout(rwl,usec) \
_rwlock_write_lock_timeout((rwl),(usec),SYNCH_FLAGS_NONE)
#define rwlock_read_lock_timeout(rwl,usec) \
_rwlock_read_lock_timeout((rwl),(usec),SYNCH_FLAGS_NONE)
 
extern void rwlock_initialize(rwlock_t *rwl);
extern void rwlock_read_unlock(rwlock_t *rwl);
extern void rwlock_write_unlock(rwlock_t *rwl);
extern int _rwlock_read_lock_timeout(rwlock_t *rwl, uint32_t usec, int flags);
extern int _rwlock_write_lock_timeout(rwlock_t *rwl, uint32_t usec, int flags);
 
#endif
 
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/synch/mutex.h
0,0 → 1,64
/*
* 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 sync
* @{
*/
/** @file
*/
 
#ifndef __MUTEX_H__
#define __MUTEX_H__
 
#include <arch/types.h>
#include <typedefs.h>
#include <synch/semaphore.h>
#include <synch/synch.h>
 
struct mutex {
semaphore_t sem;
};
 
#define mutex_lock(mtx) \
_mutex_lock_timeout((mtx),SYNCH_NO_TIMEOUT,SYNCH_FLAGS_NONE)
#define mutex_trylock(mtx) \
_mutex_lock_timeout((mtx),SYNCH_NO_TIMEOUT,SYNCH_FLAGS_NON_BLOCKING)
#define mutex_lock_timeout(mtx,usec) \
_mutex_lock_timeout((mtx),(usec),SYNCH_FLAGS_NON_BLOCKING)
#define mutex_lock_active(mtx) \
while (mutex_trylock((mtx)) != ESYNCH_OK_ATOMIC)
 
extern void mutex_initialize(mutex_t *mtx);
extern int _mutex_lock_timeout(mutex_t *mtx, uint32_t usec, int flags);
extern void mutex_unlock(mutex_t *mtx);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/synch/semaphore.h
0,0 → 1,64
/*
* 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 sync
* @{
*/
/** @file
*/
 
#ifndef __SEMAPHORE_H__
#define __SEMAPHORE_H__
 
#include <arch/types.h>
#include <typedefs.h>
#include <synch/waitq.h>
#include <synch/synch.h>
 
struct semaphore
{
waitq_t wq;
};
 
#define semaphore_down(s) \
_semaphore_down_timeout((s),SYNCH_NO_TIMEOUT,SYNCH_FLAGS_NONE)
#define semaphore_trydown(s) \
_semaphore_down_timeout((s),SYNCH_NO_TIMEOUT,SYNCH_FLAGS_NON_BLOCKING)
#define semaphore_down_timeout(s,usec) \
_semaphore_down_timeout((s),(usec),SYNCH_FLAGS_NONE)
 
extern void semaphore_initialize(semaphore_t *s, int val);
extern int _semaphore_down_timeout(semaphore_t *s, uint32_t usec, int flags);
extern void semaphore_up(semaphore_t *s);
 
#endif
 
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/synch/waitq.h
0,0 → 1,76
/*
* 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 sync
* @{
*/
/** @file
*/
 
#ifndef __WAITQ_H__
#define __WAITQ_H__
 
#include <arch/types.h>
#include <typedefs.h>
#include <synch/spinlock.h>
#include <synch/synch.h>
#include <adt/list.h>
 
#define WAKEUP_FIRST 0
#define WAKEUP_ALL 1
 
/** Wait queue structure. */
struct waitq {
 
/** Lock protecting wait queue structure.
*
* Must be acquired before T.lock for each T of type thread_t.
*/
SPINLOCK_DECLARE(lock);
 
int missed_wakeups; /**< Number of waitq_wakeup() calls that didn't find a thread to wake up. */
link_t head; /**< List of sleeping threads for wich there was no missed_wakeup. */
};
 
#define waitq_sleep(wq) \
waitq_sleep_timeout((wq),SYNCH_NO_TIMEOUT,SYNCH_FLAGS_NONE)
 
extern void waitq_initialize(waitq_t *wq);
extern int waitq_sleep_timeout(waitq_t *wq, uint32_t usec, int flags);
extern ipl_t waitq_sleep_prepare(waitq_t *wq);
extern int waitq_sleep_timeout_unsafe(waitq_t *wq, uint32_t usec, int flags);
extern void waitq_sleep_finish(waitq_t *wq, int rc, ipl_t ipl);
extern void waitq_wakeup(waitq_t *wq, bool all);
extern void _waitq_wakeup_unsafe(waitq_t *wq, bool all);
extern void waitq_interrupt_sleep(thread_t *t);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/synch/spinlock.h
0,0 → 1,121
/*
* 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 sync
* @{
*/
/** @file
*/
 
#ifndef __SPINLOCK_H__
#define __SPINLOCK_H__
 
#include <arch/types.h>
#include <typedefs.h>
#include <preemption.h>
#include <atomic.h>
#include <debug.h>
 
#ifdef CONFIG_SMP
struct spinlock {
#ifdef CONFIG_DEBUG_SPINLOCK
char *name;
#endif
atomic_t val;
};
 
/*
* SPINLOCK_DECLARE is to be used for dynamically allocated spinlocks,
* where the lock gets initialized in run time.
*/
#define SPINLOCK_DECLARE(slname) spinlock_t slname
 
/*
* SPINLOCK_INITIALIZE is to be used for statically allocated spinlocks.
* It declares and initializes the lock.
*/
#ifdef CONFIG_DEBUG_SPINLOCK
#define SPINLOCK_INITIALIZE(slname) \
spinlock_t slname = { \
.name = #slname, \
.val = { 0 } \
}
#else
#define SPINLOCK_INITIALIZE(slname) \
spinlock_t slname = { \
.val = { 0 } \
}
#endif
 
extern void spinlock_initialize(spinlock_t *sl, char *name);
extern int spinlock_trylock(spinlock_t *sl);
extern void spinlock_lock_debug(spinlock_t *sl);
 
#ifdef CONFIG_DEBUG_SPINLOCK
# define spinlock_lock(x) spinlock_lock_debug(x)
#else
# define spinlock_lock(x) atomic_lock_arch(&(x)->val)
#endif
 
/** Unlock spinlock
*
* Unlock spinlock.
*
* @param sl Pointer to spinlock_t structure.
*/
static inline void spinlock_unlock(spinlock_t *sl)
{
ASSERT(atomic_get(&sl->val) != 0);
 
/*
* Prevent critical section code from bleeding out this way down.
*/
CS_LEAVE_BARRIER();
atomic_set(&sl->val,0);
preemption_enable();
}
 
#else
 
/* On UP systems, spinlocks are effectively left out. */
#define SPINLOCK_DECLARE(name)
#define SPINLOCK_INITIALIZE(name)
 
#define spinlock_initialize(x,name)
#define spinlock_lock(x) preemption_disable()
#define spinlock_trylock(x) (preemption_disable(), 1)
#define spinlock_unlock(x) preemption_enable()
 
#endif
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/synch/synch.h
0,0 → 1,57
/*
* 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 sync
* @{
*/
/** @file
*/
 
#ifndef __SYNCH_H__
#define __SYNCH_H__
 
#define SYNCH_NO_TIMEOUT 0 /**< Request with no timeout. */
 
#define SYNCH_FLAGS_NONE 0 /**< No flags specified. */
#define SYNCH_FLAGS_NON_BLOCKING (1<<0) /**< Non-blocking operation request. */
#define SYNCH_FLAGS_INTERRUPTIBLE (1<<1) /**< Interruptible operation. */
 
#define ESYNCH_WOULD_BLOCK 1 /**< Could not satisfy the request without going to sleep. */
#define ESYNCH_TIMEOUT 2 /**< Timeout occurred. */
#define ESYNCH_INTERRUPTED 4 /**< Sleep was interrupted. */
#define ESYNCH_OK_ATOMIC 8 /**< Operation succeeded without sleeping. */
#define ESYNCH_OK_BLOCKED 16 /**< Operation succeeded and did sleep. */
 
#define SYNCH_FAILED(rc) ((rc) & (ESYNCH_WOULD_BLOCK | ESYNCH_TIMEOUT | ESYNCH_INTERRUPTED))
#define SYNCH_OK(rc) ((rc) & (ESYNCH_OK_ATOMIC | ESYNCH_OK_BLOCKED))
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/ddi/ddi.h
0,0 → 1,56
/*
* 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 genericddi
* @{
*/
/** @file
*/
 
#ifndef __DDI_H__
#define __DDI_H__
 
#include <ddi/ddi_arg.h>
#include <arch/types.h>
#include <typedefs.h>
 
unative_t sys_physmem_map(unative_t phys_base, unative_t virt_base, unative_t pages,
unative_t flags);
extern unative_t sys_iospace_enable(ddi_ioarg_t *uspace_io_arg);
extern unative_t sys_preempt_control(int enable);
 
/*
* Interface to be implemented by all architectures.
*/
extern int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/ddi/ddi_arg.h
0,0 → 1,58
/*
* 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 genericddi
* @{
*/
/** @file
*/
 
#ifndef __DDI_ARG_H__
#define __DDI_ARG_H__
 
/** Structure encapsulating arguments for SYS_MAP_PHYSMEM syscall. */
typedef struct {
unsigned long long task_id; /** ID of the destination task. */
void *phys_base; /** Physical address of starting frame. */
void *virt_base; /** Virtual address of starting page. */
unsigned long pages; /** Number of pages to map. */
int flags; /** Address space area flags for the mapping. */
} ddi_memarg_t;
 
/** Structure encapsulating arguments for SYS_ENABLE_IOSPACE syscall. */
typedef struct {
unsigned long long task_id; /** ID of the destination task. */
void *ioaddr; /** Starting I/O space address. */
unsigned long size; /** Number of bytes. */
} ddi_ioarg_t;
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/console/chardev.h
0,0 → 1,78
/*
* 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 genericconsole
* @{
*/
/** @file
*/
 
#ifndef __CHARDEV_H__
#define __CHARDEV_H__
 
#include <typedefs.h>
#include <arch/types.h>
#include <synch/waitq.h>
#include <synch/spinlock.h>
 
#define CHARDEV_BUFLEN 512
 
/* Character device operations interface. */
struct chardev_operations {
void (* suspend)(chardev_t *); /**< Suspend pushing characters. */
void (* resume)(chardev_t *); /**< Resume pushing characters. */
void (* write)(chardev_t *, char c); /**< Write character to stream. */
/** Read character directly from device, assume interrupts disabled */
char (* read)(chardev_t *);
};
 
typedef struct chardev_operations chardev_operations_t;
 
/** Character input device. */
struct chardev {
char *name;
waitq_t wq;
SPINLOCK_DECLARE(lock); /**< Protects everything below. */
uint8_t buffer[CHARDEV_BUFLEN];
count_t counter;
chardev_operations_t *op; /**< Implementation of chardev operations. */
index_t index;
void *data;
};
 
extern void chardev_initialize(char *name,
chardev_t *chardev,
chardev_operations_t *op);
extern void chardev_push_character(chardev_t *chardev, uint8_t ch);
 
#endif /* __CHARDEV_H__ */
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/console/kconsole.h
0,0 → 1,85
/*
* 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 genericconsole
* @{
*/
/** @file
*/
 
#ifndef __KCONSOLE_H__
#define __KCONSOLE_H__
 
#include <typedefs.h>
#include <adt/list.h>
#include <synch/spinlock.h>
 
#define MAX_CMDLINE 256
#define KCONSOLE_HISTORY 10
 
enum cmd_arg_type {
ARG_TYPE_INVALID = 0,
ARG_TYPE_INT,
ARG_TYPE_STRING,
ARG_TYPE_VAR /**< Variable type - either symbol or string */
};
 
/** Structure representing one argument of kconsole command line. */
struct cmd_arg {
cmd_arg_type_t type; /**< Type descriptor. */
void *buffer; /**< Buffer where to store data. */
size_t len; /**< Size of the buffer. */
unative_t intval; /**< Integer value */
cmd_arg_type_t vartype; /**< Resulting type of variable arg */
};
 
/** Structure representing one kconsole command. */
struct cmd_info {
link_t link; /**< Command list link. */
SPINLOCK_DECLARE(lock); /**< This lock protects everything below. */
const char *name; /**< Command name. */
const char *description; /**< Textual description. */
int (* func)(cmd_arg_t *); /**< Function implementing the command. */
count_t argc; /**< Number of arguments. */
cmd_arg_t *argv; /**< Argument vector. */
void (* help)(void); /**< Function for printing detailed help. */
};
 
extern spinlock_t cmd_lock;
extern link_t cmd_head;
 
extern void kconsole_init(void);
extern void kconsole(void *prompt);
 
extern int cmd_register(cmd_info_t *cmd);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/console/console.h
0,0 → 1,56
/*
* 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 genericconsole
* @{
*/
/** @file
*/
 
#ifndef __CONSOLE_H__
#define __CONSOLE_H__
 
#include <arch/types.h>
#include <typedefs.h>
 
extern chardev_t *stdin;
extern chardev_t *stdout;
 
extern uint8_t getc(chardev_t *chardev);
uint8_t _getc(chardev_t *chardev);
extern count_t gets(chardev_t *chardev, char *buf, size_t buflen);
extern void putchar(char c);
 
extern void arch_grab_console(void);
extern void arch_release_console(void);
 
#endif /* __CHARDEV_H__ */
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/console/klog.h
0,0 → 1,45
/*
* Copyright (C) 2006 Ondrej Palkovsky
* 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 genericklog
* @{
*/
/** @file
*/
 
#ifndef _KLOG_H_
#define _KLOG_H_
 
void klog_init(void);
void klog_printf(const char *fmt, ...);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/console/cmd.h
0,0 → 1,47
/*
* 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 genericconsole
* @{
*/
/** @file
*/
 
#ifndef __CMD_H__
#define __CMD_H__
 
#include <typedefs.h>
 
extern void cmd_initialize(cmd_info_t *cmd);
extern void cmd_init(void);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/security/cap.h
0,0 → 1,94
/*
* 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 generic
* @{
*/
/** @file
*/
 
/**
* @file
* @brief Capabilities definitions.
*
* Capabilities represent virtual rights that entitle their
* holder to perform certain security sensitive tasks.
*
* Each task can have arbitrary combination of the capabilities
* defined in this file. Therefore, they are required to be powers
* of two.
*/
 
#ifndef __CAP_H__
#define __CAP_H__
 
#include <syscall/sysarg64.h>
#include <arch/types.h>
#include <typedefs.h>
 
/**
* CAP_CAP allows its holder to grant/revoke arbitrary
* privilege to/from other tasks.
*/
#define CAP_CAP (1<<0)
 
/**
* CAP_MEM_MANAGER allows its holder to map physical memory
* to other tasks.
*/
#define CAP_MEM_MANAGER (1<<1)
 
/**
* CAP_IO_MANAGER allows its holder to access I/O space
* to other tasks.
*/
#define CAP_IO_MANAGER (1<<2)
 
/**
* CAP_PREEMPT_CONTROL allows its holder to disable/enable preemption.
*/
#define CAP_PREEMPT_CONTROL (1<<3)
 
/**
* CAP_IRQ_REG entitles its holder to register IRQ handlers.
*/
#define CAP_IRQ_REG (1<<4)
 
typedef uint32_t cap_t;
 
extern void cap_set(task_t *t, cap_t caps);
extern cap_t cap_get(task_t *t);
 
extern unative_t sys_cap_grant(sysarg64_t *uspace_taskid_arg, cap_t caps);
extern unative_t sys_cap_revoke(sysarg64_t *uspace_taskid_arg, cap_t caps);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/adt/hash_table.h
0,0 → 1,86
/*
* 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 genericadt
* @{
*/
/** @file
*/
 
#ifndef __HASH_TABLE_H__
#define __HASH_TABLE_H__
 
#include <adt/list.h>
#include <arch/types.h>
#include <typedefs.h>
 
/** Hash table structure. */
struct hash_table {
link_t *entry;
count_t entries;
count_t max_keys;
hash_table_operations_t *op;
};
 
/** Set of operations for hash table. */
struct hash_table_operations {
/** Hash function.
*
* @param key Array of keys needed to compute hash index. All keys must be passed.
*
* @return Index into hash table.
*/
index_t (* hash)(unative_t key[]);
/** Hash table item comparison function.
*
* @param key Array of keys that will be compared with item. It is not necessary to pass all keys.
*
* @return true if the keys match, false otherwise.
*/
bool (*compare)(unative_t key[], count_t keys, link_t *item);
 
/** Hash table item removal callback.
*
* @param item Item that was removed from the hash table.
*/
void (*remove_callback)(link_t *item);
};
 
#define hash_table_get_instance(item, type, member) list_get_instance((item), type, member)
 
extern void hash_table_create(hash_table_t *h, count_t m, count_t max_keys, hash_table_operations_t *op);
extern void hash_table_insert(hash_table_t *h, unative_t key[], link_t *item);
extern link_t *hash_table_find(hash_table_t *h, unative_t key[]);
extern void hash_table_remove(hash_table_t *h, unative_t key[], count_t keys);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/adt/list.h
0,0 → 1,187
/*
* 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 genericadt
* @{
*/
/** @file
*/
 
#ifndef __LIST_H__
#define __LIST_H__
 
#include <arch/types.h>
#include <typedefs.h>
 
/** Doubly linked list head and link type. */
struct link {
link_t *prev; /**< Pointer to the previous item in the list. */
link_t *next; /**< Pointer to the next item in the list. */
};
 
/** Declare and initialize statically allocated list.
*
* @param name Name of the new statically allocated list.
*/
#define LIST_INITIALIZE(name) link_t name = { .prev = &name, .next = &name }
 
/** Initialize doubly-linked circular list link
*
* Initialize doubly-linked list link.
*
* @param link Pointer to link_t structure to be initialized.
*/
static inline void link_initialize(link_t *link)
{
link->prev = NULL;
link->next = NULL;
}
 
/** Initialize doubly-linked circular list
*
* Initialize doubly-linked circular list.
*
* @param head Pointer to link_t structure representing head of the list.
*/
static inline void list_initialize(link_t *head)
{
head->prev = head;
head->next = head;
}
 
/** Add item to the beginning of doubly-linked circular list
*
* Add item to the beginning of doubly-linked circular list.
*
* @param link Pointer to link_t structure to be added.
* @param head Pointer to link_t structure representing head of the list.
*/
static inline void list_prepend(link_t *link, link_t *head)
{
link->next = head->next;
link->prev = head;
head->next->prev = link;
head->next = link;
}
 
/** Add item to the end of doubly-linked circular list
*
* Add item to the end of doubly-linked circular list.
*
* @param link Pointer to link_t structure to be added.
* @param head Pointer to link_t structure representing head of the list.
*/
static inline void list_append(link_t *link, link_t *head)
{
link->prev = head->prev;
link->next = head;
head->prev->next = link;
head->prev = link;
}
 
/** Remove item from doubly-linked circular list
*
* Remove item from doubly-linked circular list.
*
* @param link Pointer to link_t structure to be removed from the list it is contained in.
*/
static inline void list_remove(link_t *link)
{
link->next->prev = link->prev;
link->prev->next = link->next;
link_initialize(link);
}
 
/** Query emptiness of doubly-linked circular list
*
* Query emptiness of doubly-linked circular list.
*
* @param head Pointer to link_t structure representing head of the list.
*/
static inline bool list_empty(link_t *head)
{
return head->next == head ? true : false;
}
 
 
/** Split or concatenate headless doubly-linked circular list
*
* Split or concatenate headless doubly-linked circular list.
*
* Note that the algorithm works both directions:
* concatenates splitted lists and splits concatenated lists.
*
* @param part1 Pointer to link_t structure leading the first (half of the headless) list.
* @param part2 Pointer to link_t structure leading the second (half of the headless) list.
*/
static inline void headless_list_split_or_concat(link_t *part1, link_t *part2)
{
link_t *hlp;
 
part1->prev->next = part2;
part2->prev->next = part1;
hlp = part1->prev;
part1->prev = part2->prev;
part2->prev = hlp;
}
 
 
/** Split headless doubly-linked circular list
*
* Split headless doubly-linked circular list.
*
* @param part1 Pointer to link_t structure leading the first half of the headless list.
* @param part2 Pointer to link_t structure leading the second half of the headless list.
*/
static inline void headless_list_split(link_t *part1, link_t *part2)
{
headless_list_split_or_concat(part1, part2);
}
 
/** Concatenate two headless doubly-linked circular lists
*
* Concatenate two headless doubly-linked circular lists.
*
* @param part1 Pointer to link_t structure leading the first headless list.
* @param part2 Pointer to link_t structure leading the second headless list.
*/
static inline void headless_list_concat(link_t *part1, link_t *part2)
{
headless_list_split_or_concat(part1, part2);
}
 
#define list_get_instance(link,type,member) (type *)(((uint8_t*)(link))-((uint8_t*)&(((type *)NULL)->member)))
 
extern bool list_member(const link_t *link, const link_t *head);
extern void list_concat(link_t *head1, link_t *head2);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/adt/bitmap.h
0,0 → 1,57
/*
* 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 genericadt
* @{
*/
/** @file
*/
 
#ifndef __BITMAP_H__
#define __BITMAP_H__
 
#include <arch/types.h>
#include <typedefs.h>
 
#define BITS2BYTES(bits) (bits ? ((((bits)-1)>>3)+1) : 0)
 
typedef struct {
uint8_t *map;
count_t bits;
} bitmap_t;
 
extern void bitmap_initialize(bitmap_t *bitmap, uint8_t *map, count_t bits);
extern void bitmap_set_range(bitmap_t *bitmap, index_t start, count_t bits);
extern void bitmap_clear_range(bitmap_t *bitmap, index_t start, count_t bits);
extern void bitmap_copy(bitmap_t *dst, bitmap_t *src, count_t bits);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/adt/btree.h
0,0 → 1,104
/*
* 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 genericadt
* @{
*/
/** @file
*/
 
#ifndef __BTREE_H__
#define __BTREE_H__
 
#include <arch/types.h>
#include <typedefs.h>
#include <adt/list.h>
 
#define BTREE_M 5
#define BTREE_MAX_KEYS (BTREE_M - 1)
 
typedef uint64_t btree_key_t;
 
/** B-tree node structure. */
struct btree_node {
/** Number of keys. */
count_t keys;
 
/** Keys. We currently support only single keys. Additional room for one extra key is provided. */
btree_key_t key[BTREE_MAX_KEYS + 1];
 
/**
* Pointers to values. Sorted according to the key array. Defined only in leaf-level.
* There is room for storing value for the extra key.
*/
void *value[BTREE_MAX_KEYS + 1];
/**
* Pointers to descendants of this node sorted according to the key array.
* subtree[0] points to subtree with keys lesser than to key[0].
* subtree[1] points to subtree with keys greater than or equal to key[0] and lesser than key[1].
* ...
* There is room for storing a subtree pointer for the extra key.
*/
btree_node_t *subtree[BTREE_M + 1];
 
/** Pointer to parent node. Root node has NULL parent. */
btree_node_t *parent;
 
/** Link connecting leaf-level nodes. Defined only when this node is a leaf. */
link_t leaf_link;
 
/** Variables needed by btree_print(). */
link_t bfs_link;
int depth;
};
 
/** B-tree structure. */
struct btree {
btree_node_t *root; /**< B-tree root node pointer. */
link_t leaf_head; /**< Leaf-level list head. */
};
 
extern void btree_init(void);
 
extern void btree_create(btree_t *t);
extern void btree_destroy(btree_t *t);
 
extern void btree_insert(btree_t *t, btree_key_t key, void *value, btree_node_t *leaf_node);
extern void btree_remove(btree_t *t, btree_key_t key, btree_node_t *leaf_node);
extern void *btree_search(btree_t *t, btree_key_t key, btree_node_t **leaf_node);
 
extern btree_node_t *btree_leaf_node_left_neighbour(btree_t *t, btree_node_t *node);
extern btree_node_t *btree_leaf_node_right_neighbour(btree_t *t, btree_node_t *node);
 
extern void btree_print(btree_t *t);
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/adt/fifo.h
0,0 → 1,123
/*
* 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 genericadt
* @{
*/
/** @file
*/
 
/*
* This implementation of FIFO stores values in an array
* (static or dynamic). As such, these FIFOs have upper bound
* on number of values they can store. Push and pop operations
* are done via accessing the array through head and tail indices.
* Because of better operation ordering in fifo_pop(), the access
* policy for these two indices is to 'increment (mod size of FIFO)
* and use'.
*/
 
#ifndef __FIFO_H__
#define __FIFO_H__
 
#include <typedefs.h>
#include <mm/slab.h>
 
/** Create and initialize static FIFO.
*
* FIFO is allocated statically.
* This macro is suitable for creating smaller FIFOs.
*
* @param name Name of FIFO.
* @param t Type of values stored in FIFO.
* @param itms Number of items that can be stored in FIFO.
*/
#define FIFO_INITIALIZE_STATIC(name, t, itms) \
struct { \
t fifo[(itms)]; \
count_t items; \
index_t head; \
index_t tail; \
} name = { \
.items = (itms), \
.head = 0, \
.tail = 0 \
}
 
/** Create and prepare dynamic FIFO.
*
* FIFO is allocated dynamically.
* This macro is suitable for creating larger FIFOs.
*
* @param name Name of FIFO.
* @param t Type of values stored in FIFO.
* @param itms Number of items that can be stored in FIFO.
*/
#define FIFO_INITIALIZE_DYNAMIC(name, t, itms) \
struct { \
t *fifo; \
count_t items; \
index_t head; \
index_t tail; \
} name = { \
.fifo = NULL, \
.items = (itms), \
.head = 0, \
.tail = 0 \
}
 
/** Pop value from head of FIFO.
*
* @param name FIFO name.
*
* @return Leading value in FIFO.
*/
#define fifo_pop(name) \
name.fifo[name.head = (name.head + 1) < name.items ? (name.head + 1) : 0]
 
/** Push value to tail of FIFO.
*
* @param name FIFO name.
* @param value Value to be appended to FIFO.
*
*/
#define fifo_push(name, value) \
name.fifo[name.tail = (name.tail + 1) < name.items ? (name.tail + 1) : 0] = (value)
 
/** Allocate memory for dynamic FIFO.
*
* @param name FIFO name.
*/
#define fifo_create(name) \
name.fifo = malloc(sizeof(*name.fifo) * name.items, 0)
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/mm/frame.h
0,0 → 1,116
/*
* Copyright (C) 2005 Jakub Jermar
* Copyright (C) 2005 Sergey Bondari
* 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 genericmm
* @{
*/
/** @file
*/
 
#ifndef __FRAME_H__
#define __FRAME_H__
 
#include <arch/types.h>
#include <typedefs.h>
#include <adt/list.h>
#include <synch/spinlock.h>
#include <mm/buddy.h>
#include <arch/mm/page.h>
#include <arch/mm/frame.h>
 
#define ONE_FRAME 0
#define TWO_FRAMES 1
 
#ifdef ARCH_STACK_FRAMES
#define STACK_FRAMES ARCH_STACK_FRAMES
#else
#define STACK_FRAMES ONE_FRAME
#endif
 
#define ZONES_MAX 16 /**< Maximum number of zones in system */
 
#define ZONE_JOIN 0x1 /**< If possible, merge with neighbouring zones */
 
#define FRAME_KA 0x1 /* skip frames conflicting with user address space */
#define FRAME_ATOMIC 0x2 /* do not panic and do not sleep on failure */
#define FRAME_NO_RECLAIM 0x4 /* do not start reclaiming when no free memory */
 
#define FRAME_OK 0 /* frame_alloc return status */
#define FRAME_NO_MEMORY 1 /* frame_alloc return status */
#define FRAME_ERROR 2 /* frame_alloc return status */
 
static inline uintptr_t PFN2ADDR(pfn_t frame)
{
return (uintptr_t)(frame << FRAME_WIDTH);
}
 
static inline pfn_t ADDR2PFN(uintptr_t addr)
{
return (pfn_t)(addr >> FRAME_WIDTH);
}
 
static inline count_t SIZE2FRAMES(size_t size)
{
if (!size)
return 0;
return (count_t)((size-1) >> FRAME_WIDTH)+1;
}
 
#define IS_BUDDY_ORDER_OK(index, order) ((~(((unative_t) -1) << (order)) & (index)) == 0)
#define IS_BUDDY_LEFT_BLOCK(zone, frame) (((frame_index((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 0)
#define IS_BUDDY_RIGHT_BLOCK(zone, frame) (((frame_index((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 1)
#define IS_BUDDY_LEFT_BLOCK_ABS(zone, frame) (((frame_index_abs((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 0)
#define IS_BUDDY_RIGHT_BLOCK_ABS(zone, frame) (((frame_index_abs((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 1)
 
#define frame_alloc(order, flags) frame_alloc_generic(order, flags, NULL)
 
extern void frame_init(void);
extern void * frame_alloc_generic(uint8_t order, int flags, int *pzone);
extern void frame_free(uintptr_t frame);
extern void frame_reference_add(pfn_t pfn);
 
extern int zone_create(pfn_t start, count_t count, pfn_t confframe, int flags);
void * frame_get_parent(pfn_t frame, int hint);
void frame_set_parent(pfn_t frame, void *data, int hint);
void frame_mark_unavailable(pfn_t start, count_t count);
uintptr_t zone_conf_size(count_t count);
void zone_merge(int z1, int z2);
void zone_merge_all(void);
 
/*
* Console functions
*/
extern void zone_print_list(void);
void zone_print_one(int znum);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/mm/page.h
0,0 → 1,102
/*
* 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 genericmm
* @{
*/
/** @file
*/
 
#ifndef __PAGE_H__
#define __PAGE_H__
 
#include <arch/mm/asid.h>
#include <arch/types.h>
#include <typedefs.h>
#include <memstr.h>
 
#define PAGE_CACHEABLE_SHIFT 0
#define PAGE_NOT_CACHEABLE_SHIFT PAGE_CACHEABLE_SHIFT
#define PAGE_PRESENT_SHIFT 1
#define PAGE_NOT_PRESENT_SHIFT PAGE_PRESENT_SHIFT
#define PAGE_USER_SHIFT 2
#define PAGE_KERNEL_SHIFT PAGE_USER_SHIFT
#define PAGE_READ_SHIFT 3
#define PAGE_WRITE_SHIFT 4
#define PAGE_EXEC_SHIFT 5
#define PAGE_GLOBAL_SHIFT 6
 
#define PAGE_NOT_CACHEABLE (0<<PAGE_CACHEABLE_SHIFT)
#define PAGE_CACHEABLE (1<<PAGE_CACHEABLE_SHIFT)
 
#define PAGE_PRESENT (0<<PAGE_PRESENT_SHIFT)
#define PAGE_NOT_PRESENT (1<<PAGE_PRESENT_SHIFT)
 
#define PAGE_USER (1<<PAGE_USER_SHIFT)
#define PAGE_KERNEL (0<<PAGE_USER_SHIFT)
 
#define PAGE_READ (1<<PAGE_READ_SHIFT)
#define PAGE_WRITE (1<<PAGE_WRITE_SHIFT)
#define PAGE_EXEC (1<<PAGE_EXEC_SHIFT)
 
#define PAGE_GLOBAL (1<<PAGE_GLOBAL_SHIFT)
 
/** Page fault access type. */
enum pf_access {
PF_ACCESS_READ,
PF_ACCESS_WRITE,
PF_ACCESS_EXEC
};
typedef enum pf_access pf_access_t;
 
/** Operations to manipulate page mappings. */
struct page_mapping_operations {
void (* mapping_insert)(as_t *as, uintptr_t page, uintptr_t frame, int flags);
void (* mapping_remove)(as_t *as, uintptr_t page);
pte_t *(* mapping_find)(as_t *as, uintptr_t page);
};
typedef struct page_mapping_operations page_mapping_operations_t;
 
extern page_mapping_operations_t *page_mapping_operations;
 
extern void page_init(void);
extern void page_table_lock(as_t *as, bool lock);
extern void page_table_unlock(as_t *as, bool unlock);
extern void page_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame, int flags);
extern void page_mapping_remove(as_t *as, uintptr_t page);
extern pte_t *page_mapping_find(as_t *as, uintptr_t page);
extern pte_t *page_table_create(int flags);
extern void page_table_destroy(pte_t *page_table);
extern void map_structure(uintptr_t s, size_t size);
extern uintptr_t hw_map(uintptr_t physaddr, size_t size);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/mm/slab.h
0,0 → 1,140
/*
* Copyright (C) 2006 Ondrej Palkovsky
* 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 genericmm
* @{
*/
/** @file
*/
 
#ifndef __SLAB_H__
#define __SLAB_H__
 
#include <adt/list.h>
#include <synch/spinlock.h>
#include <atomic.h>
#include <mm/frame.h>
 
/** Minimum size to be allocated by malloc */
#define SLAB_MIN_MALLOC_W 4
 
/** Maximum size to be allocated by malloc */
#define SLAB_MAX_MALLOC_W 18
 
/** Initial Magazine size (TODO: dynamically growing magazines) */
#define SLAB_MAG_SIZE 4
 
/** If object size is less, store control structure inside SLAB */
#define SLAB_INSIDE_SIZE (PAGE_SIZE >> 3)
 
/** Maximum wasted space we allow for cache */
#define SLAB_MAX_BADNESS(cache) ((PAGE_SIZE << (cache)->order) >> 2)
 
/* slab_reclaim constants */
#define SLAB_RECLAIM_ALL 0x1 /**< Reclaim all possible memory, because
* we are in memory stress */
 
/* cache_create flags */
#define SLAB_CACHE_NOMAGAZINE 0x1 /**< Do not use per-cpu cache */
#define SLAB_CACHE_SLINSIDE 0x2 /**< Have control structure inside SLAB */
/** We add magazine cache later, if we have this flag */
#define SLAB_CACHE_MAGDEFERRED (0x4 | SLAB_CACHE_NOMAGAZINE)
 
typedef struct {
link_t link;
count_t busy; /**< Count of full slots in magazine */
count_t size; /**< Number of slots in magazine */
void *objs[0]; /**< Slots in magazine */
}slab_magazine_t;
 
typedef struct {
slab_magazine_t *current;
slab_magazine_t *last;
SPINLOCK_DECLARE(lock);
}slab_mag_cache_t;
 
 
typedef struct {
char *name;
 
link_t link;
/* Configuration */
size_t size; /**< Size of slab position - align_up(sizeof(obj)) */
int (*constructor)(void *obj, int kmflag);
int (*destructor)(void *obj);
int flags; /**< Flags changing behaviour of cache */
 
/* Computed values */
uint8_t order; /**< Order of frames to be allocated */
int objects; /**< Number of objects that fit in */
 
/* Statistics */
atomic_t allocated_slabs;
atomic_t allocated_objs;
atomic_t cached_objs;
atomic_t magazine_counter; /**< How many magazines in magazines list */
 
/* Slabs */
link_t full_slabs; /**< List of full slabs */
link_t partial_slabs; /**< List of partial slabs */
SPINLOCK_DECLARE(slablock);
/* Magazines */
link_t magazines; /**< List o full magazines */
SPINLOCK_DECLARE(maglock);
 
/** CPU cache */
slab_mag_cache_t *mag_cache;
}slab_cache_t;
 
extern slab_cache_t * slab_cache_create(char *name,
size_t size,
size_t align,
int (*constructor)(void *obj, int kmflag),
int (*destructor)(void *obj),
int flags);
extern void slab_cache_destroy(slab_cache_t *cache);
 
extern void * slab_alloc(slab_cache_t *cache, int flags);
extern void slab_free(slab_cache_t *cache, void *obj);
extern count_t slab_reclaim(int flags);
 
/** Initialize slab subsytem */
extern void slab_cache_init(void);
extern void slab_enable_cpucache(void);
 
/* kconsole debug */
extern void slab_print_list(void);
 
/* malloc support */
extern void * malloc(unsigned int size, int flags);
extern void free(void *obj);
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/mm/tlb.h
0,0 → 1,91
/*
* 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 genericmm
* @{
*/
/** @file
*/
 
#ifndef __TLB_H__
#define __TLB_H__
 
#include <arch/mm/asid.h>
#include <arch/types.h>
#include <typedefs.h>
 
/**
* Number of TLB shootdown messages that can be queued in processor
* tlb_messages queue.
*/
#define TLB_MESSAGE_QUEUE_LEN 10
 
/** Type of TLB shootdown message. */
enum tlb_invalidate_type {
TLB_INVL_INVALID = 0, /**< Invalid type. */
TLB_INVL_ALL, /**< Invalidate all entries in TLB. */
TLB_INVL_ASID, /**< Invalidate all entries belonging to one address space. */
TLB_INVL_PAGES /**< Invalidate specified page range belonging to one address space. */
};
typedef enum tlb_invalidate_type tlb_invalidate_type_t;
 
/** TLB shootdown message. */
struct tlb_shootdown_msg {
tlb_invalidate_type_t type; /**< Message type. */
asid_t asid; /**< Address space identifier. */
uintptr_t page; /**< Page address. */
count_t count; /**< Number of pages to invalidate. */
};
typedef struct tlb_shootdown_msg tlb_shootdown_msg_t;
 
extern void tlb_init(void);
 
#ifdef CONFIG_SMP
extern void tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid, uintptr_t page, count_t count);
extern void tlb_shootdown_finalize(void);
extern void tlb_shootdown_ipi_recv(void);
#else
# define tlb_shootdown_start(w, x, y, z)
# define tlb_shootdown_finalize()
# define tlb_shootdown_ipi_recv()
#endif /* CONFIG_SMP */
 
 
/* Export TLB interface that each architecture must implement. */
extern void tlb_arch_init(void);
extern void tlb_print(void);
extern void tlb_shootdown_ipi_send(void);
 
extern void tlb_invalidate_all(void);
extern void tlb_invalidate_asid(asid_t asid);
extern void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt);
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/mm/as.h
0,0 → 1,211
/*
* 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 genericmm
* @{
*/
/** @file
*/
 
#ifndef __AS_H__
#define __AS_H__
 
/** Address space area flags. */
#define AS_AREA_READ 1
#define AS_AREA_WRITE 2
#define AS_AREA_EXEC 4
#define AS_AREA_CACHEABLE 8
 
#ifdef KERNEL
 
#include <arch/mm/page.h>
#include <arch/mm/as.h>
#include <arch/mm/asid.h>
#include <arch/types.h>
#include <typedefs.h>
#include <synch/spinlock.h>
#include <synch/mutex.h>
#include <adt/list.h>
#include <adt/btree.h>
#include <elf.h>
 
/** Defined to be true if user address space and kernel address space shadow each other. */
#define KERNEL_ADDRESS_SPACE_SHADOWED KERNEL_ADDRESS_SPACE_SHADOWED_ARCH
 
#define KERNEL_ADDRESS_SPACE_START KERNEL_ADDRESS_SPACE_START_ARCH
#define KERNEL_ADDRESS_SPACE_END KERNEL_ADDRESS_SPACE_END_ARCH
#define USER_ADDRESS_SPACE_START USER_ADDRESS_SPACE_START_ARCH
#define USER_ADDRESS_SPACE_END USER_ADDRESS_SPACE_END_ARCH
 
#define IS_KA(addr) ((addr)>=KERNEL_ADDRESS_SPACE_START && (addr)<=KERNEL_ADDRESS_SPACE_END)
 
#define USTACK_ADDRESS USTACK_ADDRESS_ARCH
 
#define FLAG_AS_KERNEL (1 << 0) /**< Kernel address space. */
 
/** Address space structure.
*
* as_t contains the list of as_areas of userspace accessible
* pages for one or more tasks. Ranges of kernel memory pages are not
* supposed to figure in the list as they are shared by all tasks and
* set up during system initialization.
*/
struct as {
/** Protected by asidlock. */
link_t inactive_as_with_asid_link;
 
mutex_t lock;
 
/** Number of references (i.e tasks that reference this as). */
count_t refcount;
 
/** Number of processors on wich is this address space active. */
count_t cpu_refcount;
 
/** B+tree of address space areas. */
btree_t as_area_btree;
 
/** Page table pointer. Constant on architectures that use global page hash table. */
pte_t *page_table;
 
/** Address space identifier. Constant on architectures that do not support ASIDs.*/
asid_t asid;
};
 
struct as_operations {
pte_t *(* page_table_create)(int flags);
void (* page_table_destroy)(pte_t *page_table);
void (* page_table_lock)(as_t *as, bool lock);
void (* page_table_unlock)(as_t *as, bool unlock);
};
typedef struct as_operations as_operations_t;
 
/** Address space area attributes. */
#define AS_AREA_ATTR_NONE 0
#define AS_AREA_ATTR_PARTIAL 1 /**< Not fully initialized area. */
 
#define AS_PF_FAULT 0 /**< The page fault was not resolved by as_page_fault(). */
#define AS_PF_OK 1 /**< The page fault was resolved by as_page_fault(). */
#define AS_PF_DEFER 2 /**< The page fault was caused by memcpy_from_uspace()
or memcpy_to_uspace(). */
 
/** This structure contains information associated with the shared address space area. */
typedef struct {
mutex_t lock; /**< This lock must be acquired only when the as_area lock is held. */
count_t refcount; /**< This structure can be deallocated if refcount drops to 0. */
btree_t pagemap; /**< B+tree containing complete map of anonymous pages of the shared area. */
} share_info_t;
 
/** Address space area backend structure. */
typedef struct {
int (* page_fault)(as_area_t *area, uintptr_t addr, pf_access_t access);
void (* frame_free)(as_area_t *area, uintptr_t page, uintptr_t frame);
void (* share)(as_area_t *area);
} mem_backend_t;
 
/** Backend data stored in address space area. */
typedef union {
struct { /**< elf_backend members */
elf_header_t *elf;
elf_segment_header_t *segment;
};
struct { /**< phys_backend members */
uintptr_t base;
count_t frames;
};
} mem_backend_data_t;
 
/** Address space area structure.
*
* Each as_area_t structure describes one contiguous area of virtual memory.
* In the future, it should not be difficult to support shared areas.
*/
struct as_area {
mutex_t lock;
as_t *as; /**< Containing address space. */
int flags; /**< Flags related to the memory represented by the address space area. */
int attributes; /**< Attributes related to the address space area itself. */
count_t pages; /**< Size of this area in multiples of PAGE_SIZE. */
uintptr_t base; /**< Base address of this area. */
btree_t used_space; /**< Map of used space. */
share_info_t *sh_info; /**< If the address space area has been shared, this pointer will
reference the share info structure. */
mem_backend_t *backend; /**< Memory backend backing this address space area. */
 
/** Data to be used by the backend. */
mem_backend_data_t backend_data;
};
 
extern as_t *AS_KERNEL;
extern as_operations_t *as_operations;
 
extern spinlock_t inactive_as_with_asid_lock;
extern link_t inactive_as_with_asid_head;
 
extern void as_init(void);
 
extern as_t *as_create(int flags);
extern void as_destroy(as_t *as);
extern void as_switch(as_t *old, as_t *new);
extern int as_page_fault(uintptr_t page, pf_access_t access, istate_t *istate);
 
extern as_area_t *as_area_create(as_t *as, int flags, size_t size, uintptr_t base, int attrs,
mem_backend_t *backend, mem_backend_data_t *backend_data);
extern int as_area_destroy(as_t *as, uintptr_t address);
extern int as_area_resize(as_t *as, uintptr_t address, size_t size, int flags);
int as_area_share(as_t *src_as, uintptr_t src_base, size_t acc_size,
as_t *dst_as, uintptr_t dst_base, int dst_flags_mask);
 
extern int as_area_get_flags(as_area_t *area);
extern bool as_area_check_access(as_area_t *area, pf_access_t access);
extern size_t as_get_size(uintptr_t base);
extern int used_space_insert(as_area_t *a, uintptr_t page, count_t count);
extern int used_space_remove(as_area_t *a, uintptr_t page, count_t count);
 
/* Interface to be implemented by architectures. */
#ifndef as_install_arch
extern void as_install_arch(as_t *as);
#endif /* !def as_install_arch */
 
/* Backend declarations. */
extern mem_backend_t anon_backend;
extern mem_backend_t elf_backend;
extern mem_backend_t phys_backend;
 
/* Address space area related syscalls. */
extern unative_t sys_as_area_create(uintptr_t address, size_t size, int flags);
extern unative_t sys_as_area_resize(uintptr_t address, size_t size, int flags);
extern unative_t sys_as_area_destroy(uintptr_t address);
 
#endif /* KERNEL */
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/mm/buddy.h
0,0 → 1,78
/*
* 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 genericmm
* @{
*/
/** @file
*/
 
#ifndef __BUDDY_H__
#define __BUDDY_H__
 
#include <arch/types.h>
#include <typedefs.h>
 
#define BUDDY_SYSTEM_INNER_BLOCK 0xff
 
/** Buddy system operations to be implemented by each implementation. */
struct buddy_system_operations {
link_t *(* find_buddy)(buddy_system_t *, link_t *); /**< Return pointer to left-side or right-side buddy for block passed as argument. */
link_t *(* bisect)(buddy_system_t *, link_t *); /**< Bisect the block passed as argument and return pointer to the new right-side buddy. */
link_t *(* coalesce)(buddy_system_t *, link_t *, link_t *); /**< Coalesce two buddies into a bigger block. */
void (*set_order)(buddy_system_t *, link_t *, uint8_t); /**< Set order of block passed as argument. */
uint8_t (*get_order)(buddy_system_t *, link_t *); /**< Return order of block passed as argument. */
void (*mark_busy)(buddy_system_t *, link_t *); /**< Mark block as busy. */
void (*mark_available)(buddy_system_t *, link_t *); /**< Mark block as available. */
/** Find parent of block that has given order */
link_t *(* find_block)(buddy_system_t *, link_t *, uint8_t);
void (* print_id)(buddy_system_t *, link_t *);
};
 
struct buddy_system {
uint8_t max_order; /**< Maximal order of block which can be stored by buddy system. */
link_t *order;
buddy_system_operations_t *op;
void *data; /**< Pointer to be used by the implementation. */
};
 
extern void buddy_system_create(buddy_system_t *b,
uint8_t max_order,
buddy_system_operations_t *op, void *data);
extern link_t *buddy_system_alloc(buddy_system_t *b, uint8_t i);
extern bool buddy_system_can_alloc(buddy_system_t *b, uint8_t order);
extern void buddy_system_free(buddy_system_t *b, link_t *block);
extern void buddy_system_structure_print(buddy_system_t *b, size_t elem_size);
extern size_t buddy_conf_size(int max_order);
extern link_t *buddy_system_alloc_block(buddy_system_t *b, link_t *block);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/mm/asid.h
0,0 → 1,89
/*
* 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 genericmm
* @{
*/
/** @file
*/
 
/*
* This is generic interface for managing
* Address Space IDentifiers (ASIDs).
*/
 
#ifndef __ASID_H__
#define __ASID_H__
 
#ifndef __ASM__
 
#include <arch/mm/asid.h>
#include <typedefs.h>
 
#endif
 
#define ASID_KERNEL 0
#define ASID_INVALID 1
#define ASID_START 2
#define ASID_MAX ASID_MAX_ARCH
 
#ifndef __ASM__
 
#define ASIDS_ALLOCABLE ((ASID_MAX+1)-ASID_START)
 
extern spinlock_t asidlock;
extern link_t as_with_asid_head;
 
#ifndef asid_get
extern asid_t asid_get(void);
#endif /* !def asid_get */
 
#ifndef asid_put
extern void asid_put(asid_t asid);
#endif /* !def asid_put */
 
#ifndef asid_install
extern void asid_install(as_t *as);
#endif /* !def asid_install */
 
#ifndef asid_find_free
extern asid_t asid_find_free(void);
#endif /* !def asid_find_free */
 
#ifndef asid_put_arch
extern void asid_put_arch(asid_t asid);
#endif /* !def asid_put_arch */
 
#endif
 
#endif
 
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/ipc/sysipc.h
0,0 → 1,63
/*
* Copyright (C) 2006 Ondrej Palkovsky
* 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 genericipc
* @{
*/
/** @file
*/
 
#ifndef __SYSIPC_H__
#define __SYSIPC_H__
 
#include <ipc/ipc.h>
#include <ipc/irq.h>
#include <arch/types.h>
 
unative_t sys_ipc_call_sync_fast(unative_t phoneid, unative_t method,
unative_t arg1, ipc_data_t *data);
unative_t sys_ipc_call_sync(unative_t phoneid, ipc_data_t *question,
ipc_data_t *reply);
unative_t sys_ipc_call_async_fast(unative_t phoneid, unative_t method,
unative_t arg1, unative_t arg2);
unative_t sys_ipc_call_async(unative_t phoneid, ipc_data_t *data);
unative_t sys_ipc_answer_fast(unative_t callid, unative_t retval,
unative_t arg1, unative_t arg2);
unative_t sys_ipc_answer(unative_t callid, ipc_data_t *data);
unative_t sys_ipc_wait_for_call(ipc_data_t *calldata, uint32_t usec, int nonblocking);
unative_t sys_ipc_forward_fast(unative_t callid, unative_t phoneid,
unative_t method, unative_t arg1);
unative_t sys_ipc_hangup(int phoneid);
unative_t sys_ipc_register_irq(int irq, irq_code_t *ucode);
unative_t sys_ipc_unregister_irq(int irq);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/ipc/ipc.h
0,0 → 1,248
/*
* Copyright (C) 2006 Ondrej Palkovsky
* 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 genericipc
* @{
*/
/** @file
*/
 
#ifndef __IPC_H__
#define __IPC_H__
 
/* Length of data being transfered with IPC call */
/* - the uspace may not be able to utilize full length */
#define IPC_CALL_LEN 4
 
/** Maximum active async calls per thread */
#ifdef CONFIG_DEBUG
# define IPC_MAX_ASYNC_CALLS 4
#else
# define IPC_MAX_ASYNC_CALLS 4000
#endif
 
/* Flags for calls */
#define IPC_CALL_ANSWERED (1<<0) /**< This is answer to a call */
#define IPC_CALL_STATIC_ALLOC (1<<1) /**< This call will not be freed on error */
#define IPC_CALL_DISCARD_ANSWER (1<<2) /**< Answer will not be passed to
* userspace, will be discarded */
#define IPC_CALL_FORWARDED (1<<3) /* Call was forwarded */
#define IPC_CALL_CONN_ME_TO (1<<4) /* Identify connect_me_to answer */
#define IPC_CALL_NOTIF (1<<5) /* Interrupt notification */
 
/* Flags of callid (the addresses are aligned at least to 4,
* that is why we can use bottom 2 bits of the call address
*/
#define IPC_CALLID_ANSWERED 1 /**< Type of this msg is 'answer' */
#define IPC_CALLID_NOTIFICATION 2 /**< Type of this msg is 'notification' */
 
/* Return values from IPC_ASYNC */
#define IPC_CALLRET_FATAL -1
#define IPC_CALLRET_TEMPORARY -2
 
 
/* Macros for manipulating calling data */
#define IPC_SET_RETVAL(data, retval) ((data).args[0] = (retval))
#define IPC_SET_METHOD(data, val) ((data).args[0] = (val))
#define IPC_SET_ARG1(data, val) ((data).args[1] = (val))
#define IPC_SET_ARG2(data, val) ((data).args[2] = (val))
#define IPC_SET_ARG3(data, val) ((data).args[3] = (val))
 
#define IPC_GET_METHOD(data) ((data).args[0])
#define IPC_GET_RETVAL(data) ((data).args[0])
 
#define IPC_GET_ARG1(data) ((data).args[1])
#define IPC_GET_ARG2(data) ((data).args[2])
#define IPC_GET_ARG3(data) ((data).args[3])
 
/* Well known phone descriptors */
#define PHONE_NS 0
 
/* System-specific methods - only through special syscalls
* These methods have special behaviour
*/
/** Protocol for CONNECT - TO - ME
*
* Calling process asks the callee to create a callback connection,
* so that it can start initiating new messages.
*
* The protocol for negotiating is:
* - sys_connect_to_me - sends a message IPC_M_CONNECTTOME
* - sys_wait_for_call - upon receipt tries to allocate new phone
* - if it fails, responds with ELIMIT
* - passes call to userspace. If userspace
* responds with error, phone is deallocated and
* error is sent back to caller. Otherwise
* the call is accepted and the response is sent back.
* - the allocated phoneid is passed to userspace
* (on the receiving sid) as ARG3 of the call.
* - the caller obtains taskid of the called thread
*/
#define IPC_M_CONNECT_TO_ME 1
/** Protocol for CONNECT - ME - TO
*
* Calling process asks the callee to create for him a new connection.
* E.g. the caller wants a name server to connect him to print server.
*
* The protocol for negotiating is:
* - sys_connect_me_to - send a synchronous message to name server
* indicating that it wants to be connected to some
* service
* - arg1/2 are user specified, arg3 contains
* address of the phone that should be connected
* (TODO: it leaks to userspace)
* recipient - if ipc_answer == 0, then accept connection
* - otherwise connection refused
* - recepient may forward message. Forwarding
* system message
*
*/
#define IPC_M_CONNECT_ME_TO 2
/** This message is sent to answerbox when the phone
* is hung up
*/
#define IPC_M_PHONE_HUNGUP 3
 
/** Send as_area over IPC
* - ARG1 - src base address
* - ARG2 - size of src as(filled automatically by kernel)
* - ARG3 - flags of the area being sent
* - on answer ARG1 - dst base adress
*/
#define IPC_M_AS_AREA_SEND 5
 
/** Get as_area over IPC
* - ARG1 - Where the area will be mapped
* - ARG2 - Expected size of area
* - ARG3 - User defined argument
* on answer - the server sets ARG1 as src as address of the as_area
* to be shared, ARG2 is set to rights that will be used for sharing,
* which is returned as part of answer back to the receiver
*/
#define IPC_M_AS_AREA_RECV 6
 
 
/* Well-known methods */
#define IPC_M_LAST_SYSTEM 511
#define IPC_M_PING 512
/* User methods */
#define FIRST_USER_METHOD 1024
 
#ifdef KERNEL
 
#include <synch/mutex.h>
#include <synch/condvar.h>
#include <adt/list.h>
 
#define IPC_MAX_PHONES 16
 
typedef struct answerbox_s answerbox_t;
typedef struct phone_s phone_t;
typedef struct {
unative_t args[IPC_CALL_LEN];
phone_t *phone;
}ipc_data_t;
 
struct answerbox_s {
SPINLOCK_DECLARE(lock);
 
task_t *task;
 
waitq_t wq;
 
link_t connected_phones; /**< Phones connected to this answerbox */
link_t calls; /**< Received calls */
link_t dispatched_calls; /* Should be hash table in the future */
 
link_t answers; /**< Answered calls */
 
SPINLOCK_DECLARE(irq_lock);
link_t irq_notifs; /**< Notifications from IRQ handlers */
};
 
typedef enum {
IPC_PHONE_FREE = 0, /**< Phone is free and can be allocated */
IPC_PHONE_CONNECTING, /**< Phone is connecting somewhere */
IPC_PHONE_CONNECTED, /**< Phone is connected */
IPC_PHONE_HUNGUP, /**< Phone is hung up, waiting for answers to come */
IPC_PHONE_SLAMMED /**< Phone was hungup from server */
} ipc_phone_state_t;
 
/** Structure identifying phone (in TASK structure) */
struct phone_s {
SPINLOCK_DECLARE(lock);
link_t link;
answerbox_t *callee;
ipc_phone_state_t state;
atomic_t active_calls;
};
 
typedef struct {
link_t link;
 
int flags;
 
/* Identification of the caller */
task_t *sender;
/* The caller box is different from sender->answerbox
* for synchronous calls
*/
answerbox_t *callerbox;
 
unative_t private; /**< Private data to internal IPC */
 
ipc_data_t data; /**< Data passed from/to userspace */
}call_t;
 
extern void ipc_init(void);
extern call_t * ipc_wait_for_call(answerbox_t *box, uint32_t usec, int flags);
extern void ipc_answer(answerbox_t *box, call_t *request);
extern int ipc_call(phone_t *phone, call_t *call);
extern void ipc_call_sync(phone_t *phone, call_t *request);
extern void ipc_phone_init(phone_t *phone);
extern void ipc_phone_connect(phone_t *phone, answerbox_t *box);
extern void ipc_call_free(call_t *call);
extern call_t * ipc_call_alloc(int flags);
extern void ipc_answerbox_init(answerbox_t *box);
extern void ipc_call_static_init(call_t *call);
extern void task_print_list(void);
extern int ipc_forward(call_t *call, phone_t *newphone, answerbox_t *oldbox);
void ipc_cleanup(void);
int ipc_phone_hangup(phone_t *phone);
extern void ipc_backsend_err(phone_t *phone, call_t *call, unative_t err);
extern void ipc_print_task(task_id_t taskid);
 
extern answerbox_t *ipc_phone_0;
 
#endif
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/ipc/irq.h
0,0 → 1,93
/*
* Copyright (C) 2006 Ondrej Palkovsky
* 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 genericipc
* @{
*/
/** @file
*/
 
#ifndef __IRQ_H__
#define __IRQ_H__
 
/** Maximum length of IPC IRQ program */
#define IRQ_MAX_PROG_SIZE 10
 
/** Reserved 'virtual' messages for kernel notifications */
#define IPC_IRQ_RESERVED_VIRTUAL 10
 
#define IPC_IRQ_KLOG (-1)
#define IPC_IRQ_KBDRESTART (-2)
 
typedef enum {
CMD_MEM_READ_1 = 0,
CMD_MEM_READ_2,
CMD_MEM_READ_4,
CMD_MEM_READ_8,
CMD_MEM_WRITE_1,
CMD_MEM_WRITE_2,
CMD_MEM_WRITE_4,
CMD_MEM_WRITE_8,
CMD_PORT_READ_1,
CMD_PORT_WRITE_1,
CMD_IA64_GETCHAR,
CMD_PPC32_GETCHAR,
CMD_LAST
} irq_cmd_type;
 
typedef struct {
irq_cmd_type cmd;
void *addr;
unsigned long long value;
int dstarg;
} irq_cmd_t;
 
typedef struct {
unsigned int cmdcount;
irq_cmd_t *cmds;
} irq_code_t;
 
#ifdef KERNEL
 
#include <ipc/ipc.h>
 
extern void ipc_irq_make_table(int irqcount);
extern int ipc_irq_register(answerbox_t *box, int irq, irq_code_t *ucode);
extern void ipc_irq_send_notif(int irq);
extern void ipc_irq_send_msg(int irq, unative_t a1, unative_t a2, unative_t a3);
extern void ipc_irq_unregister(answerbox_t *box, int irq);
extern void irq_ipc_bind_arch(unative_t irq);
extern void ipc_irq_cleanup(answerbox_t *box);
 
#endif
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/ipc/ipcrsc.h
0,0 → 1,47
/*
* Copyright (C) 2006 Ondrej Palkovsky
* 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 genericipc
* @{
*/
/** @file
*/
 
#ifndef __IPCRSC_H__
#define __IPCRSC_H__
 
call_t * get_call(unative_t callid);
int phone_alloc(void);
void phone_connect(int phoneid, answerbox_t *box);
void phone_dealloc(int phoneid);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/smp/smp.h
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 generic
* @{
*/
/** @file
*/
 
#ifndef __SMP_H__
#define __SMP_H__
 
#ifdef CONFIG_SMP
extern void smp_init(void);
#else
#define smp_init() ;
#endif /* CONFIG_SMP */
 
#endif /* __SMP_H__ */
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/smp/ipi.h
0,0 → 1,49
/*
* 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 generic
* @{
*/
/** @file
*/
 
#ifndef __IPI_H__
#define __IPI_H__
 
#ifdef CONFIG_SMP
extern void ipi_broadcast(int ipi);
extern void ipi_broadcast_arch(int ipi);
#else
#define ipi_broadcast(x) ;
#endif /* CONFIG_SMP */
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/include/printf/printf_core.h
0,0 → 1,56
/*
* Copyright (C) 2006 Josef Cejka
* 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 generic
* @{
*/
/** @file
*/
 
#ifndef __PRINTF_CORE_H__
#define __PRINTF_CORE_H__
 
#include <typedefs.h>
#include <arch/arg.h>
 
/** Structure for specifying output methods for different printf clones. */
struct printf_spec {
/* Output function, returns count of printed characters or EOF */
int (*write)(void *, size_t, void *);
/* Support data - output stream specification, its state, locks,... */
void *data;
 
};
 
int printf_core(const char *fmt, struct printf_spec *ps ,va_list ap);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/src/main/main.c
0,0 → 1,329
/*
* 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 main
* @{
*/
 
/**
* @file
* @brief Main initialization kernel function for all processors.
*
* During kernel boot, all processors, after architecture dependent
* initialization, start executing code found in this file. After
* bringing up all subsystems, control is passed to scheduler().
*
* The bootstrap processor starts executing main_bsp() while
* the application processors start executing main_ap().
*
* @see scheduler()
* @see main_bsp()
* @see main_ap()
*/
 
#include <arch/asm.h>
#include <context.h>
#include <print.h>
#include <panic.h>
#include <debug.h>
#include <config.h>
#include <time/clock.h>
#include <proc/scheduler.h>
#include <proc/thread.h>
#include <proc/task.h>
#include <main/kinit.h>
#include <main/version.h>
#include <console/kconsole.h>
#include <cpu.h>
#include <align.h>
#include <interrupt.h>
#include <arch/mm/memory_init.h>
#include <mm/frame.h>
#include <mm/page.h>
#include <genarch/mm/page_pt.h>
#include <mm/tlb.h>
#include <mm/as.h>
#include <mm/slab.h>
#include <synch/waitq.h>
#include <synch/futex.h>
#include <arch/arch.h>
#include <arch.h>
#include <arch/faddr.h>
#include <typedefs.h>
#include <ipc/ipc.h>
#include <macros.h>
#include <adt/btree.h>
#include <console/klog.h>
 
#ifdef CONFIG_SMP
#include <arch/smp/apic.h>
#include <arch/smp/mps.h>
#endif /* CONFIG_SMP */
#include <smp/smp.h>
 
/** Global configuration structure. */
config_t config;
 
/** Initial user-space tasks */
init_t init = {
0
};
 
context_t ctx;
 
/*
* These 'hardcoded' variables will be intialized by
* the linker or the low level assembler code with
* appropriate sizes and addresses.
*/
uintptr_t hardcoded_load_address = 0; /**< Virtual address of where the kernel is loaded. */
size_t hardcoded_ktext_size = 0; /**< Size of the kernel code in bytes. */
size_t hardcoded_kdata_size = 0; /**< Size of the kernel data in bytes. */
 
uintptr_t stack_safe = 0; /**< Lowest safe stack virtual address */
 
void main_bsp(void);
void main_ap(void);
 
/*
* These two functions prevent stack from underflowing during the
* kernel boot phase when SP is set to the very top of the reserved
* space. The stack could get corrupted by a fooled compiler-generated
* pop sequence otherwise.
*/
static void main_bsp_separated_stack(void);
#ifdef CONFIG_SMP
static void main_ap_separated_stack(void);
#endif
 
#define CONFIG_STACK_SIZE ((1<<STACK_FRAMES)*STACK_SIZE)
 
/** Main kernel routine for bootstrap CPU.
*
* Initializes the kernel by bootstrap CPU.
* This function passes control directly to
* main_bsp_separated_stack().
*
* Assuming interrupts_disable().
*
*/
void main_bsp(void)
{
config.cpu_count = 1;
config.cpu_active = 1;
config.base = hardcoded_load_address;
config.memory_size = get_memory_size();
config.kernel_size = ALIGN_UP(hardcoded_ktext_size + hardcoded_kdata_size, PAGE_SIZE);
config.stack_size = CONFIG_STACK_SIZE;
/* Initialy the stack is placed just after the kernel */
config.stack_base = config.base + config.kernel_size;
/* Avoid placing stack on top of init */
count_t i;
for (i = 0; i < init.cnt; i++) {
if (PA_overlaps(config.stack_base, config.stack_size, init.tasks[i].addr, init.tasks[i].size))
config.stack_base = ALIGN_UP(init.tasks[i].addr + init.tasks[i].size, config.stack_size);
}
if (config.stack_base < stack_safe)
config.stack_base = ALIGN_UP(stack_safe, PAGE_SIZE);
context_save(&ctx);
context_set(&ctx, FADDR(main_bsp_separated_stack), config.stack_base, THREAD_STACK_SIZE);
context_restore(&ctx);
/* not reached */
}
 
 
/** Main kernel routine for bootstrap CPU using new stack.
*
* Second part of main_bsp().
*
*/
void main_bsp_separated_stack(void)
{
task_t *k;
thread_t *t;
count_t i;
the_initialize(THE);
 
/*
* kconsole data structures must be initialized very early
* because other subsystems will register their respective
* commands.
*/
kconsole_init();
/*
* Exception handler initialization, before architecture
* starts adding its own handlers
*/
exc_init();
 
/*
* Memory management subsystems initialization.
*/
arch_pre_mm_init();
frame_init(); /* Initialize at least 1 memory segment big enough for slab to work */
slab_cache_init();
btree_init();
as_init();
page_init();
tlb_init();
arch_post_mm_init();
 
version_print();
printf("kernel: %.*p hardcoded_ktext_size=%zdK, hardcoded_kdata_size=%zdK\n", sizeof(uintptr_t) * 2, config.base, hardcoded_ktext_size >> 10, hardcoded_kdata_size >> 10);
printf("stack: %.*p size=%zdK\n", sizeof(uintptr_t) * 2, config.stack_base, config.stack_size >> 10);
 
arch_pre_smp_init();
smp_init();
slab_enable_cpucache(); /* Slab must be initialized AFTER we know the number of processors */
 
printf("config.memory_size=%zdM\n", config.memory_size >> 20);
printf("config.cpu_count=%zd\n", config.cpu_count);
cpu_init();
calibrate_delay_loop();
clock_counter_init();
timeout_init();
scheduler_init();
task_init();
thread_init();
futex_init();
klog_init();
if (init.cnt > 0) {
for (i = 0; i < init.cnt; i++)
printf("init[%zd].addr=%.*p, init[%zd].size=%zd\n", i, sizeof(uintptr_t) * 2, init.tasks[i].addr, i, init.tasks[i].size);
} else
printf("No init tasks found\n");
ipc_init();
 
/*
* Create kernel task.
*/
k = task_create(AS_KERNEL, "KERNEL");
if (!k)
panic("can't create kernel task\n");
/*
* Create the first thread.
*/
t = thread_create(kinit, NULL, k, 0, "kinit");
if (!t)
panic("can't create kinit thread\n");
thread_ready(t);
/*
* This call to scheduler() will return to kinit,
* starting the thread of kernel threads.
*/
scheduler();
/* not reached */
}
 
 
#ifdef CONFIG_SMP
/** Main kernel routine for application CPUs.
*
* Executed by application processors, temporary stack
* is at ctx.sp which was set during BP boot.
* This function passes control directly to
* main_ap_separated_stack().
*
* Assuming interrupts_disable()'d.
*
*/
void main_ap(void)
{
/*
* Incrementing the active CPU counter will guarantee that the
* pm_init() will not attempt to build GDT and IDT tables again.
* Neither frame_init() will do the complete thing. Neither cpu_init()
* will do.
*/
config.cpu_active++;
 
/*
* The THE structure is well defined because ctx.sp is used as stack.
*/
the_initialize(THE);
arch_pre_mm_init();
frame_init();
page_init();
tlb_init();
arch_post_mm_init();
cpu_init();
calibrate_delay_loop();
 
l_apic_init();
l_apic_debug();
 
the_copy(THE, (the_t *) CPU->stack);
 
/*
* If we woke kmp up before we left the kernel stack, we could
* collide with another CPU coming up. To prevent this, we
* switch to this cpu's private stack prior to waking kmp up.
*/
context_set(&CPU->saved_context, FADDR(main_ap_separated_stack), (uintptr_t) CPU->stack, CPU_STACK_SIZE);
context_restore(&CPU->saved_context);
/* not reached */
}
 
 
/** Main kernel routine for application CPUs using new stack.
*
* Second part of main_ap().
*
*/
void main_ap_separated_stack(void)
{
/*
* Configure timeouts for this cpu.
*/
timeout_init();
 
waitq_wakeup(&ap_completion_wq, WAKEUP_FIRST);
scheduler();
/* not reached */
}
#endif /* CONFIG_SMP */
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/main/version.c
0,0 → 1,63
/*
* 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 main
* @{
*/
/** @file
*/
 
#include <main/version.h>
#include <print.h>
 
char *project = "SPARTAN kernel";
char *copyright = "Copyright (C) 2001-2006 HelenOS project";
char *release = RELEASE;
char *name = NAME;
char *arch = ARCH;
 
#ifdef REVISION
char *revision = ", revision " REVISION;
#else
char *revision = "";
#endif
 
#ifdef TIMESTAMP
char *timestamp = " on " TIMESTAMP;
#else
char *timestamp = "";
#endif
 
/** Print version information. */
void version_print(void)
{
printf("%s, release %s (%s)%s\nBuilt%s for %s\n%s\n", project, release, name, revision, timestamp, arch, copyright);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/main/kinit.c
0,0 → 1,197
/*
* 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 main
* @{
*/
 
/**
* @file
* @brief Kernel initialization thread.
*
* This file contains kinit kernel thread which carries out
* high level system initialization.
*
* This file is responsible for finishing SMP configuration
* and creation of userspace init tasks.
*/
 
#include <main/kinit.h>
#include <config.h>
#include <arch.h>
#include <proc/scheduler.h>
#include <proc/task.h>
#include <proc/thread.h>
#include <panic.h>
#include <func.h>
#include <cpu.h>
#include <arch/asm.h>
#include <mm/page.h>
#include <arch/mm/page.h>
#include <mm/as.h>
#include <mm/frame.h>
#include <print.h>
#include <memstr.h>
#include <console/console.h>
#include <interrupt.h>
#include <console/kconsole.h>
#include <security/cap.h>
 
#ifdef CONFIG_SMP
#include <arch/smp/mps.h>
#endif /* CONFIG_SMP */
 
#include <synch/waitq.h>
#include <synch/spinlock.h>
 
#ifdef CONFIG_TEST
#include <test.h>
#endif /* CONFIG_TEST */
 
/** Kernel initialization thread.
*
* kinit takes care of higher level kernel
* initialization (i.e. thread creation,
* userspace initialization etc.).
*
* @param arg Not used.
*/
void kinit(void *arg)
{
thread_t *t;
 
/*
* Detach kinit as nobody will call thread_join_timeout() on it.
*/
thread_detach(THREAD);
 
interrupts_disable();
 
#ifdef CONFIG_SMP
if (config.cpu_count > 1) {
/*
* Create the kmp thread and wait for its completion.
* cpu1 through cpuN-1 will come up consecutively and
* not mess together with kcpulb threads.
* Just a beautification.
*/
if ((t = thread_create(kmp, NULL, TASK, 0, "kmp"))) {
spinlock_lock(&t->lock);
t->flags |= X_WIRED;
t->cpu = &cpus[0];
spinlock_unlock(&t->lock);
thread_ready(t);
} else
panic("thread_create/kmp\n");
thread_join(t);
thread_detach(t);
}
#endif /* CONFIG_SMP */
/*
* Now that all CPUs are up, we can report what we've found.
*/
cpu_list();
 
#ifdef CONFIG_SMP
if (config.cpu_count > 1) {
int i;
/*
* For each CPU, create its load balancing thread.
*/
for (i = 0; i < config.cpu_count; i++) {
 
if ((t = thread_create(kcpulb, NULL, TASK, 0, "kcpulb"))) {
spinlock_lock(&t->lock);
t->flags |= X_WIRED;
t->cpu = &cpus[i];
spinlock_unlock(&t->lock);
thread_ready(t);
} else
panic("thread_create/kcpulb\n");
 
}
}
#endif /* CONFIG_SMP */
 
/*
* At this point SMP, if present, is configured.
*/
arch_post_smp_init();
 
/*
* Create kernel console.
*/
if ((t = thread_create(kconsole, "kconsole", TASK, 0, "kconsole")))
thread_ready(t);
else
panic("thread_create/kconsole\n");
 
interrupts_enable();
 
#ifdef CONFIG_TEST
test();
printf("\nTest finished, please reboot\n");
#else /* CONFIG_TEST */
 
task_t *utask;
count_t i;
for (i = 0; i < init.cnt; i++) {
/*
* Run user tasks.
*/
if (init.tasks[i].addr % FRAME_SIZE)
panic("init[%d].addr is not frame aligned", i);
 
utask = task_run_program((void *) init.tasks[i].addr, "USPACE");
if (utask) {
/*
* Set capabilities to init userspace tasks.
*/
cap_set(utask, CAP_CAP | CAP_MEM_MANAGER | CAP_IO_MANAGER | CAP_PREEMPT_CONTROL | CAP_IRQ_REG);
if (!ipc_phone_0)
ipc_phone_0 = &utask->answerbox;
} else
printf("Init task %zd not started.\n", i);
}
 
 
if (!stdin) {
while (1) {
thread_sleep(1);
printf("kinit... ");
}
}
#endif /* CONFIG_TEST */
 
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/main/uinit.c
0,0 → 1,68
/*
* 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 main
* @{
*/
 
/**
* @file
* @brief Userspace bootstrap thread.
*
* This file contains uinit kernel thread wich is used to start every
* userspace thread including threads created by SYS_THREAD_CREATE syscall.
*
* @see SYS_THREAD_CREATE
*/
#include <main/uinit.h>
#include <arch/types.h>
#include <proc/thread.h>
#include <userspace.h>
#include <mm/slab.h>
 
/** Thread used to bring up userspace thread.
*
* @param arg Pointer to structure containing userspace entry and stack addresses.
*/
void uinit(void *arg)
{
uspace_arg_t uarg;
uarg.uspace_entry = ((uspace_arg_t *) arg)->uspace_entry;
uarg.uspace_stack = ((uspace_arg_t *) arg)->uspace_stack;
uarg.uspace_uarg = ((uspace_arg_t *) arg)->uspace_uarg;
uarg.uspace_thread_function = NULL;
uarg.uspace_thread_arg = NULL;
 
free((uspace_arg_t *) arg);
userspace(&uarg);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/mm/frame.c
0,0 → 1,1149
/*
* Copyright (C) 2001-2005 Jakub Jermar
* Copyright (C) 2005 Sergey Bondari
* 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 genericmm
* @{
*/
 
/**
* @file
* @brief Physical frame allocator.
*
* This file contains the physical frame allocator and memory zone management.
* The frame allocator is built on top of the buddy allocator.
*
* @see buddy.c
*/
 
/*
* Locking order
*
* In order to access particular zone, the process must first lock
* the zones.lock, then lock the zone and then unlock the zones.lock.
* This insures, that we can fiddle with the zones in runtime without
* affecting the processes.
*
*/
 
#include <typedefs.h>
#include <arch/types.h>
#include <mm/frame.h>
#include <mm/as.h>
#include <panic.h>
#include <debug.h>
#include <adt/list.h>
#include <synch/spinlock.h>
#include <arch/asm.h>
#include <arch.h>
#include <print.h>
#include <align.h>
#include <mm/slab.h>
#include <bitops.h>
#include <macros.h>
 
typedef struct {
count_t refcount; /**< tracking of shared frames */
uint8_t buddy_order; /**< buddy system block order */
link_t buddy_link; /**< link to the next free block inside one order */
void *parent; /**< If allocated by slab, this points there */
} frame_t;
 
typedef struct {
SPINLOCK_DECLARE(lock); /**< this lock protects everything below */
pfn_t base; /**< frame_no of the first frame in the frames array */
count_t count; /**< Size of zone */
 
frame_t *frames; /**< array of frame_t structures in this zone */
count_t free_count; /**< number of free frame_t structures */
count_t busy_count; /**< number of busy frame_t structures */
buddy_system_t * buddy_system; /**< buddy system for the zone */
int flags;
} zone_t;
 
/*
* The zoneinfo.lock must be locked when accessing zoneinfo structure.
* Some of the attributes in zone_t structures are 'read-only'
*/
 
struct {
SPINLOCK_DECLARE(lock);
int count;
zone_t *info[ZONES_MAX];
} zones;
 
 
/*********************************/
/* Helper functions */
static inline index_t frame_index(zone_t *zone, frame_t *frame)
{
return (index_t)(frame - zone->frames);
}
static inline index_t frame_index_abs(zone_t *zone, frame_t *frame)
{
return (index_t)(frame - zone->frames) + zone->base;
}
static inline int frame_index_valid(zone_t *zone, index_t index)
{
return index >= 0 && index < zone->count;
}
 
/** Compute pfn_t from frame_t pointer & zone pointer */
static index_t make_frame_index(zone_t *zone, frame_t *frame)
{
return frame - zone->frames;
}
 
/** Initialize frame structure
*
* Initialize frame structure.
*
* @param frame Frame structure to be initialized.
*/
static void frame_initialize(frame_t *frame)
{
frame->refcount = 1;
frame->buddy_order = 0;
}
 
/*************************************/
/* Zoneinfo functions */
 
/**
* Insert-sort zone into zones list
*
* @param newzone New zone to be inserted into zone list
* @return zone number on success, -1 on error
*/
static int zones_add_zone(zone_t *newzone)
{
int i,j;
ipl_t ipl;
zone_t *z;
 
ipl = interrupts_disable();
spinlock_lock(&zones.lock);
/* Try to merge */
if (zones.count + 1 == ZONES_MAX)
panic("Maximum zone(%d) count exceeded.", ZONES_MAX);
for (i = 0; i < zones.count; i++) {
/* Check for overflow */
z = zones.info[i];
if (overlaps(newzone->base,newzone->count,
z->base, z->count)) {
printf("Zones overlap!\n");
return -1;
}
if (newzone->base < z->base)
break;
}
/* Move other zones up */
for (j = i;j < zones.count; j++)
zones.info[j + 1] = zones.info[j];
zones.info[i] = newzone;
zones.count++;
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
 
return i;
}
 
/**
* Try to find a zone where can we find the frame
*
* @param frame Frame number contained in zone
* @param pzone If not null, it is used as zone hint. Zone index
* is filled into the variable on success.
* @return Pointer to LOCKED zone containing frame
*
* Assume interrupts disable
*/
static zone_t * find_zone_and_lock(pfn_t frame, int *pzone)
{
int i;
int hint = pzone ? *pzone : 0;
zone_t *z;
spinlock_lock(&zones.lock);
 
if (hint >= zones.count || hint < 0)
hint = 0;
i = hint;
do {
z = zones.info[i];
spinlock_lock(&z->lock);
if (z->base <= frame && z->base + z->count > frame) {
spinlock_unlock(&zones.lock); /* Unlock the global lock */
if (pzone)
*pzone = i;
return z;
}
spinlock_unlock(&z->lock);
 
i++;
if (i >= zones.count)
i = 0;
} while(i != hint);
 
spinlock_unlock(&zones.lock);
return NULL;
}
 
/** @return True if zone can allocate specified order */
static int zone_can_alloc(zone_t *z, uint8_t order)
{
return buddy_system_can_alloc(z->buddy_system, order);
}
 
/**
* Find AND LOCK zone that can allocate order frames
*
* Assume interrupts are disabled!!
*
* @param order Size (2^order) of free space we are trying to find
* @param pzone Pointer to preferred zone or NULL, on return contains zone number
*/
static zone_t * find_free_zone_lock(uint8_t order, int *pzone)
{
int i;
zone_t *z;
int hint = pzone ? *pzone : 0;
spinlock_lock(&zones.lock);
if (hint >= zones.count)
hint = 0;
i = hint;
do {
z = zones.info[i];
spinlock_lock(&z->lock);
 
/* Check if the zone has 2^order frames area available */
if (zone_can_alloc(z, order)) {
spinlock_unlock(&zones.lock);
if (pzone)
*pzone = i;
return z;
}
spinlock_unlock(&z->lock);
if (++i >= zones.count)
i = 0;
} while(i != hint);
spinlock_unlock(&zones.lock);
return NULL;
}
 
/********************************************/
/* Buddy system functions */
 
/** Buddy system find_block implementation
*
* Find block that is parent of current list.
* That means go to lower addresses, until such block is found
*
* @param order - Order of parent must be different then this parameter!!
*/
static link_t *zone_buddy_find_block(buddy_system_t *b, link_t *child,
uint8_t order)
{
frame_t * frame;
zone_t * zone;
index_t index;
frame = list_get_instance(child, frame_t, buddy_link);
zone = (zone_t *) b->data;
 
index = frame_index(zone, frame);
do {
if (zone->frames[index].buddy_order != order) {
return &zone->frames[index].buddy_link;
}
} while(index-- > 0);
return NULL;
}
 
static void zone_buddy_print_id(buddy_system_t *b, link_t *block)
{
frame_t * frame;
zone_t * zone;
index_t index;
 
frame = list_get_instance(block, frame_t, buddy_link);
zone = (zone_t *) b->data;
index = frame_index(zone, frame);
printf("%zd", index);
}
 
/** Buddy system find_buddy implementation
*
* @param b Buddy system.
* @param block Block for which buddy should be found
*
* @return Buddy for given block if found
*/
static link_t * zone_buddy_find_buddy(buddy_system_t *b, link_t * block)
{
frame_t * frame;
zone_t * zone;
index_t index;
bool is_left, is_right;
 
frame = list_get_instance(block, frame_t, buddy_link);
zone = (zone_t *) b->data;
ASSERT(IS_BUDDY_ORDER_OK(frame_index_abs(zone, frame), frame->buddy_order));
is_left = IS_BUDDY_LEFT_BLOCK_ABS(zone, frame);
is_right = IS_BUDDY_RIGHT_BLOCK_ABS(zone, frame);
 
ASSERT(is_left ^ is_right);
if (is_left) {
index = (frame_index(zone, frame)) + (1 << frame->buddy_order);
} else { // if (is_right)
index = (frame_index(zone, frame)) - (1 << frame->buddy_order);
}
if (frame_index_valid(zone, index)) {
if (zone->frames[index].buddy_order == frame->buddy_order &&
zone->frames[index].refcount == 0) {
return &zone->frames[index].buddy_link;
}
}
 
return NULL;
}
 
/** Buddy system bisect implementation
*
* @param b Buddy system.
* @param block Block to bisect
*
* @return right block
*/
static link_t * zone_buddy_bisect(buddy_system_t *b, link_t * block) {
frame_t * frame_l, * frame_r;
 
frame_l = list_get_instance(block, frame_t, buddy_link);
frame_r = (frame_l + (1 << (frame_l->buddy_order - 1)));
return &frame_r->buddy_link;
}
 
/** Buddy system coalesce implementation
*
* @param b Buddy system.
* @param block_1 First block
* @param block_2 First block's buddy
*
* @return Coalesced block (actually block that represents lower address)
*/
static link_t * zone_buddy_coalesce(buddy_system_t *b, link_t * block_1,
link_t * block_2)
{
frame_t *frame1, *frame2;
frame1 = list_get_instance(block_1, frame_t, buddy_link);
frame2 = list_get_instance(block_2, frame_t, buddy_link);
return frame1 < frame2 ? block_1 : block_2;
}
 
/** Buddy system set_order implementation
*
* @param b Buddy system.
* @param block Buddy system block
* @param order Order to set
*/
static void zone_buddy_set_order(buddy_system_t *b, link_t * block, uint8_t order) {
frame_t * frame;
frame = list_get_instance(block, frame_t, buddy_link);
frame->buddy_order = order;
}
 
/** Buddy system get_order implementation
*
* @param b Buddy system.
* @param block Buddy system block
*
* @return Order of block
*/
static uint8_t zone_buddy_get_order(buddy_system_t *b, link_t * block) {
frame_t * frame;
frame = list_get_instance(block, frame_t, buddy_link);
return frame->buddy_order;
}
 
/** Buddy system mark_busy implementation
*
* @param b Buddy system
* @param block Buddy system block
*
*/
static void zone_buddy_mark_busy(buddy_system_t *b, link_t * block) {
frame_t * frame;
 
frame = list_get_instance(block, frame_t, buddy_link);
frame->refcount = 1;
}
 
/** Buddy system mark_available implementation
*
* @param b Buddy system
* @param block Buddy system block
*
*/
static void zone_buddy_mark_available(buddy_system_t *b, link_t * block) {
frame_t * frame;
frame = list_get_instance(block, frame_t, buddy_link);
frame->refcount = 0;
}
 
static struct buddy_system_operations zone_buddy_system_operations = {
.find_buddy = zone_buddy_find_buddy,
.bisect = zone_buddy_bisect,
.coalesce = zone_buddy_coalesce,
.set_order = zone_buddy_set_order,
.get_order = zone_buddy_get_order,
.mark_busy = zone_buddy_mark_busy,
.mark_available = zone_buddy_mark_available,
.find_block = zone_buddy_find_block,
.print_id = zone_buddy_print_id
};
 
/*************************************/
/* Zone functions */
 
/** Allocate frame in particular zone
*
* Assume zone is locked
* Panics if allocation is impossible.
*
* @param zone Zone to allocate from.
* @param order Allocate exactly 2^order frames.
*
* @return Frame index in zone
*
*/
static pfn_t zone_frame_alloc(zone_t *zone, uint8_t order)
{
pfn_t v;
link_t *tmp;
frame_t *frame;
 
/* Allocate frames from zone buddy system */
tmp = buddy_system_alloc(zone->buddy_system, order);
ASSERT(tmp);
/* Update zone information. */
zone->free_count -= (1 << order);
zone->busy_count += (1 << order);
 
/* Frame will be actually a first frame of the block. */
frame = list_get_instance(tmp, frame_t, buddy_link);
/* get frame address */
v = make_frame_index(zone, frame);
return v;
}
 
/** Free frame from zone
*
* Assume zone is locked
*
* @param zone Pointer to zone from which the frame is to be freed
* @param frame_idx Frame index relative to zone
*/
static void zone_frame_free(zone_t *zone, index_t frame_idx)
{
frame_t *frame;
uint8_t order;
 
frame = &zone->frames[frame_idx];
/* remember frame order */
order = frame->buddy_order;
 
ASSERT(frame->refcount);
 
if (!--frame->refcount) {
buddy_system_free(zone->buddy_system, &frame->buddy_link);
/* Update zone information. */
zone->free_count += (1 << order);
zone->busy_count -= (1 << order);
}
}
 
/** Return frame from zone */
static frame_t * zone_get_frame(zone_t *zone, index_t frame_idx)
{
ASSERT(frame_idx < zone->count);
return &zone->frames[frame_idx];
}
 
/** Mark frame in zone unavailable to allocation */
static void zone_mark_unavailable(zone_t *zone, index_t frame_idx)
{
frame_t *frame;
link_t *link;
 
frame = zone_get_frame(zone, frame_idx);
if (frame->refcount)
return;
link = buddy_system_alloc_block(zone->buddy_system,
&frame->buddy_link);
ASSERT(link);
zone->free_count--;
}
 
/**
* Join 2 zones
*
* Expect zone_t *z to point to space at least zone_conf_size large
*
* Assume z1 & z2 are locked
*
* @param z Target zone structure pointer
* @param z1 Zone to merge
* @param z2 Zone to merge
*/
 
static void _zone_merge(zone_t *z, zone_t *z1, zone_t *z2)
{
uint8_t max_order;
int i, z2idx;
pfn_t frame_idx;
frame_t *frame;
 
ASSERT(!overlaps(z1->base,z1->count,z2->base,z2->count));
ASSERT(z1->base < z2->base);
 
spinlock_initialize(&z->lock, "zone_lock");
z->base = z1->base;
z->count = z2->base+z2->count - z1->base;
z->flags = z1->flags & z2->flags;
 
z->free_count = z1->free_count + z2->free_count;
z->busy_count = z1->busy_count + z2->busy_count;
max_order = fnzb(z->count);
 
z->buddy_system = (buddy_system_t *)&z[1];
buddy_system_create(z->buddy_system, max_order,
&zone_buddy_system_operations,
(void *) z);
 
z->frames = (frame_t *)((void *)z->buddy_system+buddy_conf_size(max_order));
for (i = 0; i < z->count; i++) {
/* This marks all frames busy */
frame_initialize(&z->frames[i]);
}
/* Copy frames from both zones to preserve full frame orders,
* parents etc. Set all free frames with refcount=0 to 1, because
* we add all free frames to buddy allocator later again, clear
* order to 0. Don't set busy frames with refcount=0, as they
* will not be reallocated during merge and it would make later
* problems with allocation/free.
*/
for (i=0; i<z1->count; i++)
z->frames[i] = z1->frames[i];
for (i=0; i < z2->count; i++) {
z2idx = i + (z2->base - z1->base);
z->frames[z2idx] = z2->frames[i];
}
i = 0;
while (i < z->count) {
if (z->frames[i].refcount) {
/* skip busy frames */
i += 1 << z->frames[i].buddy_order;
} else { /* Free frames, set refcount=1 */
/* All free frames have refcount=0, we need not
* to check the order */
z->frames[i].refcount = 1;
z->frames[i].buddy_order = 0;
i++;
}
}
/* Add free blocks from the 2 original zones */
while (zone_can_alloc(z1, 0)) {
frame_idx = zone_frame_alloc(z1, 0);
frame = &z->frames[frame_idx];
frame->refcount = 0;
buddy_system_free(z->buddy_system, &frame->buddy_link);
}
while (zone_can_alloc(z2, 0)) {
frame_idx = zone_frame_alloc(z2, 0);
frame = &z->frames[frame_idx + (z2->base-z1->base)];
frame->refcount = 0;
buddy_system_free(z->buddy_system, &frame->buddy_link);
}
}
 
/** Return old configuration frames into the zone
*
* We have several cases
* - the conf. data is outside of zone -> exit, shall we call frame_free??
* - the conf. data was created by zone_create or
* updated with reduce_region -> free every frame
*
* @param newzone The actual zone where freeing should occur
* @param oldzone Pointer to old zone configuration data that should
* be freed from new zone
*/
static void return_config_frames(zone_t *newzone, zone_t *oldzone)
{
pfn_t pfn;
frame_t *frame;
count_t cframes;
int i;
 
pfn = ADDR2PFN((uintptr_t)KA2PA(oldzone));
cframes = SIZE2FRAMES(zone_conf_size(oldzone->count));
if (pfn < newzone->base || pfn >= newzone->base + newzone->count)
return;
 
frame = &newzone->frames[pfn - newzone->base];
ASSERT(!frame->buddy_order);
 
for (i=0; i < cframes; i++) {
newzone->busy_count++;
zone_frame_free(newzone, pfn+i-newzone->base);
}
}
 
/** Reduce allocated block to count of order 0 frames
*
* The allocated block need 2^order frames of space. Reduce all frames
* in block to order 0 and free the unneeded frames. This means, that
* when freeing the previously allocated block starting with frame_idx,
* you have to free every frame.
*
* @param zone
* @param frame_idx Index to block
* @param count Allocated space in block
*/
static void zone_reduce_region(zone_t *zone, pfn_t frame_idx, count_t count)
{
count_t i;
uint8_t order;
frame_t *frame;
ASSERT(frame_idx+count < zone->count);
 
order = zone->frames[frame_idx].buddy_order;
ASSERT((1 << order) >= count);
 
/* Reduce all blocks to order 0 */
for (i=0; i < (1 << order); i++) {
frame = &zone->frames[i + frame_idx];
frame->buddy_order = 0;
if (! frame->refcount)
frame->refcount = 1;
ASSERT(frame->refcount == 1);
}
/* Free unneeded frames */
for (i=count; i < (1 << order); i++) {
zone_frame_free(zone, i + frame_idx);
}
}
 
/** Merge zones z1 and z2
*
* - the zones must be 2 zones with no zone existing in between,
* which means that z2 = z1+1
*
* - When you create a new zone, the frame allocator configuration does
* not to be 2^order size. Once the allocator is running it is no longer
* possible, merged configuration data occupies more space :-/
*/
void zone_merge(int z1, int z2)
{
ipl_t ipl;
zone_t *zone1, *zone2, *newzone;
int cframes;
uint8_t order;
int i;
pfn_t pfn;
 
ipl = interrupts_disable();
spinlock_lock(&zones.lock);
 
if (z1 < 0 || z1 >= zones.count || z2 < 0 || z2 >= zones.count)
goto errout;
/* We can join only 2 zones with none existing inbetween */
if (z2-z1 != 1)
goto errout;
 
zone1 = zones.info[z1];
zone2 = zones.info[z2];
spinlock_lock(&zone1->lock);
spinlock_lock(&zone2->lock);
 
cframes = SIZE2FRAMES(zone_conf_size(zone2->base+zone2->count-zone1->base));
if (cframes == 1)
order = 0;
else
order = fnzb(cframes - 1) + 1;
 
/* Allocate zonedata inside one of the zones */
if (zone_can_alloc(zone1, order))
pfn = zone1->base + zone_frame_alloc(zone1, order);
else if (zone_can_alloc(zone2, order))
pfn = zone2->base + zone_frame_alloc(zone2, order);
else
goto errout2;
 
newzone = (zone_t *)PA2KA(PFN2ADDR(pfn));
 
_zone_merge(newzone, zone1, zone2);
 
/* Free unneeded config frames */
zone_reduce_region(newzone, pfn - newzone->base, cframes);
/* Subtract zone information from busy frames */
newzone->busy_count -= cframes;
 
/* Replace existing zones in zoneinfo list */
zones.info[z1] = newzone;
for (i = z2 + 1; i < zones.count; i++)
zones.info[i - 1] = zones.info[i];
zones.count--;
 
/* Free old zone information */
return_config_frames(newzone, zone1);
return_config_frames(newzone, zone2);
errout2:
/* Nobody is allowed to enter to zone, so we are safe
* to touch the spinlocks last time */
spinlock_unlock(&zone1->lock);
spinlock_unlock(&zone2->lock);
errout:
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
}
 
/**
* Merge all zones into one big zone
*
* It is reasonable to do this on systems whose bios reports parts in chunks,
* so that we could have 1 zone (it's faster).
*/
void zone_merge_all(void)
{
int count = zones.count;
 
while (zones.count > 1 && --count) {
zone_merge(0,1);
break;
}
}
 
/** Create frame zone
*
* Create new frame zone.
*
* @param start Physical address of the first frame within the zone.
* @param count Count of frames in zone
* @param z Address of configuration information of zone
* @param flags Zone flags.
*
* @return Initialized zone.
*/
static void zone_construct(pfn_t start, count_t count, zone_t *z, int flags)
{
int i;
uint8_t max_order;
 
spinlock_initialize(&z->lock, "zone_lock");
z->base = start;
z->count = count;
z->flags = flags;
z->free_count = count;
z->busy_count = 0;
 
/*
* Compute order for buddy system, initialize
*/
max_order = fnzb(count);
z->buddy_system = (buddy_system_t *)&z[1];
buddy_system_create(z->buddy_system, max_order,
&zone_buddy_system_operations,
(void *) z);
/* Allocate frames _after_ the conframe */
/* Check sizes */
z->frames = (frame_t *)((void *)z->buddy_system+buddy_conf_size(max_order));
for (i = 0; i<count; i++) {
frame_initialize(&z->frames[i]);
}
/* Stuffing frames */
for (i = 0; i < count; i++) {
z->frames[i].refcount = 0;
buddy_system_free(z->buddy_system, &z->frames[i].buddy_link);
}
}
 
/** Compute configuration data size for zone
*
* @param count Size of zone in frames
* @return Size of zone configuration info (in bytes)
*/
uintptr_t zone_conf_size(count_t count)
{
int size = sizeof(zone_t) + count*sizeof(frame_t);
int max_order;
 
max_order = fnzb(count);
size += buddy_conf_size(max_order);
return size;
}
 
/** Create and add zone to system
*
* @param start First frame number (absolute)
* @param count Size of zone in frames
* @param confframe Where configuration frames are supposed to be.
* Automatically checks, that we will not disturb the
* kernel and possibly init.
* If confframe is given _outside_ this zone, it is expected,
* that the area is already marked BUSY and big enough
* to contain zone_conf_size() amount of data.
* If the confframe is inside the area, the zone free frame
* information is modified not to include it.
*
* @return Zone number or -1 on error
*/
int zone_create(pfn_t start, count_t count, pfn_t confframe, int flags)
{
zone_t *z;
uintptr_t addr;
count_t confcount;
int i;
int znum;
 
/* Theoretically we could have here 0, practically make sure
* nobody tries to do that. If some platform requires, remove
* the assert
*/
ASSERT(confframe);
/* If conframe is supposed to be inside our zone, then make sure
* it does not span kernel & init
*/
confcount = SIZE2FRAMES(zone_conf_size(count));
if (confframe >= start && confframe < start+count) {
for (;confframe < start + count; confframe++) {
addr = PFN2ADDR(confframe);
if (overlaps(addr, PFN2ADDR(confcount), KA2PA(config.base), config.kernel_size))
continue;
if (overlaps(addr, PFN2ADDR(confcount), KA2PA(config.stack_base), config.stack_size))
continue;
bool overlap = false;
count_t i;
for (i = 0; i < init.cnt; i++)
if (overlaps(addr, PFN2ADDR(confcount), KA2PA(init.tasks[i].addr), init.tasks[i].size)) {
overlap = true;
break;
}
if (overlap)
continue;
break;
}
if (confframe >= start + count)
panic("Cannot find configuration data for zone.");
}
 
z = (zone_t *)PA2KA(PFN2ADDR(confframe));
zone_construct(start, count, z, flags);
znum = zones_add_zone(z);
if (znum == -1)
return -1;
 
/* If confdata in zone, mark as unavailable */
if (confframe >= start && confframe < start+count)
for (i=confframe; i<confframe+confcount; i++) {
zone_mark_unavailable(z, i - z->base);
}
return znum;
}
 
/***************************************/
/* Frame functions */
 
/** Set parent of frame */
void frame_set_parent(pfn_t pfn, void *data, int hint)
{
zone_t *zone = find_zone_and_lock(pfn, &hint);
 
ASSERT(zone);
 
zone_get_frame(zone, pfn-zone->base)->parent = data;
spinlock_unlock(&zone->lock);
}
 
void * frame_get_parent(pfn_t pfn, int hint)
{
zone_t *zone = find_zone_and_lock(pfn, &hint);
void *res;
 
ASSERT(zone);
res = zone_get_frame(zone, pfn - zone->base)->parent;
spinlock_unlock(&zone->lock);
return res;
}
 
/** Allocate power-of-two frames of physical memory.
*
* @param order Allocate exactly 2^order frames.
* @param flags Flags for host zone selection and address processing.
* @param status Allocation status (FRAME_OK on success), unused if NULL.
* @param pzone Preferred zone
*
* @return Physical address of the allocated frame.
*
*/
void * frame_alloc_generic(uint8_t order, int flags, int *pzone)
{
ipl_t ipl;
int freed;
pfn_t v;
zone_t *zone;
loop:
ipl = interrupts_disable();
/*
* First, find suitable frame zone.
*/
zone = find_free_zone_lock(order, pzone);
/* If no memory, reclaim some slab memory,
if it does not help, reclaim all */
if (!zone && !(flags & FRAME_NO_RECLAIM)) {
freed = slab_reclaim(0);
if (freed)
zone = find_free_zone_lock(order, pzone);
if (!zone) {
freed = slab_reclaim(SLAB_RECLAIM_ALL);
if (freed)
zone = find_free_zone_lock(order, pzone);
}
}
if (!zone) {
/*
* TODO: Sleep until frames are available again.
*/
interrupts_restore(ipl);
 
if (flags & FRAME_ATOMIC)
return 0;
panic("Sleep not implemented.\n");
goto loop;
}
v = zone_frame_alloc(zone, order);
v += zone->base;
 
spinlock_unlock(&zone->lock);
interrupts_restore(ipl);
 
if (flags & FRAME_KA)
return (void *)PA2KA(PFN2ADDR(v));
return (void *)PFN2ADDR(v);
}
 
/** Free a frame.
*
* Find respective frame structure for supplied PFN.
* Decrement frame reference count.
* If it drops to zero, move the frame structure to free list.
*
* @param Frame Physical Address of of the frame to be freed.
*/
void frame_free(uintptr_t frame)
{
ipl_t ipl;
zone_t *zone;
pfn_t pfn = ADDR2PFN(frame);
 
ipl = interrupts_disable();
/*
* First, find host frame zone for addr.
*/
zone = find_zone_and_lock(pfn,NULL);
ASSERT(zone);
zone_frame_free(zone, pfn-zone->base);
spinlock_unlock(&zone->lock);
interrupts_restore(ipl);
}
 
/** Add reference to frame.
*
* Find respective frame structure for supplied PFN and
* increment frame reference count.
*
* @param pfn Frame number of the frame to be freed.
*/
void frame_reference_add(pfn_t pfn)
{
ipl_t ipl;
zone_t *zone;
frame_t *frame;
 
ipl = interrupts_disable();
/*
* First, find host frame zone for addr.
*/
zone = find_zone_and_lock(pfn,NULL);
ASSERT(zone);
frame = &zone->frames[pfn-zone->base];
frame->refcount++;
spinlock_unlock(&zone->lock);
interrupts_restore(ipl);
}
 
/** Mark given range unavailable in frame zones */
void frame_mark_unavailable(pfn_t start, count_t count)
{
int i;
zone_t *zone;
int prefzone = 0;
for (i=0; i < count; i++) {
zone = find_zone_and_lock(start+i,&prefzone);
if (!zone) /* PFN not found */
continue;
zone_mark_unavailable(zone, start+i-zone->base);
 
spinlock_unlock(&zone->lock);
}
}
 
/** Initialize physical memory management
*
* Initialize physical memory managemnt.
*/
void frame_init(void)
{
if (config.cpu_active == 1) {
zones.count = 0;
spinlock_initialize(&zones.lock,"zones_glob_lock");
}
/* Tell the architecture to create some memory */
frame_arch_init();
if (config.cpu_active == 1) {
frame_mark_unavailable(ADDR2PFN(KA2PA(config.base)), SIZE2FRAMES(config.kernel_size));
frame_mark_unavailable(ADDR2PFN(KA2PA(config.stack_base)), SIZE2FRAMES(config.stack_size));
count_t i;
for (i = 0; i < init.cnt; i++)
frame_mark_unavailable(ADDR2PFN(KA2PA(init.tasks[i].addr)), SIZE2FRAMES(init.tasks[i].size));
 
/* Black list first frame, as allocating NULL would
* fail in some places */
frame_mark_unavailable(0, 1);
}
}
 
 
 
/** Prints list of zones
*
*/
void zone_print_list(void) {
zone_t *zone = NULL;
int i;
ipl_t ipl;
 
ipl = interrupts_disable();
spinlock_lock(&zones.lock);
printf("# Base address\tFree Frames\tBusy Frames\n");
printf(" ------------\t-----------\t-----------\n");
for (i = 0; i < zones.count; i++) {
zone = zones.info[i];
spinlock_lock(&zone->lock);
printf("%d: %.*p \t%10zd\t%10zd\n", i, sizeof(uintptr_t) * 2, PFN2ADDR(zone->base), zone->free_count, zone->busy_count);
spinlock_unlock(&zone->lock);
}
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
}
 
/** Prints zone details.
*
* @param num Zone base address or zone number.
*/
void zone_print_one(int num) {
zone_t *zone = NULL;
ipl_t ipl;
int i;
 
ipl = interrupts_disable();
spinlock_lock(&zones.lock);
 
for (i = 0; i < zones.count; i++) {
if (i == num || PFN2ADDR(zones.info[i]->base) == num) {
zone = zones.info[i];
break;
}
}
if (!zone) {
printf("Zone not found.\n");
goto out;
}
spinlock_lock(&zone->lock);
printf("Memory zone information\n");
printf("Zone base address: %#.*p\n", sizeof(uintptr_t) * 2, PFN2ADDR(zone->base));
printf("Zone size: %zd frames (%zdK)\n", zone->count, ((zone->count) * FRAME_SIZE) >> 10);
printf("Allocated space: %zd frames (%zdK)\n", zone->busy_count, (zone->busy_count * FRAME_SIZE) >> 10);
printf("Available space: %zd (%zdK)\n", zone->free_count, (zone->free_count * FRAME_SIZE) >> 10);
buddy_system_structure_print(zone->buddy_system, FRAME_SIZE);
spinlock_unlock(&zone->lock);
out:
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/mm/as.c
0,0 → 1,1537
/*
* Copyright (C) 2001-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 genericmm
* @{
*/
 
/**
* @file
* @brief Address space related functions.
*
* This file contains address space manipulation functions.
* Roughly speaking, this is a higher-level client of
* Virtual Address Translation (VAT) subsystem.
*
* Functionality provided by this file allows one to
* create address spaces and create, resize and share
* address space areas.
*
* @see page.c
*
*/
 
#include <mm/as.h>
#include <arch/mm/as.h>
#include <mm/page.h>
#include <mm/frame.h>
#include <mm/slab.h>
#include <mm/tlb.h>
#include <arch/mm/page.h>
#include <genarch/mm/page_pt.h>
#include <genarch/mm/page_ht.h>
#include <mm/asid.h>
#include <arch/mm/asid.h>
#include <synch/spinlock.h>
#include <synch/mutex.h>
#include <adt/list.h>
#include <adt/btree.h>
#include <proc/task.h>
#include <proc/thread.h>
#include <arch/asm.h>
#include <panic.h>
#include <debug.h>
#include <print.h>
#include <memstr.h>
#include <macros.h>
#include <arch.h>
#include <errno.h>
#include <config.h>
#include <align.h>
#include <arch/types.h>
#include <typedefs.h>
#include <syscall/copy.h>
#include <arch/interrupt.h>
 
/**
* Each architecture decides what functions will be used to carry out
* address space operations such as creating or locking page tables.
*/
as_operations_t *as_operations = NULL;
 
/** This lock protects inactive_as_with_asid_head list. It must be acquired before as_t mutex. */
SPINLOCK_INITIALIZE(inactive_as_with_asid_lock);
 
/**
* This list contains address spaces that are not active on any
* processor and that have valid ASID.
*/
LIST_INITIALIZE(inactive_as_with_asid_head);
 
/** Kernel address space. */
as_t *AS_KERNEL = NULL;
 
static int area_flags_to_page_flags(int aflags);
static as_area_t *find_area_and_lock(as_t *as, uintptr_t va);
static bool check_area_conflicts(as_t *as, uintptr_t va, size_t size, as_area_t *avoid_area);
static void sh_info_remove_reference(share_info_t *sh_info);
 
/** Initialize address space subsystem. */
void as_init(void)
{
as_arch_init();
AS_KERNEL = as_create(FLAG_AS_KERNEL);
if (!AS_KERNEL)
panic("can't create kernel address space\n");
}
 
/** Create address space.
*
* @param flags Flags that influence way in wich the address space is created.
*/
as_t *as_create(int flags)
{
as_t *as;
 
as = (as_t *) malloc(sizeof(as_t), 0);
link_initialize(&as->inactive_as_with_asid_link);
mutex_initialize(&as->lock);
btree_create(&as->as_area_btree);
if (flags & FLAG_AS_KERNEL)
as->asid = ASID_KERNEL;
else
as->asid = ASID_INVALID;
as->refcount = 0;
as->cpu_refcount = 0;
as->page_table = page_table_create(flags);
 
return as;
}
 
/** Destroy adress space.
*
* When there are no tasks referencing this address space (i.e. its refcount is zero),
* the address space can be destroyed.
*/
void as_destroy(as_t *as)
{
ipl_t ipl;
bool cond;
 
ASSERT(as->refcount == 0);
/*
* Since there is no reference to this area,
* it is safe not to lock its mutex.
*/
ipl = interrupts_disable();
spinlock_lock(&inactive_as_with_asid_lock);
if (as->asid != ASID_INVALID && as != AS_KERNEL) {
if (as != AS && as->cpu_refcount == 0)
list_remove(&as->inactive_as_with_asid_link);
asid_put(as->asid);
}
spinlock_unlock(&inactive_as_with_asid_lock);
 
/*
* Destroy address space areas of the address space.
* The B+tee must be walked carefully because it is
* also being destroyed.
*/
for (cond = true; cond; ) {
btree_node_t *node;
 
ASSERT(!list_empty(&as->as_area_btree.leaf_head));
node = list_get_instance(as->as_area_btree.leaf_head.next, btree_node_t, leaf_link);
 
if ((cond = node->keys)) {
as_area_destroy(as, node->key[0]);
}
}
 
btree_destroy(&as->as_area_btree);
page_table_destroy(as->page_table);
 
interrupts_restore(ipl);
free(as);
}
 
/** Create address space area of common attributes.
*
* The created address space area is added to the target address space.
*
* @param as Target address space.
* @param flags Flags of the area memory.
* @param size Size of area.
* @param base Base address of area.
* @param attrs Attributes of the area.
* @param backend Address space area backend. NULL if no backend is used.
* @param backend_data NULL or a pointer to an array holding two void *.
*
* @return Address space area on success or NULL on failure.
*/
as_area_t *as_area_create(as_t *as, int flags, size_t size, uintptr_t base, int attrs,
mem_backend_t *backend, mem_backend_data_t *backend_data)
{
ipl_t ipl;
as_area_t *a;
if (base % PAGE_SIZE)
return NULL;
 
if (!size)
return NULL;
 
/* Writeable executable areas are not supported. */
if ((flags & AS_AREA_EXEC) && (flags & AS_AREA_WRITE))
return NULL;
ipl = interrupts_disable();
mutex_lock(&as->lock);
if (!check_area_conflicts(as, base, size, NULL)) {
mutex_unlock(&as->lock);
interrupts_restore(ipl);
return NULL;
}
a = (as_area_t *) malloc(sizeof(as_area_t), 0);
 
mutex_initialize(&a->lock);
a->as = as;
a->flags = flags;
a->attributes = attrs;
a->pages = SIZE2FRAMES(size);
a->base = base;
a->sh_info = NULL;
a->backend = backend;
if (backend_data)
a->backend_data = *backend_data;
else
memsetb((uintptr_t) &a->backend_data, sizeof(a->backend_data), 0);
 
btree_create(&a->used_space);
btree_insert(&as->as_area_btree, base, (void *) a, NULL);
 
mutex_unlock(&as->lock);
interrupts_restore(ipl);
 
return a;
}
 
/** Find address space area and change it.
*
* @param as Address space.
* @param address Virtual address belonging to the area to be changed. Must be page-aligned.
* @param size New size of the virtual memory block starting at address.
* @param flags Flags influencing the remap operation. Currently unused.
*
* @return Zero on success or a value from @ref errno.h otherwise.
*/
int as_area_resize(as_t *as, uintptr_t address, size_t size, int flags)
{
as_area_t *area;
ipl_t ipl;
size_t pages;
ipl = interrupts_disable();
mutex_lock(&as->lock);
/*
* Locate the area.
*/
area = find_area_and_lock(as, address);
if (!area) {
mutex_unlock(&as->lock);
interrupts_restore(ipl);
return ENOENT;
}
 
if (area->backend == &phys_backend) {
/*
* Remapping of address space areas associated
* with memory mapped devices is not supported.
*/
mutex_unlock(&area->lock);
mutex_unlock(&as->lock);
interrupts_restore(ipl);
return ENOTSUP;
}
if (area->sh_info) {
/*
* Remapping of shared address space areas
* is not supported.
*/
mutex_unlock(&area->lock);
mutex_unlock(&as->lock);
interrupts_restore(ipl);
return ENOTSUP;
}
 
pages = SIZE2FRAMES((address - area->base) + size);
if (!pages) {
/*
* Zero size address space areas are not allowed.
*/
mutex_unlock(&area->lock);
mutex_unlock(&as->lock);
interrupts_restore(ipl);
return EPERM;
}
if (pages < area->pages) {
bool cond;
uintptr_t start_free = area->base + pages*PAGE_SIZE;
 
/*
* Shrinking the area.
* No need to check for overlaps.
*/
 
/*
* Start TLB shootdown sequence.
*/
tlb_shootdown_start(TLB_INVL_PAGES, AS->asid, area->base + pages*PAGE_SIZE, area->pages - pages);
 
/*
* Remove frames belonging to used space starting from
* the highest addresses downwards until an overlap with
* the resized address space area is found. Note that this
* is also the right way to remove part of the used_space
* B+tree leaf list.
*/
for (cond = true; cond;) {
btree_node_t *node;
ASSERT(!list_empty(&area->used_space.leaf_head));
node = list_get_instance(area->used_space.leaf_head.prev, btree_node_t, leaf_link);
if ((cond = (bool) node->keys)) {
uintptr_t b = node->key[node->keys - 1];
count_t c = (count_t) node->value[node->keys - 1];
int i = 0;
if (overlaps(b, c*PAGE_SIZE, area->base, pages*PAGE_SIZE)) {
if (b + c*PAGE_SIZE <= start_free) {
/*
* The whole interval fits completely
* in the resized address space area.
*/
break;
}
/*
* Part of the interval corresponding to b and c
* overlaps with the resized address space area.
*/
cond = false; /* we are almost done */
i = (start_free - b) >> PAGE_WIDTH;
if (!used_space_remove(area, start_free, c - i))
panic("Could not remove used space.");
} else {
/*
* The interval of used space can be completely removed.
*/
if (!used_space_remove(area, b, c))
panic("Could not remove used space.\n");
}
for (; i < c; i++) {
pte_t *pte;
page_table_lock(as, false);
pte = page_mapping_find(as, b + i*PAGE_SIZE);
ASSERT(pte && PTE_VALID(pte) && PTE_PRESENT(pte));
if (area->backend && area->backend->frame_free) {
area->backend->frame_free(area,
b + i*PAGE_SIZE, PTE_GET_FRAME(pte));
}
page_mapping_remove(as, b + i*PAGE_SIZE);
page_table_unlock(as, false);
}
}
}
 
/*
* Finish TLB shootdown sequence.
*/
tlb_invalidate_pages(AS->asid, area->base + pages*PAGE_SIZE, area->pages - pages);
tlb_shootdown_finalize();
} else {
/*
* Growing the area.
* Check for overlaps with other address space areas.
*/
if (!check_area_conflicts(as, address, pages * PAGE_SIZE, area)) {
mutex_unlock(&area->lock);
mutex_unlock(&as->lock);
interrupts_restore(ipl);
return EADDRNOTAVAIL;
}
}
 
area->pages = pages;
mutex_unlock(&area->lock);
mutex_unlock(&as->lock);
interrupts_restore(ipl);
 
return 0;
}
 
/** Destroy address space area.
*
* @param as Address space.
* @param address Address withing the area to be deleted.
*
* @return Zero on success or a value from @ref errno.h on failure.
*/
int as_area_destroy(as_t *as, uintptr_t address)
{
as_area_t *area;
uintptr_t base;
link_t *cur;
ipl_t ipl;
 
ipl = interrupts_disable();
mutex_lock(&as->lock);
 
area = find_area_and_lock(as, address);
if (!area) {
mutex_unlock(&as->lock);
interrupts_restore(ipl);
return ENOENT;
}
 
base = area->base;
 
/*
* Start TLB shootdown sequence.
*/
tlb_shootdown_start(TLB_INVL_PAGES, AS->asid, area->base, area->pages);
 
/*
* Visit only the pages mapped by used_space B+tree.
*/
for (cur = area->used_space.leaf_head.next; cur != &area->used_space.leaf_head; cur = cur->next) {
btree_node_t *node;
int i;
node = list_get_instance(cur, btree_node_t, leaf_link);
for (i = 0; i < node->keys; i++) {
uintptr_t b = node->key[i];
count_t j;
pte_t *pte;
for (j = 0; j < (count_t) node->value[i]; j++) {
page_table_lock(as, false);
pte = page_mapping_find(as, b + j*PAGE_SIZE);
ASSERT(pte && PTE_VALID(pte) && PTE_PRESENT(pte));
if (area->backend && area->backend->frame_free) {
area->backend->frame_free(area,
b + j*PAGE_SIZE, PTE_GET_FRAME(pte));
}
page_mapping_remove(as, b + j*PAGE_SIZE);
page_table_unlock(as, false);
}
}
}
 
/*
* Finish TLB shootdown sequence.
*/
tlb_invalidate_pages(AS->asid, area->base, area->pages);
tlb_shootdown_finalize();
btree_destroy(&area->used_space);
 
area->attributes |= AS_AREA_ATTR_PARTIAL;
if (area->sh_info)
sh_info_remove_reference(area->sh_info);
mutex_unlock(&area->lock);
 
/*
* Remove the empty area from address space.
*/
btree_remove(&AS->as_area_btree, base, NULL);
free(area);
mutex_unlock(&AS->lock);
interrupts_restore(ipl);
return 0;
}
 
/** Share address space area with another or the same address space.
*
* Address space area mapping is shared with a new address space area.
* If the source address space area has not been shared so far,
* a new sh_info is created. The new address space area simply gets the
* sh_info of the source area. The process of duplicating the
* mapping is done through the backend share function.
*
* @param src_as Pointer to source address space.
* @param src_base Base address of the source address space area.
* @param acc_size Expected size of the source area.
* @param dst_as Pointer to destination address space.
* @param dst_base Target base address.
* @param dst_flags_mask Destination address space area flags mask.
*
* @return Zero on success or ENOENT if there is no such task or
* if there is no such address space area,
* EPERM if there was a problem in accepting the area or
* ENOMEM if there was a problem in allocating destination
* address space area. ENOTSUP is returned if an attempt
* to share non-anonymous address space area is detected.
*/
int as_area_share(as_t *src_as, uintptr_t src_base, size_t acc_size,
as_t *dst_as, uintptr_t dst_base, int dst_flags_mask)
{
ipl_t ipl;
int src_flags;
size_t src_size;
as_area_t *src_area, *dst_area;
share_info_t *sh_info;
mem_backend_t *src_backend;
mem_backend_data_t src_backend_data;
ipl = interrupts_disable();
mutex_lock(&src_as->lock);
src_area = find_area_and_lock(src_as, src_base);
if (!src_area) {
/*
* Could not find the source address space area.
*/
mutex_unlock(&src_as->lock);
interrupts_restore(ipl);
return ENOENT;
}
if (!src_area->backend || !src_area->backend->share) {
/*
* There is now backend or the backend does not
* know how to share the area.
*/
mutex_unlock(&src_area->lock);
mutex_unlock(&src_as->lock);
interrupts_restore(ipl);
return ENOTSUP;
}
src_size = src_area->pages * PAGE_SIZE;
src_flags = src_area->flags;
src_backend = src_area->backend;
src_backend_data = src_area->backend_data;
 
/* Share the cacheable flag from the original mapping */
if (src_flags & AS_AREA_CACHEABLE)
dst_flags_mask |= AS_AREA_CACHEABLE;
 
if (src_size != acc_size || (src_flags & dst_flags_mask) != dst_flags_mask) {
mutex_unlock(&src_area->lock);
mutex_unlock(&src_as->lock);
interrupts_restore(ipl);
return EPERM;
}
 
/*
* Now we are committed to sharing the area.
* First prepare the area for sharing.
* Then it will be safe to unlock it.
*/
sh_info = src_area->sh_info;
if (!sh_info) {
sh_info = (share_info_t *) malloc(sizeof(share_info_t), 0);
mutex_initialize(&sh_info->lock);
sh_info->refcount = 2;
btree_create(&sh_info->pagemap);
src_area->sh_info = sh_info;
} else {
mutex_lock(&sh_info->lock);
sh_info->refcount++;
mutex_unlock(&sh_info->lock);
}
 
src_area->backend->share(src_area);
 
mutex_unlock(&src_area->lock);
mutex_unlock(&src_as->lock);
 
/*
* Create copy of the source address space area.
* The destination area is created with AS_AREA_ATTR_PARTIAL
* attribute set which prevents race condition with
* preliminary as_page_fault() calls.
* The flags of the source area are masked against dst_flags_mask
* to support sharing in less privileged mode.
*/
dst_area = as_area_create(dst_as, dst_flags_mask, src_size, dst_base,
AS_AREA_ATTR_PARTIAL, src_backend, &src_backend_data);
if (!dst_area) {
/*
* Destination address space area could not be created.
*/
sh_info_remove_reference(sh_info);
interrupts_restore(ipl);
return ENOMEM;
}
/*
* Now the destination address space area has been
* fully initialized. Clear the AS_AREA_ATTR_PARTIAL
* attribute and set the sh_info.
*/
mutex_lock(&dst_area->lock);
dst_area->attributes &= ~AS_AREA_ATTR_PARTIAL;
dst_area->sh_info = sh_info;
mutex_unlock(&dst_area->lock);
interrupts_restore(ipl);
return 0;
}
 
/** Check access mode for address space area.
*
* The address space area must be locked prior to this call.
*
* @param area Address space area.
* @param access Access mode.
*
* @return False if access violates area's permissions, true otherwise.
*/
bool as_area_check_access(as_area_t *area, pf_access_t access)
{
int flagmap[] = {
[PF_ACCESS_READ] = AS_AREA_READ,
[PF_ACCESS_WRITE] = AS_AREA_WRITE,
[PF_ACCESS_EXEC] = AS_AREA_EXEC
};
 
if (!(area->flags & flagmap[access]))
return false;
return true;
}
 
/** Handle page fault within the current address space.
*
* This is the high-level page fault handler. It decides
* whether the page fault can be resolved by any backend
* and if so, it invokes the backend to resolve the page
* fault.
*
* Interrupts are assumed disabled.
*
* @param page Faulting page.
* @param access Access mode that caused the fault (i.e. read/write/exec).
* @param istate Pointer to interrupted state.
*
* @return AS_PF_FAULT on page fault, AS_PF_OK on success or AS_PF_DEFER if the
* fault was caused by copy_to_uspace() or copy_from_uspace().
*/
int as_page_fault(uintptr_t page, pf_access_t access, istate_t *istate)
{
pte_t *pte;
as_area_t *area;
if (!THREAD)
return AS_PF_FAULT;
ASSERT(AS);
 
mutex_lock(&AS->lock);
area = find_area_and_lock(AS, page);
if (!area) {
/*
* No area contained mapping for 'page'.
* Signal page fault to low-level handler.
*/
mutex_unlock(&AS->lock);
goto page_fault;
}
 
if (area->attributes & AS_AREA_ATTR_PARTIAL) {
/*
* The address space area is not fully initialized.
* Avoid possible race by returning error.
*/
mutex_unlock(&area->lock);
mutex_unlock(&AS->lock);
goto page_fault;
}
 
if (!area->backend || !area->backend->page_fault) {
/*
* The address space area is not backed by any backend
* or the backend cannot handle page faults.
*/
mutex_unlock(&area->lock);
mutex_unlock(&AS->lock);
goto page_fault;
}
 
page_table_lock(AS, false);
/*
* To avoid race condition between two page faults
* on the same address, we need to make sure
* the mapping has not been already inserted.
*/
if ((pte = page_mapping_find(AS, page))) {
if (PTE_PRESENT(pte)) {
if (((access == PF_ACCESS_READ) && PTE_READABLE(pte)) ||
(access == PF_ACCESS_WRITE && PTE_WRITABLE(pte)) ||
(access == PF_ACCESS_EXEC && PTE_EXECUTABLE(pte))) {
page_table_unlock(AS, false);
mutex_unlock(&area->lock);
mutex_unlock(&AS->lock);
return AS_PF_OK;
}
}
}
/*
* Resort to the backend page fault handler.
*/
if (area->backend->page_fault(area, page, access) != AS_PF_OK) {
page_table_unlock(AS, false);
mutex_unlock(&area->lock);
mutex_unlock(&AS->lock);
goto page_fault;
}
page_table_unlock(AS, false);
mutex_unlock(&area->lock);
mutex_unlock(&AS->lock);
return AS_PF_OK;
 
page_fault:
if (THREAD->in_copy_from_uspace) {
THREAD->in_copy_from_uspace = false;
istate_set_retaddr(istate, (uintptr_t) &memcpy_from_uspace_failover_address);
} else if (THREAD->in_copy_to_uspace) {
THREAD->in_copy_to_uspace = false;
istate_set_retaddr(istate, (uintptr_t) &memcpy_to_uspace_failover_address);
} else {
return AS_PF_FAULT;
}
 
return AS_PF_DEFER;
}
 
/** Switch address spaces.
*
* Note that this function cannot sleep as it is essentially a part of
* scheduling. Sleeping here would lead to deadlock on wakeup.
*
* @param old Old address space or NULL.
* @param new New address space.
*/
void as_switch(as_t *old, as_t *new)
{
ipl_t ipl;
bool needs_asid = false;
ipl = interrupts_disable();
spinlock_lock(&inactive_as_with_asid_lock);
 
/*
* First, take care of the old address space.
*/
if (old) {
mutex_lock_active(&old->lock);
ASSERT(old->cpu_refcount);
if((--old->cpu_refcount == 0) && (old != AS_KERNEL)) {
/*
* The old address space is no longer active on
* any processor. It can be appended to the
* list of inactive address spaces with assigned
* ASID.
*/
ASSERT(old->asid != ASID_INVALID);
list_append(&old->inactive_as_with_asid_link, &inactive_as_with_asid_head);
}
mutex_unlock(&old->lock);
}
 
/*
* Second, prepare the new address space.
*/
mutex_lock_active(&new->lock);
if ((new->cpu_refcount++ == 0) && (new != AS_KERNEL)) {
if (new->asid != ASID_INVALID)
list_remove(&new->inactive_as_with_asid_link);
else
needs_asid = true; /* defer call to asid_get() until new->lock is released */
}
SET_PTL0_ADDRESS(new->page_table);
mutex_unlock(&new->lock);
 
if (needs_asid) {
/*
* Allocation of new ASID was deferred
* until now in order to avoid deadlock.
*/
asid_t asid;
asid = asid_get();
mutex_lock_active(&new->lock);
new->asid = asid;
mutex_unlock(&new->lock);
}
spinlock_unlock(&inactive_as_with_asid_lock);
interrupts_restore(ipl);
/*
* Perform architecture-specific steps.
* (e.g. write ASID to hardware register etc.)
*/
as_install_arch(new);
AS = new;
}
 
/** Convert address space area flags to page flags.
*
* @param aflags Flags of some address space area.
*
* @return Flags to be passed to page_mapping_insert().
*/
int area_flags_to_page_flags(int aflags)
{
int flags;
 
flags = PAGE_USER | PAGE_PRESENT;
if (aflags & AS_AREA_READ)
flags |= PAGE_READ;
if (aflags & AS_AREA_WRITE)
flags |= PAGE_WRITE;
if (aflags & AS_AREA_EXEC)
flags |= PAGE_EXEC;
if (aflags & AS_AREA_CACHEABLE)
flags |= PAGE_CACHEABLE;
return flags;
}
 
/** Compute flags for virtual address translation subsytem.
*
* The address space area must be locked.
* Interrupts must be disabled.
*
* @param a Address space area.
*
* @return Flags to be used in page_mapping_insert().
*/
int as_area_get_flags(as_area_t *a)
{
return area_flags_to_page_flags(a->flags);
}
 
/** Create page table.
*
* Depending on architecture, create either address space
* private or global page table.
*
* @param flags Flags saying whether the page table is for kernel address space.
*
* @return First entry of the page table.
*/
pte_t *page_table_create(int flags)
{
ASSERT(as_operations);
ASSERT(as_operations->page_table_create);
 
return as_operations->page_table_create(flags);
}
 
/** Destroy page table.
*
* Destroy page table in architecture specific way.
*
* @param page_table Physical address of PTL0.
*/
void page_table_destroy(pte_t *page_table)
{
ASSERT(as_operations);
ASSERT(as_operations->page_table_destroy);
 
as_operations->page_table_destroy(page_table);
}
 
/** Lock page table.
*
* This function should be called before any page_mapping_insert(),
* page_mapping_remove() and page_mapping_find().
*
* Locking order is such that address space areas must be locked
* prior to this call. Address space can be locked prior to this
* call in which case the lock argument is false.
*
* @param as Address space.
* @param lock If false, do not attempt to lock as->lock.
*/
void page_table_lock(as_t *as, bool lock)
{
ASSERT(as_operations);
ASSERT(as_operations->page_table_lock);
 
as_operations->page_table_lock(as, lock);
}
 
/** Unlock page table.
*
* @param as Address space.
* @param unlock If false, do not attempt to unlock as->lock.
*/
void page_table_unlock(as_t *as, bool unlock)
{
ASSERT(as_operations);
ASSERT(as_operations->page_table_unlock);
 
as_operations->page_table_unlock(as, unlock);
}
 
 
/** Find address space area and lock it.
*
* The address space must be locked and interrupts must be disabled.
*
* @param as Address space.
* @param va Virtual address.
*
* @return Locked address space area containing va on success or NULL on failure.
*/
as_area_t *find_area_and_lock(as_t *as, uintptr_t va)
{
as_area_t *a;
btree_node_t *leaf, *lnode;
int i;
a = (as_area_t *) btree_search(&as->as_area_btree, va, &leaf);
if (a) {
/* va is the base address of an address space area */
mutex_lock(&a->lock);
return a;
}
/*
* Search the leaf node and the righmost record of its left neighbour
* to find out whether this is a miss or va belongs to an address
* space area found there.
*/
/* First, search the leaf node itself. */
for (i = 0; i < leaf->keys; i++) {
a = (as_area_t *) leaf->value[i];
mutex_lock(&a->lock);
if ((a->base <= va) && (va < a->base + a->pages * PAGE_SIZE)) {
return a;
}
mutex_unlock(&a->lock);
}
 
/*
* Second, locate the left neighbour and test its last record.
* Because of its position in the B+tree, it must have base < va.
*/
if ((lnode = btree_leaf_node_left_neighbour(&as->as_area_btree, leaf))) {
a = (as_area_t *) lnode->value[lnode->keys - 1];
mutex_lock(&a->lock);
if (va < a->base + a->pages * PAGE_SIZE) {
return a;
}
mutex_unlock(&a->lock);
}
 
return NULL;
}
 
/** Check area conflicts with other areas.
*
* The address space must be locked and interrupts must be disabled.
*
* @param as Address space.
* @param va Starting virtual address of the area being tested.
* @param size Size of the area being tested.
* @param avoid_area Do not touch this area.
*
* @return True if there is no conflict, false otherwise.
*/
bool check_area_conflicts(as_t *as, uintptr_t va, size_t size, as_area_t *avoid_area)
{
as_area_t *a;
btree_node_t *leaf, *node;
int i;
/*
* We don't want any area to have conflicts with NULL page.
*/
if (overlaps(va, size, NULL, PAGE_SIZE))
return false;
/*
* The leaf node is found in O(log n), where n is proportional to
* the number of address space areas belonging to as.
* The check for conflicts is then attempted on the rightmost
* record in the left neighbour, the leftmost record in the right
* neighbour and all records in the leaf node itself.
*/
if ((a = (as_area_t *) btree_search(&as->as_area_btree, va, &leaf))) {
if (a != avoid_area)
return false;
}
/* First, check the two border cases. */
if ((node = btree_leaf_node_left_neighbour(&as->as_area_btree, leaf))) {
a = (as_area_t *) node->value[node->keys - 1];
mutex_lock(&a->lock);
if (overlaps(va, size, a->base, a->pages * PAGE_SIZE)) {
mutex_unlock(&a->lock);
return false;
}
mutex_unlock(&a->lock);
}
if ((node = btree_leaf_node_right_neighbour(&as->as_area_btree, leaf))) {
a = (as_area_t *) node->value[0];
mutex_lock(&a->lock);
if (overlaps(va, size, a->base, a->pages * PAGE_SIZE)) {
mutex_unlock(&a->lock);
return false;
}
mutex_unlock(&a->lock);
}
/* Second, check the leaf node. */
for (i = 0; i < leaf->keys; i++) {
a = (as_area_t *) leaf->value[i];
if (a == avoid_area)
continue;
mutex_lock(&a->lock);
if (overlaps(va, size, a->base, a->pages * PAGE_SIZE)) {
mutex_unlock(&a->lock);
return false;
}
mutex_unlock(&a->lock);
}
 
/*
* So far, the area does not conflict with other areas.
* Check if it doesn't conflict with kernel address space.
*/
if (!KERNEL_ADDRESS_SPACE_SHADOWED) {
return !overlaps(va, size,
KERNEL_ADDRESS_SPACE_START, KERNEL_ADDRESS_SPACE_END-KERNEL_ADDRESS_SPACE_START);
}
 
return true;
}
 
/** Return size of the address space area with given base. */
size_t as_get_size(uintptr_t base)
{
ipl_t ipl;
as_area_t *src_area;
size_t size;
 
ipl = interrupts_disable();
src_area = find_area_and_lock(AS, base);
if (src_area){
size = src_area->pages * PAGE_SIZE;
mutex_unlock(&src_area->lock);
} else {
size = 0;
}
interrupts_restore(ipl);
return size;
}
 
/** Mark portion of address space area as used.
*
* The address space area must be already locked.
*
* @param a Address space area.
* @param page First page to be marked.
* @param count Number of page to be marked.
*
* @return 0 on failure and 1 on success.
*/
int used_space_insert(as_area_t *a, uintptr_t page, count_t count)
{
btree_node_t *leaf, *node;
count_t pages;
int i;
 
ASSERT(page == ALIGN_DOWN(page, PAGE_SIZE));
ASSERT(count);
 
pages = (count_t) btree_search(&a->used_space, page, &leaf);
if (pages) {
/*
* We hit the beginning of some used space.
*/
return 0;
}
 
if (!leaf->keys) {
btree_insert(&a->used_space, page, (void *) count, leaf);
return 1;
}
 
node = btree_leaf_node_left_neighbour(&a->used_space, leaf);
if (node) {
uintptr_t left_pg = node->key[node->keys - 1], right_pg = leaf->key[0];
count_t left_cnt = (count_t) node->value[node->keys - 1], right_cnt = (count_t) leaf->value[0];
/*
* Examine the possibility that the interval fits
* somewhere between the rightmost interval of
* the left neigbour and the first interval of the leaf.
*/
if (page >= right_pg) {
/* Do nothing. */
} else if (overlaps(page, count*PAGE_SIZE, left_pg, left_cnt*PAGE_SIZE)) {
/* The interval intersects with the left interval. */
return 0;
} else if (overlaps(page, count*PAGE_SIZE, right_pg, right_cnt*PAGE_SIZE)) {
/* The interval intersects with the right interval. */
return 0;
} else if ((page == left_pg + left_cnt*PAGE_SIZE) && (page + count*PAGE_SIZE == right_pg)) {
/* The interval can be added by merging the two already present intervals. */
node->value[node->keys - 1] += count + right_cnt;
btree_remove(&a->used_space, right_pg, leaf);
return 1;
} else if (page == left_pg + left_cnt*PAGE_SIZE) {
/* The interval can be added by simply growing the left interval. */
node->value[node->keys - 1] += count;
return 1;
} else if (page + count*PAGE_SIZE == right_pg) {
/*
* The interval can be addded by simply moving base of the right
* interval down and increasing its size accordingly.
*/
leaf->value[0] += count;
leaf->key[0] = page;
return 1;
} else {
/*
* The interval is between both neigbouring intervals,
* but cannot be merged with any of them.
*/
btree_insert(&a->used_space, page, (void *) count, leaf);
return 1;
}
} else if (page < leaf->key[0]) {
uintptr_t right_pg = leaf->key[0];
count_t right_cnt = (count_t) leaf->value[0];
/*
* Investigate the border case in which the left neighbour does not
* exist but the interval fits from the left.
*/
if (overlaps(page, count*PAGE_SIZE, right_pg, right_cnt*PAGE_SIZE)) {
/* The interval intersects with the right interval. */
return 0;
} else if (page + count*PAGE_SIZE == right_pg) {
/*
* The interval can be added by moving the base of the right interval down
* and increasing its size accordingly.
*/
leaf->key[0] = page;
leaf->value[0] += count;
return 1;
} else {
/*
* The interval doesn't adjoin with the right interval.
* It must be added individually.
*/
btree_insert(&a->used_space, page, (void *) count, leaf);
return 1;
}
}
 
node = btree_leaf_node_right_neighbour(&a->used_space, leaf);
if (node) {
uintptr_t left_pg = leaf->key[leaf->keys - 1], right_pg = node->key[0];
count_t left_cnt = (count_t) leaf->value[leaf->keys - 1], right_cnt = (count_t) node->value[0];
/*
* Examine the possibility that the interval fits
* somewhere between the leftmost interval of
* the right neigbour and the last interval of the leaf.
*/
 
if (page < left_pg) {
/* Do nothing. */
} else if (overlaps(page, count*PAGE_SIZE, left_pg, left_cnt*PAGE_SIZE)) {
/* The interval intersects with the left interval. */
return 0;
} else if (overlaps(page, count*PAGE_SIZE, right_pg, right_cnt*PAGE_SIZE)) {
/* The interval intersects with the right interval. */
return 0;
} else if ((page == left_pg + left_cnt*PAGE_SIZE) && (page + count*PAGE_SIZE == right_pg)) {
/* The interval can be added by merging the two already present intervals. */
leaf->value[leaf->keys - 1] += count + right_cnt;
btree_remove(&a->used_space, right_pg, node);
return 1;
} else if (page == left_pg + left_cnt*PAGE_SIZE) {
/* The interval can be added by simply growing the left interval. */
leaf->value[leaf->keys - 1] += count;
return 1;
} else if (page + count*PAGE_SIZE == right_pg) {
/*
* The interval can be addded by simply moving base of the right
* interval down and increasing its size accordingly.
*/
node->value[0] += count;
node->key[0] = page;
return 1;
} else {
/*
* The interval is between both neigbouring intervals,
* but cannot be merged with any of them.
*/
btree_insert(&a->used_space, page, (void *) count, leaf);
return 1;
}
} else if (page >= leaf->key[leaf->keys - 1]) {
uintptr_t left_pg = leaf->key[leaf->keys - 1];
count_t left_cnt = (count_t) leaf->value[leaf->keys - 1];
/*
* Investigate the border case in which the right neighbour does not
* exist but the interval fits from the right.
*/
if (overlaps(page, count*PAGE_SIZE, left_pg, left_cnt*PAGE_SIZE)) {
/* The interval intersects with the left interval. */
return 0;
} else if (left_pg + left_cnt*PAGE_SIZE == page) {
/* The interval can be added by growing the left interval. */
leaf->value[leaf->keys - 1] += count;
return 1;
} else {
/*
* The interval doesn't adjoin with the left interval.
* It must be added individually.
*/
btree_insert(&a->used_space, page, (void *) count, leaf);
return 1;
}
}
/*
* Note that if the algorithm made it thus far, the interval can fit only
* between two other intervals of the leaf. The two border cases were already
* resolved.
*/
for (i = 1; i < leaf->keys; i++) {
if (page < leaf->key[i]) {
uintptr_t left_pg = leaf->key[i - 1], right_pg = leaf->key[i];
count_t left_cnt = (count_t) leaf->value[i - 1], right_cnt = (count_t) leaf->value[i];
 
/*
* The interval fits between left_pg and right_pg.
*/
 
if (overlaps(page, count*PAGE_SIZE, left_pg, left_cnt*PAGE_SIZE)) {
/* The interval intersects with the left interval. */
return 0;
} else if (overlaps(page, count*PAGE_SIZE, right_pg, right_cnt*PAGE_SIZE)) {
/* The interval intersects with the right interval. */
return 0;
} else if ((page == left_pg + left_cnt*PAGE_SIZE) && (page + count*PAGE_SIZE == right_pg)) {
/* The interval can be added by merging the two already present intervals. */
leaf->value[i - 1] += count + right_cnt;
btree_remove(&a->used_space, right_pg, leaf);
return 1;
} else if (page == left_pg + left_cnt*PAGE_SIZE) {
/* The interval can be added by simply growing the left interval. */
leaf->value[i - 1] += count;
return 1;
} else if (page + count*PAGE_SIZE == right_pg) {
/*
* The interval can be addded by simply moving base of the right
* interval down and increasing its size accordingly.
*/
leaf->value[i] += count;
leaf->key[i] = page;
return 1;
} else {
/*
* The interval is between both neigbouring intervals,
* but cannot be merged with any of them.
*/
btree_insert(&a->used_space, page, (void *) count, leaf);
return 1;
}
}
}
 
panic("Inconsistency detected while adding %d pages of used space at %p.\n", count, page);
}
 
/** Mark portion of address space area as unused.
*
* The address space area must be already locked.
*
* @param a Address space area.
* @param page First page to be marked.
* @param count Number of page to be marked.
*
* @return 0 on failure and 1 on success.
*/
int used_space_remove(as_area_t *a, uintptr_t page, count_t count)
{
btree_node_t *leaf, *node;
count_t pages;
int i;
 
ASSERT(page == ALIGN_DOWN(page, PAGE_SIZE));
ASSERT(count);
 
pages = (count_t) btree_search(&a->used_space, page, &leaf);
if (pages) {
/*
* We are lucky, page is the beginning of some interval.
*/
if (count > pages) {
return 0;
} else if (count == pages) {
btree_remove(&a->used_space, page, leaf);
return 1;
} else {
/*
* Find the respective interval.
* Decrease its size and relocate its start address.
*/
for (i = 0; i < leaf->keys; i++) {
if (leaf->key[i] == page) {
leaf->key[i] += count*PAGE_SIZE;
leaf->value[i] -= count;
return 1;
}
}
goto error;
}
}
 
node = btree_leaf_node_left_neighbour(&a->used_space, leaf);
if (node && page < leaf->key[0]) {
uintptr_t left_pg = node->key[node->keys - 1];
count_t left_cnt = (count_t) node->value[node->keys - 1];
 
if (overlaps(left_pg, left_cnt*PAGE_SIZE, page, count*PAGE_SIZE)) {
if (page + count*PAGE_SIZE == left_pg + left_cnt*PAGE_SIZE) {
/*
* The interval is contained in the rightmost interval
* of the left neighbour and can be removed by
* updating the size of the bigger interval.
*/
node->value[node->keys - 1] -= count;
return 1;
} else if (page + count*PAGE_SIZE < left_pg + left_cnt*PAGE_SIZE) {
count_t new_cnt;
/*
* The interval is contained in the rightmost interval
* of the left neighbour but its removal requires
* both updating the size of the original interval and
* also inserting a new interval.
*/
new_cnt = ((left_pg + left_cnt*PAGE_SIZE) - (page + count*PAGE_SIZE)) >> PAGE_WIDTH;
node->value[node->keys - 1] -= count + new_cnt;
btree_insert(&a->used_space, page + count*PAGE_SIZE, (void *) new_cnt, leaf);
return 1;
}
}
return 0;
} else if (page < leaf->key[0]) {
return 0;
}
if (page > leaf->key[leaf->keys - 1]) {
uintptr_t left_pg = leaf->key[leaf->keys - 1];
count_t left_cnt = (count_t) leaf->value[leaf->keys - 1];
 
if (overlaps(left_pg, left_cnt*PAGE_SIZE, page, count*PAGE_SIZE)) {
if (page + count*PAGE_SIZE == left_pg + left_cnt*PAGE_SIZE) {
/*
* The interval is contained in the rightmost interval
* of the leaf and can be removed by updating the size
* of the bigger interval.
*/
leaf->value[leaf->keys - 1] -= count;
return 1;
} else if (page + count*PAGE_SIZE < left_pg + left_cnt*PAGE_SIZE) {
count_t new_cnt;
/*
* The interval is contained in the rightmost interval
* of the leaf but its removal requires both updating
* the size of the original interval and
* also inserting a new interval.
*/
new_cnt = ((left_pg + left_cnt*PAGE_SIZE) - (page + count*PAGE_SIZE)) >> PAGE_WIDTH;
leaf->value[leaf->keys - 1] -= count + new_cnt;
btree_insert(&a->used_space, page + count*PAGE_SIZE, (void *) new_cnt, leaf);
return 1;
}
}
return 0;
}
/*
* The border cases have been already resolved.
* Now the interval can be only between intervals of the leaf.
*/
for (i = 1; i < leaf->keys - 1; i++) {
if (page < leaf->key[i]) {
uintptr_t left_pg = leaf->key[i - 1];
count_t left_cnt = (count_t) leaf->value[i - 1];
 
/*
* Now the interval is between intervals corresponding to (i - 1) and i.
*/
if (overlaps(left_pg, left_cnt*PAGE_SIZE, page, count*PAGE_SIZE)) {
if (page + count*PAGE_SIZE == left_pg + left_cnt*PAGE_SIZE) {
/*
* The interval is contained in the interval (i - 1)
* of the leaf and can be removed by updating the size
* of the bigger interval.
*/
leaf->value[i - 1] -= count;
return 1;
} else if (page + count*PAGE_SIZE < left_pg + left_cnt*PAGE_SIZE) {
count_t new_cnt;
/*
* The interval is contained in the interval (i - 1)
* of the leaf but its removal requires both updating
* the size of the original interval and
* also inserting a new interval.
*/
new_cnt = ((left_pg + left_cnt*PAGE_SIZE) - (page + count*PAGE_SIZE)) >> PAGE_WIDTH;
leaf->value[i - 1] -= count + new_cnt;
btree_insert(&a->used_space, page + count*PAGE_SIZE, (void *) new_cnt, leaf);
return 1;
}
}
return 0;
}
}
 
error:
panic("Inconsistency detected while removing %d pages of used space from %p.\n", count, page);
}
 
/** Remove reference to address space area share info.
*
* If the reference count drops to 0, the sh_info is deallocated.
*
* @param sh_info Pointer to address space area share info.
*/
void sh_info_remove_reference(share_info_t *sh_info)
{
bool dealloc = false;
 
mutex_lock(&sh_info->lock);
ASSERT(sh_info->refcount);
if (--sh_info->refcount == 0) {
dealloc = true;
link_t *cur;
/*
* Now walk carefully the pagemap B+tree and free/remove
* reference from all frames found there.
*/
for (cur = sh_info->pagemap.leaf_head.next; cur != &sh_info->pagemap.leaf_head; cur = cur->next) {
btree_node_t *node;
int i;
node = list_get_instance(cur, btree_node_t, leaf_link);
for (i = 0; i < node->keys; i++)
frame_free((uintptr_t) node->value[i]);
}
}
mutex_unlock(&sh_info->lock);
if (dealloc) {
btree_destroy(&sh_info->pagemap);
free(sh_info);
}
}
 
/*
* Address space related syscalls.
*/
 
/** Wrapper for as_area_create(). */
unative_t sys_as_area_create(uintptr_t address, size_t size, int flags)
{
if (as_area_create(AS, flags | AS_AREA_CACHEABLE, size, address, AS_AREA_ATTR_NONE, &anon_backend, NULL))
return (unative_t) address;
else
return (unative_t) -1;
}
 
/** Wrapper for as_area_resize(). */
unative_t sys_as_area_resize(uintptr_t address, size_t size, int flags)
{
return (unative_t) as_area_resize(AS, address, size, 0);
}
 
/** Wrapper for as_area_destroy(). */
unative_t sys_as_area_destroy(uintptr_t address)
{
return (unative_t) as_area_destroy(AS, address);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/mm/slab.c
0,0 → 1,909
/*
* Copyright (C) 2006 Ondrej Palkovsky
* 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 genericmm
* @{
*/
 
/**
* @file
* @brief Slab allocator.
*
* The slab allocator is closely modelled after OpenSolaris slab allocator.
* @see http://www.usenix.org/events/usenix01/full_papers/bonwick/bonwick_html/
*
* with the following exceptions:
* @li empty slabs are deallocated immediately
* (in Linux they are kept in linked list, in Solaris ???)
* @li empty magazines are deallocated when not needed
* (in Solaris they are held in linked list in slab cache)
*
* Following features are not currently supported but would be easy to do:
* @li cache coloring
* @li dynamic magazine growing (different magazine sizes are already
* supported, but we would need to adjust allocation strategy)
*
* The slab allocator supports per-CPU caches ('magazines') to facilitate
* good SMP scaling.
*
* When a new object is being allocated, it is first checked, if it is
* available in a CPU-bound magazine. If it is not found there, it is
* allocated from a CPU-shared slab - if a partially full one is found,
* it is used, otherwise a new one is allocated.
*
* When an object is being deallocated, it is put to a CPU-bound magazine.
* If there is no such magazine, a new one is allocated (if this fails,
* the object is deallocated into slab). If the magazine is full, it is
* put into cpu-shared list of magazines and a new one is allocated.
*
* The CPU-bound magazine is actually a pair of magazines in order to avoid
* thrashing when somebody is allocating/deallocating 1 item at the magazine
* size boundary. LIFO order is enforced, which should avoid fragmentation
* as much as possible.
*
* Every cache contains list of full slabs and list of partially full slabs.
* Empty slabs are immediately freed (thrashing will be avoided because
* of magazines).
*
* The slab information structure is kept inside the data area, if possible.
* The cache can be marked that it should not use magazines. This is used
* only for slab related caches to avoid deadlocks and infinite recursion
* (the slab allocator uses itself for allocating all it's control structures).
*
* The slab allocator allocates a lot of space and does not free it. When
* the frame allocator fails to allocate a frame, it calls slab_reclaim().
* It tries 'light reclaim' first, then brutal reclaim. The light reclaim
* releases slabs from cpu-shared magazine-list, until at least 1 slab
* is deallocated in each cache (this algorithm should probably change).
* The brutal reclaim removes all cached objects, even from CPU-bound
* magazines.
*
* @todo
* For better CPU-scaling the magazine allocation strategy should
* be extended. Currently, if the cache does not have magazine, it asks
* for non-cpu cached magazine cache to provide one. It might be feasible
* to add cpu-cached magazine cache (which would allocate it's magazines
* from non-cpu-cached mag. cache). This would provide a nice per-cpu
* buffer. The other possibility is to use the per-cache
* 'empty-magazine-list', which decreases competing for 1 per-system
* magazine cache.
*
* @todo
* it might be good to add granularity of locks even to slab level,
* we could then try_spinlock over all partial slabs and thus improve
* scalability even on slab level
*/
 
#include <synch/spinlock.h>
#include <mm/slab.h>
#include <adt/list.h>
#include <memstr.h>
#include <align.h>
#include <mm/frame.h>
#include <config.h>
#include <print.h>
#include <arch.h>
#include <panic.h>
#include <debug.h>
#include <bitops.h>
 
SPINLOCK_INITIALIZE(slab_cache_lock);
static LIST_INITIALIZE(slab_cache_list);
 
/** Magazine cache */
static slab_cache_t mag_cache;
/** Cache for cache descriptors */
static slab_cache_t slab_cache_cache;
/** Cache for external slab descriptors
* This time we want per-cpu cache, so do not make it static
* - using slab for internal slab structures will not deadlock,
* as all slab structures are 'small' - control structures of
* their caches do not require further allocation
*/
static slab_cache_t *slab_extern_cache;
/** Caches for malloc */
static slab_cache_t *malloc_caches[SLAB_MAX_MALLOC_W-SLAB_MIN_MALLOC_W+1];
char *malloc_names[] = {
"malloc-16","malloc-32","malloc-64","malloc-128",
"malloc-256","malloc-512","malloc-1K","malloc-2K",
"malloc-4K","malloc-8K","malloc-16K","malloc-32K",
"malloc-64K","malloc-128K","malloc-256K"
};
 
/** Slab descriptor */
typedef struct {
slab_cache_t *cache; /**< Pointer to parent cache */
link_t link; /* List of full/partial slabs */
void *start; /**< Start address of first available item */
count_t available; /**< Count of available items in this slab */
index_t nextavail; /**< The index of next available item */
}slab_t;
 
#ifdef CONFIG_DEBUG
static int _slab_initialized = 0;
#endif
 
/**************************************/
/* Slab allocation functions */
 
/**
* Allocate frames for slab space and initialize
*
*/
static slab_t * slab_space_alloc(slab_cache_t *cache, int flags)
{
void *data;
slab_t *slab;
size_t fsize;
int i;
int zone=0;
data = frame_alloc_generic(cache->order, FRAME_KA | flags, &zone);
if (!data) {
return NULL;
}
if (! (cache->flags & SLAB_CACHE_SLINSIDE)) {
slab = slab_alloc(slab_extern_cache, flags);
if (!slab) {
frame_free(KA2PA(data));
return NULL;
}
} else {
fsize = (PAGE_SIZE << cache->order);
slab = data + fsize - sizeof(*slab);
}
/* Fill in slab structures */
for (i=0; i < (1 << cache->order); i++)
frame_set_parent(ADDR2PFN(KA2PA(data))+i, slab, zone);
 
slab->start = data;
slab->available = cache->objects;
slab->nextavail = 0;
slab->cache = cache;
 
for (i=0; i<cache->objects;i++)
*((int *) (slab->start + i*cache->size)) = i+1;
 
atomic_inc(&cache->allocated_slabs);
return slab;
}
 
/**
* Deallocate space associated with slab
*
* @return number of freed frames
*/
static count_t slab_space_free(slab_cache_t *cache, slab_t *slab)
{
frame_free(KA2PA(slab->start));
if (! (cache->flags & SLAB_CACHE_SLINSIDE))
slab_free(slab_extern_cache, slab);
 
atomic_dec(&cache->allocated_slabs);
return 1 << cache->order;
}
 
/** Map object to slab structure */
static slab_t * obj2slab(void *obj)
{
return (slab_t *)frame_get_parent(ADDR2PFN(KA2PA(obj)), 0);
}
 
/**************************************/
/* Slab functions */
 
 
/**
* Return object to slab and call a destructor
*
* @param slab If the caller knows directly slab of the object, otherwise NULL
*
* @return Number of freed pages
*/
static count_t slab_obj_destroy(slab_cache_t *cache, void *obj,
slab_t *slab)
{
int freed = 0;
 
if (!slab)
slab = obj2slab(obj);
 
ASSERT(slab->cache == cache);
 
if (cache->destructor)
freed = cache->destructor(obj);
spinlock_lock(&cache->slablock);
ASSERT(slab->available < cache->objects);
 
*((int *)obj) = slab->nextavail;
slab->nextavail = (obj - slab->start)/cache->size;
slab->available++;
 
/* Move it to correct list */
if (slab->available == cache->objects) {
/* Free associated memory */
list_remove(&slab->link);
spinlock_unlock(&cache->slablock);
 
return freed + slab_space_free(cache, slab);
 
} else if (slab->available == 1) {
/* It was in full, move to partial */
list_remove(&slab->link);
list_prepend(&slab->link, &cache->partial_slabs);
}
spinlock_unlock(&cache->slablock);
return freed;
}
 
/**
* Take new object from slab or create new if needed
*
* @return Object address or null
*/
static void * slab_obj_create(slab_cache_t *cache, int flags)
{
slab_t *slab;
void *obj;
 
spinlock_lock(&cache->slablock);
 
if (list_empty(&cache->partial_slabs)) {
/* Allow recursion and reclaiming
* - this should work, as the slab control structures
* are small and do not need to allocate with anything
* other than frame_alloc when they are allocating,
* that's why we should get recursion at most 1-level deep
*/
spinlock_unlock(&cache->slablock);
slab = slab_space_alloc(cache, flags);
if (!slab)
return NULL;
spinlock_lock(&cache->slablock);
} else {
slab = list_get_instance(cache->partial_slabs.next,
slab_t,
link);
list_remove(&slab->link);
}
obj = slab->start + slab->nextavail * cache->size;
slab->nextavail = *((int *)obj);
slab->available--;
 
if (! slab->available)
list_prepend(&slab->link, &cache->full_slabs);
else
list_prepend(&slab->link, &cache->partial_slabs);
 
spinlock_unlock(&cache->slablock);
 
if (cache->constructor && cache->constructor(obj, flags)) {
/* Bad, bad, construction failed */
slab_obj_destroy(cache, obj, slab);
return NULL;
}
return obj;
}
 
/**************************************/
/* CPU-Cache slab functions */
 
/**
* Finds a full magazine in cache, takes it from list
* and returns it
*
* @param first If true, return first, else last mag
*/
static slab_magazine_t * get_mag_from_cache(slab_cache_t *cache,
int first)
{
slab_magazine_t *mag = NULL;
link_t *cur;
 
spinlock_lock(&cache->maglock);
if (!list_empty(&cache->magazines)) {
if (first)
cur = cache->magazines.next;
else
cur = cache->magazines.prev;
mag = list_get_instance(cur, slab_magazine_t, link);
list_remove(&mag->link);
atomic_dec(&cache->magazine_counter);
}
spinlock_unlock(&cache->maglock);
return mag;
}
 
/** Prepend magazine to magazine list in cache */
static void put_mag_to_cache(slab_cache_t *cache, slab_magazine_t *mag)
{
spinlock_lock(&cache->maglock);
 
list_prepend(&mag->link, &cache->magazines);
atomic_inc(&cache->magazine_counter);
spinlock_unlock(&cache->maglock);
}
 
/**
* Free all objects in magazine and free memory associated with magazine
*
* @return Number of freed pages
*/
static count_t magazine_destroy(slab_cache_t *cache,
slab_magazine_t *mag)
{
int i;
count_t frames = 0;
 
for (i=0;i < mag->busy; i++) {
frames += slab_obj_destroy(cache, mag->objs[i], NULL);
atomic_dec(&cache->cached_objs);
}
slab_free(&mag_cache, mag);
 
return frames;
}
 
/**
* Find full magazine, set it as current and return it
*
* Assume cpu_magazine lock is held
*/
static slab_magazine_t * get_full_current_mag(slab_cache_t *cache)
{
slab_magazine_t *cmag, *lastmag, *newmag;
 
cmag = cache->mag_cache[CPU->id].current;
lastmag = cache->mag_cache[CPU->id].last;
if (cmag) { /* First try local CPU magazines */
if (cmag->busy)
return cmag;
 
if (lastmag && lastmag->busy) {
cache->mag_cache[CPU->id].current = lastmag;
cache->mag_cache[CPU->id].last = cmag;
return lastmag;
}
}
/* Local magazines are empty, import one from magazine list */
newmag = get_mag_from_cache(cache, 1);
if (!newmag)
return NULL;
 
if (lastmag)
magazine_destroy(cache, lastmag);
 
cache->mag_cache[CPU->id].last = cmag;
cache->mag_cache[CPU->id].current = newmag;
return newmag;
}
 
/**
* Try to find object in CPU-cache magazines
*
* @return Pointer to object or NULL if not available
*/
static void * magazine_obj_get(slab_cache_t *cache)
{
slab_magazine_t *mag;
void *obj;
 
if (!CPU)
return NULL;
 
spinlock_lock(&cache->mag_cache[CPU->id].lock);
 
mag = get_full_current_mag(cache);
if (!mag) {
spinlock_unlock(&cache->mag_cache[CPU->id].lock);
return NULL;
}
obj = mag->objs[--mag->busy];
spinlock_unlock(&cache->mag_cache[CPU->id].lock);
atomic_dec(&cache->cached_objs);
return obj;
}
 
/**
* Assure that the current magazine is empty, return pointer to it, or NULL if
* no empty magazine is available and cannot be allocated
*
* Assume mag_cache[CPU->id].lock is held
*
* We have 2 magazines bound to processor.
* First try the current.
* If full, try the last.
* If full, put to magazines list.
* allocate new, exchange last & current
*
*/
static slab_magazine_t * make_empty_current_mag(slab_cache_t *cache)
{
slab_magazine_t *cmag,*lastmag,*newmag;
 
cmag = cache->mag_cache[CPU->id].current;
lastmag = cache->mag_cache[CPU->id].last;
 
if (cmag) {
if (cmag->busy < cmag->size)
return cmag;
if (lastmag && lastmag->busy < lastmag->size) {
cache->mag_cache[CPU->id].last = cmag;
cache->mag_cache[CPU->id].current = lastmag;
return lastmag;
}
}
/* current | last are full | nonexistent, allocate new */
/* We do not want to sleep just because of caching */
/* Especially we do not want reclaiming to start, as
* this would deadlock */
newmag = slab_alloc(&mag_cache, FRAME_ATOMIC | FRAME_NO_RECLAIM);
if (!newmag)
return NULL;
newmag->size = SLAB_MAG_SIZE;
newmag->busy = 0;
 
/* Flush last to magazine list */
if (lastmag)
put_mag_to_cache(cache, lastmag);
 
/* Move current as last, save new as current */
cache->mag_cache[CPU->id].last = cmag;
cache->mag_cache[CPU->id].current = newmag;
 
return newmag;
}
 
/**
* Put object into CPU-cache magazine
*
* @return 0 - success, -1 - could not get memory
*/
static int magazine_obj_put(slab_cache_t *cache, void *obj)
{
slab_magazine_t *mag;
 
if (!CPU)
return -1;
 
spinlock_lock(&cache->mag_cache[CPU->id].lock);
 
mag = make_empty_current_mag(cache);
if (!mag) {
spinlock_unlock(&cache->mag_cache[CPU->id].lock);
return -1;
}
mag->objs[mag->busy++] = obj;
 
spinlock_unlock(&cache->mag_cache[CPU->id].lock);
atomic_inc(&cache->cached_objs);
return 0;
}
 
 
/**************************************/
/* Slab cache functions */
 
/** Return number of objects that fit in certain cache size */
static int comp_objects(slab_cache_t *cache)
{
if (cache->flags & SLAB_CACHE_SLINSIDE)
return ((PAGE_SIZE << cache->order) - sizeof(slab_t)) / cache->size;
else
return (PAGE_SIZE << cache->order) / cache->size;
}
 
/** Return wasted space in slab */
static int badness(slab_cache_t *cache)
{
int objects;
int ssize;
 
objects = comp_objects(cache);
ssize = PAGE_SIZE << cache->order;
if (cache->flags & SLAB_CACHE_SLINSIDE)
ssize -= sizeof(slab_t);
return ssize - objects*cache->size;
}
 
/**
* Initialize mag_cache structure in slab cache
*/
static void make_magcache(slab_cache_t *cache)
{
int i;
ASSERT(_slab_initialized >= 2);
 
cache->mag_cache = malloc(sizeof(slab_mag_cache_t)*config.cpu_count,0);
for (i=0; i < config.cpu_count; i++) {
memsetb((uintptr_t)&cache->mag_cache[i],
sizeof(cache->mag_cache[i]), 0);
spinlock_initialize(&cache->mag_cache[i].lock,
"slab_maglock_cpu");
}
}
 
/** Initialize allocated memory as a slab cache */
static void
_slab_cache_create(slab_cache_t *cache,
char *name,
size_t size,
size_t align,
int (*constructor)(void *obj, int kmflag),
int (*destructor)(void *obj),
int flags)
{
int pages;
ipl_t ipl;
 
memsetb((uintptr_t)cache, sizeof(*cache), 0);
cache->name = name;
 
if (align < sizeof(unative_t))
align = sizeof(unative_t);
size = ALIGN_UP(size, align);
cache->size = size;
 
cache->constructor = constructor;
cache->destructor = destructor;
cache->flags = flags;
 
list_initialize(&cache->full_slabs);
list_initialize(&cache->partial_slabs);
list_initialize(&cache->magazines);
spinlock_initialize(&cache->slablock, "slab_lock");
spinlock_initialize(&cache->maglock, "slab_maglock");
if (! (cache->flags & SLAB_CACHE_NOMAGAZINE))
make_magcache(cache);
 
/* Compute slab sizes, object counts in slabs etc. */
if (cache->size < SLAB_INSIDE_SIZE)
cache->flags |= SLAB_CACHE_SLINSIDE;
 
/* Minimum slab order */
pages = SIZE2FRAMES(cache->size);
/* We need the 2^order >= pages */
if (pages == 1)
cache->order = 0;
else
cache->order = fnzb(pages-1)+1;
 
while (badness(cache) > SLAB_MAX_BADNESS(cache)) {
cache->order += 1;
}
cache->objects = comp_objects(cache);
/* If info fits in, put it inside */
if (badness(cache) > sizeof(slab_t))
cache->flags |= SLAB_CACHE_SLINSIDE;
 
/* Add cache to cache list */
ipl = interrupts_disable();
spinlock_lock(&slab_cache_lock);
 
list_append(&cache->link, &slab_cache_list);
 
spinlock_unlock(&slab_cache_lock);
interrupts_restore(ipl);
}
 
/** Create slab cache */
slab_cache_t * slab_cache_create(char *name,
size_t size,
size_t align,
int (*constructor)(void *obj, int kmflag),
int (*destructor)(void *obj),
int flags)
{
slab_cache_t *cache;
 
cache = slab_alloc(&slab_cache_cache, 0);
_slab_cache_create(cache, name, size, align, constructor, destructor,
flags);
return cache;
}
 
/**
* Reclaim space occupied by objects that are already free
*
* @param flags If contains SLAB_RECLAIM_ALL, do aggressive freeing
* @return Number of freed pages
*/
static count_t _slab_reclaim(slab_cache_t *cache, int flags)
{
int i;
slab_magazine_t *mag;
count_t frames = 0;
int magcount;
if (cache->flags & SLAB_CACHE_NOMAGAZINE)
return 0; /* Nothing to do */
 
/* We count up to original magazine count to avoid
* endless loop
*/
magcount = atomic_get(&cache->magazine_counter);
while (magcount-- && (mag=get_mag_from_cache(cache,0))) {
frames += magazine_destroy(cache,mag);
if (!(flags & SLAB_RECLAIM_ALL) && frames)
break;
}
if (flags & SLAB_RECLAIM_ALL) {
/* Free cpu-bound magazines */
/* Destroy CPU magazines */
for (i=0; i<config.cpu_count; i++) {
spinlock_lock(&cache->mag_cache[i].lock);
 
mag = cache->mag_cache[i].current;
if (mag)
frames += magazine_destroy(cache, mag);
cache->mag_cache[i].current = NULL;
mag = cache->mag_cache[i].last;
if (mag)
frames += magazine_destroy(cache, mag);
cache->mag_cache[i].last = NULL;
 
spinlock_unlock(&cache->mag_cache[i].lock);
}
}
 
return frames;
}
 
/** Check that there are no slabs and remove cache from system */
void slab_cache_destroy(slab_cache_t *cache)
{
ipl_t ipl;
 
/* First remove cache from link, so that we don't need
* to disable interrupts later
*/
 
ipl = interrupts_disable();
spinlock_lock(&slab_cache_lock);
 
list_remove(&cache->link);
 
spinlock_unlock(&slab_cache_lock);
interrupts_restore(ipl);
 
/* Do not lock anything, we assume the software is correct and
* does not touch the cache when it decides to destroy it */
/* Destroy all magazines */
_slab_reclaim(cache, SLAB_RECLAIM_ALL);
 
/* All slabs must be empty */
if (!list_empty(&cache->full_slabs) \
|| !list_empty(&cache->partial_slabs))
panic("Destroying cache that is not empty.");
 
if (!(cache->flags & SLAB_CACHE_NOMAGAZINE))
free(cache->mag_cache);
slab_free(&slab_cache_cache, cache);
}
 
/** Allocate new object from cache - if no flags given, always returns
memory */
void * slab_alloc(slab_cache_t *cache, int flags)
{
ipl_t ipl;
void *result = NULL;
/* Disable interrupts to avoid deadlocks with interrupt handlers */
ipl = interrupts_disable();
 
if (!(cache->flags & SLAB_CACHE_NOMAGAZINE)) {
result = magazine_obj_get(cache);
}
if (!result)
result = slab_obj_create(cache, flags);
 
interrupts_restore(ipl);
 
if (result)
atomic_inc(&cache->allocated_objs);
 
return result;
}
 
/** Return object to cache, use slab if known */
static void _slab_free(slab_cache_t *cache, void *obj, slab_t *slab)
{
ipl_t ipl;
 
ipl = interrupts_disable();
 
if ((cache->flags & SLAB_CACHE_NOMAGAZINE) \
|| magazine_obj_put(cache, obj)) {
 
slab_obj_destroy(cache, obj, slab);
 
}
interrupts_restore(ipl);
atomic_dec(&cache->allocated_objs);
}
 
/** Return slab object to cache */
void slab_free(slab_cache_t *cache, void *obj)
{
_slab_free(cache,obj,NULL);
}
 
/* Go through all caches and reclaim what is possible */
count_t slab_reclaim(int flags)
{
slab_cache_t *cache;
link_t *cur;
count_t frames = 0;
 
spinlock_lock(&slab_cache_lock);
 
/* TODO: Add assert, that interrupts are disabled, otherwise
* memory allocation from interrupts can deadlock.
*/
 
for (cur = slab_cache_list.next;cur!=&slab_cache_list; cur=cur->next) {
cache = list_get_instance(cur, slab_cache_t, link);
frames += _slab_reclaim(cache, flags);
}
 
spinlock_unlock(&slab_cache_lock);
 
return frames;
}
 
 
/* Print list of slabs */
void slab_print_list(void)
{
slab_cache_t *cache;
link_t *cur;
ipl_t ipl;
ipl = interrupts_disable();
spinlock_lock(&slab_cache_lock);
printf("slab name\t Osize\t Pages\t Obj/pg\t Slabs\t Cached\tAllocobjs\tCtl\n");
for (cur = slab_cache_list.next;cur!=&slab_cache_list; cur=cur->next) {
cache = list_get_instance(cur, slab_cache_t, link);
printf("%s\t%7zd\t%7zd\t%7zd\t%7zd\t%7zd\t%7zd\t\t%s\n", cache->name, cache->size,
(1 << cache->order), cache->objects,
atomic_get(&cache->allocated_slabs),
atomic_get(&cache->cached_objs),
atomic_get(&cache->allocated_objs),
cache->flags & SLAB_CACHE_SLINSIDE ? "In" : "Out");
}
spinlock_unlock(&slab_cache_lock);
interrupts_restore(ipl);
}
 
void slab_cache_init(void)
{
int i, size;
 
/* Initialize magazine cache */
_slab_cache_create(&mag_cache,
"slab_magazine",
sizeof(slab_magazine_t)+SLAB_MAG_SIZE*sizeof(void*),
sizeof(uintptr_t),
NULL, NULL,
SLAB_CACHE_NOMAGAZINE | SLAB_CACHE_SLINSIDE);
/* Initialize slab_cache cache */
_slab_cache_create(&slab_cache_cache,
"slab_cache",
sizeof(slab_cache_cache),
sizeof(uintptr_t),
NULL, NULL,
SLAB_CACHE_NOMAGAZINE | SLAB_CACHE_SLINSIDE);
/* Initialize external slab cache */
slab_extern_cache = slab_cache_create("slab_extern",
sizeof(slab_t),
0, NULL, NULL,
SLAB_CACHE_SLINSIDE | SLAB_CACHE_MAGDEFERRED);
 
/* Initialize structures for malloc */
for (i=0, size=(1<<SLAB_MIN_MALLOC_W);
i < (SLAB_MAX_MALLOC_W-SLAB_MIN_MALLOC_W+1);
i++, size <<= 1) {
malloc_caches[i] = slab_cache_create(malloc_names[i],
size, 0,
NULL,NULL, SLAB_CACHE_MAGDEFERRED);
}
#ifdef CONFIG_DEBUG
_slab_initialized = 1;
#endif
}
 
/** Enable cpu_cache
*
* Kernel calls this function, when it knows the real number of
* processors.
* Allocate slab for cpucache and enable it on all existing
* slabs that are SLAB_CACHE_MAGDEFERRED
*/
void slab_enable_cpucache(void)
{
link_t *cur;
slab_cache_t *s;
 
#ifdef CONFIG_DEBUG
_slab_initialized = 2;
#endif
 
spinlock_lock(&slab_cache_lock);
for (cur=slab_cache_list.next; cur != &slab_cache_list;cur=cur->next){
s = list_get_instance(cur, slab_cache_t, link);
if ((s->flags & SLAB_CACHE_MAGDEFERRED) != SLAB_CACHE_MAGDEFERRED)
continue;
make_magcache(s);
s->flags &= ~SLAB_CACHE_MAGDEFERRED;
}
 
spinlock_unlock(&slab_cache_lock);
}
 
/**************************************/
/* kalloc/kfree functions */
void * malloc(unsigned int size, int flags)
{
int idx;
 
ASSERT(_slab_initialized);
ASSERT(size && size <= (1 << SLAB_MAX_MALLOC_W));
if (size < (1 << SLAB_MIN_MALLOC_W))
size = (1 << SLAB_MIN_MALLOC_W);
 
idx = fnzb(size-1) - SLAB_MIN_MALLOC_W + 1;
 
return slab_alloc(malloc_caches[idx], flags);
}
 
void free(void *obj)
{
slab_t *slab;
 
if (!obj) return;
 
slab = obj2slab(obj);
_slab_free(slab->cache, obj, slab);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/mm/tlb.c
0,0 → 1,189
/*
* 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 genericmm
* @{
*/
 
/**
* @file
* @brief Generic TLB shootdown algorithm.
*
* The algorithm implemented here is based on the CMU TLB shootdown
* algorithm and is further simplified (e.g. all CPUs receive all TLB
* shootdown messages).
*/
 
#include <mm/tlb.h>
#include <mm/asid.h>
#include <arch/mm/tlb.h>
#include <smp/ipi.h>
#include <synch/spinlock.h>
#include <typedefs.h>
#include <atomic.h>
#include <arch/interrupt.h>
#include <config.h>
#include <arch.h>
#include <panic.h>
#include <debug.h>
 
/**
* This lock is used for synchronisation between sender and
* recipients of TLB shootdown message. It must be acquired
* before CPU structure lock.
*/
SPINLOCK_INITIALIZE(tlblock);
 
void tlb_init(void)
{
tlb_arch_init();
}
 
#ifdef CONFIG_SMP
 
/** Send TLB shootdown message.
*
* This function attempts to deliver TLB shootdown message
* to all other processors.
*
* This function must be called with interrupts disabled.
*
* @param type Type describing scope of shootdown.
* @param asid Address space, if required by type.
* @param page Virtual page address, if required by type.
* @param count Number of pages, if required by type.
*/
void tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid, uintptr_t page, count_t count)
{
int i;
 
CPU->tlb_active = 0;
spinlock_lock(&tlblock);
for (i = 0; i < config.cpu_count; i++) {
cpu_t *cpu;
if (i == CPU->id)
continue;
 
cpu = &cpus[i];
spinlock_lock(&cpu->lock);
if (cpu->tlb_messages_count == TLB_MESSAGE_QUEUE_LEN) {
/*
* The message queue is full.
* Erase the queue and store one TLB_INVL_ALL message.
*/
cpu->tlb_messages_count = 1;
cpu->tlb_messages[0].type = TLB_INVL_ALL;
cpu->tlb_messages[0].asid = ASID_INVALID;
cpu->tlb_messages[0].page = 0;
cpu->tlb_messages[0].count = 0;
} else {
/*
* Enqueue the message.
*/
cpu->tlb_messages[cpu->tlb_messages_count].type = type;
cpu->tlb_messages[cpu->tlb_messages_count].asid = asid;
cpu->tlb_messages[cpu->tlb_messages_count].page = page;
cpu->tlb_messages[cpu->tlb_messages_count].count = count;
cpu->tlb_messages_count++;
}
spinlock_unlock(&cpu->lock);
}
tlb_shootdown_ipi_send();
 
busy_wait:
for (i = 0; i < config.cpu_count; i++)
if (cpus[i].tlb_active)
goto busy_wait;
}
 
/** Finish TLB shootdown sequence. */
void tlb_shootdown_finalize(void)
{
spinlock_unlock(&tlblock);
CPU->tlb_active = 1;
}
 
void tlb_shootdown_ipi_send(void)
{
ipi_broadcast(VECTOR_TLB_SHOOTDOWN_IPI);
}
 
/** Receive TLB shootdown message. */
void tlb_shootdown_ipi_recv(void)
{
tlb_invalidate_type_t type;
asid_t asid;
uintptr_t page;
count_t count;
int i;
ASSERT(CPU);
CPU->tlb_active = 0;
spinlock_lock(&tlblock);
spinlock_unlock(&tlblock);
spinlock_lock(&CPU->lock);
ASSERT(CPU->tlb_messages_count <= TLB_MESSAGE_QUEUE_LEN);
 
for (i = 0; i < CPU->tlb_messages_count; CPU->tlb_messages_count--) {
type = CPU->tlb_messages[i].type;
asid = CPU->tlb_messages[i].asid;
page = CPU->tlb_messages[i].page;
count = CPU->tlb_messages[i].count;
 
switch (type) {
case TLB_INVL_ALL:
tlb_invalidate_all();
break;
case TLB_INVL_ASID:
tlb_invalidate_asid(asid);
break;
case TLB_INVL_PAGES:
ASSERT(count);
tlb_invalidate_pages(asid, page, count);
break;
default:
panic("unknown type (%d)\n", type);
break;
}
if (type == TLB_INVL_ALL)
break;
}
spinlock_unlock(&CPU->lock);
CPU->tlb_active = 1;
}
 
#endif /* CONFIG_SMP */
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/mm/backend_anon.c
0,0 → 1,209
/*
* 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 genericmm
* @{
*/
 
/**
* @file
* @brief Backend for anonymous memory address space areas.
*
*/
 
#include <mm/as.h>
#include <mm/page.h>
#include <genarch/mm/page_pt.h>
#include <genarch/mm/page_ht.h>
#include <mm/frame.h>
#include <mm/slab.h>
#include <synch/mutex.h>
#include <adt/list.h>
#include <adt/btree.h>
#include <errno.h>
#include <arch/types.h>
#include <typedefs.h>
#include <align.h>
#include <arch.h>
 
static int anon_page_fault(as_area_t *area, uintptr_t addr, pf_access_t access);
static void anon_frame_free(as_area_t *area, uintptr_t page, uintptr_t frame);
static void anon_share(as_area_t *area);
 
mem_backend_t anon_backend = {
.page_fault = anon_page_fault,
.frame_free = anon_frame_free,
.share = anon_share
};
 
/** Service a page fault in the anonymous memory address space area.
*
* The address space area and page tables must be already locked.
*
* @param area Pointer to the address space area.
* @param addr Faulting virtual address.
* @param access Access mode that caused the fault (i.e. read/write/exec).
*
* @return AS_PF_FAULT on failure (i.e. page fault) or AS_PF_OK on success (i.e. serviced).
*/
int anon_page_fault(as_area_t *area, uintptr_t addr, pf_access_t access)
{
uintptr_t frame;
 
if (!as_area_check_access(area, access))
return AS_PF_FAULT;
 
if (area->sh_info) {
btree_node_t *leaf;
/*
* The area is shared, chances are that the mapping can be found
* in the pagemap of the address space area share info structure.
* In the case that the pagemap does not contain the respective
* mapping, a new frame is allocated and the mapping is created.
*/
mutex_lock(&area->sh_info->lock);
frame = (uintptr_t) btree_search(&area->sh_info->pagemap,
ALIGN_DOWN(addr, PAGE_SIZE) - area->base, &leaf);
if (!frame) {
bool allocate = true;
int i;
/*
* Zero can be returned as a valid frame address.
* Just a small workaround.
*/
for (i = 0; i < leaf->keys; i++) {
if (leaf->key[i] == ALIGN_DOWN(addr, PAGE_SIZE)) {
allocate = false;
break;
}
}
if (allocate) {
frame = (uintptr_t) frame_alloc(ONE_FRAME, 0);
memsetb(PA2KA(frame), FRAME_SIZE, 0);
/*
* Insert the address of the newly allocated frame to the pagemap.
*/
btree_insert(&area->sh_info->pagemap, ALIGN_DOWN(addr, PAGE_SIZE) - area->base, (void *) frame, leaf);
}
}
frame_reference_add(ADDR2PFN(frame));
mutex_unlock(&area->sh_info->lock);
} else {
 
/*
* In general, there can be several reasons that
* can have caused this fault.
*
* - non-existent mapping: the area is an anonymous
* area (e.g. heap or stack) and so far has not been
* allocated a frame for the faulting page
*
* - non-present mapping: another possibility,
* currently not implemented, would be frame
* reuse; when this becomes a possibility,
* do not forget to distinguish between
* the different causes
*/
frame = (uintptr_t)frame_alloc(ONE_FRAME, 0);
memsetb(PA2KA(frame), FRAME_SIZE, 0);
}
/*
* Map 'page' to 'frame'.
* Note that TLB shootdown is not attempted as only new information is being
* inserted into page tables.
*/
page_mapping_insert(AS, addr, frame, as_area_get_flags(area));
if (!used_space_insert(area, ALIGN_DOWN(addr, PAGE_SIZE), 1))
panic("Could not insert used space.\n");
return AS_PF_OK;
}
 
/** Free a frame that is backed by the anonymous memory backend.
*
* The address space area and page tables must be already locked.
*
* @param area Ignored.
* @param page Ignored.
* @param frame Frame to be released.
*/
void anon_frame_free(as_area_t *area, uintptr_t page, uintptr_t frame)
{
frame_free(frame);
}
 
/** Share the anonymous address space area.
*
* Sharing of anonymous area is done by duplicating its entire mapping
* to the pagemap. Page faults will primarily search for frames there.
*
* The address space and address space area must be already locked.
*
* @param area Address space area to be shared.
*/
void anon_share(as_area_t *area)
{
link_t *cur;
 
/*
* Copy used portions of the area to sh_info's page map.
*/
mutex_lock(&area->sh_info->lock);
for (cur = area->used_space.leaf_head.next; cur != &area->used_space.leaf_head; cur = cur->next) {
btree_node_t *node;
int i;
node = list_get_instance(cur, btree_node_t, leaf_link);
for (i = 0; i < node->keys; i++) {
uintptr_t base = node->key[i];
count_t count = (count_t) node->value[i];
int j;
for (j = 0; j < count; j++) {
pte_t *pte;
page_table_lock(area->as, false);
pte = page_mapping_find(area->as, base + j*PAGE_SIZE);
ASSERT(pte && PTE_VALID(pte) && PTE_PRESENT(pte));
btree_insert(&area->sh_info->pagemap, (base + j*PAGE_SIZE) - area->base,
(void *) PTE_GET_FRAME(pte), NULL);
page_table_unlock(area->as, false);
frame_reference_add(ADDR2PFN(PTE_GET_FRAME(pte)));
}
}
}
mutex_unlock(&area->sh_info->lock);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/mm/buddy.c
0,0 → 1,325
/*
* 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 genericmm
* @{
*/
 
/**
* @file
* @brief Buddy allocator framework.
*
* This file contains buddy system allocator framework.
* Specialized functions are needed for this abstract framework
* to be useful.
*/
 
#include <mm/buddy.h>
#include <mm/frame.h>
#include <arch/types.h>
#include <typedefs.h>
#include <adt/list.h>
#include <debug.h>
#include <print.h>
 
/** Return size needed for the buddy configuration data */
size_t buddy_conf_size(int max_order)
{
return sizeof(buddy_system_t) + (max_order + 1) * sizeof(link_t);
}
 
 
/** Create buddy system
*
* Allocate memory for and initialize new buddy system.
*
* @param b Preallocated buddy system control data.
* @param max_order The biggest allocable size will be 2^max_order.
* @param op Operations for new buddy system.
* @param data Pointer to be used by implementation.
*
* @return New buddy system.
*/
void buddy_system_create(buddy_system_t *b,
uint8_t max_order,
buddy_system_operations_t *op,
void *data)
{
int i;
 
ASSERT(max_order < BUDDY_SYSTEM_INNER_BLOCK);
 
ASSERT(op->find_buddy);
ASSERT(op->set_order);
ASSERT(op->get_order);
ASSERT(op->bisect);
ASSERT(op->coalesce);
ASSERT(op->mark_busy);
 
/*
* Use memory after our own structure
*/
b->order = (link_t *) (&b[1]);
for (i = 0; i <= max_order; i++)
list_initialize(&b->order[i]);
 
b->max_order = max_order;
b->op = op;
b->data = data;
}
 
/** Check if buddy system can allocate block
*
* @param b Buddy system pointer
* @param i Size of the block (2^i)
*
* @return True if block can be allocated
*/
bool buddy_system_can_alloc(buddy_system_t *b, uint8_t i) {
uint8_t k;
/*
* If requested block is greater then maximal block
* we know immediatly that we cannot satisfy the request.
*/
if (i > b->max_order) return false;
 
/*
* Check if any bigger or equal order has free elements
*/
for (k=i; k <= b->max_order; k++) {
if (!list_empty(&b->order[k])) {
return true;
}
}
return false;
}
 
/** Allocate PARTICULAR block from buddy system
*
* @ return Block of data or NULL if no such block was found
*/
link_t *buddy_system_alloc_block(buddy_system_t *b, link_t *block)
{
link_t *left,*right, *tmp;
uint8_t order;
 
left = b->op->find_block(b, block, BUDDY_SYSTEM_INNER_BLOCK);
ASSERT(left);
list_remove(left);
while (1) {
if (! b->op->get_order(b,left)) {
b->op->mark_busy(b, left);
return left;
}
order = b->op->get_order(b, left);
 
right = b->op->bisect(b, left);
b->op->set_order(b, left, order-1);
b->op->set_order(b, right, order-1);
 
tmp = b->op->find_block(b, block, BUDDY_SYSTEM_INNER_BLOCK);
 
if (tmp == right) {
right = left;
left = tmp;
}
ASSERT(tmp == left);
b->op->mark_busy(b, left);
buddy_system_free(b, right);
b->op->mark_available(b, left);
}
}
 
/** Allocate block from buddy system.
*
* @param b Buddy system pointer.
* @param i Returned block will be 2^i big.
*
* @return Block of data represented by link_t.
*/
link_t *buddy_system_alloc(buddy_system_t *b, uint8_t i)
{
link_t *res, *hlp;
 
ASSERT(i <= b->max_order);
 
/*
* If the list of order i is not empty,
* the request can be immediatelly satisfied.
*/
if (!list_empty(&b->order[i])) {
res = b->order[i].next;
list_remove(res);
b->op->mark_busy(b, res);
return res;
}
/*
* If order i is already the maximal order,
* the request cannot be satisfied.
*/
if (i == b->max_order)
return NULL;
 
/*
* Try to recursively satisfy the request from higher order lists.
*/
hlp = buddy_system_alloc(b, i + 1);
/*
* The request could not be satisfied
* from higher order lists.
*/
if (!hlp)
return NULL;
res = hlp;
/*
* Bisect the block and set order of both of its parts to i.
*/
hlp = b->op->bisect(b, res);
b->op->set_order(b, res, i);
b->op->set_order(b, hlp, i);
/*
* Return the other half to buddy system. Mark the first part
* full, so that it won't coalesce again.
*/
b->op->mark_busy(b, res);
buddy_system_free(b, hlp);
return res;
}
 
/** Return block to buddy system.
*
* @param b Buddy system pointer.
* @param block Block to return.
*/
void buddy_system_free(buddy_system_t *b, link_t *block)
{
link_t *buddy, *hlp;
uint8_t i;
 
/*
* Determine block's order.
*/
i = b->op->get_order(b, block);
 
ASSERT(i <= b->max_order);
 
if (i != b->max_order) {
/*
* See if there is any buddy in the list of order i.
*/
buddy = b->op->find_buddy(b, block);
if (buddy) {
 
ASSERT(b->op->get_order(b, buddy) == i);
/*
* Remove buddy from the list of order i.
*/
list_remove(buddy);
/*
* Invalidate order of both block and buddy.
*/
b->op->set_order(b, block, BUDDY_SYSTEM_INNER_BLOCK);
b->op->set_order(b, buddy, BUDDY_SYSTEM_INNER_BLOCK);
/*
* Coalesce block and buddy into one block.
*/
hlp = b->op->coalesce(b, block, buddy);
 
/*
* Set order of the coalesced block to i + 1.
*/
b->op->set_order(b, hlp, i + 1);
 
/*
* Recursively add the coalesced block to the list of order i + 1.
*/
buddy_system_free(b, hlp);
return;
}
}
 
/*
* Insert block into the list of order i.
*/
list_append(block, &b->order[i]);
 
}
 
/** Prints out structure of buddy system
*
* @param b Pointer to buddy system
* @param elem_size Element size
*/
void buddy_system_structure_print(buddy_system_t *b, size_t elem_size) {
index_t i;
count_t cnt, elem_count = 0, block_count = 0;
link_t * cur;
 
printf("Order\tBlocks\tSize \tBlock size\tElems per block\n");
printf("-----\t------\t--------\t----------\t---------------\n");
for (i=0;i <= b->max_order; i++) {
cnt = 0;
if (!list_empty(&b->order[i])) {
for (cur = b->order[i].next; cur != &b->order[i]; cur = cur->next)
cnt++;
}
printf("#%zd\t%5zd\t%7zdK\t%8zdK\t%6zd\t", i, cnt, (cnt * (1 << i) * elem_size) >> 10, ((1 << i) * elem_size) >> 10, 1 << i);
if (!list_empty(&b->order[i])) {
for (cur = b->order[i].next; cur != &b->order[i]; cur = cur->next) {
b->op->print_id(b, cur);
printf(" ");
}
}
printf("\n");
block_count += cnt;
elem_count += (1 << i) * cnt;
}
printf("-----\t------\t--------\t----------\t---------------\n");
printf("Buddy system contains %zd free elements (%zd blocks)\n" , elem_count, block_count);
 
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/mm/backend_phys.c
0,0 → 1,95
/*
* 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 genericmm
* @{
*/
 
/**
* @file
* @brief Backend for address space areas backed by continuous physical memory.
*/
 
#include <debug.h>
#include <arch/types.h>
#include <typedefs.h>
#include <mm/as.h>
#include <mm/frame.h>
#include <mm/slab.h>
#include <memstr.h>
#include <macros.h>
#include <arch.h>
#include <align.h>
 
static int phys_page_fault(as_area_t *area, uintptr_t addr, pf_access_t access);
static void phys_share(as_area_t *area);
 
mem_backend_t phys_backend = {
.page_fault = phys_page_fault,
.frame_free = NULL,
.share = phys_share
};
 
/** Service a page fault in the address space area backed by physical memory.
*
* The address space area and page tables must be already locked.
*
* @param area Pointer to the address space area.
* @param addr Faulting virtual address.
* @param access Access mode that caused the fault (i.e. read/write/exec).
*
* @return AS_PF_FAULT on failure (i.e. page fault) or AS_PF_OK on success (i.e. serviced).
*/
int phys_page_fault(as_area_t *area, uintptr_t addr, pf_access_t access)
{
uintptr_t base = area->backend_data.base;
 
if (!as_area_check_access(area, access))
return AS_PF_FAULT;
 
ASSERT(addr - area->base < area->backend_data.frames * FRAME_SIZE);
page_mapping_insert(AS, addr, base + (addr - area->base), as_area_get_flags(area));
if (!used_space_insert(area, ALIGN_DOWN(addr, PAGE_SIZE), 1))
panic("Could not insert used space.\n");
 
return AS_PF_OK;
}
 
/** Share address space area backed by physical memory.
*
* Do actually nothing as sharing of address space areas
* that are backed up by physical memory is very easy.
* Note that the function must be defined so that
* as_area_share() will succeed.
*/
void phys_share(as_area_t *area)
{
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/mm/page.c
0,0 → 1,143
/*
* Copyright (C) 2001-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 genericmm
* @{
*/
 
/**
* @file
* @brief Virtual Address Translation subsystem.
*
* This file contains code for creating, destroying and searching
* mappings between virtual addresses and physical addresses.
* Functions here are mere wrappers that call the real implementation.
* They however, define the single interface.
*/
 
#include <mm/page.h>
#include <arch/mm/page.h>
#include <arch/mm/asid.h>
#include <mm/as.h>
#include <mm/frame.h>
#include <arch/types.h>
#include <typedefs.h>
#include <arch/asm.h>
#include <memstr.h>
#include <debug.h>
#include <arch.h>
 
/** Virtual operations for page subsystem. */
page_mapping_operations_t *page_mapping_operations = NULL;
 
void page_init(void)
{
page_arch_init();
}
 
/** Map memory structure
*
* Identity-map memory structure
* considering possible crossings
* of page boundaries.
*
* @param s Address of the structure.
* @param size Size of the structure.
*/
void map_structure(uintptr_t s, size_t size)
{
int i, cnt, length;
 
length = size + (s - (s & ~(PAGE_SIZE - 1)));
cnt = length / PAGE_SIZE + (length % PAGE_SIZE > 0);
 
for (i = 0; i < cnt; i++)
page_mapping_insert(AS_KERNEL, s + i * PAGE_SIZE, s + i * PAGE_SIZE, PAGE_NOT_CACHEABLE);
 
}
 
/** Insert mapping of page to frame.
*
* Map virtual address page to physical address frame
* using flags. Allocate and setup any missing page tables.
*
* The page table must be locked and interrupts must be disabled.
*
* @param as Address space to wich page belongs.
* @param page Virtual address of the page to be mapped.
* @param frame Physical address of memory frame to which the mapping is done.
* @param flags Flags to be used for mapping.
*/
void page_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame, int flags)
{
ASSERT(page_mapping_operations);
ASSERT(page_mapping_operations->mapping_insert);
page_mapping_operations->mapping_insert(as, page, frame, flags);
}
 
/** Remove mapping of page.
*
* Remove any mapping of page within address space as.
* TLB shootdown should follow in order to make effects of
* this call visible.
*
* The page table must be locked and interrupts must be disabled.
*
* @param as Address space to wich page belongs.
* @param page Virtual address of the page to be demapped.
*/
void page_mapping_remove(as_t *as, uintptr_t page)
{
ASSERT(page_mapping_operations);
ASSERT(page_mapping_operations->mapping_remove);
page_mapping_operations->mapping_remove(as, page);
}
 
/** Find mapping for virtual page
*
* Find mapping for virtual page.
*
* The page table must be locked and interrupts must be disabled.
*
* @param as Address space to wich page belongs.
* @param page Virtual page.
*
* @return NULL if there is no such mapping; requested mapping otherwise.
*/
pte_t *page_mapping_find(as_t *as, uintptr_t page)
{
ASSERT(page_mapping_operations);
ASSERT(page_mapping_operations->mapping_find);
 
return page_mapping_operations->mapping_find(as, page);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/mm/backend_elf.c
0,0 → 1,309
/*
* 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 genericmm
* @{
*/
 
/**
* @file
* @brief Backend for address space areas backed by an ELF image.
*/
 
#include <elf.h>
#include <debug.h>
#include <arch/types.h>
#include <typedefs.h>
#include <mm/as.h>
#include <mm/frame.h>
#include <mm/slab.h>
#include <mm/page.h>
#include <genarch/mm/page_pt.h>
#include <genarch/mm/page_ht.h>
#include <align.h>
#include <memstr.h>
#include <macros.h>
#include <arch.h>
 
static int elf_page_fault(as_area_t *area, uintptr_t addr, pf_access_t access);
static void elf_frame_free(as_area_t *area, uintptr_t page, uintptr_t frame);
static void elf_share(as_area_t *area);
 
mem_backend_t elf_backend = {
.page_fault = elf_page_fault,
.frame_free = elf_frame_free,
.share = elf_share
};
 
/** Service a page fault in the ELF backend address space area.
*
* The address space area and page tables must be already locked.
*
* @param area Pointer to the address space area.
* @param addr Faulting virtual address.
* @param access Access mode that caused the fault (i.e. read/write/exec).
*
* @return AS_PF_FAULT on failure (i.e. page fault) or AS_PF_OK on success (i.e. serviced).
*/
int elf_page_fault(as_area_t *area, uintptr_t addr, pf_access_t access)
{
elf_header_t *elf = area->backend_data.elf;
elf_segment_header_t *entry = area->backend_data.segment;
btree_node_t *leaf;
uintptr_t base, frame;
index_t i;
 
if (!as_area_check_access(area, access))
return AS_PF_FAULT;
 
ASSERT((addr >= entry->p_vaddr) && (addr < entry->p_vaddr + entry->p_memsz));
i = (addr - entry->p_vaddr) >> PAGE_WIDTH;
base = (uintptr_t) (((void *) elf) + entry->p_offset);
ASSERT(ALIGN_UP(base, FRAME_SIZE) == base);
 
if (area->sh_info) {
bool found = false;
 
/*
* The address space area is shared.
*/
mutex_lock(&area->sh_info->lock);
frame = (uintptr_t) btree_search(&area->sh_info->pagemap,
ALIGN_DOWN(addr, PAGE_SIZE) - area->base, &leaf);
if (!frame) {
int i;
 
/*
* Workaround for valid NULL address.
*/
 
for (i = 0; i < leaf->keys; i++) {
if (leaf->key[i] == ALIGN_DOWN(addr, PAGE_SIZE)) {
found = true;
break;
}
}
}
if (frame || found) {
frame_reference_add(ADDR2PFN(frame));
page_mapping_insert(AS, addr, frame, as_area_get_flags(area));
if (!used_space_insert(area, ALIGN_DOWN(addr, PAGE_SIZE), 1))
panic("Could not insert used space.\n");
mutex_unlock(&area->sh_info->lock);
return AS_PF_OK;
}
}
/*
* The area is either not shared or the pagemap does not contain the mapping.
*/
if (ALIGN_DOWN(addr, PAGE_SIZE) + PAGE_SIZE < entry->p_vaddr + entry->p_filesz) {
/*
* Initialized portion of the segment. The memory is backed
* directly by the content of the ELF image. Pages are
* only copied if the segment is writable so that there
* can be more instantions of the same memory ELF image
* used at a time. Note that this could be later done
* as COW.
*/
if (entry->p_flags & PF_W) {
frame = (uintptr_t)frame_alloc(ONE_FRAME, 0);
memcpy((void *) PA2KA(frame), (void *) (base + i*FRAME_SIZE), FRAME_SIZE);
if (area->sh_info) {
frame_reference_add(ADDR2PFN(frame));
btree_insert(&area->sh_info->pagemap, ALIGN_DOWN(addr, PAGE_SIZE) - area->base,
(void *) frame, leaf);
}
 
} else {
frame = KA2PA(base + i*FRAME_SIZE);
}
} else if (ALIGN_DOWN(addr, PAGE_SIZE) >= ALIGN_UP(entry->p_vaddr + entry->p_filesz, PAGE_SIZE)) {
/*
* This is the uninitialized portion of the segment.
* It is not physically present in the ELF image.
* To resolve the situation, a frame must be allocated
* and cleared.
*/
frame = (uintptr_t)frame_alloc(ONE_FRAME, 0);
memsetb(PA2KA(frame), FRAME_SIZE, 0);
 
if (area->sh_info) {
frame_reference_add(ADDR2PFN(frame));
btree_insert(&area->sh_info->pagemap, ALIGN_DOWN(addr, PAGE_SIZE) - area->base,
(void *) frame, leaf);
}
 
} else {
size_t size;
/*
* The mixed case.
* The lower part is backed by the ELF image and
* the upper part is anonymous memory.
*/
size = entry->p_filesz - (i<<PAGE_WIDTH);
frame = (uintptr_t)frame_alloc(ONE_FRAME, 0);
memsetb(PA2KA(frame) + size, FRAME_SIZE - size, 0);
memcpy((void *) PA2KA(frame), (void *) (base + i*FRAME_SIZE), size);
 
if (area->sh_info) {
frame_reference_add(ADDR2PFN(frame));
btree_insert(&area->sh_info->pagemap, ALIGN_DOWN(addr, PAGE_SIZE) - area->base,
(void *) frame, leaf);
}
 
}
if (area->sh_info)
mutex_unlock(&area->sh_info->lock);
page_mapping_insert(AS, addr, frame, as_area_get_flags(area));
if (!used_space_insert(area, ALIGN_DOWN(addr, PAGE_SIZE), 1))
panic("Could not insert used space.\n");
 
return AS_PF_OK;
}
 
/** Free a frame that is backed by the ELF backend.
*
* The address space area and page tables must be already locked.
*
* @param area Pointer to the address space area.
* @param page Page that is mapped to frame. Must be aligned to PAGE_SIZE.
* @param frame Frame to be released.
*
*/
void elf_frame_free(as_area_t *area, uintptr_t page, uintptr_t frame)
{
elf_header_t *elf = area->backend_data.elf;
elf_segment_header_t *entry = area->backend_data.segment;
uintptr_t base;
index_t i;
ASSERT((page >= entry->p_vaddr) && (page < entry->p_vaddr + entry->p_memsz));
i = (page - entry->p_vaddr) >> PAGE_WIDTH;
base = (uintptr_t) (((void *) elf) + entry->p_offset);
ASSERT(ALIGN_UP(base, FRAME_SIZE) == base);
if (page + PAGE_SIZE < ALIGN_UP(entry->p_vaddr + entry->p_filesz, PAGE_SIZE)) {
if (entry->p_flags & PF_W) {
/*
* Free the frame with the copy of writable segment data.
*/
frame_free(frame);
}
} else {
/*
* The frame is either anonymous memory or the mixed case (i.e. lower
* part is backed by the ELF image and the upper is anonymous).
* In any case, a frame needs to be freed.
*/
frame_free(frame);
}
}
 
/** Share ELF image backed address space area.
*
* If the area is writable, then all mapped pages are duplicated in the pagemap.
* Otherwise only portions of the area that are not backed by the ELF image
* are put into the pagemap.
*
* The address space and address space area must be locked prior to the call.
*
* @param area Address space area.
*/
void elf_share(as_area_t *area)
{
elf_segment_header_t *entry = area->backend_data.segment;
link_t *cur;
btree_node_t *leaf, *node;
uintptr_t start_anon = entry->p_vaddr + entry->p_filesz;
 
/*
* Find the node in which to start linear search.
*/
if (area->flags & AS_AREA_WRITE) {
node = list_get_instance(area->used_space.leaf_head.next, btree_node_t, leaf_link);
} else {
(void) btree_search(&area->sh_info->pagemap, start_anon, &leaf);
node = btree_leaf_node_left_neighbour(&area->sh_info->pagemap, leaf);
if (!node)
node = leaf;
}
 
/*
* Copy used anonymous portions of the area to sh_info's page map.
*/
mutex_lock(&area->sh_info->lock);
for (cur = &node->leaf_link; cur != &area->used_space.leaf_head; cur = cur->next) {
int i;
node = list_get_instance(cur, btree_node_t, leaf_link);
for (i = 0; i < node->keys; i++) {
uintptr_t base = node->key[i];
count_t count = (count_t) node->value[i];
int j;
/*
* Skip read-only areas of used space that are backed
* by the ELF image.
*/
if (!(area->flags & AS_AREA_WRITE))
if (base + count*PAGE_SIZE <= start_anon)
continue;
for (j = 0; j < count; j++) {
pte_t *pte;
/*
* Skip read-only pages that are backed by the ELF image.
*/
if (!(area->flags & AS_AREA_WRITE))
if (base + (j + 1)*PAGE_SIZE <= start_anon)
continue;
page_table_lock(area->as, false);
pte = page_mapping_find(area->as, base + j*PAGE_SIZE);
ASSERT(pte && PTE_VALID(pte) && PTE_PRESENT(pte));
btree_insert(&area->sh_info->pagemap, (base + j*PAGE_SIZE) - area->base,
(void *) PTE_GET_FRAME(pte), NULL);
page_table_unlock(area->as, false);
frame_reference_add(ADDR2PFN(PTE_GET_FRAME(pte)));
}
}
}
mutex_unlock(&area->sh_info->lock);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/syscall/copy.c
0,0 → 1,132
/*
* 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 generic
* @{
*/
 
/**
* @file
* @brief Copying between kernel and userspace.
*
* This file contains sanitized functions for copying data
* between kernel and userspace.
*/
 
#include <syscall/copy.h>
#include <proc/thread.h>
#include <mm/as.h>
#include <macros.h>
#include <arch.h>
#include <errno.h>
#include <typedefs.h>
 
/** Copy data from userspace to kernel.
*
* Provisions are made to return value even after page fault.
*
* This function can be called only from syscall.
*
* @param dst Destination kernel address.
* @param uspace_src Source userspace address.
* @param size Size of the data to be copied.
*
* @return 0 on success or error code from @ref errno.h.
*/
int copy_from_uspace(void *dst, const void *uspace_src, size_t size)
{
ipl_t ipl;
int rc;
ASSERT(THREAD);
ASSERT(!THREAD->in_copy_from_uspace);
if (!KERNEL_ADDRESS_SPACE_SHADOWED) {
if (overlaps((uintptr_t) uspace_src, size,
KERNEL_ADDRESS_SPACE_START, KERNEL_ADDRESS_SPACE_END-KERNEL_ADDRESS_SPACE_START)) {
/*
* The userspace source block conflicts with kernel address space.
*/
return EPERM;
}
}
ipl = interrupts_disable();
THREAD->in_copy_from_uspace = true;
rc = memcpy_from_uspace(dst, uspace_src, size);
 
THREAD->in_copy_from_uspace = false;
 
interrupts_restore(ipl);
return !rc ? EPERM : 0;
}
 
/** Copy data from kernel to userspace.
*
* Provisions are made to return value even after page fault.
*
* This function can be called only from syscall.
*
* @param uspace_dst Destination userspace address.
* @param src Source kernel address.
* @param size Size of the data to be copied.
*
* @return 0 on success or error code from @ref errno.h.
*/
int copy_to_uspace(void *uspace_dst, const void *src, size_t size)
{
ipl_t ipl;
int rc;
ASSERT(THREAD);
ASSERT(!THREAD->in_copy_from_uspace);
if (!KERNEL_ADDRESS_SPACE_SHADOWED) {
if (overlaps((uintptr_t) uspace_dst, size,
KERNEL_ADDRESS_SPACE_START, KERNEL_ADDRESS_SPACE_END-KERNEL_ADDRESS_SPACE_START)) {
/*
* The userspace destination block conflicts with kernel address space.
*/
return EPERM;
}
}
ipl = interrupts_disable();
THREAD->in_copy_from_uspace = true;
rc = memcpy_to_uspace(uspace_dst, src, size);
 
THREAD->in_copy_from_uspace = false;
 
interrupts_restore(ipl);
return !rc ? EPERM : 0;
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/syscall/syscall.c
0,0 → 1,164
/*
* Copyright (C) 2005 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 generic
* @{
*/
 
/**
* @file
* @brief Syscall table and syscall wrappers.
*/
#include <syscall/syscall.h>
#include <proc/thread.h>
#include <proc/task.h>
#include <mm/as.h>
#include <print.h>
#include <putchar.h>
#include <errno.h>
#include <arch.h>
#include <debug.h>
#include <ipc/sysipc.h>
#include <synch/futex.h>
#include <ddi/ddi.h>
#include <security/cap.h>
#include <syscall/copy.h>
#include <sysinfo/sysinfo.h>
#include <console/console.h>
#include <console/klog.h>
 
/** Print using kernel facility
*
* Some simulators can print only through kernel. Userspace can use
* this syscall to facilitate it.
*/
static unative_t sys_io(int fd, const void * buf, size_t count)
{
size_t i;
char *data;
int rc;
 
if (count > PAGE_SIZE)
return ELIMIT;
 
data = malloc(count, 0);
if (!data)
return ENOMEM;
rc = copy_from_uspace(data, buf, count);
if (rc) {
free(data);
return rc;
}
 
for (i = 0; i < count; i++)
putchar(data[i]);
free(data);
return count;
}
 
/** Tell kernel to get keyboard/console access again */
static unative_t sys_debug_enable_console(void)
{
arch_grab_console();
return 0;
}
 
/** Dispatch system call */
unative_t syscall_handler(unative_t a1, unative_t a2, unative_t a3,
unative_t a4, unative_t id)
{
unative_t rc;
 
if (id < SYSCALL_END)
rc = syscall_table[id](a1,a2,a3,a4);
else {
klog_printf("TASK %lld: Unknown syscall id %d",TASK->taskid,id);
task_kill(TASK->taskid);
thread_exit();
}
if (THREAD->interrupted)
thread_exit();
return rc;
}
 
syshandler_t syscall_table[SYSCALL_END] = {
sys_io,
sys_tls_set,
/* Thread and task related syscalls. */
sys_thread_create,
sys_thread_exit,
sys_task_get_id,
/* Synchronization related syscalls. */
sys_futex_sleep_timeout,
sys_futex_wakeup,
/* Address space related syscalls. */
sys_as_area_create,
sys_as_area_resize,
sys_as_area_destroy,
 
/* IPC related syscalls. */
sys_ipc_call_sync_fast,
sys_ipc_call_sync,
sys_ipc_call_async_fast,
sys_ipc_call_async,
sys_ipc_answer_fast,
sys_ipc_answer,
sys_ipc_forward_fast,
sys_ipc_wait_for_call,
sys_ipc_hangup,
sys_ipc_register_irq,
sys_ipc_unregister_irq,
 
/* Capabilities related syscalls. */
sys_cap_grant,
sys_cap_revoke,
 
/* DDI related syscalls. */
sys_physmem_map,
sys_iospace_enable,
sys_preempt_control,
/* Sysinfo syscalls */
sys_sysinfo_valid,
sys_sysinfo_value,
/* Debug calls */
sys_debug_enable_console
};
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/src/proc/the.c
0,0 → 1,77
/*
* 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 genericproc
* @{
*/
 
/**
* @file
* @brief THE structure functions.
*
* This file contains functions to manage the THE structure.
* The THE structure exists at the base address of every kernel
* stack and carries information about current settings
* (e.g. current CPU, current thread, task and address space
* and current preemption counter).
*/
 
#include <arch.h>
#include <typedefs.h>
 
 
/** Initialize THE structure
*
* Initialize THE structure passed as argument.
*
* @param the THE structure to be initialized.
*/
void the_initialize(the_t *the)
{
the->preemption_disabled = 0;
the->cpu = NULL;
the->thread = NULL;
the->task = NULL;
the->as = NULL;
the->context = 0;
}
 
/** Copy THE structure
*
* Copy the source THE structure to the destination THE structure.
*
* @param src The source THE structure.
* @param dst The destination THE structure.
*/
void the_copy(the_t *src, the_t *dst)
{
*dst = *src;
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/proc/task.c
0,0 → 1,500
/*
* 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 genericproc
* @{
*/
 
/**
* @file
* @brief Task management.
*/
 
#include <main/uinit.h>
#include <proc/thread.h>
#include <proc/task.h>
#include <proc/uarg.h>
#include <mm/as.h>
#include <mm/slab.h>
#include <synch/spinlock.h>
#include <arch.h>
#include <panic.h>
#include <adt/btree.h>
#include <adt/list.h>
#include <ipc/ipc.h>
#include <security/cap.h>
#include <memstr.h>
#include <print.h>
#include <elf.h>
#include <errno.h>
#include <syscall/copy.h>
#include <console/klog.h>
 
#ifndef LOADED_PROG_STACK_PAGES_NO
#define LOADED_PROG_STACK_PAGES_NO 1
#endif
 
/** Spinlock protecting the tasks_btree B+tree. */
SPINLOCK_INITIALIZE(tasks_lock);
 
/** B+tree of active tasks.
*
* The task is guaranteed to exist after it was found in the tasks_btree as long as:
* @li the tasks_lock is held,
* @li the task's lock is held when task's lock is acquired before releasing tasks_lock or
* @li the task's refcount is grater than 0
*
*/
btree_t tasks_btree;
 
static task_id_t task_counter = 0;
 
static void ktaskclnp(void *arg);
static void ktaskgc(void *arg);
 
/** Initialize tasks
*
* Initialize kernel tasks support.
*
*/
void task_init(void)
{
TASK = NULL;
btree_create(&tasks_btree);
}
 
 
/** Create new task
*
* Create new task with no threads.
*
* @param as Task's address space.
* @param name Symbolic name.
*
* @return New task's structure
*
*/
task_t *task_create(as_t *as, char *name)
{
ipl_t ipl;
task_t *ta;
int i;
ta = (task_t *) malloc(sizeof(task_t), 0);
 
task_create_arch(ta);
 
spinlock_initialize(&ta->lock, "task_ta_lock");
list_initialize(&ta->th_head);
ta->as = as;
ta->name = name;
ta->main_thread = NULL;
ta->refcount = 0;
ta->context = THE->context;
 
ta->capabilities = 0;
ta->accept_new_threads = true;
ipc_answerbox_init(&ta->answerbox);
for (i=0; i < IPC_MAX_PHONES;i++)
ipc_phone_init(&ta->phones[i]);
if (ipc_phone_0)
ipc_phone_connect(&ta->phones[0], ipc_phone_0);
atomic_set(&ta->active_calls, 0);
 
mutex_initialize(&ta->futexes_lock);
btree_create(&ta->futexes);
ipl = interrupts_disable();
 
/*
* Increment address space reference count.
* TODO: Reconsider the locking scheme.
*/
mutex_lock(&as->lock);
as->refcount++;
mutex_unlock(&as->lock);
 
spinlock_lock(&tasks_lock);
 
ta->taskid = ++task_counter;
btree_insert(&tasks_btree, (btree_key_t) ta->taskid, (void *) ta, NULL);
 
spinlock_unlock(&tasks_lock);
interrupts_restore(ipl);
 
return ta;
}
 
/** Destroy task.
*
* @param t Task to be destroyed.
*/
void task_destroy(task_t *t)
{
task_destroy_arch(t);
btree_destroy(&t->futexes);
 
mutex_lock_active(&t->as->lock);
if (--t->as->refcount == 0) {
mutex_unlock(&t->as->lock);
as_destroy(t->as);
/*
* t->as is destroyed.
*/
} else {
mutex_unlock(&t->as->lock);
}
free(t);
TASK = NULL;
}
 
/** Create new task with 1 thread and run it
*
* @param program_addr Address of program executable image.
* @param name Program name.
*
* @return Task of the running program or NULL on error.
*/
task_t * task_run_program(void *program_addr, char *name)
{
as_t *as;
as_area_t *a;
int rc;
thread_t *t1, *t2;
task_t *task;
uspace_arg_t *kernel_uarg;
 
as = as_create(0);
ASSERT(as);
 
rc = elf_load((elf_header_t *) program_addr, as);
if (rc != EE_OK) {
as_destroy(as);
return NULL;
}
kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0);
kernel_uarg->uspace_entry = (void *) ((elf_header_t *) program_addr)->e_entry;
kernel_uarg->uspace_stack = (void *) USTACK_ADDRESS;
kernel_uarg->uspace_thread_function = NULL;
kernel_uarg->uspace_thread_arg = NULL;
kernel_uarg->uspace_uarg = NULL;
task = task_create(as, name);
ASSERT(task);
 
/*
* Create the data as_area.
*/
a = as_area_create(as, AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE,
LOADED_PROG_STACK_PAGES_NO*PAGE_SIZE,
USTACK_ADDRESS, AS_AREA_ATTR_NONE, &anon_backend, NULL);
 
/*
* Create the main thread.
*/
t1 = thread_create(uinit, kernel_uarg, task, 0, "uinit");
ASSERT(t1);
/*
* Create killer thread for the new task.
*/
t2 = thread_create(ktaskgc, t1, task, 0, "ktaskgc");
ASSERT(t2);
thread_ready(t2);
 
thread_ready(t1);
 
return task;
}
 
/** Syscall for reading task ID from userspace.
*
* @param uspace_task_id Userspace address of 8-byte buffer where to store current task ID.
*
* @return 0 on success or an error code from @ref errno.h.
*/
unative_t sys_task_get_id(task_id_t *uspace_task_id)
{
/*
* No need to acquire lock on TASK because taskid
* remains constant for the lifespan of the task.
*/
return (unative_t) copy_to_uspace(uspace_task_id, &TASK->taskid, sizeof(TASK->taskid));
}
 
/** Find task structure corresponding to task ID.
*
* The tasks_lock must be already held by the caller of this function
* and interrupts must be disabled.
*
* @param id Task ID.
*
* @return Task structure address or NULL if there is no such task ID.
*/
task_t *task_find_by_id(task_id_t id)
{
btree_node_t *leaf;
return (task_t *) btree_search(&tasks_btree, (btree_key_t) id, &leaf);
}
 
/** Kill task.
*
* @param id ID of the task to be killed.
*
* @return 0 on success or an error code from errno.h
*/
int task_kill(task_id_t id)
{
ipl_t ipl;
task_t *ta;
thread_t *t;
link_t *cur;
 
if (id == 1)
return EPERM;
ipl = interrupts_disable();
spinlock_lock(&tasks_lock);
 
if (!(ta = task_find_by_id(id))) {
spinlock_unlock(&tasks_lock);
interrupts_restore(ipl);
return ENOENT;
}
 
spinlock_lock(&ta->lock);
ta->refcount++;
spinlock_unlock(&ta->lock);
 
btree_remove(&tasks_btree, ta->taskid, NULL);
spinlock_unlock(&tasks_lock);
t = thread_create(ktaskclnp, NULL, ta, 0, "ktaskclnp");
spinlock_lock(&ta->lock);
ta->accept_new_threads = false;
ta->refcount--;
 
/*
* Interrupt all threads except ktaskclnp.
*/
for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) {
thread_t *thr;
bool sleeping = false;
thr = list_get_instance(cur, thread_t, th_link);
if (thr == t)
continue;
spinlock_lock(&thr->lock);
thr->interrupted = true;
if (thr->state == Sleeping)
sleeping = true;
spinlock_unlock(&thr->lock);
if (sleeping)
waitq_interrupt_sleep(thr);
}
spinlock_unlock(&ta->lock);
interrupts_restore(ipl);
if (t)
thread_ready(t);
 
return 0;
}
 
/** Print task list */
void task_print_list(void)
{
link_t *cur;
ipl_t ipl;
/* Messing with thread structures, avoid deadlock */
ipl = interrupts_disable();
spinlock_lock(&tasks_lock);
 
for (cur = tasks_btree.leaf_head.next; cur != &tasks_btree.leaf_head; cur = cur->next) {
btree_node_t *node;
int i;
node = list_get_instance(cur, btree_node_t, leaf_link);
for (i = 0; i < node->keys; i++) {
task_t *t;
int j;
 
t = (task_t *) node->value[i];
spinlock_lock(&t->lock);
printf("%s(%lld): context=%ld, address=%#zx, as=%#zx, ActiveCalls: %zd",
t->name, t->taskid, t->context, t, t->as, atomic_get(&t->active_calls));
for (j=0; j < IPC_MAX_PHONES; j++) {
if (t->phones[j].callee)
printf(" Ph(%zd): %#zx ", j, t->phones[j].callee);
}
printf("\n");
spinlock_unlock(&t->lock);
}
}
 
spinlock_unlock(&tasks_lock);
interrupts_restore(ipl);
}
 
/** Kernel thread used to cleanup the task after it is killed. */
void ktaskclnp(void *arg)
{
ipl_t ipl;
thread_t *t = NULL, *main_thread;
link_t *cur;
bool again;
 
thread_detach(THREAD);
 
loop:
ipl = interrupts_disable();
spinlock_lock(&TASK->lock);
main_thread = TASK->main_thread;
/*
* Find a thread to join.
*/
again = false;
for (cur = TASK->th_head.next; cur != &TASK->th_head; cur = cur->next) {
t = list_get_instance(cur, thread_t, th_link);
 
spinlock_lock(&t->lock);
if (t == THREAD) {
spinlock_unlock(&t->lock);
continue;
} else if (t == main_thread) {
spinlock_unlock(&t->lock);
continue;
} else if (t->join_type != None) {
spinlock_unlock(&t->lock);
again = true;
continue;
} else {
t->join_type = TaskClnp;
spinlock_unlock(&t->lock);
again = false;
break;
}
}
spinlock_unlock(&TASK->lock);
interrupts_restore(ipl);
if (again) {
/*
* Other cleanup (e.g. ktaskgc) is in progress.
*/
scheduler();
goto loop;
}
if (t != THREAD) {
ASSERT(t != main_thread); /* uninit is joined and detached in ktaskgc */
thread_join(t);
thread_detach(t);
goto loop; /* go for another thread */
}
/*
* Now there are no other threads in this task
* and no new threads can be created.
*/
ipc_cleanup();
futex_cleanup();
klog_printf("Cleanup of task %lld completed.", TASK->taskid);
}
 
/** Kernel thread used to kill the userspace task when its main thread exits.
*
* This thread waits until the main userspace thread (i.e. uninit) exits.
* When this happens, the task is killed. In the meantime, exited threads
* are garbage collected.
*
* @param arg Pointer to the thread structure of the task's main thread.
*/
void ktaskgc(void *arg)
{
thread_t *t = (thread_t *) arg;
loop:
/*
* Userspace threads cannot detach themselves,
* therefore the thread pointer is guaranteed to be valid.
*/
if (thread_join_timeout(t, 1000000, SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT) { /* sleep uninterruptibly here! */
ipl_t ipl;
link_t *cur;
thread_t *thr = NULL;
/*
* The join timed out. Try to do some garbage collection of Undead threads.
*/
more_gc:
ipl = interrupts_disable();
spinlock_lock(&TASK->lock);
for (cur = TASK->th_head.next; cur != &TASK->th_head; cur = cur->next) {
thr = list_get_instance(cur, thread_t, th_link);
spinlock_lock(&thr->lock);
if (thr != t && thr->state == Undead && thr->join_type == None) {
thr->join_type = TaskGC;
spinlock_unlock(&thr->lock);
break;
}
spinlock_unlock(&thr->lock);
thr = NULL;
}
spinlock_unlock(&TASK->lock);
interrupts_restore(ipl);
if (thr) {
thread_join(thr);
thread_detach(thr);
scheduler();
goto more_gc;
}
goto loop;
}
thread_detach(t);
task_kill(TASK->taskid);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/proc/thread.c
0,0 → 1,615
/*
* 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 genericproc
* @{
*/
 
/**
* @file
* @brief Thread management functions.
*/
 
#include <proc/scheduler.h>
#include <proc/thread.h>
#include <proc/task.h>
#include <proc/uarg.h>
#include <mm/frame.h>
#include <mm/page.h>
#include <arch/asm.h>
#include <arch.h>
#include <synch/synch.h>
#include <synch/spinlock.h>
#include <synch/waitq.h>
#include <synch/rwlock.h>
#include <cpu.h>
#include <func.h>
#include <context.h>
#include <adt/btree.h>
#include <adt/list.h>
#include <typedefs.h>
#include <time/clock.h>
#include <config.h>
#include <arch/interrupt.h>
#include <smp/ipi.h>
#include <arch/faddr.h>
#include <atomic.h>
#include <memstr.h>
#include <print.h>
#include <mm/slab.h>
#include <debug.h>
#include <main/uinit.h>
#include <syscall/copy.h>
#include <errno.h>
 
 
/** Thread states */
char *thread_states[] = {
"Invalid",
"Running",
"Sleeping",
"Ready",
"Entering",
"Exiting",
"Undead"
};
 
/** Lock protecting the threads_btree B+tree. For locking rules, see declaration thereof. */
SPINLOCK_INITIALIZE(threads_lock);
 
/** B+tree of all threads.
*
* When a thread is found in the threads_btree B+tree, it is guaranteed to exist as long
* as the threads_lock is held.
*/
btree_t threads_btree;
 
SPINLOCK_INITIALIZE(tidlock);
uint32_t last_tid = 0;
 
static slab_cache_t *thread_slab;
#ifdef ARCH_HAS_FPU
slab_cache_t *fpu_context_slab;
#endif
 
/** Thread wrapper
*
* This wrapper is provided to ensure that every thread
* makes a call to thread_exit() when its implementing
* function returns.
*
* interrupts_disable() is assumed.
*
*/
static void cushion(void)
{
void (*f)(void *) = THREAD->thread_code;
void *arg = THREAD->thread_arg;
 
/* this is where each thread wakes up after its creation */
spinlock_unlock(&THREAD->lock);
interrupts_enable();
 
f(arg);
thread_exit();
/* not reached */
}
 
/** Initialization and allocation for thread_t structure */
static int thr_constructor(void *obj, int kmflags)
{
thread_t *t = (thread_t *) obj;
 
spinlock_initialize(&t->lock, "thread_t_lock");
link_initialize(&t->rq_link);
link_initialize(&t->wq_link);
link_initialize(&t->th_link);
#ifdef ARCH_HAS_FPU
# ifdef CONFIG_FPU_LAZY
t->saved_fpu_context = NULL;
# else
t->saved_fpu_context = slab_alloc(fpu_context_slab,kmflags);
if (!t->saved_fpu_context)
return -1;
# endif
#endif
 
t->kstack = frame_alloc(STACK_FRAMES, FRAME_KA | kmflags);
if (! t->kstack) {
#ifdef ARCH_HAS_FPU
if (t->saved_fpu_context)
slab_free(fpu_context_slab,t->saved_fpu_context);
#endif
return -1;
}
 
return 0;
}
 
/** Destruction of thread_t object */
static int thr_destructor(void *obj)
{
thread_t *t = (thread_t *) obj;
 
frame_free(KA2PA(t->kstack));
#ifdef ARCH_HAS_FPU
if (t->saved_fpu_context)
slab_free(fpu_context_slab,t->saved_fpu_context);
#endif
return 1; /* One page freed */
}
 
/** Initialize threads
*
* Initialize kernel threads support.
*
*/
void thread_init(void)
{
THREAD = NULL;
atomic_set(&nrdy,0);
thread_slab = slab_cache_create("thread_slab",
sizeof(thread_t),0,
thr_constructor, thr_destructor, 0);
#ifdef ARCH_HAS_FPU
fpu_context_slab = slab_cache_create("fpu_slab",
sizeof(fpu_context_t),
FPU_CONTEXT_ALIGN,
NULL, NULL, 0);
#endif
 
btree_create(&threads_btree);
}
 
/** Make thread ready
*
* Switch thread t to the ready state.
*
* @param t Thread to make ready.
*
*/
void thread_ready(thread_t *t)
{
cpu_t *cpu;
runq_t *r;
ipl_t ipl;
int i, avg;
 
ipl = interrupts_disable();
 
spinlock_lock(&t->lock);
 
ASSERT(! (t->state == Ready));
 
i = (t->priority < RQ_COUNT -1) ? ++t->priority : t->priority;
cpu = CPU;
if (t->flags & X_WIRED) {
cpu = t->cpu;
}
t->state = Ready;
spinlock_unlock(&t->lock);
/*
* Append t to respective ready queue on respective processor.
*/
r = &cpu->rq[i];
spinlock_lock(&r->lock);
list_append(&t->rq_link, &r->rq_head);
r->n++;
spinlock_unlock(&r->lock);
 
atomic_inc(&nrdy);
avg = atomic_get(&nrdy) / config.cpu_active;
atomic_inc(&cpu->nrdy);
 
interrupts_restore(ipl);
}
 
/** Destroy thread memory structure
*
* Detach thread from all queues, cpus etc. and destroy it.
*
* Assume thread->lock is held!!
*/
void thread_destroy(thread_t *t)
{
bool destroy_task = false;
 
ASSERT(t->state == Exiting || t->state == Undead);
ASSERT(t->task);
ASSERT(t->cpu);
 
spinlock_lock(&t->cpu->lock);
if(t->cpu->fpu_owner==t)
t->cpu->fpu_owner=NULL;
spinlock_unlock(&t->cpu->lock);
 
spinlock_unlock(&t->lock);
 
spinlock_lock(&threads_lock);
btree_remove(&threads_btree, (btree_key_t) ((uintptr_t ) t), NULL);
spinlock_unlock(&threads_lock);
 
/*
* Detach from the containing task.
*/
spinlock_lock(&t->task->lock);
list_remove(&t->th_link);
if (--t->task->refcount == 0) {
t->task->accept_new_threads = false;
destroy_task = true;
}
spinlock_unlock(&t->task->lock);
if (destroy_task)
task_destroy(t->task);
slab_free(thread_slab, t);
}
 
/** Create new thread
*
* Create a new thread.
*
* @param func Thread's implementing function.
* @param arg Thread's implementing function argument.
* @param task Task to which the thread belongs.
* @param flags Thread flags.
* @param name Symbolic name.
*
* @return New thread's structure on success, NULL on failure.
*
*/
thread_t *thread_create(void (* func)(void *), void *arg, task_t *task, int flags, char *name)
{
thread_t *t;
ipl_t ipl;
t = (thread_t *) slab_alloc(thread_slab, 0);
if (!t)
return NULL;
 
thread_create_arch(t);
/* Not needed, but good for debugging */
memsetb((uintptr_t) t->kstack, THREAD_STACK_SIZE * 1 << STACK_FRAMES, 0);
ipl = interrupts_disable();
spinlock_lock(&tidlock);
t->tid = ++last_tid;
spinlock_unlock(&tidlock);
interrupts_restore(ipl);
context_save(&t->saved_context);
context_set(&t->saved_context, FADDR(cushion), (uintptr_t) t->kstack, THREAD_STACK_SIZE);
the_initialize((the_t *) t->kstack);
ipl = interrupts_disable();
t->saved_context.ipl = interrupts_read();
interrupts_restore(ipl);
memcpy(t->name, name, THREAD_NAME_BUFLEN);
t->context = THE->context;
t->thread_code = func;
t->thread_arg = arg;
t->ticks = -1;
t->priority = -1; /* start in rq[0] */
t->cpu = NULL;
t->flags = 0;
t->state = Entering;
t->call_me = NULL;
t->call_me_with = NULL;
timeout_initialize(&t->sleep_timeout);
t->sleep_interruptible = false;
t->sleep_queue = NULL;
t->timeout_pending = 0;
 
t->in_copy_from_uspace = false;
t->in_copy_to_uspace = false;
 
t->interrupted = false;
t->join_type = None;
t->detached = false;
waitq_initialize(&t->join_wq);
t->rwlock_holder_type = RWLOCK_NONE;
t->task = task;
t->fpu_context_exists = 0;
t->fpu_context_engaged = 0;
/*
* Attach to the containing task.
*/
ipl = interrupts_disable();
spinlock_lock(&task->lock);
if (!task->accept_new_threads) {
spinlock_unlock(&task->lock);
slab_free(thread_slab, t);
interrupts_restore(ipl);
return NULL;
}
list_append(&t->th_link, &task->th_head);
if (task->refcount++ == 0)
task->main_thread = t;
spinlock_unlock(&task->lock);
 
/*
* Register this thread in the system-wide list.
*/
spinlock_lock(&threads_lock);
btree_insert(&threads_btree, (btree_key_t) ((uintptr_t) t), (void *) t, NULL);
spinlock_unlock(&threads_lock);
interrupts_restore(ipl);
return t;
}
 
/** Terminate thread.
*
* End current thread execution and switch it to the exiting
* state. All pending timeouts are executed.
*
*/
void thread_exit(void)
{
ipl_t ipl;
 
restart:
ipl = interrupts_disable();
spinlock_lock(&THREAD->lock);
if (THREAD->timeout_pending) { /* busy waiting for timeouts in progress */
spinlock_unlock(&THREAD->lock);
interrupts_restore(ipl);
goto restart;
}
THREAD->state = Exiting;
spinlock_unlock(&THREAD->lock);
scheduler();
 
/* Not reached */
while (1)
;
}
 
 
/** Thread sleep
*
* Suspend execution of the current thread.
*
* @param sec Number of seconds to sleep.
*
*/
void thread_sleep(uint32_t sec)
{
thread_usleep(sec*1000000);
}
 
/** Wait for another thread to exit.
*
* @param t Thread to join on exit.
* @param usec Timeout in microseconds.
* @param flags Mode of operation.
*
* @return An error code from errno.h or an error code from synch.h.
*/
int thread_join_timeout(thread_t *t, uint32_t usec, int flags)
{
ipl_t ipl;
int rc;
 
if (t == THREAD)
return EINVAL;
 
/*
* Since thread join can only be called once on an undetached thread,
* the thread pointer is guaranteed to be still valid.
*/
ipl = interrupts_disable();
spinlock_lock(&t->lock);
ASSERT(!t->detached);
spinlock_unlock(&t->lock);
interrupts_restore(ipl);
rc = waitq_sleep_timeout(&t->join_wq, usec, flags);
return rc;
}
 
/** Detach thread.
*
* Mark the thread as detached, if the thread is already in the Undead state,
* deallocate its resources.
*
* @param t Thread to be detached.
*/
void thread_detach(thread_t *t)
{
ipl_t ipl;
 
/*
* Since the thread is expected to not be already detached,
* pointer to it must be still valid.
*/
ipl = interrupts_disable();
spinlock_lock(&t->lock);
ASSERT(!t->detached);
if (t->state == Undead) {
thread_destroy(t); /* unlocks &t->lock */
interrupts_restore(ipl);
return;
} else {
t->detached = true;
}
spinlock_unlock(&t->lock);
interrupts_restore(ipl);
}
 
/** Thread usleep
*
* Suspend execution of the current thread.
*
* @param usec Number of microseconds to sleep.
*
*/
void thread_usleep(uint32_t usec)
{
waitq_t wq;
waitq_initialize(&wq);
 
(void) waitq_sleep_timeout(&wq, usec, SYNCH_FLAGS_NON_BLOCKING);
}
 
/** Register thread out-of-context invocation
*
* Register a function and its argument to be executed
* on next context switch to the current thread.
*
* @param call_me Out-of-context function.
* @param call_me_with Out-of-context function argument.
*
*/
void thread_register_call_me(void (* call_me)(void *), void *call_me_with)
{
ipl_t ipl;
ipl = interrupts_disable();
spinlock_lock(&THREAD->lock);
THREAD->call_me = call_me;
THREAD->call_me_with = call_me_with;
spinlock_unlock(&THREAD->lock);
interrupts_restore(ipl);
}
 
/** Print list of threads debug info */
void thread_print_list(void)
{
link_t *cur;
ipl_t ipl;
/* Messing with thread structures, avoid deadlock */
ipl = interrupts_disable();
spinlock_lock(&threads_lock);
 
for (cur = threads_btree.leaf_head.next; cur != &threads_btree.leaf_head; cur = cur->next) {
btree_node_t *node;
int i;
 
node = list_get_instance(cur, btree_node_t, leaf_link);
for (i = 0; i < node->keys; i++) {
thread_t *t;
t = (thread_t *) node->value[i];
printf("%s: address=%#zx, tid=%zd, context=%ld, state=%s, task=%#zx, code=%#zx, stack=%#zx, cpu=",
t->name, t, t->tid, t->context, thread_states[t->state], t->task, t->thread_code, t->kstack);
if (t->cpu)
printf("cpu%zd", t->cpu->id);
else
printf("none");
if (t->state == Sleeping) {
printf(", kst=%#zx", t->kstack);
printf(", wq=%#zx", t->sleep_queue);
}
printf("\n");
}
}
 
spinlock_unlock(&threads_lock);
interrupts_restore(ipl);
}
 
/** Check whether thread exists.
*
* Note that threads_lock must be already held and
* interrupts must be already disabled.
*
* @param t Pointer to thread.
*
* @return True if thread t is known to the system, false otherwise.
*/
bool thread_exists(thread_t *t)
{
btree_node_t *leaf;
return btree_search(&threads_btree, (btree_key_t) ((uintptr_t) t), &leaf) != NULL;
}
 
/** Process syscall to create new thread.
*
*/
unative_t sys_thread_create(uspace_arg_t *uspace_uarg, char *uspace_name)
{
thread_t *t;
char namebuf[THREAD_NAME_BUFLEN];
uspace_arg_t *kernel_uarg;
uint32_t tid;
int rc;
 
rc = copy_from_uspace(namebuf, uspace_name, THREAD_NAME_BUFLEN);
if (rc != 0)
return (unative_t) rc;
 
kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0);
rc = copy_from_uspace(kernel_uarg, uspace_uarg, sizeof(uspace_arg_t));
if (rc != 0) {
free(kernel_uarg);
return (unative_t) rc;
}
 
if ((t = thread_create(uinit, kernel_uarg, TASK, 0, namebuf))) {
tid = t->tid;
thread_ready(t);
return (unative_t) tid;
} else {
free(kernel_uarg);
}
 
return (unative_t) ENOMEM;
}
 
/** Process syscall to terminate thread.
*
*/
unative_t sys_thread_exit(int uspace_status)
{
thread_exit();
/* Unreachable */
return 0;
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/proc/scheduler.c
0,0 → 1,701
/*
* 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 genericproc
* @{
*/
 
/**
* @file
* @brief Scheduler and load balancing.
*
* This file contains the scheduler and kcpulb kernel thread which
* performs load-balancing of per-CPU run queues.
*/
 
#include <proc/scheduler.h>
#include <proc/thread.h>
#include <proc/task.h>
#include <mm/frame.h>
#include <mm/page.h>
#include <mm/as.h>
#include <time/delay.h>
#include <arch/asm.h>
#include <arch/faddr.h>
#include <atomic.h>
#include <synch/spinlock.h>
#include <config.h>
#include <context.h>
#include <func.h>
#include <arch.h>
#include <adt/list.h>
#include <panic.h>
#include <typedefs.h>
#include <cpu.h>
#include <print.h>
#include <debug.h>
 
static void before_task_runs(void);
static void before_thread_runs(void);
static void after_thread_ran(void);
static void scheduler_separated_stack(void);
 
atomic_t nrdy; /**< Number of ready threads in the system. */
 
/** Carry out actions before new task runs. */
void before_task_runs(void)
{
before_task_runs_arch();
}
 
/** Take actions before new thread runs.
*
* Perform actions that need to be
* taken before the newly selected
* tread is passed control.
*
* THREAD->lock is locked on entry
*
*/
void before_thread_runs(void)
{
before_thread_runs_arch();
#ifdef CONFIG_FPU_LAZY
if(THREAD==CPU->fpu_owner)
fpu_enable();
else
fpu_disable();
#else
fpu_enable();
if (THREAD->fpu_context_exists)
fpu_context_restore(THREAD->saved_fpu_context);
else {
fpu_init();
THREAD->fpu_context_exists=1;
}
#endif
}
 
/** Take actions after THREAD had run.
*
* Perform actions that need to be
* taken after the running thread
* had been preempted by the scheduler.
*
* THREAD->lock is locked on entry
*
*/
void after_thread_ran(void)
{
after_thread_ran_arch();
}
 
#ifdef CONFIG_FPU_LAZY
void scheduler_fpu_lazy_request(void)
{
restart:
fpu_enable();
spinlock_lock(&CPU->lock);
 
/* Save old context */
if (CPU->fpu_owner != NULL) {
spinlock_lock(&CPU->fpu_owner->lock);
fpu_context_save(CPU->fpu_owner->saved_fpu_context);
/* don't prevent migration */
CPU->fpu_owner->fpu_context_engaged=0;
spinlock_unlock(&CPU->fpu_owner->lock);
CPU->fpu_owner = NULL;
}
 
spinlock_lock(&THREAD->lock);
if (THREAD->fpu_context_exists) {
fpu_context_restore(THREAD->saved_fpu_context);
} else {
/* Allocate FPU context */
if (!THREAD->saved_fpu_context) {
/* Might sleep */
spinlock_unlock(&THREAD->lock);
spinlock_unlock(&CPU->lock);
THREAD->saved_fpu_context = slab_alloc(fpu_context_slab,
0);
/* We may have switched CPUs during slab_alloc */
goto restart;
}
fpu_init();
THREAD->fpu_context_exists=1;
}
CPU->fpu_owner=THREAD;
THREAD->fpu_context_engaged = 1;
spinlock_unlock(&THREAD->lock);
 
spinlock_unlock(&CPU->lock);
}
#endif
 
/** Initialize scheduler
*
* Initialize kernel scheduler.
*
*/
void scheduler_init(void)
{
}
 
/** Get thread to be scheduled
*
* Get the optimal thread to be scheduled
* according to thread accounting and scheduler
* policy.
*
* @return Thread to be scheduled.
*
*/
static thread_t *find_best_thread(void)
{
thread_t *t;
runq_t *r;
int i;
 
ASSERT(CPU != NULL);
 
loop:
interrupts_enable();
if (atomic_get(&CPU->nrdy) == 0) {
/*
* For there was nothing to run, the CPU goes to sleep
* until a hardware interrupt or an IPI comes.
* This improves energy saving and hyperthreading.
*/
 
/*
* An interrupt might occur right now and wake up a thread.
* In such case, the CPU will continue to go to sleep
* even though there is a runnable thread.
*/
 
cpu_sleep();
goto loop;
}
 
interrupts_disable();
for (i = 0; i<RQ_COUNT; i++) {
r = &CPU->rq[i];
spinlock_lock(&r->lock);
if (r->n == 0) {
/*
* If this queue is empty, try a lower-priority queue.
*/
spinlock_unlock(&r->lock);
continue;
}
 
atomic_dec(&CPU->nrdy);
atomic_dec(&nrdy);
r->n--;
 
/*
* Take the first thread from the queue.
*/
t = list_get_instance(r->rq_head.next, thread_t, rq_link);
list_remove(&t->rq_link);
 
spinlock_unlock(&r->lock);
 
spinlock_lock(&t->lock);
t->cpu = CPU;
 
t->ticks = us2ticks((i+1)*10000);
t->priority = i; /* correct rq index */
 
/*
* Clear the X_STOLEN flag so that t can be migrated when load balancing needs emerge.
*/
t->flags &= ~X_STOLEN;
spinlock_unlock(&t->lock);
 
return t;
}
goto loop;
 
}
 
/** Prevent rq starvation
*
* Prevent low priority threads from starving in rq's.
*
* When the function decides to relink rq's, it reconnects
* respective pointers so that in result threads with 'pri'
* greater or equal start are moved to a higher-priority queue.
*
* @param start Threshold priority.
*
*/
static void relink_rq(int start)
{
link_t head;
runq_t *r;
int i, n;
 
list_initialize(&head);
spinlock_lock(&CPU->lock);
if (CPU->needs_relink > NEEDS_RELINK_MAX) {
for (i = start; i<RQ_COUNT-1; i++) {
/* remember and empty rq[i + 1] */
r = &CPU->rq[i + 1];
spinlock_lock(&r->lock);
list_concat(&head, &r->rq_head);
n = r->n;
r->n = 0;
spinlock_unlock(&r->lock);
/* append rq[i + 1] to rq[i] */
r = &CPU->rq[i];
spinlock_lock(&r->lock);
list_concat(&r->rq_head, &head);
r->n += n;
spinlock_unlock(&r->lock);
}
CPU->needs_relink = 0;
}
spinlock_unlock(&CPU->lock);
 
}
 
/** The scheduler
*
* The thread scheduling procedure.
* Passes control directly to
* scheduler_separated_stack().
*
*/
void scheduler(void)
{
volatile ipl_t ipl;
 
ASSERT(CPU != NULL);
 
ipl = interrupts_disable();
 
if (atomic_get(&haltstate))
halt();
if (THREAD) {
spinlock_lock(&THREAD->lock);
#ifndef CONFIG_FPU_LAZY
fpu_context_save(THREAD->saved_fpu_context);
#endif
if (!context_save(&THREAD->saved_context)) {
/*
* This is the place where threads leave scheduler();
*/
spinlock_unlock(&THREAD->lock);
interrupts_restore(THREAD->saved_context.ipl);
return;
}
 
/*
* Interrupt priority level of preempted thread is recorded here
* to facilitate scheduler() invocations from interrupts_disable()'d
* code (e.g. waitq_sleep_timeout()).
*/
THREAD->saved_context.ipl = ipl;
}
 
/*
* Through the 'THE' structure, we keep track of THREAD, TASK, CPU, VM
* and preemption counter. At this point THE could be coming either
* from THREAD's or CPU's stack.
*/
the_copy(THE, (the_t *) CPU->stack);
 
/*
* We may not keep the old stack.
* Reason: If we kept the old stack and got blocked, for instance, in
* find_best_thread(), the old thread could get rescheduled by another
* CPU and overwrite the part of its own stack that was also used by
* the scheduler on this CPU.
*
* Moreover, we have to bypass the compiler-generated POP sequence
* which is fooled by SP being set to the very top of the stack.
* Therefore the scheduler() function continues in
* scheduler_separated_stack().
*/
context_save(&CPU->saved_context);
context_set(&CPU->saved_context, FADDR(scheduler_separated_stack), (uintptr_t) CPU->stack, CPU_STACK_SIZE);
context_restore(&CPU->saved_context);
/* not reached */
}
 
/** Scheduler stack switch wrapper
*
* Second part of the scheduler() function
* using new stack. Handling the actual context
* switch to a new thread.
*
* Assume THREAD->lock is held.
*/
void scheduler_separated_stack(void)
{
int priority;
ASSERT(CPU != NULL);
if (THREAD) {
/* must be run after the switch to scheduler stack */
after_thread_ran();
 
switch (THREAD->state) {
case Running:
spinlock_unlock(&THREAD->lock);
thread_ready(THREAD);
break;
 
case Exiting:
repeat:
if (THREAD->detached) {
thread_destroy(THREAD);
} else {
/*
* The thread structure is kept allocated until somebody
* calls thread_detach() on it.
*/
if (!spinlock_trylock(&THREAD->join_wq.lock)) {
/*
* Avoid deadlock.
*/
spinlock_unlock(&THREAD->lock);
delay(10);
spinlock_lock(&THREAD->lock);
goto repeat;
}
_waitq_wakeup_unsafe(&THREAD->join_wq, false);
spinlock_unlock(&THREAD->join_wq.lock);
THREAD->state = Undead;
spinlock_unlock(&THREAD->lock);
}
break;
case Sleeping:
/*
* Prefer the thread after it's woken up.
*/
THREAD->priority = -1;
 
/*
* We need to release wq->lock which we locked in waitq_sleep().
* Address of wq->lock is kept in THREAD->sleep_queue.
*/
spinlock_unlock(&THREAD->sleep_queue->lock);
 
/*
* Check for possible requests for out-of-context invocation.
*/
if (THREAD->call_me) {
THREAD->call_me(THREAD->call_me_with);
THREAD->call_me = NULL;
THREAD->call_me_with = NULL;
}
 
spinlock_unlock(&THREAD->lock);
 
break;
 
default:
/*
* Entering state is unexpected.
*/
panic("tid%d: unexpected state %s\n", THREAD->tid, thread_states[THREAD->state]);
break;
}
 
THREAD = NULL;
}
 
THREAD = find_best_thread();
spinlock_lock(&THREAD->lock);
priority = THREAD->priority;
spinlock_unlock(&THREAD->lock);
 
relink_rq(priority);
 
/*
* If both the old and the new task are the same, lots of work is avoided.
*/
if (TASK != THREAD->task) {
as_t *as1 = NULL;
as_t *as2;
 
if (TASK) {
spinlock_lock(&TASK->lock);
as1 = TASK->as;
spinlock_unlock(&TASK->lock);
}
 
spinlock_lock(&THREAD->task->lock);
as2 = THREAD->task->as;
spinlock_unlock(&THREAD->task->lock);
/*
* Note that it is possible for two tasks to share one address space.
*/
if (as1 != as2) {
/*
* Both tasks and address spaces are different.
* Replace the old one with the new one.
*/
as_switch(as1, as2);
}
TASK = THREAD->task;
before_task_runs();
}
 
spinlock_lock(&THREAD->lock);
THREAD->state = Running;
 
#ifdef SCHEDULER_VERBOSE
printf("cpu%d: tid %d (priority=%d,ticks=%lld,nrdy=%ld)\n", CPU->id, THREAD->tid, THREAD->priority, THREAD->ticks, atomic_get(&CPU->nrdy));
#endif
 
/*
* Some architectures provide late kernel PA2KA(identity)
* mapping in a page fault handler. However, the page fault
* handler uses the kernel stack of the running thread and
* therefore cannot be used to map it. The kernel stack, if
* necessary, is to be mapped in before_thread_runs(). This
* function must be executed before the switch to the new stack.
*/
before_thread_runs();
 
/*
* Copy the knowledge of CPU, TASK, THREAD and preemption counter to thread's stack.
*/
the_copy(THE, (the_t *) THREAD->kstack);
context_restore(&THREAD->saved_context);
/* not reached */
}
 
#ifdef CONFIG_SMP
/** Load balancing thread
*
* SMP load balancing thread, supervising thread supplies
* for the CPU it's wired to.
*
* @param arg Generic thread argument (unused).
*
*/
void kcpulb(void *arg)
{
thread_t *t;
int count, average, i, j, k = 0;
ipl_t ipl;
 
/*
* Detach kcpulb as nobody will call thread_join_timeout() on it.
*/
thread_detach(THREAD);
loop:
/*
* Work in 1s intervals.
*/
thread_sleep(1);
 
not_satisfied:
/*
* Calculate the number of threads that will be migrated/stolen from
* other CPU's. Note that situation can have changed between two
* passes. Each time get the most up to date counts.
*/
average = atomic_get(&nrdy) / config.cpu_active + 1;
count = average - atomic_get(&CPU->nrdy);
 
if (count <= 0)
goto satisfied;
 
/*
* Searching least priority queues on all CPU's first and most priority queues on all CPU's last.
*/
for (j=RQ_COUNT-1; j >= 0; j--) {
for (i=0; i < config.cpu_active; i++) {
link_t *l;
runq_t *r;
cpu_t *cpu;
 
cpu = &cpus[(i + k) % config.cpu_active];
 
/*
* Not interested in ourselves.
* Doesn't require interrupt disabling for kcpulb is X_WIRED.
*/
if (CPU == cpu)
continue;
if (atomic_get(&cpu->nrdy) <= average)
continue;
 
ipl = interrupts_disable();
r = &cpu->rq[j];
spinlock_lock(&r->lock);
if (r->n == 0) {
spinlock_unlock(&r->lock);
interrupts_restore(ipl);
continue;
}
t = NULL;
l = r->rq_head.prev; /* search rq from the back */
while (l != &r->rq_head) {
t = list_get_instance(l, thread_t, rq_link);
/*
* We don't want to steal CPU-wired threads neither threads already stolen.
* The latter prevents threads from migrating between CPU's without ever being run.
* We don't want to steal threads whose FPU context is still in CPU.
*/
spinlock_lock(&t->lock);
if ( (!(t->flags & (X_WIRED | X_STOLEN))) && (!(t->fpu_context_engaged)) ) {
/*
* Remove t from r.
*/
spinlock_unlock(&t->lock);
atomic_dec(&cpu->nrdy);
atomic_dec(&nrdy);
 
r->n--;
list_remove(&t->rq_link);
 
break;
}
spinlock_unlock(&t->lock);
l = l->prev;
t = NULL;
}
spinlock_unlock(&r->lock);
 
if (t) {
/*
* Ready t on local CPU
*/
spinlock_lock(&t->lock);
#ifdef KCPULB_VERBOSE
printf("kcpulb%d: TID %d -> cpu%d, nrdy=%ld, avg=%nd\n", CPU->id, t->tid, CPU->id, atomic_get(&CPU->nrdy), atomic_get(&nrdy) / config.cpu_active);
#endif
t->flags |= X_STOLEN;
t->state = Entering;
spinlock_unlock(&t->lock);
thread_ready(t);
 
interrupts_restore(ipl);
if (--count == 0)
goto satisfied;
/*
* We are not satisfied yet, focus on another CPU next time.
*/
k++;
continue;
}
interrupts_restore(ipl);
}
}
 
if (atomic_get(&CPU->nrdy)) {
/*
* Be a little bit light-weight and let migrated threads run.
*/
scheduler();
} else {
/*
* We failed to migrate a single thread.
* Give up this turn.
*/
goto loop;
}
goto not_satisfied;
 
satisfied:
goto loop;
}
 
#endif /* CONFIG_SMP */
 
 
/** Print information about threads & scheduler queues */
void sched_print_list(void)
{
ipl_t ipl;
int cpu,i;
runq_t *r;
thread_t *t;
link_t *cur;
 
/* We are going to mess with scheduler structures,
* let's not be interrupted */
ipl = interrupts_disable();
for (cpu=0;cpu < config.cpu_count; cpu++) {
 
if (!cpus[cpu].active)
continue;
 
spinlock_lock(&cpus[cpu].lock);
printf("cpu%d: address=%p, nrdy=%ld, needs_relink=%ld\n",
cpus[cpu].id, &cpus[cpu], atomic_get(&cpus[cpu].nrdy), cpus[cpu].needs_relink);
for (i=0; i<RQ_COUNT; i++) {
r = &cpus[cpu].rq[i];
spinlock_lock(&r->lock);
if (!r->n) {
spinlock_unlock(&r->lock);
continue;
}
printf("\trq[%d]: ", i);
for (cur=r->rq_head.next; cur!=&r->rq_head; cur=cur->next) {
t = list_get_instance(cur, thread_t, rq_link);
printf("%d(%s) ", t->tid,
thread_states[t->state]);
}
printf("\n");
spinlock_unlock(&r->lock);
}
spinlock_unlock(&cpus[cpu].lock);
}
interrupts_restore(ipl);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/synch/rwlock.c
0,0 → 1,389
/*
* 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 sync
* @{
*/
 
/**
* @file
* @brief Reader/Writer locks.
*
* A reader/writer lock can be held by multiple readers at a time.
* Or it can be exclusively held by a sole writer at a time.
*
* These locks are not recursive.
* Because a technique called direct hand-off is used and because
* waiting takes place in a single wait queue, neither readers
* nor writers will suffer starvation.
*
* If there is a writer followed by a reader waiting for the rwlock
* and the writer times out, all leading readers are automatically woken up
* and allowed in.
*/
 
/*
* NOTE ON rwlock_holder_type
* This field is set on an attempt to acquire the exclusive mutex
* to the respective value depending whether the caller is a reader
* or a writer. The field is examined only if the thread had been
* previously blocked on the exclusive mutex. Thus it is save
* to store the rwlock type in the thread structure, because
* each thread can block on only one rwlock at a time.
*/
#include <synch/rwlock.h>
#include <synch/spinlock.h>
#include <synch/mutex.h>
#include <synch/waitq.h>
#include <synch/synch.h>
#include <adt/list.h>
#include <typedefs.h>
#include <arch/asm.h>
#include <arch.h>
#include <proc/thread.h>
#include <panic.h>
 
#define ALLOW_ALL 0
#define ALLOW_READERS_ONLY 1
 
static void let_others_in(rwlock_t *rwl, int readers_only);
static void release_spinlock(void *arg);
 
/** Initialize reader/writer lock
*
* Initialize reader/writer lock.
*
* @param rwl Reader/Writer lock.
*/
void rwlock_initialize(rwlock_t *rwl) {
spinlock_initialize(&rwl->lock, "rwlock_t");
mutex_initialize(&rwl->exclusive);
rwl->readers_in = 0;
}
 
/** Acquire reader/writer lock for reading
*
* Acquire reader/writer lock for reading.
* Timeout and willingness to block may be specified.
*
* @param rwl Reader/Writer lock.
* @param usec Timeout in microseconds.
* @param flags Specify mode of operation.
*
* For exact description of possible combinations of
* usec and flags, see comment for waitq_sleep_timeout().
*
* @return See comment for waitq_sleep_timeout().
*/
int _rwlock_write_lock_timeout(rwlock_t *rwl, uint32_t usec, int flags)
{
ipl_t ipl;
int rc;
ipl = interrupts_disable();
spinlock_lock(&THREAD->lock);
THREAD->rwlock_holder_type = RWLOCK_WRITER;
spinlock_unlock(&THREAD->lock);
interrupts_restore(ipl);
 
/*
* Writers take the easy part.
* They just need to acquire the exclusive mutex.
*/
rc = _mutex_lock_timeout(&rwl->exclusive, usec, flags);
if (SYNCH_FAILED(rc)) {
 
/*
* Lock operation timed out or was interrupted.
* The state of rwl is UNKNOWN at this point.
* No claims about its holder can be made.
*/
ipl = interrupts_disable();
spinlock_lock(&rwl->lock);
/*
* Now when rwl is locked, we can inspect it again.
* If it is held by some readers already, we can let
* readers from the head of the wait queue in.
*/
if (rwl->readers_in)
let_others_in(rwl, ALLOW_READERS_ONLY);
spinlock_unlock(&rwl->lock);
interrupts_restore(ipl);
}
return rc;
}
 
/** Acquire reader/writer lock for writing
*
* Acquire reader/writer lock for writing.
* Timeout and willingness to block may be specified.
*
* @param rwl Reader/Writer lock.
* @param usec Timeout in microseconds.
* @param flags Select mode of operation.
*
* For exact description of possible combinations of
* usec and flags, see comment for waitq_sleep_timeout().
*
* @return See comment for waitq_sleep_timeout().
*/
int _rwlock_read_lock_timeout(rwlock_t *rwl, uint32_t usec, int flags)
{
int rc;
ipl_t ipl;
ipl = interrupts_disable();
spinlock_lock(&THREAD->lock);
THREAD->rwlock_holder_type = RWLOCK_READER;
spinlock_unlock(&THREAD->lock);
 
spinlock_lock(&rwl->lock);
 
/*
* Find out whether we can get what we want without blocking.
*/
rc = mutex_trylock(&rwl->exclusive);
if (SYNCH_FAILED(rc)) {
 
/*
* 'exclusive' mutex is being held by someone else.
* If the holder is a reader and there is no one
* else waiting for it, we can enter the critical
* section.
*/
 
if (rwl->readers_in) {
spinlock_lock(&rwl->exclusive.sem.wq.lock);
if (list_empty(&rwl->exclusive.sem.wq.head)) {
/*
* We can enter.
*/
spinlock_unlock(&rwl->exclusive.sem.wq.lock);
goto shortcut;
}
spinlock_unlock(&rwl->exclusive.sem.wq.lock);
}
 
/*
* In order to prevent a race condition when a reader
* could block another reader at the head of the waitq,
* we register a function to unlock rwl->lock
* after this thread is put asleep.
*/
#ifdef CONFIG_SMP
thread_register_call_me(release_spinlock, &rwl->lock);
#else
thread_register_call_me(release_spinlock, NULL);
#endif
rc = _mutex_lock_timeout(&rwl->exclusive, usec, flags);
switch (rc) {
case ESYNCH_WOULD_BLOCK:
/*
* release_spinlock() wasn't called
*/
thread_register_call_me(NULL, NULL);
spinlock_unlock(&rwl->lock);
case ESYNCH_TIMEOUT:
case ESYNCH_INTERRUPTED:
/*
* The sleep timed out.
* We just restore interrupt priority level.
*/
case ESYNCH_OK_BLOCKED:
/*
* We were woken with rwl->readers_in already incremented.
* Note that this arrangement avoids race condition between
* two concurrent readers. (Race is avoided if 'exclusive' is
* locked at the same time as 'readers_in' is incremented.
* Same time means both events happen atomically when
* rwl->lock is held.)
*/
interrupts_restore(ipl);
break;
case ESYNCH_OK_ATOMIC:
panic("_mutex_lock_timeout()==ESYNCH_OK_ATOMIC\n");
break;
default:
panic("invalid ESYNCH\n");
break;
}
return rc;
}
 
shortcut:
 
/*
* We can increment readers_in only if we didn't go to sleep.
* For sleepers, rwlock_let_others_in() will do the job.
*/
rwl->readers_in++;
spinlock_unlock(&rwl->lock);
interrupts_restore(ipl);
 
return ESYNCH_OK_ATOMIC;
}
 
/** Release reader/writer lock held by writer
*
* Release reader/writer lock held by writer.
* Handoff reader/writer lock ownership directly
* to waiting readers or a writer.
*
* @param rwl Reader/Writer lock.
*/
void rwlock_write_unlock(rwlock_t *rwl)
{
ipl_t ipl;
ipl = interrupts_disable();
spinlock_lock(&rwl->lock);
let_others_in(rwl, ALLOW_ALL);
spinlock_unlock(&rwl->lock);
interrupts_restore(ipl);
}
 
/** Release reader/writer lock held by reader
*
* Release reader/writer lock held by reader.
* Handoff reader/writer lock ownership directly
* to a waiting writer or don't do anything if more
* readers poses the lock.
*
* @param rwl Reader/Writer lock.
*/
void rwlock_read_unlock(rwlock_t *rwl)
{
ipl_t ipl;
 
ipl = interrupts_disable();
spinlock_lock(&rwl->lock);
if (!--rwl->readers_in)
let_others_in(rwl, ALLOW_ALL);
spinlock_unlock(&rwl->lock);
interrupts_restore(ipl);
}
 
 
/** Direct handoff of reader/writer lock ownership.
*
* Direct handoff of reader/writer lock ownership
* to waiting readers or a writer.
*
* Must be called with rwl->lock locked.
* Must be called with interrupts_disable()'d.
*
* @param rwl Reader/Writer lock.
* @param readers_only See the description below.
*
* If readers_only is false: (unlock scenario)
* Let the first sleeper on 'exclusive' mutex in, no matter
* whether it is a reader or a writer. If there are more leading
* readers in line, let each of them in.
*
* Otherwise: (timeout scenario)
* Let all leading readers in.
*/
void let_others_in(rwlock_t *rwl, int readers_only)
{
rwlock_type_t type = RWLOCK_NONE;
thread_t *t = NULL;
bool one_more = true;
spinlock_lock(&rwl->exclusive.sem.wq.lock);
 
if (!list_empty(&rwl->exclusive.sem.wq.head))
t = list_get_instance(rwl->exclusive.sem.wq.head.next, thread_t, wq_link);
do {
if (t) {
spinlock_lock(&t->lock);
type = t->rwlock_holder_type;
spinlock_unlock(&t->lock);
}
/*
* If readers_only is true, we wake all leading readers
* if and only if rwl is locked by another reader.
* Assumption: readers_only ==> rwl->readers_in
*/
if (readers_only && (type != RWLOCK_READER))
break;
 
 
if (type == RWLOCK_READER) {
/*
* Waking up a reader.
* We are responsible for incrementing rwl->readers_in for it.
*/
rwl->readers_in++;
}
 
/*
* Only the last iteration through this loop can increment
* rwl->exclusive.sem.wq.missed_wakeup's. All preceeding
* iterations will wake up a thread.
*/
/* We call the internal version of waitq_wakeup, which
* relies on the fact that the waitq is already locked.
*/
_waitq_wakeup_unsafe(&rwl->exclusive.sem.wq, WAKEUP_FIRST);
t = NULL;
if (!list_empty(&rwl->exclusive.sem.wq.head)) {
t = list_get_instance(rwl->exclusive.sem.wq.head.next, thread_t, wq_link);
if (t) {
spinlock_lock(&t->lock);
if (t->rwlock_holder_type != RWLOCK_READER)
one_more = false;
spinlock_unlock(&t->lock);
}
}
} while ((type == RWLOCK_READER) && t && one_more);
 
spinlock_unlock(&rwl->exclusive.sem.wq.lock);
}
 
/** Release spinlock callback
*
* This is a callback function invoked from the scheduler.
* The callback is registered in _rwlock_read_lock_timeout().
*
* @param arg Spinlock.
*/
void release_spinlock(void *arg)
{
spinlock_unlock((spinlock_t *) arg);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/synch/mutex.c
0,0 → 1,84
/*
* 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 sync
* @{
*/
 
/**
* @file
* @brief Mutexes.
*/
#include <synch/mutex.h>
#include <synch/semaphore.h>
#include <synch/synch.h>
 
/** Initialize mutex
*
* Initialize mutex.
*
* @param mtx Mutex.
*/
void mutex_initialize(mutex_t *mtx)
{
semaphore_initialize(&mtx->sem, 1);
}
 
/** Acquire mutex
*
* Acquire mutex.
* Timeout mode and non-blocking mode can be requested.
*
* @param mtx Mutex.
* @param usec Timeout in microseconds.
* @param flags Specify mode of operation.
*
* For exact description of possible combinations of
* usec and flags, see comment for waitq_sleep_timeout().
*
* @return See comment for waitq_sleep_timeout().
*/
int _mutex_lock_timeout(mutex_t *mtx, uint32_t usec, int flags)
{
return _semaphore_down_timeout(&mtx->sem, usec, flags);
}
 
/** Release mutex
*
* Release mutex.
*
* @param mtx Mutex.
*/
void mutex_unlock(mutex_t *mtx)
{
semaphore_up(&mtx->sem);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/synch/spinlock.c
0,0 → 1,162
/*
* 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 sync
* @{
*/
 
/**
* @file
* @brief Spinlocks.
*/
#include <synch/spinlock.h>
#include <atomic.h>
#include <arch/barrier.h>
#include <arch.h>
#include <preemption.h>
#include <print.h>
#include <debug.h>
#include <symtab.h>
 
#ifdef CONFIG_FB
#include <genarch/fb/fb.h>
#endif
 
#ifdef CONFIG_SMP
 
/** Initialize spinlock
*
* Initialize spinlock.
*
* @param sl Pointer to spinlock_t structure.
*/
void spinlock_initialize(spinlock_t *sl, char *name)
{
atomic_set(&sl->val, 0);
#ifdef CONFIG_DEBUG_SPINLOCK
sl->name = name;
#endif
}
 
/** Lock spinlock
*
* Lock spinlock.
* This version has limitted ability to report
* possible occurence of deadlock.
*
* @param sl Pointer to spinlock_t structure.
*/
#ifdef CONFIG_DEBUG_SPINLOCK
#define DEADLOCK_THRESHOLD 100000000
void spinlock_lock_debug(spinlock_t *sl)
{
count_t i = 0;
char *symbol;
bool deadlock_reported = false;
 
preemption_disable();
while (test_and_set(&sl->val)) {
 
/*
* We need to be careful about printflock and fb_lock.
* Both of them are used to report deadlocks via
* printf() and fb_putchar().
*
* We trust our code that there is no possible deadlock
* caused by these two locks (except when an exception
* is triggered for instance by printf() or fb_putchar()).
* However, we encountered false positives caused by very
* slow VESA framebuffer interaction (especially when
* run in a simulator) that caused problems with both
* printflock and fb_lock.
*
* Possible deadlocks on both printflock and fb_lock
* are therefore not reported as they would cause an
* infinite recursion.
*/
if (sl == &printflock)
continue;
#ifdef CONFIG_FB
if (sl == &fb_lock)
continue;
#endif
if (i++ > DEADLOCK_THRESHOLD) {
printf("cpu%d: looping on spinlock %.*p:%s, caller=%.*p",
CPU->id, sizeof(uintptr_t) * 2, sl, sl->name, sizeof(uintptr_t) * 2, CALLER);
symbol = get_symtab_entry(CALLER);
if (symbol)
printf("(%s)", symbol);
printf("\n");
i = 0;
deadlock_reported = true;
}
}
 
if (deadlock_reported)
printf("cpu%d: not deadlocked\n", CPU->id);
 
/*
* Prevent critical section code from bleeding out this way up.
*/
CS_ENTER_BARRIER();
}
#endif
 
/** Lock spinlock conditionally
*
* Lock spinlock conditionally.
* If the spinlock is not available at the moment,
* signal failure.
*
* @param sl Pointer to spinlock_t structure.
*
* @return Zero on failure, non-zero otherwise.
*/
int spinlock_trylock(spinlock_t *sl)
{
int rc;
preemption_disable();
rc = !test_and_set(&sl->val);
 
/*
* Prevent critical section code from bleeding out this way up.
*/
CS_ENTER_BARRIER();
 
if (!rc)
preemption_enable();
return rc;
}
 
#endif
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/synch/semaphore.c
0,0 → 1,98
/*
* 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 sync
* @{
*/
 
/**
* @file
* @brief Semaphores.
*/
 
#include <synch/semaphore.h>
#include <synch/waitq.h>
#include <synch/spinlock.h>
#include <synch/synch.h>
#include <arch/asm.h>
#include <arch.h>
 
/** Initialize semaphore
*
* Initialize semaphore.
*
* @param s Semaphore.
* @param val Maximal number of threads allowed to enter critical section.
*/
void semaphore_initialize(semaphore_t *s, int val)
{
ipl_t ipl;
waitq_initialize(&s->wq);
ipl = interrupts_disable();
 
spinlock_lock(&s->wq.lock);
s->wq.missed_wakeups = val;
spinlock_unlock(&s->wq.lock);
 
interrupts_restore(ipl);
}
 
/** Semaphore down
*
* Semaphore down.
* Conditional mode and mode with timeout can be requested.
*
* @param s Semaphore.
* @param usec Timeout in microseconds.
* @param flags Select mode of operation.
*
* For exact description of possible combinations of
* usec and flags, see comment for waitq_sleep_timeout().
*
* @return See comment for waitq_sleep_timeout().
*/
int _semaphore_down_timeout(semaphore_t *s, uint32_t usec, int flags)
{
return waitq_sleep_timeout(&s->wq, usec, flags);
}
 
/** Semaphore up
*
* Semaphore up.
*
* @param s Semaphore.
*/
void semaphore_up(semaphore_t *s)
{
waitq_wakeup(&s->wq, WAKEUP_FIRST);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/synch/waitq.c
0,0 → 1,454
/*
* 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 sync
* @{
*/
 
/**
* @file
* @brief Wait queue.
*
* Wait queue is the basic synchronization primitive upon which all
* other synchronization primitives build.
*
* It allows threads to wait for an event in first-come, first-served
* fashion. Conditional operation as well as timeouts and interruptions
* are supported.
*/
 
#include <synch/waitq.h>
#include <synch/synch.h>
#include <synch/spinlock.h>
#include <proc/thread.h>
#include <proc/scheduler.h>
#include <arch/asm.h>
#include <arch/types.h>
#include <typedefs.h>
#include <time/timeout.h>
#include <arch.h>
#include <context.h>
#include <adt/list.h>
 
static void waitq_timeouted_sleep(void *data);
 
/** Initialize wait queue
*
* Initialize wait queue.
*
* @param wq Pointer to wait queue to be initialized.
*/
void waitq_initialize(waitq_t *wq)
{
spinlock_initialize(&wq->lock, "waitq_lock");
list_initialize(&wq->head);
wq->missed_wakeups = 0;
}
 
/** Handle timeout during waitq_sleep_timeout() call
*
* This routine is called when waitq_sleep_timeout() timeouts.
* Interrupts are disabled.
*
* It is supposed to try to remove 'its' thread from the wait queue;
* it can eventually fail to achieve this goal when these two events
* overlap. In that case it behaves just as though there was no
* timeout at all.
*
* @param data Pointer to the thread that called waitq_sleep_timeout().
*/
void waitq_timeouted_sleep(void *data)
{
thread_t *t = (thread_t *) data;
waitq_t *wq;
bool do_wakeup = false;
 
spinlock_lock(&threads_lock);
if (!thread_exists(t))
goto out;
 
grab_locks:
spinlock_lock(&t->lock);
if ((wq = t->sleep_queue)) { /* assignment */
if (!spinlock_trylock(&wq->lock)) {
spinlock_unlock(&t->lock);
goto grab_locks; /* avoid deadlock */
}
 
list_remove(&t->wq_link);
t->saved_context = t->sleep_timeout_context;
do_wakeup = true;
t->sleep_queue = NULL;
spinlock_unlock(&wq->lock);
}
t->timeout_pending = false;
spinlock_unlock(&t->lock);
if (do_wakeup)
thread_ready(t);
 
out:
spinlock_unlock(&threads_lock);
}
 
/** Interrupt sleeping thread.
*
* This routine attempts to interrupt a thread from its sleep in a waitqueue.
* If the thread is not found sleeping, no action is taken.
*
* @param t Thread to be interrupted.
*/
void waitq_interrupt_sleep(thread_t *t)
{
waitq_t *wq;
bool do_wakeup = false;
ipl_t ipl;
 
ipl = interrupts_disable();
spinlock_lock(&threads_lock);
if (!thread_exists(t))
goto out;
 
grab_locks:
spinlock_lock(&t->lock);
if ((wq = t->sleep_queue)) { /* assignment */
if (!(t->sleep_interruptible)) {
/*
* The sleep cannot be interrupted.
*/
spinlock_unlock(&t->lock);
goto out;
}
if (!spinlock_trylock(&wq->lock)) {
spinlock_unlock(&t->lock);
goto grab_locks; /* avoid deadlock */
}
 
if (t->timeout_pending && timeout_unregister(&t->sleep_timeout))
t->timeout_pending = false;
 
list_remove(&t->wq_link);
t->saved_context = t->sleep_interruption_context;
do_wakeup = true;
t->sleep_queue = NULL;
spinlock_unlock(&wq->lock);
}
spinlock_unlock(&t->lock);
 
if (do_wakeup)
thread_ready(t);
 
out:
spinlock_unlock(&threads_lock);
interrupts_restore(ipl);
}
 
/** Sleep until either wakeup, timeout or interruption occurs
*
* This is a sleep implementation which allows itself to time out or to be
* interrupted from the sleep, restoring a failover context.
*
* Sleepers are organised in a FIFO fashion in a structure called wait queue.
*
* This function is really basic in that other functions as waitq_sleep()
* and all the *_timeout() functions use it.
*
* @param wq Pointer to wait queue.
* @param usec Timeout in microseconds.
* @param flags Specify mode of the sleep.
*
* The sleep can be interrupted only if the
* SYNCH_FLAGS_INTERRUPTIBLE bit is specified in flags.
* If usec is greater than zero, regardless of the value of the
* SYNCH_FLAGS_NON_BLOCKING bit in flags, the call will not return until either timeout,
* interruption or wakeup comes.
*
* If usec is zero and the SYNCH_FLAGS_NON_BLOCKING bit is not set in flags, the call
* will not return until wakeup or interruption comes.
*
* If usec is zero and the SYNCH_FLAGS_NON_BLOCKING bit is set in flags, the call will
* immediately return, reporting either success or failure.
*
* @return Returns one of: ESYNCH_WOULD_BLOCK, ESYNCH_TIMEOUT, ESYNCH_INTERRUPTED,
* ESYNCH_OK_ATOMIC, ESYNCH_OK_BLOCKED.
*
* @li ESYNCH_WOULD_BLOCK means that the sleep failed because at the time
* of the call there was no pending wakeup.
*
* @li ESYNCH_TIMEOUT means that the sleep timed out.
*
* @li ESYNCH_INTERRUPTED means that somebody interrupted the sleeping thread.
*
* @li ESYNCH_OK_ATOMIC means that the sleep succeeded and that there was
* a pending wakeup at the time of the call. The caller was not put
* asleep at all.
*
* @li ESYNCH_OK_BLOCKED means that the sleep succeeded; the full sleep was
* attempted.
*/
int waitq_sleep_timeout(waitq_t *wq, uint32_t usec, int flags)
{
ipl_t ipl;
int rc;
ipl = waitq_sleep_prepare(wq);
rc = waitq_sleep_timeout_unsafe(wq, usec, flags);
waitq_sleep_finish(wq, rc, ipl);
return rc;
}
 
/** Prepare to sleep in a waitq.
*
* This function will return holding the lock of the wait queue
* and interrupts disabled.
*
* @param wq Wait queue.
*
* @return Interrupt level as it existed on entry to this function.
*/
ipl_t waitq_sleep_prepare(waitq_t *wq)
{
ipl_t ipl;
restart:
ipl = interrupts_disable();
 
if (THREAD) { /* needed during system initiailzation */
/*
* Busy waiting for a delayed timeout.
* This is an important fix for the race condition between
* a delayed timeout and a next call to waitq_sleep_timeout().
* Simply, the thread is not allowed to go to sleep if
* there are timeouts in progress.
*/
spinlock_lock(&THREAD->lock);
if (THREAD->timeout_pending) {
spinlock_unlock(&THREAD->lock);
interrupts_restore(ipl);
goto restart;
}
spinlock_unlock(&THREAD->lock);
}
spinlock_lock(&wq->lock);
return ipl;
}
 
/** Finish waiting in a wait queue.
*
* This function restores interrupts to the state that existed prior
* to the call to waitq_sleep_prepare(). If necessary, the wait queue
* lock is released.
*
* @param wq Wait queue.
* @param rc Return code of waitq_sleep_timeout_unsafe().
* @param ipl Interrupt level returned by waitq_sleep_prepare().
*/
void waitq_sleep_finish(waitq_t *wq, int rc, ipl_t ipl)
{
switch (rc) {
case ESYNCH_WOULD_BLOCK:
case ESYNCH_OK_ATOMIC:
spinlock_unlock(&wq->lock);
break;
default:
break;
}
interrupts_restore(ipl);
}
 
/** Internal implementation of waitq_sleep_timeout().
*
* This function implements logic of sleeping in a wait queue.
* This call must be preceeded by a call to waitq_sleep_prepare()
* and followed by a call to waitq_slee_finish().
*
* @param wq See waitq_sleep_timeout().
* @param usec See waitq_sleep_timeout().
* @param flags See waitq_sleep_timeout().
*
* @return See waitq_sleep_timeout().
*/
int waitq_sleep_timeout_unsafe(waitq_t *wq, uint32_t usec, int flags)
{
/* checks whether to go to sleep at all */
if (wq->missed_wakeups) {
wq->missed_wakeups--;
return ESYNCH_OK_ATOMIC;
}
else {
if ((flags & SYNCH_FLAGS_NON_BLOCKING) && (usec == 0)) {
/* return immediatelly instead of going to sleep */
return ESYNCH_WOULD_BLOCK;
}
}
/*
* Now we are firmly decided to go to sleep.
*/
spinlock_lock(&THREAD->lock);
 
if (flags & SYNCH_FLAGS_INTERRUPTIBLE) {
 
/*
* If the thread was already interrupted,
* don't go to sleep at all.
*/
if (THREAD->interrupted) {
spinlock_unlock(&THREAD->lock);
spinlock_unlock(&wq->lock);
return ESYNCH_INTERRUPTED;
}
 
/*
* Set context that will be restored if the sleep
* of this thread is ever interrupted.
*/
THREAD->sleep_interruptible = true;
if (!context_save(&THREAD->sleep_interruption_context)) {
/* Short emulation of scheduler() return code. */
spinlock_unlock(&THREAD->lock);
return ESYNCH_INTERRUPTED;
}
 
} else {
THREAD->sleep_interruptible = false;
}
 
if (usec) {
/* We use the timeout variant. */
if (!context_save(&THREAD->sleep_timeout_context)) {
/* Short emulation of scheduler() return code. */
spinlock_unlock(&THREAD->lock);
return ESYNCH_TIMEOUT;
}
THREAD->timeout_pending = true;
timeout_register(&THREAD->sleep_timeout, (uint64_t) usec, waitq_timeouted_sleep, THREAD);
}
 
list_append(&THREAD->wq_link, &wq->head);
 
/*
* Suspend execution.
*/
THREAD->state = Sleeping;
THREAD->sleep_queue = wq;
 
spinlock_unlock(&THREAD->lock);
 
scheduler(); /* wq->lock is released in scheduler_separated_stack() */
return ESYNCH_OK_BLOCKED;
}
 
 
/** Wake up first thread sleeping in a wait queue
*
* Wake up first thread sleeping in a wait queue.
* This is the SMP- and IRQ-safe wrapper meant for
* general use.
*
* Besides its 'normal' wakeup operation, it attempts
* to unregister possible timeout.
*
* @param wq Pointer to wait queue.
* @param all If this is non-zero, all sleeping threads
* will be woken up and missed count will be zeroed.
*/
void waitq_wakeup(waitq_t *wq, bool all)
{
ipl_t ipl;
 
ipl = interrupts_disable();
spinlock_lock(&wq->lock);
 
_waitq_wakeup_unsafe(wq, all);
 
spinlock_unlock(&wq->lock);
interrupts_restore(ipl);
}
 
/** Internal SMP- and IRQ-unsafe version of waitq_wakeup()
*
* This is the internal SMP- and IRQ-unsafe version
* of waitq_wakeup(). It assumes wq->lock is already
* locked and interrupts are already disabled.
*
* @param wq Pointer to wait queue.
* @param all If this is non-zero, all sleeping threads
* will be woken up and missed count will be zeroed.
*/
void _waitq_wakeup_unsafe(waitq_t *wq, bool all)
{
thread_t *t;
 
loop:
if (list_empty(&wq->head)) {
wq->missed_wakeups++;
if (all)
wq->missed_wakeups = 0;
return;
}
 
t = list_get_instance(wq->head.next, thread_t, wq_link);
/*
* Lock the thread prior to removing it from the wq.
* This is not necessary because of mutual exclusion
* (the link belongs to the wait queue), but because
* of synchronization with waitq_timeouted_sleep()
* and waitq_interrupt_sleep().
*
* In order for these two functions to work, the following
* invariant must hold:
*
* t->sleep_queue != NULL <=> t sleeps in a wait queue
*
* For an observer who locks the thread, the invariant
* holds only when the lock is held prior to removing
* it from the wait queue.
*/
spinlock_lock(&t->lock);
list_remove(&t->wq_link);
if (t->timeout_pending && timeout_unregister(&t->sleep_timeout))
t->timeout_pending = false;
t->sleep_queue = NULL;
spinlock_unlock(&t->lock);
 
thread_ready(t);
 
if (all)
goto loop;
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/synch/futex.c
0,0 → 1,339
/*
* 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 sync
* @{
*/
 
/**
* @file
* @brief Kernel backend for futexes.
*/
 
#include <synch/futex.h>
#include <synch/rwlock.h>
#include <synch/spinlock.h>
#include <synch/synch.h>
#include <mm/frame.h>
#include <mm/page.h>
#include <mm/slab.h>
#include <proc/thread.h>
#include <proc/task.h>
#include <genarch/mm/page_pt.h>
#include <genarch/mm/page_ht.h>
#include <adt/hash_table.h>
#include <adt/list.h>
#include <arch.h>
#include <align.h>
#include <panic.h>
#include <errno.h>
#include <print.h>
 
#define FUTEX_HT_SIZE 1024 /* keep it a power of 2 */
 
static void futex_initialize(futex_t *futex);
 
static futex_t *futex_find(uintptr_t paddr);
static index_t futex_ht_hash(unative_t *key);
static bool futex_ht_compare(unative_t *key, count_t keys, link_t *item);
static void futex_ht_remove_callback(link_t *item);
 
/**
* Read-write lock protecting global futex hash table.
* It is also used to serialize access to all futex_t structures.
* Must be acquired before the task futex B+tree lock.
*/
static rwlock_t futex_ht_lock;
 
/** Futex hash table. */
static hash_table_t futex_ht;
 
/** Futex hash table operations. */
static hash_table_operations_t futex_ht_ops = {
.hash = futex_ht_hash,
.compare = futex_ht_compare,
.remove_callback = futex_ht_remove_callback
};
 
/** Initialize futex subsystem. */
void futex_init(void)
{
rwlock_initialize(&futex_ht_lock);
hash_table_create(&futex_ht, FUTEX_HT_SIZE, 1, &futex_ht_ops);
}
 
/** Initialize kernel futex structure.
*
* @param futex Kernel futex structure.
*/
void futex_initialize(futex_t *futex)
{
waitq_initialize(&futex->wq);
link_initialize(&futex->ht_link);
futex->paddr = 0;
futex->refcount = 1;
}
 
/** Sleep in futex wait queue.
*
* @param uaddr Userspace address of the futex counter.
* @param usec If non-zero, number of microseconds this thread is willing to sleep.
* @param flags Select mode of operation.
*
* @return One of ESYNCH_TIMEOUT, ESYNCH_OK_ATOMIC and ESYNCH_OK_BLOCKED. See synch.h.
* If there is no physical mapping for uaddr ENOENT is returned.
*/
unative_t sys_futex_sleep_timeout(uintptr_t uaddr, uint32_t usec, int flags)
{
futex_t *futex;
uintptr_t paddr;
pte_t *t;
ipl_t ipl;
ipl = interrupts_disable();
 
/*
* Find physical address of futex counter.
*/
page_table_lock(AS, true);
t = page_mapping_find(AS, ALIGN_DOWN(uaddr, PAGE_SIZE));
if (!t || !PTE_VALID(t) || !PTE_PRESENT(t)) {
page_table_unlock(AS, true);
interrupts_restore(ipl);
return (unative_t) ENOENT;
}
paddr = PTE_GET_FRAME(t) + (uaddr - ALIGN_DOWN(uaddr, PAGE_SIZE));
page_table_unlock(AS, true);
interrupts_restore(ipl);
 
futex = futex_find(paddr);
return (unative_t) waitq_sleep_timeout(&futex->wq, usec, flags | SYNCH_FLAGS_INTERRUPTIBLE);
}
 
/** Wakeup one thread waiting in futex wait queue.
*
* @param uaddr Userspace address of the futex counter.
*
* @return ENOENT if there is no physical mapping for uaddr.
*/
unative_t sys_futex_wakeup(uintptr_t uaddr)
{
futex_t *futex;
uintptr_t paddr;
pte_t *t;
ipl_t ipl;
ipl = interrupts_disable();
/*
* Find physical address of futex counter.
*/
page_table_lock(AS, true);
t = page_mapping_find(AS, ALIGN_DOWN(uaddr, PAGE_SIZE));
if (!t || !PTE_VALID(t) || !PTE_PRESENT(t)) {
page_table_unlock(AS, true);
interrupts_restore(ipl);
return (unative_t) ENOENT;
}
paddr = PTE_GET_FRAME(t) + (uaddr - ALIGN_DOWN(uaddr, PAGE_SIZE));
page_table_unlock(AS, true);
interrupts_restore(ipl);
 
futex = futex_find(paddr);
waitq_wakeup(&futex->wq, WAKEUP_FIRST);
return 0;
}
 
/** Find kernel address of the futex structure corresponding to paddr.
*
* If the structure does not exist already, a new one is created.
*
* @param paddr Physical address of the userspace futex counter.
*
* @return Address of the kernel futex structure.
*/
futex_t *futex_find(uintptr_t paddr)
{
link_t *item;
futex_t *futex;
btree_node_t *leaf;
/*
* Find the respective futex structure
* or allocate new one if it does not exist already.
*/
rwlock_read_lock(&futex_ht_lock);
item = hash_table_find(&futex_ht, &paddr);
if (item) {
futex = hash_table_get_instance(item, futex_t, ht_link);
 
/*
* See if the current task knows this futex.
*/
mutex_lock(&TASK->futexes_lock);
if (!btree_search(&TASK->futexes, paddr, &leaf)) {
/*
* The futex is new to the current task.
* However, we only have read access.
* Gain write access and try again.
*/
mutex_unlock(&TASK->futexes_lock);
goto gain_write_access;
}
mutex_unlock(&TASK->futexes_lock);
 
rwlock_read_unlock(&futex_ht_lock);
} else {
gain_write_access:
/*
* Upgrade to writer is not currently supported,
* therefore, it is necessary to release the read lock
* and reacquire it as a writer.
*/
rwlock_read_unlock(&futex_ht_lock);
 
rwlock_write_lock(&futex_ht_lock);
/*
* Avoid possible race condition by searching
* the hash table once again with write access.
*/
item = hash_table_find(&futex_ht, &paddr);
if (item) {
futex = hash_table_get_instance(item, futex_t, ht_link);
/*
* See if this futex is known to the current task.
*/
mutex_lock(&TASK->futexes_lock);
if (!btree_search(&TASK->futexes, paddr, &leaf)) {
/*
* The futex is new to the current task.
* Upgrade its reference count and put it to the
* current task's B+tree of known futexes.
*/
futex->refcount++;
btree_insert(&TASK->futexes, paddr, futex, leaf);
}
mutex_unlock(&TASK->futexes_lock);
rwlock_write_unlock(&futex_ht_lock);
} else {
futex = (futex_t *) malloc(sizeof(futex_t), 0);
futex_initialize(futex);
futex->paddr = paddr;
hash_table_insert(&futex_ht, &paddr, &futex->ht_link);
/*
* This is the first task referencing the futex.
* It can be directly inserted into its
* B+tree of known futexes.
*/
mutex_lock(&TASK->futexes_lock);
btree_insert(&TASK->futexes, paddr, futex, NULL);
mutex_unlock(&TASK->futexes_lock);
rwlock_write_unlock(&futex_ht_lock);
}
}
return futex;
}
 
/** Compute hash index into futex hash table.
*
* @param key Address where the key (i.e. physical address of futex counter) is stored.
*
* @return Index into futex hash table.
*/
index_t futex_ht_hash(unative_t *key)
{
return *key & (FUTEX_HT_SIZE-1);
}
 
/** Compare futex hash table item with a key.
*
* @param key Address where the key (i.e. physical address of futex counter) is stored.
*
* @return True if the item matches the key. False otherwise.
*/
bool futex_ht_compare(unative_t *key, count_t keys, link_t *item)
{
futex_t *futex;
 
ASSERT(keys == 1);
 
futex = hash_table_get_instance(item, futex_t, ht_link);
return *key == futex->paddr;
}
 
/** Callback for removal items from futex hash table.
*
* @param item Item removed from the hash table.
*/
void futex_ht_remove_callback(link_t *item)
{
futex_t *futex;
 
futex = hash_table_get_instance(item, futex_t, ht_link);
free(futex);
}
 
/** Remove references from futexes known to the current task. */
void futex_cleanup(void)
{
link_t *cur;
rwlock_write_lock(&futex_ht_lock);
mutex_lock(&TASK->futexes_lock);
 
for (cur = TASK->futexes.leaf_head.next; cur != &TASK->futexes.leaf_head; cur = cur->next) {
btree_node_t *node;
int i;
node = list_get_instance(cur, btree_node_t, leaf_link);
for (i = 0; i < node->keys; i++) {
futex_t *ftx;
uintptr_t paddr = node->key[i];
ftx = (futex_t *) node->value[i];
if (--ftx->refcount == 0)
hash_table_remove(&futex_ht, &paddr, 1);
}
}
mutex_unlock(&TASK->futexes_lock);
rwlock_write_unlock(&futex_ht_lock);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/synch/condvar.c
0,0 → 1,108
/*
* 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 sync
* @{
*/
 
/**
* @file
* @brief Condition variables.
*/
 
#include <synch/condvar.h>
#include <synch/mutex.h>
#include <synch/waitq.h>
#include <synch/synch.h>
#include <arch.h>
#include <typedefs.h>
 
/** Initialize condition variable.
*
* @param cv Condition variable.
*/
void condvar_initialize(condvar_t *cv)
{
waitq_initialize(&cv->wq);
}
 
/**
* Signal the condition has become true
* to the first waiting thread by waking it up.
*
* @param cv Condition variable.
*/
void condvar_signal(condvar_t *cv)
{
waitq_wakeup(&cv->wq, WAKEUP_FIRST);
}
 
/**
* Signal the condition has become true
* to all waiting threads by waking them up.
*
* @param cv Condition variable.
*/
void condvar_broadcast(condvar_t *cv)
{
waitq_wakeup(&cv->wq, WAKEUP_ALL);
}
 
/** Wait for the condition becoming true.
*
* @param cv Condition variable.
* @param mtx Mutex.
* @param usec Timeout value in microseconds.
* @param flags Select mode of operation.
*
* For exact description of meaning of possible combinations
* of usec and flags, see comment for waitq_sleep_timeout().
* Note that when SYNCH_FLAGS_NON_BLOCKING is specified here,
* ESYNCH_WOULD_BLOCK is always returned.
*
* @return See comment for waitq_sleep_timeout().
*/
int _condvar_wait_timeout(condvar_t *cv, mutex_t *mtx, uint32_t usec, int flags)
{
int rc;
ipl_t ipl;
 
ipl = waitq_sleep_prepare(&cv->wq);
mutex_unlock(mtx);
 
cv->wq.missed_wakeups = 0; /* Enforce blocking. */
rc = waitq_sleep_timeout_unsafe(&cv->wq, usec, flags);
 
mutex_lock(mtx);
waitq_sleep_finish(&cv->wq, rc, ipl);
 
return rc;
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/debug/symtab.c
0,0 → 1,202
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 genericdebug
* @{
*/
 
/**
* @file
* @brief Kernel symbol resolver.
*/
 
#include <symtab.h>
#include <typedefs.h>
#include <arch/byteorder.h>
#include <func.h>
#include <print.h>
 
/** Return entry that seems most likely to correspond to argument.
*
* Return entry that seems most likely to correspond
* to address passed in the argument.
*
* @param addr Address.
*
* @return Pointer to respective symbol string on success, NULL otherwise.
*/
char * get_symtab_entry(unative_t addr)
{
count_t i;
 
for (i=1;symbol_table[i].address_le;++i) {
if (addr < uint64_t_le2host(symbol_table[i].address_le))
break;
}
if (addr >= uint64_t_le2host(symbol_table[i-1].address_le))
return symbol_table[i-1].symbol_name;
return NULL;
}
 
/** Find symbols that match the parameter forward and print them.
*
* @param name - search string
* @param startpos - starting position, changes to found position
* @return Pointer to the part of string that should be completed or NULL
*/
static char * symtab_search_one(const char *name, int *startpos)
{
int namelen = strlen(name);
char *curname;
int i,j;
int colonoffset = -1;
 
for (i=0;name[i];i++)
if (name[i] == ':') {
colonoffset = i;
break;
}
 
for (i=*startpos;symbol_table[i].address_le;++i) {
/* Find a ':' in name */
curname = symbol_table[i].symbol_name;
for (j=0; curname[j] && curname[j] != ':'; j++)
;
if (!curname[j])
continue;
j -= colonoffset;
curname += j;
if (strlen(curname) < namelen)
continue;
if (strncmp(curname, name, namelen) == 0) {
*startpos = i;
return curname+namelen;
}
}
return NULL;
}
 
/** Return address that corresponds to the entry
*
* Search symbol table, and if there is one match, return it
*
* @param name Name of the symbol
* @return 0 - Not found, -1 - Duplicate symbol, other - address of symbol
*/
uintptr_t get_symbol_addr(const char *name)
{
count_t found = 0;
uintptr_t addr = NULL;
char *hint;
int i;
 
i = 0;
while ((hint=symtab_search_one(name, &i))) {
if (!strlen(hint)) {
addr = uint64_t_le2host(symbol_table[i].address_le);
found++;
}
i++;
}
if (found > 1)
return ((uintptr_t) -1);
return addr;
}
 
/** Find symbols that match parameter and prints them */
void symtab_print_search(const char *name)
{
int i;
uintptr_t addr;
char *realname;
 
 
i = 0;
while (symtab_search_one(name, &i)) {
addr = uint64_t_le2host(symbol_table[i].address_le);
realname = symbol_table[i].symbol_name;
printf("%.*p: %s\n", sizeof(uintptr_t) * 2, addr, realname);
i++;
}
}
 
/** Symtab completion
*
* @param input - Search string, completes to symbol name
* @returns - 0 - nothing found, 1 - success, >1 print duplicates
*/
int symtab_compl(char *input)
{
char output[MAX_SYMBOL_NAME+1];
int startpos = 0;
char *foundtxt;
int found = 0;
int i;
char *name = input;
 
/* Allow completion of pointers */
if (name[0] == '*' || name[0] == '&')
name++;
 
/* Do not print everything */
if (!strlen(name))
return 0;
 
output[0] = '\0';
 
while ((foundtxt = symtab_search_one(name, &startpos))) {
startpos++;
if (!found)
strncpy(output, foundtxt, strlen(foundtxt)+1);
else {
for (i=0; output[i] && foundtxt[i] && output[i]==foundtxt[i]; i++)
;
output[i] = '\0';
}
found++;
}
if (!found)
return 0;
 
if (found > 1 && !strlen(output)) {
printf("\n");
startpos = 0;
while ((foundtxt = symtab_search_one(name, &startpos))) {
printf("%s\n", symbol_table[startpos].symbol_name);
startpos++;
}
}
strncpy(input, output, MAX_SYMBOL_NAME);
return found;
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/src/cpu/cpu.c
0,0 → 1,114
/*
* 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 generic
* @{
*/
 
/**
* @file
* @brief CPU subsystem initialization and listing.
*/
#include <cpu.h>
#include <arch.h>
#include <arch/cpu.h>
#include <mm/slab.h>
#include <mm/page.h>
#include <mm/frame.h>
#include <arch/types.h>
#include <config.h>
#include <panic.h>
#include <typedefs.h>
#include <memstr.h>
#include <adt/list.h>
#include <print.h>
 
cpu_t *cpus;
 
/** Initialize CPUs
*
* Initialize kernel CPUs support.
*
*/
void cpu_init(void) {
int i, j;
#ifdef CONFIG_SMP
if (config.cpu_active == 1) {
#endif /* CONFIG_SMP */
cpus = (cpu_t *) malloc(sizeof(cpu_t) * config.cpu_count,
FRAME_ATOMIC);
if (!cpus)
panic("malloc/cpus");
 
/* initialize everything */
memsetb((uintptr_t) cpus, sizeof(cpu_t) * config.cpu_count, 0);
 
for (i=0; i < config.cpu_count; i++) {
cpus[i].stack = (uint8_t *) frame_alloc(STACK_FRAMES, FRAME_KA | FRAME_ATOMIC);
cpus[i].id = i;
spinlock_initialize(&cpus[i].lock, "cpu_t.lock");
 
for (j = 0; j < RQ_COUNT; j++) {
spinlock_initialize(&cpus[i].rq[j].lock, "rq_t.lock");
list_initialize(&cpus[i].rq[j].rq_head);
}
}
#ifdef CONFIG_SMP
}
#endif /* CONFIG_SMP */
 
CPU = &cpus[config.cpu_active-1];
CPU->active = 1;
CPU->tlb_active = 1;
cpu_identify();
cpu_arch_init();
}
 
/** List all processors. */
void cpu_list(void)
{
int i;
 
for (i = 0; i < config.cpu_count; i++) {
if (cpus[i].active)
cpu_print_report(&cpus[i]);
else
printf("cpu%d: not active\n", i);
}
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/src/sysinfo/sysinfo.c
0,0 → 1,310
/*
* Copyright (C) 2006 Jakub Vana
* 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 generic
* @{
*/
/** @file
*/
 
#include <sysinfo/sysinfo.h>
#include <mm/slab.h>
#include <print.h>
#include <syscall/copy.h>
 
sysinfo_item_t *_root = NULL;
 
 
static sysinfo_item_t *sysinfo_find_item(const char *name, sysinfo_item_t *subtree)
{
if (subtree == NULL)
return NULL;
while (subtree != NULL) {
int i = 0;
char *a = (char *) name;
char *b = subtree->name;
while ((a[i] == b[i]) && (b[i]))
i++;
if ((!a[i]) && (!b[i])) /* Last name in path matches */
return subtree;
if ((a[i] == '.') && (!b[i])) { /* Middle name in path matches */
if (subtree->subinfo_type == SYSINFO_SUBINFO_TABLE)
return sysinfo_find_item(a + i + 1, subtree->subinfo.table);
//if (subtree->subinfo_type == SYSINFO_SUBINFO_FUNCTION) /* Subinfo managed by subsystem */
// return NULL;
return NULL; /* No subinfo */
}
/* No matches try next */
subtree = subtree->next;
i = 0;
}
return NULL;
}
 
static sysinfo_item_t *sysinfo_create_path(const char *name, sysinfo_item_t **psubtree)
{
sysinfo_item_t *subtree;
subtree = *psubtree;
if (subtree == NULL) {
sysinfo_item_t *item = malloc(sizeof(sysinfo_item_t), 0);
int i = 0, j;
ASSERT(item);
*psubtree = item;
item->next = NULL;
item->val_type = SYSINFO_VAL_UNDEFINED;
item->subinfo.table = NULL;
 
while (name[i] && (name[i] != '.'))
i++;
item->name = malloc(i, 0);
ASSERT(item->name);
 
for (j = 0; j < i; j++)
item->name[j] = name[j];
item->name[j] = 0;
if (name[i]) { /* =='.' */
item->subinfo_type = SYSINFO_SUBINFO_TABLE;
return sysinfo_create_path(name + i + 1, &(item->subinfo.table));
}
item->subinfo_type = SYSINFO_SUBINFO_NONE;
return item;
}
 
while (subtree != NULL) {
int i = 0, j;
char *a = (char *) name;
char *b = subtree->name;
while ((a[i] == b[i]) && (b[i]))
i++;
if ((!a[i]) && (!b[i])) /* Last name in path matches */
return subtree;
if ((a[i] == '.') && (!b[i])) { /* Middle name in path matches */
if (subtree->subinfo_type == SYSINFO_SUBINFO_TABLE)
return sysinfo_create_path(a + i + 1, &(subtree->subinfo.table));
if (subtree->subinfo_type == SYSINFO_SUBINFO_NONE) {
subtree->subinfo_type = SYSINFO_SUBINFO_TABLE;
return sysinfo_create_path(a + i + 1,&(subtree->subinfo.table));
}
//if (subtree->subinfo_type == SYSINFO_SUBINFO_FUNCTION) /* Subinfo managed by subsystem */
// return NULL;
return NULL;
}
/* No matches try next or create new*/
if (subtree->next == NULL) {
sysinfo_item_t *item = malloc(sizeof(sysinfo_item_t), 0);
ASSERT(item);
subtree->next = item;
item->next = NULL;
item->val_type = SYSINFO_VAL_UNDEFINED;
item->subinfo.table = NULL;
 
i = 0;
while (name[i] && (name[i] != '.'))
i++;
 
item->name = malloc(i, 0);
ASSERT(item->name);
for (j = 0; j < i; j++)
item->name[j] = name[j];
item->name[j] = 0;
 
if(name[i]) { /* =='.' */
item->subinfo_type = SYSINFO_SUBINFO_TABLE;
return sysinfo_create_path(name + i + 1, &(item->subinfo.table));
}
item->subinfo_type = SYSINFO_SUBINFO_NONE;
return item;
} else {
subtree = subtree->next;
i = 0;
}
}
panic("Not reached\n");
return NULL;
}
 
void sysinfo_set_item_val(const char *name, sysinfo_item_t **root, unative_t val)
{
if (root == NULL)
root = &_root;
/* If already created create only returns pointer
If not, create it */
sysinfo_item_t *item = sysinfo_create_path(name, root);
if (item != NULL) { /* If in subsystem, unable to create or return so unable to set */
item->val.val=val;
item->val_type = SYSINFO_VAL_VAL;
}
}
 
void sysinfo_set_item_function(const char *name, sysinfo_item_t **root, sysinfo_val_fn_t fn)
{
if (root == NULL)
root = &_root;
/* If already created create only returns pointer
If not, create it */
sysinfo_item_t *item = sysinfo_create_path(name, root);
if (item != NULL) { /* If in subsystem, unable to create or return so unable to set */
item->val.fn=fn;
item->val_type = SYSINFO_VAL_FUNCTION;
}
}
 
 
void sysinfo_set_item_undefined(const char *name, sysinfo_item_t **root)
{
if (root == NULL)
root = &_root;
/* If already created create only returns pointer
If not, create it */
sysinfo_item_t *item = sysinfo_create_path(name, root);
if (item != NULL)
item->val_type = SYSINFO_VAL_UNDEFINED;
}
 
 
void sysinfo_dump(sysinfo_item_t **proot, int depth)
{
sysinfo_item_t *root;
if (proot == NULL)
proot = &_root;
root = *proot;
while (root != NULL) {
int i;
unative_t val = 0;
char *vtype = NULL;
for (i = 0; i < depth; i++)
printf(" ");
switch (root->val_type) {
case SYSINFO_VAL_UNDEFINED:
val = 0;
vtype = "UND";
break;
case SYSINFO_VAL_VAL:
val = root->val.val;
vtype = "VAL";
break;
case SYSINFO_VAL_FUNCTION:
val = ((sysinfo_val_fn_t) (root->val.fn)) (root);
vtype = "FUN";
break;
}
printf("%s %s val:%d(%x) sub:%s\n", root->name, vtype, val, val, (root->subinfo_type == SYSINFO_SUBINFO_NONE) ? "NON" : ((root->subinfo_type == SYSINFO_SUBINFO_TABLE) ? "TAB" : "FUN"));
if (root->subinfo_type == SYSINFO_SUBINFO_TABLE)
sysinfo_dump(&(root -> subinfo.table), depth + 1);
root = root->next;
}
}
 
sysinfo_rettype_t sysinfo_get_val(const char *name, sysinfo_item_t **root)
{
// TODO: Implement Subsystem subinfo (by function implemented subinfo)
 
sysinfo_rettype_t ret = {0, false};
 
if (root == NULL)
root = &_root;
sysinfo_item_t *item = sysinfo_find_item(name, *root);
if (item != NULL) {
if (item->val_type == SYSINFO_VAL_UNDEFINED)
return ret;
else
ret.valid = true;
if (item->val_type == SYSINFO_VAL_VAL)
ret.val = item->val.val;
else
ret.val = ((sysinfo_val_fn_t) (item->val.fn)) (item);
}
return ret;
}
 
unative_t sys_sysinfo_valid(unative_t ptr, unative_t len)
{
char *str;
sysinfo_rettype_t ret = {0, 0};
str = malloc(len + 1, 0);
ASSERT(str);
if (!((copy_from_uspace(str, (void *) ptr, len + 1)) || (str[len])))
ret = sysinfo_get_val(str, NULL);
free(str);
return ret.valid;
}
 
unative_t sys_sysinfo_value(unative_t ptr, unative_t len)
{
char *str;
sysinfo_rettype_t ret = {0, 0};
str = malloc(len + 1, 0);
ASSERT(str);
if (!((copy_from_uspace(str, (void *) ptr, len + 1)) || (str[len])))
ret = sysinfo_get_val(str, NULL);
free(str);
return ret.val;
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/interrupt/interrupt.c
0,0 → 1,153
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 genericinterrupt
* @{
*/
/**
* @file
* @brief Interrupt redirector.
*
* This file provides means of registering interrupt handlers
* by kernel functions and calling the handlers when interrupts
* occur.
*/
 
#include <interrupt.h>
#include <debug.h>
#include <console/kconsole.h>
#include <console/console.h>
#include <console/chardev.h>
#include <console/cmd.h>
#include <panic.h>
#include <print.h>
#include <symtab.h>
 
static struct {
const char *name;
iroutine f;
} exc_table[IVT_ITEMS];
 
SPINLOCK_INITIALIZE(exctbl_lock);
 
/** Register exception handler
*
* @param n Exception number
* @param name Description
* @param f Exception handler
*/
iroutine exc_register(int n, const char *name, iroutine f)
{
ASSERT(n < IVT_ITEMS);
iroutine old;
spinlock_lock(&exctbl_lock);
 
old = exc_table[n].f;
exc_table[n].f = f;
exc_table[n].name = name;
 
spinlock_unlock(&exctbl_lock);
 
return old;
}
 
/** Dispatch exception according to exception table
*
* Called directly from the assembler code.
* CPU is interrupts_disable()'d.
*/
void exc_dispatch(int n, istate_t *istate)
{
ASSERT(n < IVT_ITEMS);
exc_table[n].f(n + IVT_FIRST, istate);
/* This is a safe place to exit exiting thread */
if (THREAD && THREAD->interrupted && istate_from_uspace(istate))
thread_exit();
}
 
/** Default 'null' exception handler */
static void exc_undef(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "Unhandled exception %d.", n);
panic("Unhandled exception %d.", n);
}
 
/** kconsole cmd - print all exceptions */
static int exc_print_cmd(cmd_arg_t *argv)
{
int i;
char *symbol;
 
spinlock_lock(&exctbl_lock);
printf("Exc Description Handler\n");
for (i=0; i < IVT_ITEMS; i++) {
symbol = get_symtab_entry((unative_t)exc_table[i].f);
if (!symbol)
symbol = "not found";
printf("%d %s %.*p(%s)\n", i + IVT_FIRST, exc_table[i].name,
sizeof(uintptr_t) * 2, exc_table[i].f,symbol);
if (!((i+1) % 20)) {
printf("Press any key to continue.");
spinlock_unlock(&exctbl_lock);
getc(stdin);
spinlock_lock(&exctbl_lock);
printf("\n");
}
}
spinlock_unlock(&exctbl_lock);
return 1;
}
 
static cmd_info_t exc_info = {
.name = "exc",
.description = "Print exception table.",
.func = exc_print_cmd,
.help = NULL,
.argc = 0,
.argv = NULL
};
 
/** Initialize generic exception handling support */
void exc_init(void)
{
int i;
 
for (i=0;i < IVT_ITEMS; i++)
exc_register(i, "undef", (iroutine) exc_undef);
 
cmd_initialize(&exc_info);
if (!cmd_register(&exc_info))
panic("could not register command %s\n", exc_info.name);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/time/delay.c
0,0 → 1,68
/*
* 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 time
* @{
*/
 
/**
* @file
* @brief Active delay function.
*/
#include <time/delay.h>
#include <arch/types.h>
#include <cpu.h>
#include <arch/asm.h>
#include <arch.h>
 
/** Active delay
*
* Delay the execution for the given number
* of microseconds (or slightly more). The delay
* is implemented as CPU calibrated active loop.
*
* @param usec Number of microseconds to sleep.
*/
void delay(uint32_t usec)
{
ipl_t ipl;
/*
* The delay loop is calibrated for each and every
* CPU in the system. Therefore it is necessary to
* call interrupts_disable() before calling the
* asm_delay_loop().
*/
ipl = interrupts_disable();
asm_delay_loop(usec * CPU->delay_loop_const);
interrupts_restore(ipl);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/time/timeout.c
0,0 → 1,218
/*
* 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 time
* @{
*/
 
/**
* @file
* @brief Timeout management functions.
*/
 
#include <time/timeout.h>
#include <typedefs.h>
#include <arch/types.h>
#include <config.h>
#include <panic.h>
#include <synch/spinlock.h>
#include <func.h>
#include <cpu.h>
#include <arch/asm.h>
#include <arch.h>
 
 
/** Initialize timeouts
*
* Initialize kernel timeouts.
*
*/
void timeout_init(void)
{
spinlock_initialize(&CPU->timeoutlock, "timeout_lock");
list_initialize(&CPU->timeout_active_head);
}
 
 
/** Reinitialize timeout
*
* Initialize all members except the lock.
*
* @param t Timeout to be initialized.
*
*/
void timeout_reinitialize(timeout_t *t)
{
t->cpu = NULL;
t->ticks = 0;
t->handler = NULL;
t->arg = NULL;
link_initialize(&t->link);
}
 
 
/** Initialize timeout
*
* Initialize all members including the lock.
*
* @param t Timeout to be initialized.
*
*/
void timeout_initialize(timeout_t *t)
{
spinlock_initialize(&t->lock, "timeout_t_lock");
timeout_reinitialize(t);
}
 
 
/** Register timeout
*
* Insert timeout handler f (with argument arg)
* to timeout list and make it execute in
* time microseconds (or slightly more).
*
* @param t Timeout structure.
* @param time Number of usec in the future to execute
* the handler.
* @param f Timeout handler function.
* @param arg Timeout handler argument.
*
*/
void timeout_register(timeout_t *t, uint64_t time, timeout_handler_t f, void *arg)
{
timeout_t *hlp = NULL;
link_t *l, *m;
ipl_t ipl;
uint64_t sum;
 
ipl = interrupts_disable();
spinlock_lock(&CPU->timeoutlock);
spinlock_lock(&t->lock);
 
if (t->cpu)
panic("t->cpu != 0");
 
t->cpu = CPU;
t->ticks = us2ticks(time);
t->handler = f;
t->arg = arg;
 
/*
* Insert t into the active timeouts list according to t->ticks.
*/
sum = 0;
l = CPU->timeout_active_head.next;
while (l != &CPU->timeout_active_head) {
hlp = list_get_instance(l, timeout_t, link);
spinlock_lock(&hlp->lock);
if (t->ticks < sum + hlp->ticks) {
spinlock_unlock(&hlp->lock);
break;
}
sum += hlp->ticks;
spinlock_unlock(&hlp->lock);
l = l->next;
}
 
m = l->prev;
list_prepend(&t->link, m); /* avoid using l->prev */
 
/*
* Adjust t->ticks according to ticks accumulated in h's predecessors.
*/
t->ticks -= sum;
 
/*
* Decrease ticks of t's immediate succesor by t->ticks.
*/
if (l != &CPU->timeout_active_head) {
spinlock_lock(&hlp->lock);
hlp->ticks -= t->ticks;
spinlock_unlock(&hlp->lock);
}
 
spinlock_unlock(&t->lock);
spinlock_unlock(&CPU->timeoutlock);
interrupts_restore(ipl);
}
 
 
/** Unregister timeout
*
* Remove timeout from timeout list.
*
* @param t Timeout to unregister.
*
* @return true on success, false on failure.
*/
bool timeout_unregister(timeout_t *t)
{
timeout_t *hlp;
link_t *l;
ipl_t ipl;
 
grab_locks:
ipl = interrupts_disable();
spinlock_lock(&t->lock);
if (!t->cpu) {
spinlock_unlock(&t->lock);
interrupts_restore(ipl);
return false;
}
if (!spinlock_trylock(&t->cpu->timeoutlock)) {
spinlock_unlock(&t->lock);
interrupts_restore(ipl);
goto grab_locks;
}
/*
* Now we know for sure that t hasn't been activated yet
* and is lurking in t->cpu->timeout_active_head queue.
*/
 
l = t->link.next;
if (l != &t->cpu->timeout_active_head) {
hlp = list_get_instance(l, timeout_t, link);
spinlock_lock(&hlp->lock);
hlp->ticks += t->ticks;
spinlock_unlock(&hlp->lock);
}
list_remove(&t->link);
spinlock_unlock(&t->cpu->timeoutlock);
 
timeout_reinitialize(t);
spinlock_unlock(&t->lock);
 
interrupts_restore(ipl);
return true;
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/time/clock.c
0,0 → 1,191
/*
* 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 time
* @{
*/
 
/**
* @file
* @brief High-level clock interrupt handler.
*
* This file contains the clock() function which is the source
* of preemption. It is also responsible for executing expired
* timeouts.
*/
#include <time/clock.h>
#include <time/timeout.h>
#include <arch/types.h>
#include <config.h>
#include <synch/spinlock.h>
#include <synch/waitq.h>
#include <func.h>
#include <proc/scheduler.h>
#include <cpu.h>
#include <arch.h>
#include <adt/list.h>
#include <atomic.h>
#include <proc/thread.h>
#include <sysinfo/sysinfo.h>
#include <arch/barrier.h>
 
/* Pointers to public variables with time */
struct ptime {
unative_t seconds1;
unative_t useconds;
unative_t seconds2;
};
struct ptime *public_time;
/* Variable holding fragment of second, so that we would update
* seconds correctly
*/
static unative_t secfrag = 0;
 
/** Initialize realtime clock counter
*
* The applications (and sometimes kernel) need to access accurate
* information about realtime data. We allocate 1 page with these
* data and update it periodically.
*
*
*/
void clock_counter_init(void)
{
void *faddr;
 
faddr = frame_alloc(0, FRAME_ATOMIC);
if (!faddr)
panic("Cannot allocate page for clock");
public_time = (struct ptime *)PA2KA(faddr);
 
/* TODO: We would need some arch dependent settings here */
public_time->seconds1 = 0;
public_time->seconds2 = 0;
public_time->useconds = 0;
 
sysinfo_set_item_val("clock.faddr", NULL, (unative_t)faddr);
}
 
 
/** Update public counters
*
* Update it only on first processor
* TODO: Do we really need so many write barriers?
*/
static void clock_update_counters(void)
{
if (CPU->id == 0) {
secfrag += 1000000/HZ;
if (secfrag >= 1000000) {
secfrag -= 1000000;
public_time->seconds1++;
write_barrier();
public_time->useconds = secfrag;
write_barrier();
public_time->seconds2 = public_time->seconds1;
} else
public_time->useconds += 1000000/HZ;
}
}
 
/** Clock routine
*
* Clock routine executed from clock interrupt handler
* (assuming interrupts_disable()'d). Runs expired timeouts
* and preemptive scheduling.
*
*/
void clock(void)
{
link_t *l;
timeout_t *h;
timeout_handler_t f;
void *arg;
count_t missed_clock_ticks = CPU->missed_clock_ticks;
int i;
 
/*
* To avoid lock ordering problems,
* run all expired timeouts as you visit them.
*/
for (i = 0; i <= missed_clock_ticks; i++) {
clock_update_counters();
spinlock_lock(&CPU->timeoutlock);
while ((l = CPU->timeout_active_head.next) != &CPU->timeout_active_head) {
h = list_get_instance(l, timeout_t, link);
spinlock_lock(&h->lock);
if (h->ticks-- != 0) {
spinlock_unlock(&h->lock);
break;
}
list_remove(l);
f = h->handler;
arg = h->arg;
timeout_reinitialize(h);
spinlock_unlock(&h->lock);
spinlock_unlock(&CPU->timeoutlock);
 
f(arg);
 
spinlock_lock(&CPU->timeoutlock);
}
spinlock_unlock(&CPU->timeoutlock);
}
CPU->missed_clock_ticks = 0;
 
/*
* Do CPU usage accounting and find out whether to preempt THREAD.
*/
 
if (THREAD) {
uint64_t ticks;
spinlock_lock(&CPU->lock);
CPU->needs_relink += 1 + missed_clock_ticks;
spinlock_unlock(&CPU->lock);
spinlock_lock(&THREAD->lock);
if ((ticks = THREAD->ticks)) {
if (ticks >= 1 + missed_clock_ticks)
THREAD->ticks -= 1 + missed_clock_ticks;
else
THREAD->ticks = 0;
}
spinlock_unlock(&THREAD->lock);
if (!ticks && !PREEMPTION_DISABLED) {
scheduler();
}
}
 
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/ddi/ddi.c
0,0 → 1,208
/*
* 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 genericddi
* @{
*/
/**
* @file
* @brief Device Driver Interface functions.
*
* This file contains functions that comprise the Device Driver Interface.
* These are the functions for mapping physical memory and enabling I/O
* space to tasks.
*/
 
#include <ddi/ddi.h>
#include <ddi/ddi_arg.h>
#include <proc/task.h>
#include <security/cap.h>
#include <mm/frame.h>
#include <mm/as.h>
#include <synch/spinlock.h>
#include <syscall/copy.h>
#include <arch.h>
#include <align.h>
#include <errno.h>
 
/** Map piece of physical memory into virtual address space of current task.
*
* @param pf Physical frame address of the starting frame.
* @param vp Virtual page address of the starting page.
* @param pages Number of pages to map.
* @param flags Address space area flags for the mapping.
*
* @return 0 on success, EPERM if the caller lacks capabilities to use this syscall,
* ENOENT if there is no task matching the specified ID and ENOMEM if
* there was a problem in creating address space area.
*/
static int ddi_physmem_map(uintptr_t pf, uintptr_t vp, count_t pages, int flags)
{
ipl_t ipl;
cap_t caps;
mem_backend_data_t backend_data;
 
backend_data.base = pf;
backend_data.frames = pages;
/*
* Make sure the caller is authorised to make this syscall.
*/
caps = cap_get(TASK);
if (!(caps & CAP_MEM_MANAGER))
return EPERM;
 
ipl = interrupts_disable();
spinlock_lock(&TASK->lock);
if (!as_area_create(TASK->as, flags, pages * PAGE_SIZE, vp, AS_AREA_ATTR_NONE,
&phys_backend, &backend_data)) {
/*
* The address space area could not have been created.
* We report it using ENOMEM.
*/
spinlock_unlock(&TASK->lock);
interrupts_restore(ipl);
return ENOMEM;
}
/*
* Mapping is created on-demand during page fault.
*/
spinlock_unlock(&TASK->lock);
interrupts_restore(ipl);
return 0;
}
 
/** Enable range of I/O space for task.
*
* @param id Task ID of the destination task.
* @param ioaddr Starting I/O address.
* @param size Size of the enabled I/O space..
*
* @return 0 on success, EPERM if the caller lacks capabilities to use this syscall,
* ENOENT if there is no task matching the specified ID.
*/
static int ddi_iospace_enable(task_id_t id, uintptr_t ioaddr, size_t size)
{
ipl_t ipl;
cap_t caps;
task_t *t;
int rc;
/*
* Make sure the caller is authorised to make this syscall.
*/
caps = cap_get(TASK);
if (!(caps & CAP_IO_MANAGER))
return EPERM;
ipl = interrupts_disable();
spinlock_lock(&tasks_lock);
t = task_find_by_id(id);
if (!t) {
/*
* There is no task with the specified ID.
*/
spinlock_unlock(&tasks_lock);
interrupts_restore(ipl);
return ENOENT;
}
 
/* Lock the task and release the lock protecting tasks_btree. */
spinlock_lock(&t->lock);
spinlock_unlock(&tasks_lock);
 
rc = ddi_iospace_enable_arch(t, ioaddr, size);
spinlock_unlock(&t->lock);
interrupts_restore(ipl);
return rc;
}
 
/** Wrapper for SYS_MAP_PHYSMEM syscall.
*
* @param phys_base Physical base address to map
* @param virt_base Destination virtual address
* @param pages Number of pages
* @param flags Flags of newly mapped pages
*
* @return 0 on success, otherwise it returns error code found in errno.h
*/
unative_t sys_physmem_map(unative_t phys_base, unative_t virt_base, unative_t pages,
unative_t flags)
{
return (unative_t) ddi_physmem_map(ALIGN_DOWN((uintptr_t) phys_base, FRAME_SIZE),
ALIGN_DOWN((uintptr_t) virt_base, PAGE_SIZE), (count_t) pages,
(int) flags);
}
 
/** Wrapper for SYS_ENABLE_IOSPACE syscall.
*
* @param uspace_io_arg User space address of DDI argument structure.
*
* @return 0 on success, otherwise it returns error code found in errno.h
*/
unative_t sys_iospace_enable(ddi_ioarg_t *uspace_io_arg)
{
ddi_ioarg_t arg;
int rc;
rc = copy_from_uspace(&arg, uspace_io_arg, sizeof(ddi_ioarg_t));
if (rc != 0)
return (unative_t) rc;
return (unative_t) ddi_iospace_enable((task_id_t) arg.task_id, (uintptr_t) arg.ioaddr, (size_t) arg.size);
}
 
/** Disable or enable preemption.
*
* @param enable If non-zero, the preemption counter will be decremented, leading to potential
* enabling of preemption. Otherwise the preemption counter will be incremented,
* preventing preemption from occurring.
*
* @return Zero on success or EPERM if callers capabilities are not sufficient.
*/
unative_t sys_preempt_control(int enable)
{
if (! cap_get(TASK) & CAP_PREEMPT_CONTROL)
return EPERM;
if (enable)
preemption_enable();
else
preemption_disable();
return 0;
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/src/printf/printf_core.c
0,0 → 1,724
/*
* Copyright (C) 2001-2004 Jakub Jermar
* Copyright (C) 2006 Josef Cejka
* 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 generic
* @{
*/
/**
* @file
* @brief Printing functions.
*/
 
#include <printf/printf_core.h>
#include <putchar.h>
#include <print.h>
#include <synch/spinlock.h>
#include <arch/arg.h>
#include <arch/asm.h>
 
#include <arch.h>
 
SPINLOCK_INITIALIZE(printflock); /**< printf spinlock */
 
#define __PRINTF_FLAG_PREFIX 0x00000001 /**< show prefixes 0x or 0*/
#define __PRINTF_FLAG_SIGNED 0x00000002 /**< signed / unsigned number */
#define __PRINTF_FLAG_ZEROPADDED 0x00000004 /**< print leading zeroes */
#define __PRINTF_FLAG_LEFTALIGNED 0x00000010 /**< align to left */
#define __PRINTF_FLAG_SHOWPLUS 0x00000020 /**< always show + sign */
#define __PRINTF_FLAG_SPACESIGN 0x00000040 /**< print space instead of plus */
#define __PRINTF_FLAG_BIGCHARS 0x00000080 /**< show big characters */
#define __PRINTF_FLAG_NEGATIVE 0x00000100 /**< number has - sign */
 
#define PRINT_NUMBER_BUFFER_SIZE (64+5) /**< Buffer big enought for 64 bit number
* printed in base 2, sign, prefix and
* 0 to terminate string.. (last one is only for better testing
* end of buffer by zero-filling subroutine)*/
 
/** Enumeration of possible arguments types.
*/
typedef enum {
PrintfQualifierByte = 0,
PrintfQualifierShort,
PrintfQualifierInt,
PrintfQualifierLong,
PrintfQualifierLongLong,
PrintfQualifierNative,
PrintfQualifierPointer
} qualifier_t;
 
static char digits_small[] = "0123456789abcdef"; /**< Small hexadecimal characters */
static char digits_big[] = "0123456789ABCDEF"; /**< Big hexadecimal characters */
 
/** Checks c for a digit.
* @param c One character.
* @return nonzero if c is from interval '0 to '9'.
*/
static inline int isdigit(int c)
{
return ((c >= '0' )&&( c <= '9'));
}
 
/** Compute length of given zero terminated string.
* @param str Pointer to valid string.
* @return string length without trailing zero.
*/
static unative_t strlen(const char *str)
{
unative_t counter = 0;
 
while (str[counter] != 0) {
counter++;
}
 
return counter;
}
 
/** Print count chars from buffer without adding newline
* @param buf Buffer with size at least count bytes - NULL pointer NOT allowed!
* @param count
* @param ps output method and its data
* @return number of printed characters
*/
static int printf_putnchars(const char * buf, size_t count, struct printf_spec *ps)
{
return ps->write((void *)buf, count, ps->data);
}
 
/** Print string without added newline
* @param str string to print
* @param ps write function specification and support data
* @return number of printed characters
*/
static int printf_putstr(const char * str, struct printf_spec *ps)
{
size_t count;
if (str == NULL) {
return printf_putnchars("(NULL)", 6, ps);
}
 
count = strlen(str);
 
return ps->write((void *) str, count, ps->data);
}
 
/** Print one character to output
* @param c one character
* @param ps output method
* @return number of printed characters
*/
static int printf_putchar(int c, struct printf_spec *ps)
{
unsigned char ch = c;
return ps->write((void *) &ch, 1, ps->data);
}
 
/** Print one formatted character
* @param c character to print
* @param width
* @param flags
* @return number of printed characters, negative value on fail
*/
static int print_char(char c, int width, uint64_t flags, struct printf_spec *ps)
{
int counter = 0;
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
while (--width > 0) { /* one space is consumed by character itself hence predecrement */
if (printf_putchar(' ', ps) > 0)
++counter;
}
}
if (printf_putchar(c, ps) > 0)
counter++;
 
while (--width > 0) { /* one space is consumed by character itself hence predecrement */
if (printf_putchar(' ', ps) > 0)
++counter;
}
return ++counter;
}
 
/** Print one string
* @param s string
* @param width
* @param precision
* @param flags
* @return number of printed characters or negative value on fail
*/
static int print_string(char *s, int width, int precision, uint64_t flags, struct printf_spec *ps)
{
int counter = 0;
size_t size;
int retval;
 
if (s == NULL) {
return printf_putstr("(NULL)", ps);
}
size = strlen(s);
 
/* print leading spaces */
 
if (precision == 0)
precision = size;
 
width -= precision;
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
counter++;
}
}
 
while (precision > size) {
precision--;
if (printf_putchar(' ', ps) == 1)
++counter;
}
if ((retval = printf_putnchars(s, precision, ps)) < 0) {
return -counter;
}
counter += retval;
 
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
++counter;
}
return counter;
}
 
 
/** Print number in given base
*
* Print significant digits of a number in given
* base.
*
* @param num Number to print.
* @param width
* @param precision
* @param base Base to print the number in (should
* be in range 2 .. 16).
* @param flags output modifiers
* @return number of written characters or EOF
*
*/
static int print_number(uint64_t num, int width, int precision, int base , uint64_t flags, struct printf_spec *ps)
{
char *digits = digits_small;
char d[PRINT_NUMBER_BUFFER_SIZE]; /* this is good enough even for base == 2, prefix and sign */
char *ptr = &d[PRINT_NUMBER_BUFFER_SIZE - 1];
int size = 0; /* size of number with all prefixes and signs */
int number_size; /* size of plain number */
char sgn;
int retval;
int counter = 0;
if (flags & __PRINTF_FLAG_BIGCHARS)
digits = digits_big;
*ptr-- = 0; /* Put zero at end of string */
 
if (num == 0) {
*ptr-- = '0';
size++;
} else {
do {
*ptr-- = digits[num % base];
size++;
} while (num /= base);
}
number_size = size;
 
/* Collect sum of all prefixes/signs/... to calculate padding and leading zeroes */
if (flags & __PRINTF_FLAG_PREFIX) {
switch(base) {
case 2: /* Binary formating is not standard, but usefull */
size += 2;
break;
case 8:
size++;
break;
case 16:
size += 2;
break;
}
}
 
sgn = 0;
if (flags & __PRINTF_FLAG_SIGNED) {
if (flags & __PRINTF_FLAG_NEGATIVE) {
sgn = '-';
size++;
} else if (flags & __PRINTF_FLAG_SHOWPLUS) {
sgn = '+';
size++;
} else if (flags & __PRINTF_FLAG_SPACESIGN) {
sgn = ' ';
size++;
}
}
 
if (flags & __PRINTF_FLAG_LEFTALIGNED) {
flags &= ~__PRINTF_FLAG_ZEROPADDED;
}
 
/* if number is leftaligned or precision is specified then zeropadding is ignored */
if (flags & __PRINTF_FLAG_ZEROPADDED) {
if ((precision == 0) && (width > size)) {
precision = width - size + number_size;
}
}
 
/* print leading spaces */
if (number_size > precision) /* We must print whole number not only a part */
precision = number_size;
 
width -= precision + size - number_size;
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
counter++;
}
}
/* print sign */
if (sgn) {
if (printf_putchar(sgn, ps) == 1)
counter++;
}
/* print prefix */
if (flags & __PRINTF_FLAG_PREFIX) {
switch(base) {
case 2: /* Binary formating is not standard, but usefull */
if (printf_putchar('0', ps) == 1)
counter++;
if (flags & __PRINTF_FLAG_BIGCHARS) {
if (printf_putchar('B', ps) == 1)
counter++;
} else {
if (printf_putchar('b', ps) == 1)
counter++;
}
break;
case 8:
if (printf_putchar('o', ps) == 1)
counter++;
break;
case 16:
if (printf_putchar('0', ps) == 1)
counter++;
if (flags & __PRINTF_FLAG_BIGCHARS) {
if (printf_putchar('X', ps) == 1)
counter++;
} else {
if (printf_putchar('x', ps) == 1)
counter++;
}
break;
}
}
 
/* print leading zeroes */
precision -= number_size;
while (precision-- > 0) {
if (printf_putchar('0', ps) == 1)
counter++;
}
 
/* print number itself */
 
if ((retval = printf_putstr(++ptr, ps)) > 0) {
counter += retval;
}
/* print ending spaces */
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
counter++;
}
 
return counter;
}
 
 
/** Print formatted string.
*
* Print string formatted according to the fmt parameter
* and variadic arguments. Each formatting directive
* must have the following form:
*
* \% [ FLAGS ] [ WIDTH ] [ .PRECISION ] [ TYPE ] CONVERSION
*
* FLAGS:@n
* - "#" Force to print prefix.
* For conversion \%o the prefix is 0, for %x and \%X prefixes are 0x and 0X
* and for conversion \%b the prefix is 0b.
*
* - "-" Align to left.
*
* - "+" Print positive sign just as negative.
*
* - " " If the printed number is positive and "+" flag is not set, print space in
* place of sign.
*
* - "0" Print 0 as padding instead of spaces. Zeroes are placed between sign and the
* rest of the number. This flag is ignored if "-" flag is specified.
*
* WIDTH:@n
* - Specify minimal width of printed argument. If it is bigger, width is ignored.
* If width is specified with a "*" character instead of number, width is taken from
* parameter list. And integer parameter is expected before parameter for processed
* conversion specification. If this value is negative its absolute value is taken
* and the "-" flag is set.
*
* PRECISION:@n
* - Value precision. For numbers it specifies minimum valid numbers.
* Smaller numbers are printed with leading zeroes. Bigger numbers are not affected.
* Strings with more than precision characters are cut off.
* Just as with width, an "*" can be used used instead of a number.
* An integer value is then expected in parameters. When both width and precision
* are specified using "*", the first parameter is used for width and the second one
* for precision.
*
* TYPE:@n
* - "hh" Signed or unsigned char.@n
* - "h" Signed or usigned short.@n
* - "" Signed or usigned int (default value).@n
* - "l" Signed or usigned long int.@n
* - "ll" Signed or usigned long long int.@n
* - "z" unative_t (non-standard extension).@n
*
*
* CONVERSION:@n
* - % Print percentile character itself.
*
* - c Print single character.
*
* - s Print zero terminated string. If a NULL value is passed as value, "(NULL)" is printed instead.
*
* - P, p Print value of a pointer. Void * value is expected and it is printed in hexadecimal notation with prefix
* (as with \%#X or \%#x for 32bit or \%#X / \%#x for 64bit long pointers).
*
* - b Print value as unsigned binary number. Prefix is not printed by default. (Nonstandard extension.)
*
* - o Print value as unsigned octal number. Prefix is not printed by default.
*
* - d,i Print signed decimal number. There is no difference between d and i conversion.
*
* - u Print unsigned decimal number.
*
* - X, x Print hexadecimal number with upper- or lower-case. Prefix is not printed by default.
*
* All other characters from fmt except the formatting directives
* are printed in verbatim.
*
* @param fmt Formatting NULL terminated string.
* @return Number of printed characters or negative value on failure.
*/
int printf_core(const char *fmt, struct printf_spec *ps, va_list ap)
{
int irqpri;
int i = 0, j = 0; /**< i is index of currently processed char from fmt, j is index to the first not printed nonformating character */
int end;
int counter; /**< counter of printed characters */
int retval; /**< used to store return values from called functions */
char c;
qualifier_t qualifier; /* type of argument */
int base; /**< base in which will be parameter (numbers only) printed */
uint64_t number; /**< argument value */
size_t size; /**< byte size of integer parameter */
int width, precision;
uint64_t flags;
counter = 0;
irqpri = interrupts_disable();
spinlock_lock(&printflock);
 
while ((c = fmt[i])) {
/* control character */
if (c == '%' ) {
/* print common characters if any processed */
if (i > j) {
if ((retval = printf_putnchars(&fmt[j], (size_t)(i - j), ps)) < 0) { /* error */
counter = -counter;
goto out;
}
counter += retval;
}
j = i;
/* parse modifiers */
flags = 0;
end = 0;
do {
++i;
switch (c = fmt[i]) {
case '#': flags |= __PRINTF_FLAG_PREFIX; break;
case '-': flags |= __PRINTF_FLAG_LEFTALIGNED; break;
case '+': flags |= __PRINTF_FLAG_SHOWPLUS; break;
case ' ': flags |= __PRINTF_FLAG_SPACESIGN; break;
case '0': flags |= __PRINTF_FLAG_ZEROPADDED; break;
default: end = 1;
};
} while (end == 0);
/* width & '*' operator */
width = 0;
if (isdigit(fmt[i])) {
while (isdigit(fmt[i])) {
width *= 10;
width += fmt[i++] - '0';
}
} else if (fmt[i] == '*') {
/* get width value from argument list*/
i++;
width = (int)va_arg(ap, int);
if (width < 0) {
/* negative width means to set '-' flag */
width *= -1;
flags |= __PRINTF_FLAG_LEFTALIGNED;
}
}
/* precision and '*' operator */
precision = 0;
if (fmt[i] == '.') {
++i;
if (isdigit(fmt[i])) {
while (isdigit(fmt[i])) {
precision *= 10;
precision += fmt[i++] - '0';
}
} else if (fmt[i] == '*') {
/* get precision value from argument list*/
i++;
precision = (int)va_arg(ap, int);
if (precision < 0) {
/* negative precision means to ignore it */
precision = 0;
}
}
}
 
switch (fmt[i++]) {
/** TODO: unimplemented qualifiers:
* t ptrdiff_t - ISO C 99
*/
case 'h': /* char or short */
qualifier = PrintfQualifierShort;
if (fmt[i] == 'h') {
i++;
qualifier = PrintfQualifierByte;
}
break;
case 'l': /* long or long long*/
qualifier = PrintfQualifierLong;
if (fmt[i] == 'l') {
i++;
qualifier = PrintfQualifierLongLong;
}
break;
case 'z': /* unative_t */
qualifier = PrintfQualifierNative;
break;
default:
qualifier = PrintfQualifierInt; /* default type */
--i;
}
base = 10;
 
switch (c = fmt[i]) {
 
/*
* String and character conversions.
*/
case 's':
if ((retval = print_string(va_arg(ap, char*), width, precision, flags, ps)) < 0) {
counter = -counter;
goto out;
};
counter += retval;
j = i + 1;
goto next_char;
case 'c':
c = va_arg(ap, unsigned int);
if ((retval = print_char(c, width, flags, ps)) < 0) {
counter = -counter;
goto out;
};
counter += retval;
j = i + 1;
goto next_char;
 
/*
* Integer values
*/
case 'P': /* pointer */
flags |= __PRINTF_FLAG_BIGCHARS;
case 'p':
flags |= __PRINTF_FLAG_PREFIX;
base = 16;
qualifier = PrintfQualifierPointer;
break;
case 'b':
base = 2;
break;
case 'o':
base = 8;
break;
case 'd':
case 'i':
flags |= __PRINTF_FLAG_SIGNED;
case 'u':
break;
case 'X':
flags |= __PRINTF_FLAG_BIGCHARS;
case 'x':
base = 16;
break;
/* percentile itself */
case '%':
j = i;
goto next_char;
/*
* Bad formatting.
*/
default:
/* Unknown format
* now, the j is index of '%' so we will
* print whole bad format sequence
*/
goto next_char;
}
/* Print integers */
/* print number */
switch (qualifier) {
case PrintfQualifierByte:
size = sizeof(unsigned char);
number = (uint64_t)va_arg(ap, unsigned int);
break;
case PrintfQualifierShort:
size = sizeof(unsigned short);
number = (uint64_t)va_arg(ap, unsigned int);
break;
case PrintfQualifierInt:
size = sizeof(unsigned int);
number = (uint64_t)va_arg(ap, unsigned int);
break;
case PrintfQualifierLong:
size = sizeof(unsigned long);
number = (uint64_t)va_arg(ap, unsigned long);
break;
case PrintfQualifierLongLong:
size = sizeof(unsigned long long);
number = (uint64_t)va_arg(ap, unsigned long long);
break;
case PrintfQualifierPointer:
size = sizeof(void *);
number = (uint64_t)(unsigned long)va_arg(ap, void *);
break;
case PrintfQualifierNative:
size = sizeof(unative_t);
number = (uint64_t)va_arg(ap, unative_t);
break;
default: /* Unknown qualifier */
counter = -counter;
goto out;
}
if (flags & __PRINTF_FLAG_SIGNED) {
if (number & (0x1 << (size*8 - 1))) {
flags |= __PRINTF_FLAG_NEGATIVE;
if (size == sizeof(uint64_t)) {
number = -((int64_t)number);
} else {
number = ~number;
number &= (~((0xFFFFFFFFFFFFFFFFll) << (size * 8)));
number++;
}
}
}
 
if ((retval = print_number(number, width, precision, base, flags, ps)) < 0) {
counter = -counter;
goto out;
};
 
counter += retval;
j = i + 1;
}
next_char:
++i;
}
if (i > j) {
if ((retval = printf_putnchars(&fmt[j], (unative_t)(i - j), ps)) < 0) { /* error */
counter = -counter;
goto out;
}
counter += retval;
}
 
out:
spinlock_unlock(&printflock);
interrupts_restore(irqpri);
return counter;
}
 
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/src/printf/printf.c
0,0 → 1,54
/*
* Copyright (C) 2006 Josef Cejka
* 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 generic
* @{
*/
/** @file
*/
 
#include <print.h>
 
int printf(const char *fmt, ...)
{
int ret;
va_list args;
 
va_start(args, fmt);
 
ret = vprintf(fmt, args);
va_end(args);
 
return ret;
}
 
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/src/printf/snprintf.c
0,0 → 1,53
/*
* Copyright (C) 2006 Josef Cejka
* 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 generic
* @{
*/
/** @file
*/
 
#include <print.h>
#include <printf/printf_core.h>
 
int snprintf(char *str, size_t size, const char *fmt, ...)
{
int ret;
va_list args;
va_start(args, fmt);
ret = vsnprintf(str, size, fmt, args);
 
va_end(args);
 
return ret;
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/src/printf/sprintf.c
0,0 → 1,52
/*
* Copyright (C) 2006 Josef Cejka
* 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 generic
* @{
*/
/** @file
*/
 
#include <print.h>
 
int sprintf(char *str, const char *fmt, ...)
{
int ret;
va_list args;
va_start(args, fmt);
ret = vsprintf(str, fmt, args);
 
va_end(args);
 
return ret;
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/src/printf/vprintf.c
0,0 → 1,60
/*
* Copyright (C) 2006 Josef Cejka
* 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 generic
* @{
*/
/** @file
*/
 
#include <print.h>
#include <printf/printf_core.h>
#include <putchar.h>
 
int vprintf_write(const char *str, size_t count, void *unused);
 
int vprintf_write(const char *str, size_t count, void *unused)
{
size_t i = 0;
for (; i < count; i++)
putchar(str[i]);
return i;
}
 
int vprintf(const char *fmt, va_list ap)
{
struct printf_spec ps = {(int(*)(void *, size_t, void *))vprintf_write, NULL};
return printf_core(fmt, &ps, ap);
 
}
 
 
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/src/printf/vsnprintf.c
0,0 → 1,105
/*
* Copyright (C) 2006 Josef Cejka
* 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 generic
* @{
*/
/** @file
*/
 
#include <print.h>
#include <printf/printf_core.h>
#include <memstr.h>
 
struct vsnprintf_data {
size_t size; /* total space for string */
size_t len; /* count of currently used characters */
char *string; /* destination string */
};
 
int vsnprintf_write(const char *str, size_t count, struct vsnprintf_data *data);
 
/** Write string to given buffer.
* Write at most data->size characters including trailing zero. According to C99, snprintf() has to return number
* of characters that would have been written if enough space had been available. Hence the return value is not
* number of really printed characters but size of the input string. Number of really used characters
* is stored in data->len.
* @param str source string to print
* @param count size of source string
* @param data structure with destination string, counter of used space and total string size.
* @return number of characters to print (not characters really printed!)
*/
int vsnprintf_write(const char *str, size_t count, struct vsnprintf_data *data)
{
size_t i;
i = data->size - data->len;
 
if (i == 0) {
return count;
}
if (i == 1) {
/* We have only one free byte left in buffer => write there trailing zero */
data->string[data->size - 1] = 0;
data->len = data->size;
return count;
}
if (i <= count) {
/* We have not enought space for whole string with the trailing zero => print only a part of string */
memcpy((void *)(data->string + data->len), (void *)str, i - 1);
data->string[data->size - 1] = 0;
data->len = data->size;
return count;
}
/* Buffer is big enought to print whole string */
memcpy((void *)(data->string + data->len), (void *)str, count);
data->len += count;
/* Put trailing zero at end, but not count it into data->len so it could be rewritten next time */
data->string[data->len] = 0;
 
return count;
}
 
int vsnprintf(char *str, size_t size, const char *fmt, va_list ap)
{
struct vsnprintf_data data = {size, 0, str};
struct printf_spec ps = {(int(*)(void *, size_t, void *))vsnprintf_write, &data};
 
/* Print 0 at end of string - fix the case that nothing will be printed */
if (size > 0)
str[0] = 0;
/* vsnprintf_write ensures that str will be terminated by zero. */
return printf_core(fmt, &ps, ap);
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/src/printf/vsprintf.c
0,0 → 1,45
/*
* Copyright (C) 2006 Josef Cejka
* 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 generic
* @{
*/
/** @file
*/
 
#include <print.h>
 
int vsprintf(char *str, const char *fmt, va_list ap)
{
return vsnprintf(str, (size_t)-1, fmt, ap);
}
 
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/src/console/console.c
0,0 → 1,170
/*
* Copyright (C) 2003 Josef Cejka
* 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 genericconsole
* @{
*/
/** @file
*/
 
#include <console/console.h>
#include <console/chardev.h>
#include <synch/waitq.h>
#include <synch/spinlock.h>
#include <arch/types.h>
#include <typedefs.h>
#include <arch.h>
#include <func.h>
#include <print.h>
#include <atomic.h>
 
#define BUFLEN 2048
static char debug_buffer[BUFLEN];
static size_t offset = 0;
/** Initialize stdout to something that does not print, but does not fail
*
* Save data in some buffer so that it could be retrieved in the debugger
*/
static void null_putchar(chardev_t *d, const char ch)
{
if (offset >= BUFLEN)
offset = 0;
debug_buffer[offset++] = ch;
}
 
static chardev_operations_t null_stdout_ops = {
.write = null_putchar
};
chardev_t null_stdout = {
.name = "null",
.op = &null_stdout_ops
};
 
/** Standard input character device. */
chardev_t *stdin = NULL;
chardev_t *stdout = &null_stdout;
 
/** Get character from character device. Do not echo character.
*
* @param chardev Character device.
*
* @return Character read.
*/
uint8_t _getc(chardev_t *chardev)
{
uint8_t ch;
ipl_t ipl;
 
if (atomic_get(&haltstate)) {
/* If we are here, we are hopefully on the processor, that
* issued the 'halt' command, so proceed to read the character
* directly from input
*/
if (chardev->op->read)
return chardev->op->read(chardev);
/* no other way of interacting with user, halt */
if (CPU)
printf("cpu%d: ", CPU->id);
else
printf("cpu: ");
printf("halted - no kconsole\n");
cpu_halt();
}
 
waitq_sleep(&chardev->wq);
ipl = interrupts_disable();
spinlock_lock(&chardev->lock);
ch = chardev->buffer[(chardev->index - chardev->counter) % CHARDEV_BUFLEN];
chardev->counter--;
spinlock_unlock(&chardev->lock);
interrupts_restore(ipl);
 
chardev->op->resume(chardev);
 
return ch;
}
 
/** Get string from character device.
*
* Read characters from character device until first occurrence
* of newline character.
*
* @param chardev Character device.
* @param buf Buffer where to store string terminated by '\0'.
* @param buflen Size of the buffer.
*
* @return Number of characters read.
*/
count_t gets(chardev_t *chardev, char *buf, size_t buflen)
{
index_t index = 0;
char ch;
 
while (index < buflen) {
ch = _getc(chardev);
if (ch == '\b') {
if (index > 0) {
index--;
/* Space backspace, space */
putchar('\b');
putchar(' ');
putchar('\b');
}
continue;
}
putchar(ch);
 
if (ch == '\n') { /* end of string => write 0, return */
buf[index] = '\0';
return (count_t) index;
}
buf[index++] = ch;
}
return (count_t) index;
}
 
/** Get character from device & echo it to screen */
uint8_t getc(chardev_t *chardev)
{
uint8_t ch;
 
ch = _getc(chardev);
putchar(ch);
return ch;
}
 
void putchar(char c)
{
if (stdout->op->write)
stdout->op->write(stdout, c);
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/src/console/cmd.c
0,0 → 1,811
/*
* 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 genericconsole
* @{
*/
 
/**
* @file cmd.c
* @brief Kernel console command wrappers.
*
* This file is meant to contain all wrapper functions for
* all kconsole commands. The point is in separating
* kconsole specific wrappers from kconsole-unaware functions
* from other subsystems.
*/
 
#include <console/cmd.h>
#include <console/console.h>
#include <console/kconsole.h>
#include <print.h>
#include <panic.h>
#include <typedefs.h>
#include <arch/types.h>
#include <adt/list.h>
#include <arch.h>
#include <func.h>
#include <macros.h>
#include <debug.h>
#include <symtab.h>
#include <cpu.h>
#include <mm/tlb.h>
#include <arch/mm/tlb.h>
#include <mm/frame.h>
#include <main/version.h>
#include <mm/slab.h>
#include <proc/scheduler.h>
#include <proc/thread.h>
#include <proc/task.h>
#include <ipc/ipc.h>
#include <ipc/irq.h>
 
/* Data and methods for 'help' command. */
static int cmd_help(cmd_arg_t *argv);
static cmd_info_t help_info = {
.name = "help",
.description = "List of supported commands.",
.func = cmd_help,
.argc = 0
};
 
static cmd_info_t exit_info = {
.name = "exit",
.description ="Exit kconsole",
.argc = 0
};
 
static int cmd_continue(cmd_arg_t *argv);
static cmd_info_t continue_info = {
.name = "continue",
.description ="Return console back to userspace.",
.func = cmd_continue,
.argc = 0
};
 
/* Data and methods for 'description' command. */
static int cmd_desc(cmd_arg_t *argv);
static void desc_help(void);
static char desc_buf[MAX_CMDLINE+1];
static cmd_arg_t desc_argv = {
.type = ARG_TYPE_STRING,
.buffer = desc_buf,
.len = sizeof(desc_buf)
};
static cmd_info_t desc_info = {
.name = "describe",
.description = "Describe specified command.",
.help = desc_help,
.func = cmd_desc,
.argc = 1,
.argv = &desc_argv
};
 
/* Data and methods for 'symaddr' command. */
static int cmd_symaddr(cmd_arg_t *argv);
static char symaddr_buf[MAX_CMDLINE+1];
static cmd_arg_t symaddr_argv = {
.type = ARG_TYPE_STRING,
.buffer = symaddr_buf,
.len = sizeof(symaddr_buf)
};
static cmd_info_t symaddr_info = {
.name = "symaddr",
.description = "Return symbol address.",
.func = cmd_symaddr,
.argc = 1,
.argv = &symaddr_argv
};
 
static char set_buf[MAX_CMDLINE+1];
static int cmd_set4(cmd_arg_t *argv);
static cmd_arg_t set4_argv[] = {
{
.type = ARG_TYPE_STRING,
.buffer = set_buf,
.len = sizeof(set_buf)
},
{
.type = ARG_TYPE_INT
}
};
static cmd_info_t set4_info = {
.name = "set4",
.description = "set <dest_addr> <value> - 4byte version",
.func = cmd_set4,
.argc = 2,
.argv = set4_argv
};
 
/* Data and methods for 'call0' command. */
static char call0_buf[MAX_CMDLINE+1];
static char carg1_buf[MAX_CMDLINE+1];
static char carg2_buf[MAX_CMDLINE+1];
static char carg3_buf[MAX_CMDLINE+1];
 
static int cmd_call0(cmd_arg_t *argv);
static cmd_arg_t call0_argv = {
.type = ARG_TYPE_STRING,
.buffer = call0_buf,
.len = sizeof(call0_buf)
};
static cmd_info_t call0_info = {
.name = "call0",
.description = "call0 <function> -> call function().",
.func = cmd_call0,
.argc = 1,
.argv = &call0_argv
};
 
/* Data and methods for 'call1' command. */
static int cmd_call1(cmd_arg_t *argv);
static cmd_arg_t call1_argv[] = {
{
.type = ARG_TYPE_STRING,
.buffer = call0_buf,
.len = sizeof(call0_buf)
},
{
.type = ARG_TYPE_VAR,
.buffer = carg1_buf,
.len = sizeof(carg1_buf)
}
};
static cmd_info_t call1_info = {
.name = "call1",
.description = "call1 <function> <arg1> -> call function(arg1).",
.func = cmd_call1,
.argc = 2,
.argv = call1_argv
};
 
/* Data and methods for 'call2' command. */
static int cmd_call2(cmd_arg_t *argv);
static cmd_arg_t call2_argv[] = {
{
.type = ARG_TYPE_STRING,
.buffer = call0_buf,
.len = sizeof(call0_buf)
},
{
.type = ARG_TYPE_VAR,
.buffer = carg1_buf,
.len = sizeof(carg1_buf)
},
{
.type = ARG_TYPE_VAR,
.buffer = carg2_buf,
.len = sizeof(carg2_buf)
}
};
static cmd_info_t call2_info = {
.name = "call2",
.description = "call2 <function> <arg1> <arg2> -> call function(arg1,arg2).",
.func = cmd_call2,
.argc = 3,
.argv = call2_argv
};
 
/* Data and methods for 'call3' command. */
static int cmd_call3(cmd_arg_t *argv);
static cmd_arg_t call3_argv[] = {
{
.type = ARG_TYPE_STRING,
.buffer = call0_buf,
.len = sizeof(call0_buf)
},
{
.type = ARG_TYPE_VAR,
.buffer = carg1_buf,
.len = sizeof(carg1_buf)
},
{
.type = ARG_TYPE_VAR,
.buffer = carg2_buf,
.len = sizeof(carg2_buf)
},
{
.type = ARG_TYPE_VAR,
.buffer = carg3_buf,
.len = sizeof(carg3_buf)
}
 
};
static cmd_info_t call3_info = {
.name = "call3",
.description = "call3 <function> <arg1> <arg2> <arg3> -> call function(arg1,arg2,arg3).",
.func = cmd_call3,
.argc = 4,
.argv = call3_argv
};
 
/* Data and methods for 'halt' command. */
static int cmd_halt(cmd_arg_t *argv);
static cmd_info_t halt_info = {
.name = "halt",
.description = "Halt the kernel.",
.func = cmd_halt,
.argc = 0
};
 
/* Data and methods for 'tlb' command. */
static int cmd_tlb(cmd_arg_t *argv);
cmd_info_t tlb_info = {
.name = "tlb",
.description = "Print TLB of current processor.",
.help = NULL,
.func = cmd_tlb,
.argc = 0,
.argv = NULL
};
 
static int cmd_threads(cmd_arg_t *argv);
static cmd_info_t threads_info = {
.name = "threads",
.description = "List all threads.",
.func = cmd_threads,
.argc = 0
};
 
static int cmd_tasks(cmd_arg_t *argv);
static cmd_info_t tasks_info = {
.name = "tasks",
.description = "List all tasks.",
.func = cmd_tasks,
.argc = 0
};
 
 
static int cmd_sched(cmd_arg_t *argv);
static cmd_info_t sched_info = {
.name = "scheduler",
.description = "List all scheduler information.",
.func = cmd_sched,
.argc = 0
};
 
static int cmd_slabs(cmd_arg_t *argv);
static cmd_info_t slabs_info = {
.name = "slabs",
.description = "List slab caches.",
.func = cmd_slabs,
.argc = 0
};
 
/* Data and methods for 'zones' command */
static int cmd_zones(cmd_arg_t *argv);
static cmd_info_t zones_info = {
.name = "zones",
.description = "List of memory zones.",
.func = cmd_zones,
.argc = 0
};
 
/* Data and methods for 'ipc_task' command */
static int cmd_ipc_task(cmd_arg_t *argv);
static cmd_arg_t ipc_task_argv = {
.type = ARG_TYPE_INT,
};
static cmd_info_t ipc_task_info = {
.name = "ipc_task",
.description = "ipc_task <taskid> Show IPC information of given task.",
.func = cmd_ipc_task,
.argc = 1,
.argv = &ipc_task_argv
};
 
/* Data and methods for 'zone' command */
static int cmd_zone(cmd_arg_t *argv);
static cmd_arg_t zone_argv = {
.type = ARG_TYPE_INT,
};
 
static cmd_info_t zone_info = {
.name = "zone",
.description = "Show memory zone structure.",
.func = cmd_zone,
.argc = 1,
.argv = &zone_argv
};
 
/* Data and methods for 'cpus' command. */
static int cmd_cpus(cmd_arg_t *argv);
cmd_info_t cpus_info = {
.name = "cpus",
.description = "List all processors.",
.help = NULL,
.func = cmd_cpus,
.argc = 0,
.argv = NULL
};
 
/* Data and methods for 'version' command. */
static int cmd_version(cmd_arg_t *argv);
cmd_info_t version_info = {
.name = "version",
.description = "Print version information.",
.help = NULL,
.func = cmd_version,
.argc = 0,
.argv = NULL
};
 
static cmd_info_t *basic_commands[] = {
&call0_info,
&call1_info,
&call2_info,
&call3_info,
&continue_info,
&cpus_info,
&desc_info,
&exit_info,
&halt_info,
&help_info,
&ipc_task_info,
&set4_info,
&slabs_info,
&symaddr_info,
&sched_info,
&threads_info,
&tasks_info,
&tlb_info,
&version_info,
&zones_info,
&zone_info,
NULL
};
 
 
/** Initialize command info structure.
*
* @param cmd Command info structure.
*
*/
void cmd_initialize(cmd_info_t *cmd)
{
spinlock_initialize(&cmd->lock, "cmd");
link_initialize(&cmd->link);
}
 
/** Initialize and register commands. */
void cmd_init(void)
{
int i;
 
for (i=0;basic_commands[i]; i++) {
cmd_initialize(basic_commands[i]);
if (!cmd_register(basic_commands[i]))
panic("could not register command %s\n",
basic_commands[i]->name);
}
}
 
 
/** List supported commands.
*
* @param argv Argument vector.
*
* @return 0 on failure, 1 on success.
*/
int cmd_help(cmd_arg_t *argv)
{
link_t *cur;
 
spinlock_lock(&cmd_lock);
for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
cmd_info_t *hlp;
hlp = list_get_instance(cur, cmd_info_t, link);
spinlock_lock(&hlp->lock);
printf("%s - %s\n", hlp->name, hlp->description);
 
spinlock_unlock(&hlp->lock);
}
spinlock_unlock(&cmd_lock);
 
return 1;
}
 
/** Describe specified command.
*
* @param argv Argument vector.
*
* @return 0 on failure, 1 on success.
*/
int cmd_desc(cmd_arg_t *argv)
{
link_t *cur;
 
spinlock_lock(&cmd_lock);
for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
cmd_info_t *hlp;
hlp = list_get_instance(cur, cmd_info_t, link);
spinlock_lock(&hlp->lock);
 
if (strncmp(hlp->name, (const char *) argv->buffer, strlen(hlp->name)) == 0) {
printf("%s - %s\n", hlp->name, hlp->description);
if (hlp->help)
hlp->help();
spinlock_unlock(&hlp->lock);
break;
}
 
spinlock_unlock(&hlp->lock);
}
spinlock_unlock(&cmd_lock);
 
return 1;
}
 
/** Search symbol table */
int cmd_symaddr(cmd_arg_t *argv)
{
symtab_print_search(argv->buffer);
return 1;
}
 
/** Call function with zero parameters */
int cmd_call0(cmd_arg_t *argv)
{
uintptr_t symaddr;
char *symbol;
unative_t (*f)(void);
#ifdef ia64
struct {
unative_t f;
unative_t gp;
}fptr;
#endif
 
symaddr = get_symbol_addr(argv->buffer);
if (!symaddr)
printf("Symbol %s not found.\n", argv->buffer);
else if (symaddr == (uintptr_t) -1) {
symtab_print_search(argv->buffer);
printf("Duplicate symbol, be more specific.\n");
} else {
symbol = get_symtab_entry(symaddr);
printf("Calling f(): %.*p: %s\n", sizeof(uintptr_t) * 2, symaddr, symbol);
#ifdef ia64
fptr.f = symaddr;
fptr.gp = ((unative_t *)cmd_call2)[1];
f = (unative_t (*)(void)) &fptr;
#else
f = (unative_t (*)(void)) symaddr;
#endif
printf("Result: %#zx\n", f());
}
return 1;
}
 
/** Call function with one parameter */
int cmd_call1(cmd_arg_t *argv)
{
uintptr_t symaddr;
char *symbol;
unative_t (*f)(unative_t,...);
unative_t arg1 = argv[1].intval;
#ifdef ia64
struct {
unative_t f;
unative_t gp;
}fptr;
#endif
 
symaddr = get_symbol_addr(argv->buffer);
if (!symaddr)
printf("Symbol %s not found.\n", argv->buffer);
else if (symaddr == (uintptr_t) -1) {
symtab_print_search(argv->buffer);
printf("Duplicate symbol, be more specific.\n");
} else {
symbol = get_symtab_entry(symaddr);
 
printf("Calling f(%#zx): %.*p: %s\n", arg1, sizeof(uintptr_t) * 2, symaddr, symbol);
#ifdef ia64
fptr.f = symaddr;
fptr.gp = ((unative_t *)cmd_call2)[1];
f = (unative_t (*)(unative_t,...)) &fptr;
#else
f = (unative_t (*)(unative_t,...)) symaddr;
#endif
printf("Result: %#zx\n", f(arg1));
}
return 1;
}
 
/** Call function with two parameters */
int cmd_call2(cmd_arg_t *argv)
{
uintptr_t symaddr;
char *symbol;
unative_t (*f)(unative_t,unative_t,...);
unative_t arg1 = argv[1].intval;
unative_t arg2 = argv[2].intval;
#ifdef ia64
struct {
unative_t f;
unative_t gp;
}fptr;
#endif
 
symaddr = get_symbol_addr(argv->buffer);
if (!symaddr)
printf("Symbol %s not found.\n", argv->buffer);
else if (symaddr == (uintptr_t) -1) {
symtab_print_search(argv->buffer);
printf("Duplicate symbol, be more specific.\n");
} else {
symbol = get_symtab_entry(symaddr);
printf("Calling f(0x%zx,0x%zx): %.*p: %s\n",
arg1, arg2, sizeof(uintptr_t) * 2, symaddr, symbol);
#ifdef ia64
fptr.f = symaddr;
fptr.gp = ((unative_t *)cmd_call2)[1];
f = (unative_t (*)(unative_t,unative_t,...)) &fptr;
#else
f = (unative_t (*)(unative_t,unative_t,...)) symaddr;
#endif
printf("Result: %#zx\n", f(arg1, arg2));
}
return 1;
}
 
/** Call function with three parameters */
int cmd_call3(cmd_arg_t *argv)
{
uintptr_t symaddr;
char *symbol;
unative_t (*f)(unative_t,unative_t,unative_t,...);
unative_t arg1 = argv[1].intval;
unative_t arg2 = argv[2].intval;
unative_t arg3 = argv[3].intval;
#ifdef ia64
struct {
unative_t f;
unative_t gp;
}fptr;
#endif
 
symaddr = get_symbol_addr(argv->buffer);
if (!symaddr)
printf("Symbol %s not found.\n", argv->buffer);
else if (symaddr == (uintptr_t) -1) {
symtab_print_search(argv->buffer);
printf("Duplicate symbol, be more specific.\n");
} else {
symbol = get_symtab_entry(symaddr);
printf("Calling f(0x%zx,0x%zx, 0x%zx): %.*p: %s\n",
arg1, arg2, arg3, sizeof(uintptr_t) * 2, symaddr, symbol);
#ifdef ia64
fptr.f = symaddr;
fptr.gp = ((unative_t *)cmd_call2)[1];
f = (unative_t (*)(unative_t,unative_t,unative_t,...)) &fptr;
#else
f = (unative_t (*)(unative_t,unative_t,unative_t,...)) symaddr;
#endif
printf("Result: %#zx\n", f(arg1, arg2, arg3));
}
return 1;
}
 
 
/** Print detailed description of 'describe' command. */
void desc_help(void)
{
printf("Syntax: describe command_name\n");
}
 
/** Halt the kernel.
*
* @param argv Argument vector (ignored).
*
* @return 0 on failure, 1 on success (never returns).
*/
int cmd_halt(cmd_arg_t *argv)
{
halt();
return 1;
}
 
/** Command for printing TLB contents.
*
* @param argv Not used.
*
* @return Always returns 1.
*/
int cmd_tlb(cmd_arg_t *argv)
{
tlb_print();
return 1;
}
 
/** Write 4 byte value to address */
int cmd_set4(cmd_arg_t *argv)
{
uint32_t *addr ;
uint32_t arg1 = argv[1].intval;
bool pointer = false;
 
if (((char *)argv->buffer)[0] == '*') {
addr = (uint32_t *) get_symbol_addr(argv->buffer+1);
pointer = true;
} else if (((char *)argv->buffer)[0] >= '0' &&
((char *)argv->buffer)[0] <= '9')
addr = (uint32_t *)atoi((char *)argv->buffer);
else
addr = (uint32_t *)get_symbol_addr(argv->buffer);
 
if (!addr)
printf("Symbol %s not found.\n", argv->buffer);
else if (addr == (uint32_t *) -1) {
symtab_print_search(argv->buffer);
printf("Duplicate symbol, be more specific.\n");
} else {
if (pointer)
addr = (uint32_t *)(*(unative_t *)addr);
printf("Writing 0x%x -> %.*p\n", arg1, sizeof(uintptr_t) * 2, addr);
*addr = arg1;
}
return 1;
}
 
/** Command for listings SLAB caches
*
* @param argv Ignores
*
* @return Always 1
*/
int cmd_slabs(cmd_arg_t * argv) {
slab_print_list();
return 1;
}
 
 
/** Command for listings Thread information
*
* @param argv Ignores
*
* @return Always 1
*/
int cmd_threads(cmd_arg_t * argv) {
thread_print_list();
return 1;
}
 
/** Command for listings Task information
*
* @param argv Ignores
*
* @return Always 1
*/
int cmd_tasks(cmd_arg_t * argv) {
task_print_list();
return 1;
}
 
/** Command for listings Thread information
*
* @param argv Ignores
*
* @return Always 1
*/
int cmd_sched(cmd_arg_t * argv) {
sched_print_list();
return 1;
}
 
/** Command for listing memory zones
*
* @param argv Ignored
*
* return Always 1
*/
int cmd_zones(cmd_arg_t * argv) {
zone_print_list();
return 1;
}
 
/** Command for memory zone details
*
* @param argv Integer argument from cmdline expected
*
* return Always 1
*/
int cmd_zone(cmd_arg_t * argv) {
zone_print_one(argv[0].intval);
return 1;
}
 
/** Command for printing task ipc details
*
* @param argv Integer argument from cmdline expected
*
* return Always 1
*/
int cmd_ipc_task(cmd_arg_t * argv) {
ipc_print_task(argv[0].intval);
return 1;
}
 
 
/** Command for listing processors.
*
* @param argv Ignored.
*
* return Always 1.
*/
int cmd_cpus(cmd_arg_t *argv)
{
cpu_list();
return 1;
}
 
/** Command for printing kernel version.
*
* @param argv Ignored.
*
* return Always 1.
*/
int cmd_version(cmd_arg_t *argv)
{
version_print();
return 1;
}
 
/** Command for returning console back to userspace.
*
* @param argv Ignored.
*
* return Always 1.
*/
int cmd_continue(cmd_arg_t *argv)
{
printf("The kernel will now relinquish the console.\n");
printf("Use userspace controls to redraw the screen.\n");
arch_release_console();
ipc_irq_send_msg(IPC_IRQ_KBDRESTART, 0, 0, 0);
return 1;
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/src/console/chardev.c
0,0 → 1,79
/*
* 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 genericconsole
* @{
*/
/** @file
*/
 
#include <console/chardev.h>
#include <putchar.h>
#include <synch/waitq.h>
#include <synch/spinlock.h>
 
/** Initialize character device.
*
* @param chardev Character device.
* @param op Implementation of character device operations.
*/
void chardev_initialize(char *name,chardev_t *chardev,
chardev_operations_t *op)
{
chardev->name = name;
 
waitq_initialize(&chardev->wq);
spinlock_initialize(&chardev->lock, "chardev");
chardev->counter = 0;
chardev->index = 0;
chardev->op = op;
}
 
/** Push character read from input character device.
*
* @param chardev Character device.
* @param ch Character being pushed.
*/
void chardev_push_character(chardev_t *chardev, uint8_t ch)
{
spinlock_lock(&chardev->lock);
chardev->counter++;
if (chardev->counter == CHARDEV_BUFLEN - 1) {
/* buffer full => disable device interrupt */
chardev->op->suspend(chardev);
}
chardev->buffer[chardev->index++] = ch;
chardev->index = chardev->index % CHARDEV_BUFLEN; /* index modulo size of buffer */
waitq_wakeup(&chardev->wq, WAKEUP_FIRST);
spinlock_unlock(&chardev->lock);
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/src/console/klog.c
0,0 → 1,110
/*
* Copyright (C) 2006 Ondrej Palkovsky
* 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 genericklog
* @{
*/
/** @file
*/
 
#include <mm/frame.h>
#include <sysinfo/sysinfo.h>
#include <console/klog.h>
#include <print.h>
#include <ipc/irq.h>
 
/* Order of frame to be allocated for klog communication */
#define KLOG_ORDER 0
 
static char *klog;
static int klogsize;
static int klogpos;
 
SPINLOCK_INITIALIZE(klog_lock);
 
/** Initialize kernel logging facility
*
* Allocate pages that are to be shared with uspace for console data.
* The shared area is a circular buffer. Userspace application may
* be notified on new data with indication of position and size
* of the data within the circular buffer.
*/
void klog_init(void)
{
void *faddr;
 
faddr = frame_alloc(KLOG_ORDER, FRAME_ATOMIC);
if (!faddr)
panic("Cannot allocate page for klog");
klog = (char *)PA2KA(faddr);
sysinfo_set_item_val("klog.faddr", NULL, (unative_t)faddr);
sysinfo_set_item_val("klog.pages", NULL, 1 << KLOG_ORDER);
 
klogsize = PAGE_SIZE << KLOG_ORDER;
klogpos = 0;
}
 
static void klog_vprintf(const char *fmt, va_list args)
{
int ret;
va_list atst;
 
va_copy(atst, args);
spinlock_lock(&klog_lock);
 
ret = vsnprintf(klog+klogpos, klogsize-klogpos, fmt, atst);
if (ret >= klogsize-klogpos) {
klogpos = 0;
if (ret >= klogsize)
goto out;
}
ipc_irq_send_msg(IPC_IRQ_KLOG, klogpos, ret, 0);
klogpos += ret;
if (klogpos >= klogsize)
klogpos = 0;
out:
spinlock_unlock(&klog_lock);
va_end(atst);
}
 
/** Printf a message to kernel-uspace log */
void klog_printf(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
klog_vprintf(fmt, args);
 
va_end(args);
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/src/console/kconsole.c
0,0 → 1,631
/*
* 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 genericconsole
* @{
*/
 
/**
* @file kconsole.c
* @brief Kernel console.
*
* This file contains kernel thread managing the kernel console.
*/
 
#include <console/kconsole.h>
#include <console/console.h>
#include <console/chardev.h>
#include <console/cmd.h>
#include <print.h>
#include <panic.h>
#include <typedefs.h>
#include <arch/types.h>
#include <adt/list.h>
#include <arch.h>
#include <macros.h>
#include <debug.h>
#include <func.h>
#include <symtab.h>
#include <macros.h>
 
/** Simple kernel console.
*
* The console is realized by kernel thread kconsole.
* It doesn't understand any useful command on its own,
* but makes it possible for other kernel subsystems to
* register their own commands.
*/
/** Locking.
*
* There is a list of cmd_info_t structures. This list
* is protected by cmd_lock spinlock. Note that specially
* the link elements of cmd_info_t are protected by
* this lock.
*
* Each cmd_info_t also has its own lock, which protects
* all elements thereof except the link element.
*
* cmd_lock must be acquired before any cmd_info lock.
* When locking two cmd info structures, structure with
* lower address must be locked first.
*/
SPINLOCK_INITIALIZE(cmd_lock); /**< Lock protecting command list. */
LIST_INITIALIZE(cmd_head); /**< Command list. */
 
static cmd_info_t *parse_cmdline(char *cmdline, size_t len);
static bool parse_argument(char *cmdline, size_t len, index_t *start, index_t *end);
static char history[KCONSOLE_HISTORY][MAX_CMDLINE] = {};
 
/** Initialize kconsole data structures. */
void kconsole_init(void)
{
int i;
 
cmd_init();
for (i=0; i<KCONSOLE_HISTORY; i++)
history[i][0] = '\0';
}
 
 
/** Register kconsole command.
*
* @param cmd Structure describing the command.
*
* @return 0 on failure, 1 on success.
*/
int cmd_register(cmd_info_t *cmd)
{
link_t *cur;
spinlock_lock(&cmd_lock);
/*
* Make sure the command is not already listed.
*/
for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
cmd_info_t *hlp;
hlp = list_get_instance(cur, cmd_info_t, link);
 
if (hlp == cmd) {
/* The command is already there. */
spinlock_unlock(&cmd_lock);
return 0;
}
 
/* Avoid deadlock. */
if (hlp < cmd) {
spinlock_lock(&hlp->lock);
spinlock_lock(&cmd->lock);
} else {
spinlock_lock(&cmd->lock);
spinlock_lock(&hlp->lock);
}
if ((strncmp(hlp->name,
cmd->name, max(strlen(cmd->name),
strlen(hlp->name))) == 0)) {
/* The command is already there. */
spinlock_unlock(&hlp->lock);
spinlock_unlock(&cmd->lock);
spinlock_unlock(&cmd_lock);
return 0;
}
spinlock_unlock(&hlp->lock);
spinlock_unlock(&cmd->lock);
}
/*
* Now the command can be added.
*/
list_append(&cmd->link, &cmd_head);
spinlock_unlock(&cmd_lock);
return 1;
}
 
/** Print count times a character */
static void rdln_print_c(char ch, int count)
{
int i;
for (i=0;i<count;i++)
putchar(ch);
}
 
/** Insert character to string */
static void insert_char(char *str, char ch, int pos)
{
int i;
for (i=strlen(str);i > pos; i--)
str[i] = str[i-1];
str[pos] = ch;
}
 
/** Try to find a command beginning with prefix */
static const char * cmdtab_search_one(const char *name,link_t **startpos)
{
int namelen = strlen(name);
const char *curname;
 
spinlock_lock(&cmd_lock);
 
if (!*startpos)
*startpos = cmd_head.next;
 
for (;*startpos != &cmd_head;*startpos = (*startpos)->next) {
cmd_info_t *hlp;
hlp = list_get_instance(*startpos, cmd_info_t, link);
 
curname = hlp->name;
if (strlen(curname) < namelen)
continue;
if (strncmp(curname, name, namelen) == 0) {
spinlock_unlock(&cmd_lock);
return curname+namelen;
}
}
spinlock_unlock(&cmd_lock);
return NULL;
}
 
 
/** Command completion of the commands
*
* @param name - string to match, changed to hint on exit
* @return number of found matches
*/
static int cmdtab_compl(char *name)
{
char output[MAX_SYMBOL_NAME+1];
link_t *startpos = NULL;
const char *foundtxt;
int found = 0;
int i;
 
output[0] = '\0';
while ((foundtxt = cmdtab_search_one(name, &startpos))) {
startpos = startpos->next;
if (!found)
strncpy(output, foundtxt, strlen(foundtxt)+1);
else {
for (i=0; output[i] && foundtxt[i] && output[i]==foundtxt[i]; i++)
;
output[i] = '\0';
}
found++;
}
if (!found)
return 0;
 
if (found > 1 && !strlen(output)) {
printf("\n");
startpos = NULL;
while ((foundtxt = cmdtab_search_one(name, &startpos))) {
cmd_info_t *hlp;
hlp = list_get_instance(startpos, cmd_info_t, link);
printf("%s - %s\n", hlp->name, hlp->description);
startpos = startpos->next;
}
}
strncpy(name, output, MAX_SYMBOL_NAME);
return found;
}
 
static char * clever_readline(const char *prompt, chardev_t *input)
{
static int histposition = 0;
 
char tmp[MAX_CMDLINE+1];
int curlen = 0, position = 0;
char *current = history[histposition];
int i;
char mod; /* Command Modifier */
char c;
 
printf("%s> ", prompt);
while (1) {
c = _getc(input);
if (c == '\n') {
putchar(c);
break;
} if (c == '\b') { /* Backspace */
if (position == 0)
continue;
for (i=position; i<curlen;i++)
current[i-1] = current[i];
curlen--;
position--;
putchar('\b');
for (i=position;i<curlen;i++)
putchar(current[i]);
putchar(' ');
rdln_print_c('\b',curlen-position+1);
continue;
}
if (c == '\t') { /* Tabulator */
int found;
 
/* Move to the end of the word */
for (;position<curlen && current[position]!=' ';position++)
putchar(current[position]);
/* Copy to tmp last word */
for (i=position-1;i >= 0 && current[i]!=' ' ;i--)
;
/* If word begins with * or &, skip it */
if (tmp[0] == '*' || tmp[0] == '&')
for (i=1;tmp[i];i++)
tmp[i-1] = tmp[i];
i++; /* I is at the start of the word */
strncpy(tmp, current+i, position-i+1);
 
if (i==0) { /* Command completion */
found = cmdtab_compl(tmp);
} else { /* Symtab completion */
found = symtab_compl(tmp);
}
 
if (found == 0)
continue;
for (i=0;tmp[i] && curlen < MAX_CMDLINE;i++,curlen++)
insert_char(current, tmp[i], i+position);
 
if (strlen(tmp) || found==1) { /* If we have a hint */
for (i=position;i<curlen;i++)
putchar(current[i]);
position += strlen(tmp);
/* Add space to end */
if (found == 1 && position == curlen && \
curlen < MAX_CMDLINE) {
current[position] = ' ';
curlen++;
position++;
putchar(' ');
}
} else { /* No hint, table was printed */
printf("%s> ", prompt);
for (i=0; i<curlen;i++)
putchar(current[i]);
position += strlen(tmp);
}
rdln_print_c('\b', curlen-position);
continue;
}
if (c == 0x1b) { /* Special command */
mod = _getc(input);
c = _getc(input);
 
if (mod != 0x5b && mod != 0x4f)
continue;
 
if (c == 0x33 && _getc(input) == 0x7e) {
/* Delete */
if (position == curlen)
continue;
for (i=position+1; i<curlen;i++) {
putchar(current[i]);
current[i-1] = current[i];
}
putchar(' ');
rdln_print_c('\b',curlen-position);
curlen--;
}
else if (c == 0x48) { /* Home */
rdln_print_c('\b',position);
position = 0;
}
else if (c == 0x46) { /* End */
for (i=position;i<curlen;i++)
putchar(current[i]);
position = curlen;
}
else if (c == 0x44) { /* Left */
if (position > 0) {
putchar('\b');
position--;
}
continue;
}
else if (c == 0x43) { /* Right */
if (position < curlen) {
putchar(current[position]);
position++;
}
continue;
}
else if (c == 0x41 || c == 0x42) {
/* Up,down */
rdln_print_c('\b',position);
rdln_print_c(' ',curlen);
rdln_print_c('\b',curlen);
if (c == 0x41) /* Up */
histposition--;
else
histposition++;
if (histposition < 0)
histposition = KCONSOLE_HISTORY -1 ;
else
histposition = histposition % KCONSOLE_HISTORY;
current = history[histposition];
printf("%s", current);
curlen = strlen(current);
position = curlen;
continue;
}
continue;
}
if (curlen >= MAX_CMDLINE)
continue;
 
insert_char(current, c, position);
 
curlen++;
for (i=position;i<curlen;i++)
putchar(current[i]);
position++;
rdln_print_c('\b',curlen-position);
}
if (curlen) {
histposition++;
histposition = histposition % KCONSOLE_HISTORY;
}
current[curlen] = '\0';
return current;
}
 
/** Kernel console managing thread.
*
* @param prompt Kernel console prompt (e.g kconsole/panic).
*/
void kconsole(void *prompt)
{
cmd_info_t *cmd_info;
count_t len;
char *cmdline;
 
if (!stdin) {
printf("%s: no stdin\n", __FUNCTION__);
return;
}
while (true) {
cmdline = clever_readline(prompt, stdin);
len = strlen(cmdline);
if (!len)
continue;
cmd_info = parse_cmdline(cmdline, len);
if (!cmd_info)
continue;
if (strncmp(cmd_info->name,"exit", \
min(strlen(cmd_info->name),5)) == 0)
break;
(void) cmd_info->func(cmd_info->argv);
}
}
 
static int parse_int_arg(char *text, size_t len, unative_t *result)
{
char symname[MAX_SYMBOL_NAME];
uintptr_t symaddr;
bool isaddr = false;
bool isptr = false;
/* If we get a name, try to find it in symbol table */
if (text[0] == '&') {
isaddr = true;
text++;len--;
} else if (text[0] == '*') {
isptr = true;
text++;len--;
}
if (text[0] < '0' || text[0] > '9') {
strncpy(symname, text, min(len+1, MAX_SYMBOL_NAME));
symaddr = get_symbol_addr(symname);
if (!symaddr) {
printf("Symbol %s not found.\n",symname);
return -1;
}
if (symaddr == (uintptr_t) -1) {
printf("Duplicate symbol %s.\n",symname);
symtab_print_search(symname);
return -1;
}
if (isaddr)
*result = (unative_t)symaddr;
else if (isptr)
*result = **((unative_t **)symaddr);
else
*result = *((unative_t *)symaddr);
} else { /* It's a number - convert it */
*result = atoi(text);
if (isptr)
*result = *((unative_t *)*result);
}
 
return 0;
}
 
/** Parse command line.
*
* @param cmdline Command line as read from input device.
* @param len Command line length.
*
* @return Structure describing the command.
*/
cmd_info_t *parse_cmdline(char *cmdline, size_t len)
{
index_t start = 0, end = 0;
cmd_info_t *cmd = NULL;
link_t *cur;
int i;
int error = 0;
if (!parse_argument(cmdline, len, &start, &end)) {
/* Command line did not contain alphanumeric word. */
return NULL;
}
 
spinlock_lock(&cmd_lock);
for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
cmd_info_t *hlp;
hlp = list_get_instance(cur, cmd_info_t, link);
spinlock_lock(&hlp->lock);
if (strncmp(hlp->name, &cmdline[start], max(strlen(hlp->name),
end-start+1)) == 0) {
cmd = hlp;
break;
}
spinlock_unlock(&hlp->lock);
}
spinlock_unlock(&cmd_lock);
if (!cmd) {
/* Unknown command. */
printf("Unknown command.\n");
return NULL;
}
 
/* cmd == hlp is locked */
/*
* The command line must be further analyzed and
* the parameters therefrom must be matched and
* converted to those specified in the cmd info
* structure.
*/
 
for (i = 0; i < cmd->argc; i++) {
char *buf;
start = end + 1;
if (!parse_argument(cmdline, len, &start, &end)) {
printf("Too few arguments.\n");
spinlock_unlock(&cmd->lock);
return NULL;
}
error = 0;
switch (cmd->argv[i].type) {
case ARG_TYPE_STRING:
buf = cmd->argv[i].buffer;
strncpy(buf, (const char *) &cmdline[start], min((end - start) + 2, cmd->argv[i].len));
buf[min((end - start) + 1, cmd->argv[i].len - 1)] = '\0';
break;
case ARG_TYPE_INT:
if (parse_int_arg(cmdline+start, end-start+1,
&cmd->argv[i].intval))
error = 1;
break;
case ARG_TYPE_VAR:
if (start != end && cmdline[start] == '"' && cmdline[end] == '"') {
buf = cmd->argv[i].buffer;
strncpy(buf, (const char *) &cmdline[start+1],
min((end-start), cmd->argv[i].len));
buf[min((end - start), cmd->argv[i].len - 1)] = '\0';
cmd->argv[i].intval = (unative_t) buf;
cmd->argv[i].vartype = ARG_TYPE_STRING;
} else if (!parse_int_arg(cmdline+start, end-start+1,
&cmd->argv[i].intval))
cmd->argv[i].vartype = ARG_TYPE_INT;
else {
printf("Unrecognized variable argument.\n");
error = 1;
}
break;
case ARG_TYPE_INVALID:
default:
printf("invalid argument type\n");
error = 1;
break;
}
}
if (error) {
spinlock_unlock(&cmd->lock);
return NULL;
}
start = end + 1;
if (parse_argument(cmdline, len, &start, &end)) {
printf("Too many arguments.\n");
spinlock_unlock(&cmd->lock);
return NULL;
}
spinlock_unlock(&cmd->lock);
return cmd;
}
 
/** Parse argument.
*
* Find start and end positions of command line argument.
*
* @param cmdline Command line as read from the input device.
* @param len Number of characters in cmdline.
* @param start On entry, 'start' contains pointer to the index
* of first unprocessed character of cmdline.
* On successful exit, it marks beginning of the next argument.
* @param end Undefined on entry. On exit, 'end' points to the last character
* of the next argument.
*
* @return false on failure, true on success.
*/
bool parse_argument(char *cmdline, size_t len, index_t *start, index_t *end)
{
int i;
bool found_start = false;
ASSERT(start != NULL);
ASSERT(end != NULL);
for (i = *start; i < len; i++) {
if (!found_start) {
if (is_white(cmdline[i]))
(*start)++;
else
found_start = true;
} else {
if (is_white(cmdline[i]))
break;
}
}
*end = i - 1;
 
return found_start;
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/src/lib/elf.c
0,0 → 1,225
/*
* Copyright (C) 2006 Sergey Bondari
* 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 generic
* @{
*/
 
/**
* @file
* @brief Kernel ELF loader.
*/
 
#include <elf.h>
#include <debug.h>
#include <arch/types.h>
#include <typedefs.h>
#include <mm/as.h>
#include <mm/frame.h>
#include <mm/slab.h>
#include <align.h>
#include <memstr.h>
#include <macros.h>
#include <arch.h>
 
static char *error_codes[] = {
"no error",
"invalid image",
"address space error",
"incompatible image",
"unsupported image type",
"irrecoverable error"
};
 
static int segment_header(elf_segment_header_t *entry, elf_header_t *elf, as_t *as);
static int section_header(elf_section_header_t *entry, elf_header_t *elf, as_t *as);
static int load_segment(elf_segment_header_t *entry, elf_header_t *elf, as_t *as);
 
/** ELF loader
*
* @param header Pointer to ELF header in memory
* @param as Created and properly mapped address space
* @return EE_OK on success
*/
int elf_load(elf_header_t *header, as_t * as)
{
int i, rc;
 
/* Identify ELF */
if (header->e_ident[EI_MAG0] != ELFMAG0 || header->e_ident[EI_MAG1] != ELFMAG1 ||
header->e_ident[EI_MAG2] != ELFMAG2 || header->e_ident[EI_MAG3] != ELFMAG3) {
return EE_INVALID;
}
/* Identify ELF compatibility */
if (header->e_ident[EI_DATA] != ELF_DATA_ENCODING || header->e_machine != ELF_MACHINE ||
header->e_ident[EI_VERSION] != EV_CURRENT || header->e_version != EV_CURRENT ||
header->e_ident[EI_CLASS] != ELF_CLASS) {
return EE_INCOMPATIBLE;
}
 
if (header->e_phentsize != sizeof(elf_segment_header_t))
return EE_INCOMPATIBLE;
 
if (header->e_shentsize != sizeof(elf_section_header_t))
return EE_INCOMPATIBLE;
 
/* Check if the object type is supported. */
if (header->e_type != ET_EXEC)
return EE_UNSUPPORTED;
 
/* Walk through all segment headers and process them. */
for (i = 0; i < header->e_phnum; i++) {
rc = segment_header(&((elf_segment_header_t *)(((uint8_t *) header) + header->e_phoff))[i], header, as);
if (rc != EE_OK)
return rc;
}
 
/* Inspect all section headers and proccess them. */
for (i = 0; i < header->e_shnum; i++) {
rc = section_header(&((elf_section_header_t *)(((uint8_t *) header) + header->e_shoff))[i], header, as);
if (rc != EE_OK)
return rc;
}
 
return EE_OK;
}
 
/** Print error message according to error code.
*
* @param rc Return code returned by elf_load().
*
* @return NULL terminated description of error.
*/
char *elf_error(int rc)
{
ASSERT(rc < sizeof(error_codes)/sizeof(char *));
 
return error_codes[rc];
}
 
/** Process segment header.
*
* @param entry Segment header.
* @param elf ELF header.
* @param as Address space into wich the ELF is being loaded.
*
* @return EE_OK on success, error code otherwise.
*/
static int segment_header(elf_segment_header_t *entry, elf_header_t *elf, as_t *as)
{
switch (entry->p_type) {
case PT_NULL:
case PT_PHDR:
break;
case PT_LOAD:
return load_segment(entry, elf, as);
break;
case PT_DYNAMIC:
case PT_INTERP:
case PT_SHLIB:
case PT_NOTE:
case PT_LOPROC:
case PT_HIPROC:
default:
return EE_UNSUPPORTED;
break;
}
return EE_OK;
}
 
/** Load segment described by program header entry.
*
* @param entry Program header entry describing segment to be loaded.
* @param elf ELF header.
* @param as Address space into wich the ELF is being loaded.
*
* @return EE_OK on success, error code otherwise.
*/
int load_segment(elf_segment_header_t *entry, elf_header_t *elf, as_t *as)
{
as_area_t *a;
int flags = 0;
mem_backend_data_t backend_data;
backend_data.elf = elf;
backend_data.segment = entry;
 
if (entry->p_align > 1) {
if ((entry->p_offset % entry->p_align) != (entry->p_vaddr % entry->p_align)) {
return EE_INVALID;
}
}
 
if (entry->p_flags & PF_X)
flags |= AS_AREA_EXEC;
if (entry->p_flags & PF_W)
flags |= AS_AREA_WRITE;
if (entry->p_flags & PF_R)
flags |= AS_AREA_READ;
flags |= AS_AREA_CACHEABLE;
 
/*
* Check if the virtual address starts on page boundary.
*/
if (ALIGN_UP(entry->p_vaddr, PAGE_SIZE) != entry->p_vaddr)
return EE_UNSUPPORTED;
 
a = as_area_create(as, flags, entry->p_memsz, entry->p_vaddr, AS_AREA_ATTR_NONE,
&elf_backend, &backend_data);
if (!a)
return EE_MEMORY;
/*
* The segment will be mapped on demand by elf_page_fault().
*/
 
return EE_OK;
}
 
/** Process section header.
*
* @param entry Segment header.
* @param elf ELF header.
* @param as Address space into wich the ELF is being loaded.
*
* @return EE_OK on success, error code otherwise.
*/
static int section_header(elf_section_header_t *entry, elf_header_t *elf, as_t *as)
{
switch (entry->sh_type) {
default:
break;
}
return EE_OK;
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/lib/memstr.c
0,0 → 1,119
/*
* 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 generic
* @{
*/
 
/**
* @file
* @brief Memory string operations.
*
* This file provides architecture independent functions
* to manipulate blocks of memory. These functions
* are optimized as much as generic functions of
* this type can be. However, architectures are
* free to provide even more optimized versions of these
* functions.
*/
 
#include <memstr.h>
#include <arch/types.h>
#include <align.h>
 
/** Copy block of memory
*
* Copy cnt bytes from src address to dst address.
* The copying is done word-by-word and then byte-by-byte.
* The source and destination memory areas cannot overlap.
*
* @param src Origin address to copy from.
* @param dst Origin address to copy to.
* @param cnt Number of bytes to copy.
*
*/
void *_memcpy(void * dst, const void *src, size_t cnt)
{
int i, j;
if (ALIGN_UP((uintptr_t) src, sizeof(unative_t)) != (uintptr_t) src ||
ALIGN_UP((uintptr_t) dst, sizeof(unative_t)) != (uintptr_t) dst) {
for (i = 0; i < cnt; i++)
((uint8_t *) dst)[i] = ((uint8_t *) src)[i];
} else {
for (i = 0; i < cnt/sizeof(unative_t); i++)
((unative_t *) dst)[i] = ((unative_t *) src)[i];
for (j = 0; j < cnt%sizeof(unative_t); j++)
((uint8_t *)(((unative_t *) dst) + i))[j] = ((uint8_t *)(((unative_t *) src) + i))[j];
}
return (char *)src;
}
 
/** Fill block of memory
*
* Fill cnt bytes at dst address with the value x.
* The filling is done byte-by-byte.
*
* @param dst Origin address to fill.
* @param cnt Number of bytes to fill.
* @param x Value to fill.
*
*/
void _memsetb(uintptr_t dst, size_t cnt, uint8_t x)
{
int i;
uint8_t *p = (uint8_t *) dst;
for(i=0; i<cnt; i++)
p[i] = x;
}
 
/** Fill block of memory
*
* Fill cnt words at dst address with the value x.
* The filling is done word-by-word.
*
* @param dst Origin address to fill.
* @param cnt Number of words to fill.
* @param x Value to fill.
*
*/
void _memsetw(uintptr_t dst, size_t cnt, uint16_t x)
{
int i;
uint16_t *p = (uint16_t *) dst;
for(i=0; i<cnt; i++)
p[i] = x;
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/lib/sort.c
0,0 → 1,203
/*
* Copyright (C) 2005 Sergey Bondari
* 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 generic
* @{
*/
 
/**
* @file
* @brief Sorting functions.
*
* This files contains functions implementing several sorting
* algorithms (e.g. quick sort and bubble sort).
*/
#include <mm/slab.h>
#include <memstr.h>
#include <sort.h>
#include <panic.h>
 
#define EBUFSIZE 32
 
void _qsort(void * data, count_t n, size_t e_size, int (* cmp) (void * a, void * b), void *tmp, void *pivot);
void _bubblesort(void * data, count_t n, size_t e_size, int (* cmp) (void * a, void * b), void *slot);
 
/** Quicksort wrapper
*
* This is only a wrapper that takes care of memory allocations for storing
* the pivot and temporary elements for generic quicksort algorithm.
*
* This function _can_ sleep
*
* @param data Pointer to data to be sorted.
* @param n Number of elements to be sorted.
* @param e_size Size of one element.
* @param cmp Comparator function.
*
*/
void qsort(void * data, count_t n, size_t e_size, int (* cmp) (void * a, void * b))
{
uint8_t buf_tmp[EBUFSIZE];
uint8_t buf_pivot[EBUFSIZE];
void * tmp = buf_tmp;
void * pivot = buf_pivot;
 
if (e_size > EBUFSIZE) {
pivot = (void *) malloc(e_size, 0);
tmp = (void *) malloc(e_size, 0);
}
 
_qsort(data, n, e_size, cmp, tmp, pivot);
if (e_size > EBUFSIZE) {
free(tmp);
free(pivot);
}
}
 
/** Quicksort
*
* Apply generic quicksort algorithm on supplied data, using pre-allocated buffers.
*
* @param data Pointer to data to be sorted.
* @param n Number of elements to be sorted.
* @param e_size Size of one element.
* @param cmp Comparator function.
* @param tmp Pointer to scratch memory buffer e_size bytes long.
* @param pivot Pointer to scratch memory buffer e_size bytes long.
*
*/
void _qsort(void * data, count_t n, size_t e_size, int (* cmp) (void * a, void * b), void *tmp, void *pivot)
{
if (n > 4) {
int i = 0, j = n - 1;
 
memcpy(pivot, data, e_size);
 
while (1) {
while ((cmp(data + i * e_size, pivot) < 0) && i < n) i++;
while ((cmp(data + j * e_size, pivot) >=0) && j > 0) j--;
if (i<j) {
memcpy(tmp, data + i * e_size, e_size);
memcpy(data + i * e_size, data + j * e_size, e_size);
memcpy(data + j * e_size, tmp, e_size);
} else {
break;
}
}
 
_qsort(data, j + 1, e_size, cmp, tmp, pivot);
_qsort(data + (j + 1) * e_size, n - j - 1, e_size, cmp, tmp, pivot);
} else {
_bubblesort(data, n, e_size, cmp, tmp);
}
}
 
/** Bubblesort wrapper
*
* This is only a wrapper that takes care of memory allocation for storing
* the slot element for generic bubblesort algorithm.
*
* @param data Pointer to data to be sorted.
* @param n Number of elements to be sorted.
* @param e_size Size of one element.
* @param cmp Comparator function.
*
*/
void bubblesort(void * data, count_t n, size_t e_size, int (* cmp) (void * a, void * b))
{
uint8_t buf_slot[EBUFSIZE];
void * slot = buf_slot;
if (e_size > EBUFSIZE) {
slot = (void *) malloc(e_size, 0);
}
 
_bubblesort(data, n, e_size, cmp, slot);
if (e_size > EBUFSIZE) {
free(slot);
}
}
 
/** Bubblesort
*
* Apply generic bubblesort algorithm on supplied data, using pre-allocated buffer.
*
* @param data Pointer to data to be sorted.
* @param n Number of elements to be sorted.
* @param e_size Size of one element.
* @param cmp Comparator function.
* @param slot Pointer to scratch memory buffer e_size bytes long.
*
*/
void _bubblesort(void * data, count_t n, size_t e_size, int (* cmp) (void * a, void * b), void *slot)
{
bool done = false;
void * p;
 
while (!done) {
done = true;
for (p = data; p < data + e_size * (n - 1); p = p + e_size) {
if (cmp(p, p + e_size) == 1) {
memcpy(slot, p, e_size);
memcpy(p, p + e_size, e_size);
memcpy(p + e_size, slot, e_size);
done = false;
}
}
}
 
}
 
/*
* Comparator returns 1 if a > b, 0 if a == b, -1 if a < b
*/
int int_cmp(void * a, void * b)
{
return (* (int *) a > * (int*)b) ? 1 : (*(int *)a < * (int *)b) ? -1 : 0;
}
 
int uint8_t_cmp(void * a, void * b)
{
return (* (uint8_t *) a > * (uint8_t *)b) ? 1 : (*(uint8_t *)a < * (uint8_t *)b) ? -1 : 0;
}
 
int uint16_t_cmp(void * a, void * b)
{
return (* (uint16_t *) a > * (uint16_t *)b) ? 1 : (*(uint16_t *)a < * (uint16_t *)b) ? -1 : 0;
}
 
int uint32_t_cmp(void * a, void * b)
{
return (* (uint32_t *) a > * (uint32_t *)b) ? 1 : (*(uint32_t *)a < * (uint32_t *)b) ? -1 : 0;
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/lib/func.c
0,0 → 1,196
/*
* 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 generic
* @{
*/
 
/**
* @file
* @brief Miscellaneous functions.
*/
 
#include <func.h>
#include <print.h>
#include <cpu.h>
#include <arch/asm.h>
#include <arch.h>
#include <typedefs.h>
#include <console/kconsole.h>
 
atomic_t haltstate = {0}; /**< Halt flag */
 
 
/** Halt wrapper
*
* Set halt flag and halt the cpu.
*
*/
void halt()
{
#ifdef CONFIG_DEBUG
bool rundebugger = false;
 
// TODO test_and_set not defined on all arches
// if (!test_and_set(&haltstate))
if (!atomic_get(&haltstate)) {
atomic_set(&haltstate, 1);
rundebugger = true;
}
#else
atomic_set(&haltstate, 1);
#endif
 
interrupts_disable();
#ifdef CONFIG_DEBUG
if (rundebugger) {
printf("\n");
kconsole("panic"); /* Run kconsole as a last resort to user */
}
#endif
if (CPU)
printf("cpu%d: halted\n", CPU->id);
else
printf("cpu: halted\n");
cpu_halt();
}
 
/** Return number of characters in a string.
*
* @param str NULL terminated string.
*
* @return Number of characters in str.
*/
size_t strlen(const char *str)
{
int i;
for (i = 0; str[i]; i++)
;
return i;
}
 
/** Compare two NULL terminated strings
*
* Do a char-by-char comparison of two NULL terminated strings.
* The strings are considered equal iff they consist of the same
* characters on the minimum of their lengths and specified maximal
* length.
*
* @param src First string to compare.
* @param dst Second string to compare.
* @param len Maximal length for comparison.
*
* @return 0 if the strings are equal, -1 if first is smaller, 1 if second smaller.
*
*/
int strncmp(const char *src, const char *dst, size_t len)
{
int i;
i = 0;
for (;*src && *dst && i < len;src++,dst++,i++) {
if (*src < *dst)
return -1;
if (*src > *dst)
return 1;
}
if (i == len || *src == *dst)
return 0;
if (!*src)
return -1;
return 1;
}
 
/** Copy NULL terminated string.
*
* Copy at most 'len' characters from string 'src' to 'dest'.
* If 'src' is shorter than 'len', '\0' is inserted behind the
* last copied character.
*
* @param src Source string.
* @param dest Destination buffer.
* @param len Size of destination buffer.
*/
void strncpy(char *dest, const char *src, size_t len)
{
int i;
for (i = 0; i < len; i++) {
if (!(dest[i] = src[i]))
return;
}
dest[i-1] = '\0';
}
 
/** Convert ascii representation to unative_t
*
* Supports 0x for hexa & 0 for octal notation.
* Does not check for overflows, does not support negative numbers
*
* @param text Textual representation of number
* @return Converted number or 0 if no valid number ofund
*/
unative_t atoi(const char *text)
{
int base = 10;
unative_t result = 0;
 
if (text[0] == '0' && text[1] == 'x') {
base = 16;
text += 2;
} else if (text[0] == '0')
base = 8;
 
while (*text) {
if (base != 16 && \
((*text >= 'A' && *text <= 'F' )
|| (*text >='a' && *text <='f')))
break;
if (base == 8 && *text >='8')
break;
 
if (*text >= '0' && *text <= '9') {
result *= base;
result += *text - '0';
} else if (*text >= 'A' && *text <= 'F') {
result *= base;
result += *text - 'A' + 10;
} else if (*text >= 'a' && *text <= 'f') {
result *= base;
result += *text - 'a' + 10;
} else
break;
text++;
}
 
return result;
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/security/cap.c
0,0 → 1,185
/*
* 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 generic
* @{
*/
 
/**
* @file cap.c
* @brief Capabilities control.
*
* @see cap.h
*/
#include <security/cap.h>
#include <proc/task.h>
#include <synch/spinlock.h>
#include <syscall/sysarg64.h>
#include <syscall/copy.h>
#include <arch.h>
#include <typedefs.h>
#include <errno.h>
 
/** Set capabilities.
*
* @param t Task whose capabilities are to be changed.
* @param caps New set of capabilities.
*/
void cap_set(task_t *t, cap_t caps)
{
ipl_t ipl;
ipl = interrupts_disable();
spinlock_lock(&t->lock);
t->capabilities = caps;
spinlock_unlock(&t->lock);
interrupts_restore(ipl);
}
 
/** Get capabilities.
*
* @param t Task whose capabilities are to be returned.
* @return Task's capabilities.
*/
cap_t cap_get(task_t *t)
{
ipl_t ipl;
cap_t caps;
ipl = interrupts_disable();
spinlock_lock(&t->lock);
caps = t->capabilities;
spinlock_unlock(&t->lock);
interrupts_restore(ipl);
return caps;
}
 
/** Grant capabilities to a task.
*
* The calling task must have the CAP_CAP capability.
*
* @param uspace_taskid_arg Userspace structure holding destination task ID.
* @param caps Capabilities to grant.
*
* @return Zero on success or an error code from @ref errno.h.
*/
unative_t sys_cap_grant(sysarg64_t *uspace_taskid_arg, cap_t caps)
{
sysarg64_t taskid_arg;
task_t *t;
ipl_t ipl;
int rc;
if (!(cap_get(TASK) & CAP_CAP))
return (unative_t) EPERM;
rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t));
if (rc != 0)
return (unative_t) rc;
ipl = interrupts_disable();
spinlock_lock(&tasks_lock);
t = task_find_by_id((task_id_t) taskid_arg.value);
if (!t) {
spinlock_unlock(&tasks_lock);
interrupts_restore(ipl);
return (unative_t) ENOENT;
}
spinlock_lock(&t->lock);
cap_set(t, cap_get(t) | caps);
spinlock_unlock(&t->lock);
spinlock_unlock(&tasks_lock);
 
interrupts_restore(ipl);
return 0;
}
 
/** Revoke capabilities from a task.
*
* The calling task must have the CAP_CAP capability or the caller must
* attempt to revoke capabilities from itself.
*
* @param uspace_taskid_arg Userspace structure holding destination task ID.
* @param caps Capabilities to revoke.
*
* @return Zero on success or an error code from @ref errno.h.
*/
unative_t sys_cap_revoke(sysarg64_t *uspace_taskid_arg, cap_t caps)
{
sysarg64_t taskid_arg;
task_t *t;
ipl_t ipl;
int rc;
rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t));
if (rc != 0)
return (unative_t) rc;
 
ipl = interrupts_disable();
spinlock_lock(&tasks_lock);
t = task_find_by_id((task_id_t) taskid_arg.value);
if (!t) {
spinlock_unlock(&tasks_lock);
interrupts_restore(ipl);
return (unative_t) ENOENT;
}
 
/*
* Revoking capabilities is different from granting them in that
* a task can revoke capabilities from itself even if it
* doesn't have CAP_CAP.
*/
if (!(cap_get(TASK) & CAP_CAP) || !(t == TASK)) {
spinlock_unlock(&tasks_lock);
interrupts_restore(ipl);
return (unative_t) EPERM;
}
spinlock_lock(&t->lock);
cap_set(t, cap_get(t) & ~caps);
spinlock_unlock(&t->lock);
 
spinlock_unlock(&tasks_lock);
 
interrupts_restore(ipl);
return 0;
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/generic/src/adt/hash_table.c
0,0 → 1,177
/*
* 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 genericadt
* @{
*/
 
/**
* @file
* @brief Implementation of generic chained hash table.
*
* This file contains implementation of generic chained hash table.
*/
 
#include <adt/hash_table.h>
#include <adt/list.h>
#include <typedefs.h>
#include <arch/types.h>
#include <debug.h>
#include <mm/slab.h>
#include <memstr.h>
 
/** Create chained hash table.
*
* @param h Hash table structure. Will be initialized by this call.
* @param m Number of slots in the hash table.
* @param max_keys Maximal number of keys needed to identify an item.
* @param op Hash table operations structure.
*/
void hash_table_create(hash_table_t *h, count_t m, count_t max_keys, hash_table_operations_t *op)
{
int i;
 
ASSERT(h);
ASSERT(op && op->hash && op->compare);
ASSERT(max_keys > 0);
h->entry = malloc(m * sizeof(link_t), 0);
if (!h->entry) {
panic("cannot allocate memory for hash table\n");
}
memsetb((uintptr_t) h->entry, m * sizeof(link_t), 0);
for (i = 0; i < m; i++)
list_initialize(&h->entry[i]);
h->entries = m;
h->max_keys = max_keys;
h->op = op;
}
 
/** Insert item into hash table.
*
* @param h Hash table.
* @param key Array of all keys necessary to compute hash index.
* @param item Item to be inserted into the hash table.
*/
void hash_table_insert(hash_table_t *h, unative_t key[], link_t *item)
{
index_t chain;
 
ASSERT(item);
ASSERT(h && h->op && h->op->hash && h->op->compare);
 
chain = h->op->hash(key);
ASSERT(chain < h->entries);
list_append(item, &h->entry[chain]);
}
 
/** Search hash table for an item matching keys.
*
* @param h Hash table.
* @param key Array of all keys needed to compute hash index.
*
* @return Matching item on success, NULL if there is no such item.
*/
link_t *hash_table_find(hash_table_t *h, unative_t key[])
{
link_t *cur;
index_t chain;
 
ASSERT(h && h->op && h->op->hash && h->op->compare);
 
chain = h->op->hash(key);
ASSERT(chain < h->entries);
for (cur = h->entry[chain].next; cur != &h->entry[chain]; cur = cur->next) {
if (h->op->compare(key, h->max_keys, cur)) {
/*
* The entry is there.
*/
return cur;
}
}
return NULL;
}
 
/** Remove all matching items from hash table.
*
* For each removed item, h->remove_callback() is called.
*
* @param h Hash table.
* @param key Array of keys that will be compared against items of the hash table.
* @param keys Number of keys in the key array.
*/
void hash_table_remove(hash_table_t *h, unative_t key[], count_t keys)
{
index_t chain;
link_t *cur;
 
ASSERT(h && h->op && h->op->hash && h->op->compare && h->op->remove_callback);
ASSERT(keys <= h->max_keys);
if (keys == h->max_keys) {
 
/*
* All keys are known, hash_table_find() can be used to find the entry.
*/
cur = hash_table_find(h, key);
if (cur) {
list_remove(cur);
h->op->remove_callback(cur);
}
return;
}
/*
* Fewer keys were passed.
* Any partially matching entries are to be removed.
*/
for (chain = 0; chain < h->entries; chain++) {
for (cur = h->entry[chain].next; cur != &h->entry[chain]; cur = cur->next) {
if (h->op->compare(key, keys, cur)) {
link_t *hlp;
hlp = cur;
cur = cur->prev;
list_remove(hlp);
h->op->remove_callback(hlp);
continue;
}
}
}
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/adt/bitmap.c
0,0 → 1,189
/*
* 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 genericadt
* @{
*/
/**
* @file
* @brief Implementation of bitmap ADT.
*
* This file implements bitmap ADT and provides functions for
* setting and clearing ranges of bits.
*/
 
#include <adt/bitmap.h>
#include <typedefs.h>
#include <arch/types.h>
#include <align.h>
#include <debug.h>
#include <macros.h>
 
#define ALL_ONES 0xff
#define ALL_ZEROES 0x00
 
/** Initialize bitmap.
*
* No portion of the bitmap is set or cleared by this function.
*
* @param bitmap Bitmap structure.
* @param map Address of the memory used to hold the map.
* @param bits Number of bits stored in bitmap.
*/
void bitmap_initialize(bitmap_t *bitmap, uint8_t *map, count_t bits)
{
bitmap->map = map;
bitmap->bits = bits;
}
 
/** Set range of bits.
*
* @param bitmap Bitmap structure.
* @param start Starting bit.
* @param bits Number of bits to set.
*/
void bitmap_set_range(bitmap_t *bitmap, index_t start, count_t bits)
{
index_t i=0;
index_t aligned_start;
count_t lub; /* leading unaligned bits */
count_t amb; /* aligned middle bits */
count_t tab; /* trailing aligned bits */
ASSERT(start + bits <= bitmap->bits);
aligned_start = ALIGN_UP(start, 8);
lub = min(aligned_start - start, bits);
amb = bits > lub ? bits - lub : 0;
tab = amb % 8;
if ( start + bits < aligned_start ) {
/*
* Set bits in the middle of byte
*/
bitmap->map[start / 8] |= ((1 << lub)-1) << (start&7);
return;
}
if (lub) {
/*
* Make sure to set any leading unaligned bits.
*/
bitmap->map[start / 8] |= ~((1 << (8 - lub)) - 1);
}
for (i = 0; i < amb / 8; i++) {
/*
* The middle bits can be set byte by byte.
*/
bitmap->map[aligned_start / 8 + i] = ALL_ONES;
}
if (tab) {
/*
* Make sure to set any trailing aligned bits.
*/
bitmap->map[aligned_start / 8 + i] |= (1 << tab) - 1;
}
}
 
/** Clear range of bits.
*
* @param bitmap Bitmap structure.
* @param start Starting bit.
* @param bits Number of bits to clear.
*/
void bitmap_clear_range(bitmap_t *bitmap, index_t start, count_t bits)
{
index_t i=0;
index_t aligned_start;
count_t lub; /* leading unaligned bits */
count_t amb; /* aligned middle bits */
count_t tab; /* trailing aligned bits */
ASSERT(start + bits <= bitmap->bits);
aligned_start = ALIGN_UP(start, 8);
lub = min(aligned_start - start, bits);
amb = bits > lub ? bits - lub : 0;
tab = amb % 8;
 
if ( start + bits < aligned_start )
{
/*
* Set bits in the middle of byte
*/
bitmap->map[start / 8] &= ~(((1 << lub)-1) << (start&7));
return;
}
 
 
if (lub) {
/*
* Make sure to clear any leading unaligned bits.
*/
bitmap->map[start / 8] &= (1 << (8 - lub)) - 1;
}
for (i = 0; i < amb / 8; i++) {
/*
* The middle bits can be cleared byte by byte.
*/
bitmap->map[aligned_start / 8 + i] = ALL_ZEROES;
}
if (tab) {
/*
* Make sure to clear any trailing aligned bits.
*/
bitmap->map[aligned_start / 8 + i] &= ~((1 << tab) - 1);
}
 
}
 
/** Copy portion of one bitmap into another bitmap.
*
* @param dst Destination bitmap.
* @param src Source bitmap.
* @param bits Number of bits to copy.
*/
void bitmap_copy(bitmap_t *dst, bitmap_t *src, count_t bits)
{
index_t i;
ASSERT(bits <= dst->bits);
ASSERT(bits <= src->bits);
for (i = 0; i < bits / 8; i++)
dst->map[i] = src->map[i];
if (bits % 8) {
bitmap_clear_range(dst, i * 8, bits % 8);
dst->map[i] |= src->map[i] & ((1 << (bits % 8)) - 1);
}
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/adt/btree.c
0,0 → 1,1002
/*
* 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 genericadt
* @{
*/
 
/**
* @file
* @brief B+tree implementation.
*
* This file implements B+tree type and operations.
*
* The B+tree has the following properties:
* @li it is a ballanced 3-4-5 tree (i.e. BTREE_M = 5)
* @li values (i.e. pointers to values) are stored only in leaves
* @li leaves are linked in a list
*
* Be carefull when using these trees. They need to allocate
* and deallocate memory for their index nodes and as such
* can sleep.
*/
 
#include <adt/btree.h>
#include <adt/list.h>
#include <mm/slab.h>
#include <debug.h>
#include <panic.h>
#include <typedefs.h>
#include <print.h>
 
static void btree_destroy_subtree(btree_node_t *root);
static void _btree_insert(btree_t *t, btree_key_t key, void *value, btree_node_t *rsubtree, btree_node_t *node);
static void _btree_remove(btree_t *t, btree_key_t key, btree_node_t *node);
static void node_initialize(btree_node_t *node);
static void node_insert_key_and_lsubtree(btree_node_t *node, btree_key_t key, void *value, btree_node_t *lsubtree);
static void node_insert_key_and_rsubtree(btree_node_t *node, btree_key_t key, void *value, btree_node_t *rsubtree);
static void node_remove_key_and_lsubtree(btree_node_t *node, btree_key_t key);
static void node_remove_key_and_rsubtree(btree_node_t *node, btree_key_t key);
static btree_node_t *node_split(btree_node_t *node, btree_key_t key, void *value, btree_node_t *rsubtree, btree_key_t *median);
static btree_node_t *node_combine(btree_node_t *node);
static index_t find_key_by_subtree(btree_node_t *node, btree_node_t *subtree, bool right);
static void rotate_from_right(btree_node_t *lnode, btree_node_t *rnode, index_t idx);
static void rotate_from_left(btree_node_t *lnode, btree_node_t *rnode, index_t idx);
static bool try_insert_by_rotation_to_left(btree_node_t *node, btree_key_t key, void *value, btree_node_t *rsubtree);
static bool try_insert_by_rotation_to_right(btree_node_t *node, btree_key_t key, void *value, btree_node_t *rsubtree);
static bool try_rotation_from_left(btree_node_t *rnode);
static bool try_rotation_from_right(btree_node_t *lnode);
 
#define ROOT_NODE(n) (!(n)->parent)
#define INDEX_NODE(n) ((n)->subtree[0] != NULL)
#define LEAF_NODE(n) ((n)->subtree[0] == NULL)
 
#define FILL_FACTOR ((BTREE_M-1)/2)
 
#define MEDIAN_LOW_INDEX(n) (((n)->keys-1)/2)
#define MEDIAN_HIGH_INDEX(n) ((n)->keys/2)
#define MEDIAN_LOW(n) ((n)->key[MEDIAN_LOW_INDEX((n))]);
#define MEDIAN_HIGH(n) ((n)->key[MEDIAN_HIGH_INDEX((n))]);
 
static slab_cache_t *btree_node_slab;
 
/** Initialize B-trees. */
void btree_init(void)
{
btree_node_slab = slab_cache_create("btree_node_slab", sizeof(btree_node_t), 0, NULL, NULL, SLAB_CACHE_MAGDEFERRED);
}
 
/** Create empty B-tree.
*
* @param t B-tree.
*/
void btree_create(btree_t *t)
{
list_initialize(&t->leaf_head);
t->root = (btree_node_t *) slab_alloc(btree_node_slab, 0);
node_initialize(t->root);
list_append(&t->root->leaf_link, &t->leaf_head);
}
 
/** Destroy empty B-tree. */
void btree_destroy(btree_t *t)
{
btree_destroy_subtree(t->root);
}
 
/** Insert key-value pair into B-tree.
*
* @param t B-tree.
* @param key Key to be inserted.
* @param value Value to be inserted.
* @param leaf_node Leaf node where the insertion should begin.
*/
void btree_insert(btree_t *t, btree_key_t key, void *value, btree_node_t *leaf_node)
{
btree_node_t *lnode;
ASSERT(value);
lnode = leaf_node;
if (!lnode) {
if (btree_search(t, key, &lnode)) {
panic("B-tree %p already contains key %d\n", t, key);
}
}
_btree_insert(t, key, value, NULL, lnode);
}
 
/** Destroy subtree rooted in a node.
*
* @param root Root of the subtree.
*/
void btree_destroy_subtree(btree_node_t *root)
{
int i;
 
if (root->keys) {
for (i = 0; i < root->keys + 1; i++) {
if (root->subtree[i])
btree_destroy_subtree(root->subtree[i]);
}
}
slab_free(btree_node_slab, root);
}
 
/** Recursively insert into B-tree.
*
* @param t B-tree.
* @param key Key to be inserted.
* @param value Value to be inserted.
* @param rsubtree Right subtree of the inserted key.
* @param node Start inserting into this node.
*/
void _btree_insert(btree_t *t, btree_key_t key, void *value, btree_node_t *rsubtree, btree_node_t *node)
{
if (node->keys < BTREE_MAX_KEYS) {
/*
* Node conatins enough space, the key can be stored immediately.
*/
node_insert_key_and_rsubtree(node, key, value, rsubtree);
} else if (try_insert_by_rotation_to_left(node, key, value, rsubtree)) {
/*
* The key-value-rsubtree triplet has been inserted because
* some keys could have been moved to the left sibling.
*/
} else if (try_insert_by_rotation_to_right(node, key, value, rsubtree)) {
/*
* The key-value-rsubtree triplet has been inserted because
* some keys could have been moved to the right sibling.
*/
} else {
btree_node_t *rnode;
btree_key_t median;
/*
* Node is full and both siblings (if both exist) are full too.
* Split the node and insert the smallest key from the node containing
* bigger keys (i.e. the new node) into its parent.
*/
 
rnode = node_split(node, key, value, rsubtree, &median);
 
if (LEAF_NODE(node)) {
list_prepend(&rnode->leaf_link, &node->leaf_link);
}
if (ROOT_NODE(node)) {
/*
* We split the root node. Create new root.
*/
t->root = (btree_node_t *) slab_alloc(btree_node_slab, 0);
node->parent = t->root;
rnode->parent = t->root;
node_initialize(t->root);
/*
* Left-hand side subtree will be the old root (i.e. node).
* Right-hand side subtree will be rnode.
*/
t->root->subtree[0] = node;
 
t->root->depth = node->depth + 1;
}
_btree_insert(t, median, NULL, rnode, node->parent);
}
}
 
/** Remove B-tree node.
*
* @param t B-tree.
* @param key Key to be removed from the B-tree along with its associated value.
* @param leaf_node If not NULL, pointer to the leaf node where the key is found.
*/
void btree_remove(btree_t *t, btree_key_t key, btree_node_t *leaf_node)
{
btree_node_t *lnode;
lnode = leaf_node;
if (!lnode) {
if (!btree_search(t, key, &lnode)) {
panic("B-tree %p does not contain key %d\n", t, key);
}
}
_btree_remove(t, key, lnode);
}
 
/** Recursively remove B-tree node.
*
* @param t B-tree.
* @param key Key to be removed from the B-tree along with its associated value.
* @param node Node where the key being removed resides.
*/
void _btree_remove(btree_t *t, btree_key_t key, btree_node_t *node)
{
if (ROOT_NODE(node)) {
if (node->keys == 1 && node->subtree[0]) {
/*
* Free the current root and set new root.
*/
t->root = node->subtree[0];
t->root->parent = NULL;
slab_free(btree_node_slab, node);
} else {
/*
* Remove the key from the root node.
* Note that the right subtree is removed because when
* combining two nodes, the left-side sibling is preserved
* and the right-side sibling is freed.
*/
node_remove_key_and_rsubtree(node, key);
}
return;
}
if (node->keys <= FILL_FACTOR) {
/*
* If the node is below the fill factor,
* try to borrow keys from left or right sibling.
*/
if (!try_rotation_from_left(node))
try_rotation_from_right(node);
}
if (node->keys > FILL_FACTOR) {
int i;
 
/*
* The key can be immediatelly removed.
*
* Note that the right subtree is removed because when
* combining two nodes, the left-side sibling is preserved
* and the right-side sibling is freed.
*/
node_remove_key_and_rsubtree(node, key);
for (i = 0; i < node->parent->keys; i++) {
if (node->parent->key[i] == key)
node->parent->key[i] = node->key[0];
}
} else {
index_t idx;
btree_node_t *rnode, *parent;
 
/*
* The node is below the fill factor as well as its left and right sibling.
* Resort to combining the node with one of its siblings.
* The node which is on the left is preserved and the node on the right is
* freed.
*/
parent = node->parent;
node_remove_key_and_rsubtree(node, key);
rnode = node_combine(node);
if (LEAF_NODE(rnode))
list_remove(&rnode->leaf_link);
idx = find_key_by_subtree(parent, rnode, true);
ASSERT((int) idx != -1);
slab_free(btree_node_slab, rnode);
_btree_remove(t, parent->key[idx], parent);
}
}
 
/** Search key in a B-tree.
*
* @param t B-tree.
* @param key Key to be searched.
* @param leaf_node Address where to put pointer to visited leaf node.
*
* @return Pointer to value or NULL if there is no such key.
*/
void *btree_search(btree_t *t, btree_key_t key, btree_node_t **leaf_node)
{
btree_node_t *cur, *next;
/*
* Iteratively descend to the leaf that can contain the searched key.
*/
for (cur = t->root; cur; cur = next) {
 
/* Last iteration will set this with proper leaf node address. */
*leaf_node = cur;
/*
* The key can be in the leftmost subtree.
* Test it separately.
*/
if (key < cur->key[0]) {
next = cur->subtree[0];
continue;
} else {
void *val;
int i;
/*
* Now if the key is smaller than cur->key[i]
* it can only mean that the value is in cur->subtree[i]
* or it is not in the tree at all.
*/
for (i = 1; i < cur->keys; i++) {
if (key < cur->key[i]) {
next = cur->subtree[i];
val = cur->value[i - 1];
 
if (LEAF_NODE(cur))
return key == cur->key[i - 1] ? val : NULL;
 
goto descend;
}
}
/*
* Last possibility is that the key is in the rightmost subtree.
*/
next = cur->subtree[i];
val = cur->value[i - 1];
if (LEAF_NODE(cur))
return key == cur->key[i - 1] ? val : NULL;
}
descend:
;
}
 
/*
* The key was not found in the *leaf_node and is smaller than any of its keys.
*/
return NULL;
}
 
/** Return pointer to B-tree leaf node's left neighbour.
*
* @param t B-tree.
* @param node Node whose left neighbour will be returned.
*
* @return Left neighbour of the node or NULL if the node does not have the left neighbour.
*/
btree_node_t *btree_leaf_node_left_neighbour(btree_t *t, btree_node_t *node)
{
ASSERT(LEAF_NODE(node));
if (node->leaf_link.prev != &t->leaf_head)
return list_get_instance(node->leaf_link.prev, btree_node_t, leaf_link);
else
return NULL;
}
 
/** Return pointer to B-tree leaf node's right neighbour.
*
* @param t B-tree.
* @param node Node whose right neighbour will be returned.
*
* @return Right neighbour of the node or NULL if the node does not have the right neighbour.
*/
btree_node_t *btree_leaf_node_right_neighbour(btree_t *t, btree_node_t *node)
{
ASSERT(LEAF_NODE(node));
if (node->leaf_link.next != &t->leaf_head)
return list_get_instance(node->leaf_link.next, btree_node_t, leaf_link);
else
return NULL;
}
 
/** Initialize B-tree node.
*
* @param node B-tree node.
*/
void node_initialize(btree_node_t *node)
{
int i;
 
node->keys = 0;
/* Clean also space for the extra key. */
for (i = 0; i < BTREE_MAX_KEYS + 1; i++) {
node->key[i] = 0;
node->value[i] = NULL;
node->subtree[i] = NULL;
}
node->subtree[i] = NULL;
node->parent = NULL;
link_initialize(&node->leaf_link);
 
link_initialize(&node->bfs_link);
node->depth = 0;
}
 
/** Insert key-value-lsubtree triplet into B-tree node.
*
* It is actually possible to have more keys than BTREE_MAX_KEYS.
* This feature is used during insert by right rotation.
*
* @param node B-tree node into wich the new key is to be inserted.
* @param key The key to be inserted.
* @param value Pointer to value to be inserted.
* @param lsubtree Pointer to the left subtree.
*/
void node_insert_key_and_lsubtree(btree_node_t *node, btree_key_t key, void *value, btree_node_t *lsubtree)
{
int i;
 
for (i = 0; i < node->keys; i++) {
if (key < node->key[i]) {
int j;
for (j = node->keys; j > i; j--) {
node->key[j] = node->key[j - 1];
node->value[j] = node->value[j - 1];
node->subtree[j + 1] = node->subtree[j];
}
node->subtree[j + 1] = node->subtree[j];
break;
}
}
node->key[i] = key;
node->value[i] = value;
node->subtree[i] = lsubtree;
node->keys++;
}
 
/** Insert key-value-rsubtree triplet into B-tree node.
*
* It is actually possible to have more keys than BTREE_MAX_KEYS.
* This feature is used during splitting the node when the
* number of keys is BTREE_MAX_KEYS + 1. Insert by left rotation
* also makes use of this feature.
*
* @param node B-tree node into wich the new key is to be inserted.
* @param key The key to be inserted.
* @param value Pointer to value to be inserted.
* @param rsubtree Pointer to the right subtree.
*/
void node_insert_key_and_rsubtree(btree_node_t *node, btree_key_t key, void *value, btree_node_t *rsubtree)
{
int i;
 
for (i = 0; i < node->keys; i++) {
if (key < node->key[i]) {
int j;
for (j = node->keys; j > i; j--) {
node->key[j] = node->key[j - 1];
node->value[j] = node->value[j - 1];
node->subtree[j + 1] = node->subtree[j];
}
break;
}
}
node->key[i] = key;
node->value[i] = value;
node->subtree[i + 1] = rsubtree;
node->keys++;
}
 
/** Remove key and its left subtree pointer from B-tree node.
*
* Remove the key and eliminate gaps in node->key array.
* Note that the value pointer and the left subtree pointer
* is removed from the node as well.
*
* @param node B-tree node.
* @param key Key to be removed.
*/
void node_remove_key_and_lsubtree(btree_node_t *node, btree_key_t key)
{
int i, j;
for (i = 0; i < node->keys; i++) {
if (key == node->key[i]) {
for (j = i + 1; j < node->keys; j++) {
node->key[j - 1] = node->key[j];
node->value[j - 1] = node->value[j];
node->subtree[j - 1] = node->subtree[j];
}
node->subtree[j - 1] = node->subtree[j];
node->keys--;
return;
}
}
panic("node %p does not contain key %d\n", node, key);
}
 
/** Remove key and its right subtree pointer from B-tree node.
*
* Remove the key and eliminate gaps in node->key array.
* Note that the value pointer and the right subtree pointer
* is removed from the node as well.
*
* @param node B-tree node.
* @param key Key to be removed.
*/
void node_remove_key_and_rsubtree(btree_node_t *node, btree_key_t key)
{
int i, j;
for (i = 0; i < node->keys; i++) {
if (key == node->key[i]) {
for (j = i + 1; j < node->keys; j++) {
node->key[j - 1] = node->key[j];
node->value[j - 1] = node->value[j];
node->subtree[j] = node->subtree[j + 1];
}
node->keys--;
return;
}
}
panic("node %p does not contain key %d\n", node, key);
}
 
/** Split full B-tree node and insert new key-value-right-subtree triplet.
*
* This function will split a node and return a pointer to a newly created
* node containing keys greater than or equal to the greater of medians
* (or median) of the old keys and the newly added key. It will also write
* the median key to a memory address supplied by the caller.
*
* If the node being split is an index node, the median will not be
* included in the new node. If the node is a leaf node,
* the median will be copied there.
*
* @param node B-tree node wich is going to be split.
* @param key The key to be inserted.
* @param value Pointer to the value to be inserted.
* @param rsubtree Pointer to the right subtree of the key being added.
* @param median Address in memory, where the median key will be stored.
*
* @return Newly created right sibling of node.
*/
btree_node_t *node_split(btree_node_t *node, btree_key_t key, void *value, btree_node_t *rsubtree, btree_key_t *median)
{
btree_node_t *rnode;
int i, j;
 
ASSERT(median);
ASSERT(node->keys == BTREE_MAX_KEYS);
 
/*
* Use the extra space to store the extra node.
*/
node_insert_key_and_rsubtree(node, key, value, rsubtree);
 
/*
* Compute median of keys.
*/
*median = MEDIAN_HIGH(node);
/*
* Allocate and initialize new right sibling.
*/
rnode = (btree_node_t *) slab_alloc(btree_node_slab, 0);
node_initialize(rnode);
rnode->parent = node->parent;
rnode->depth = node->depth;
/*
* Copy big keys, values and subtree pointers to the new right sibling.
* If this is an index node, do not copy the median.
*/
i = (int) INDEX_NODE(node);
for (i += MEDIAN_HIGH_INDEX(node), j = 0; i < node->keys; i++, j++) {
rnode->key[j] = node->key[i];
rnode->value[j] = node->value[i];
rnode->subtree[j] = node->subtree[i];
/*
* Fix parent links in subtrees.
*/
if (rnode->subtree[j])
rnode->subtree[j]->parent = rnode;
}
rnode->subtree[j] = node->subtree[i];
if (rnode->subtree[j])
rnode->subtree[j]->parent = rnode;
 
rnode->keys = j; /* Set number of keys of the new node. */
node->keys /= 2; /* Shrink the old node. */
return rnode;
}
 
/** Combine node with any of its siblings.
*
* The siblings are required to be below the fill factor.
*
* @param node Node to combine with one of its siblings.
*
* @return Pointer to the rightmost of the two nodes.
*/
btree_node_t *node_combine(btree_node_t *node)
{
index_t idx;
btree_node_t *rnode;
int i;
 
ASSERT(!ROOT_NODE(node));
idx = find_key_by_subtree(node->parent, node, false);
if (idx == node->parent->keys) {
/*
* Rightmost subtree of its parent, combine with the left sibling.
*/
idx--;
rnode = node;
node = node->parent->subtree[idx];
} else {
rnode = node->parent->subtree[idx + 1];
}
 
/* Index nodes need to insert parent node key in between left and right node. */
if (INDEX_NODE(node))
node->key[node->keys++] = node->parent->key[idx];
/* Copy the key-value-subtree triplets from the right node. */
for (i = 0; i < rnode->keys; i++) {
node->key[node->keys + i] = rnode->key[i];
node->value[node->keys + i] = rnode->value[i];
if (INDEX_NODE(node)) {
node->subtree[node->keys + i] = rnode->subtree[i];
rnode->subtree[i]->parent = node;
}
}
if (INDEX_NODE(node)) {
node->subtree[node->keys + i] = rnode->subtree[i];
rnode->subtree[i]->parent = node;
}
 
node->keys += rnode->keys;
 
return rnode;
}
 
/** Find key by its left or right subtree.
*
* @param node B-tree node.
* @param subtree Left or right subtree of a key found in node.
* @param right If true, subtree is a right subtree. If false, subtree is a left subtree.
*
* @return Index of the key associated with the subtree.
*/
index_t find_key_by_subtree(btree_node_t *node, btree_node_t *subtree, bool right)
{
int i;
for (i = 0; i < node->keys + 1; i++) {
if (subtree == node->subtree[i])
return i - (int) (right != false);
}
panic("node %p does not contain subtree %p\n", node, subtree);
}
 
/** Rotate one key-value-rsubtree triplet from the left sibling to the right sibling.
*
* The biggest key and its value and right subtree is rotated from the left node
* to the right. If the node is an index node, than the parent node key belonging to
* the left node takes part in the rotation.
*
* @param lnode Left sibling.
* @param rnode Right sibling.
* @param idx Index of the parent node key that is taking part in the rotation.
*/
void rotate_from_left(btree_node_t *lnode, btree_node_t *rnode, index_t idx)
{
btree_key_t key;
 
key = lnode->key[lnode->keys - 1];
if (LEAF_NODE(lnode)) {
void *value;
 
value = lnode->value[lnode->keys - 1];
node_remove_key_and_rsubtree(lnode, key);
node_insert_key_and_lsubtree(rnode, key, value, NULL);
lnode->parent->key[idx] = key;
} else {
btree_node_t *rsubtree;
 
rsubtree = lnode->subtree[lnode->keys];
node_remove_key_and_rsubtree(lnode, key);
node_insert_key_and_lsubtree(rnode, lnode->parent->key[idx], NULL, rsubtree);
lnode->parent->key[idx] = key;
 
/* Fix parent link of the reconnected right subtree. */
rsubtree->parent = rnode;
}
 
}
 
/** Rotate one key-value-lsubtree triplet from the right sibling to the left sibling.
*
* The smallest key and its value and left subtree is rotated from the right node
* to the left. If the node is an index node, than the parent node key belonging to
* the right node takes part in the rotation.
*
* @param lnode Left sibling.
* @param rnode Right sibling.
* @param idx Index of the parent node key that is taking part in the rotation.
*/
void rotate_from_right(btree_node_t *lnode, btree_node_t *rnode, index_t idx)
{
btree_key_t key;
 
key = rnode->key[0];
if (LEAF_NODE(rnode)) {
void *value;
 
value = rnode->value[0];
node_remove_key_and_lsubtree(rnode, key);
node_insert_key_and_rsubtree(lnode, key, value, NULL);
rnode->parent->key[idx] = rnode->key[0];
} else {
btree_node_t *lsubtree;
 
lsubtree = rnode->subtree[0];
node_remove_key_and_lsubtree(rnode, key);
node_insert_key_and_rsubtree(lnode, rnode->parent->key[idx], NULL, lsubtree);
rnode->parent->key[idx] = key;
 
/* Fix parent link of the reconnected left subtree. */
lsubtree->parent = lnode;
}
 
}
 
/** Insert key-value-rsubtree triplet and rotate the node to the left, if this operation can be done.
*
* Left sibling of the node (if it exists) is checked for free space.
* If there is free space, the key is inserted and the smallest key of
* the node is moved there. The index node which is the parent of both
* nodes is fixed.
*
* @param node B-tree node.
* @param inskey Key to be inserted.
* @param insvalue Value to be inserted.
* @param rsubtree Right subtree of inskey.
*
* @return True if the rotation was performed, false otherwise.
*/
bool try_insert_by_rotation_to_left(btree_node_t *node, btree_key_t inskey, void *insvalue, btree_node_t *rsubtree)
{
index_t idx;
btree_node_t *lnode;
 
/*
* If this is root node, the rotation can not be done.
*/
if (ROOT_NODE(node))
return false;
idx = find_key_by_subtree(node->parent, node, true);
if ((int) idx == -1) {
/*
* If this node is the leftmost subtree of its parent,
* the rotation can not be done.
*/
return false;
}
lnode = node->parent->subtree[idx];
if (lnode->keys < BTREE_MAX_KEYS) {
/*
* The rotaion can be done. The left sibling has free space.
*/
node_insert_key_and_rsubtree(node, inskey, insvalue, rsubtree);
rotate_from_right(lnode, node, idx);
return true;
}
 
return false;
}
 
/** Insert key-value-rsubtree triplet and rotate the node to the right, if this operation can be done.
*
* Right sibling of the node (if it exists) is checked for free space.
* If there is free space, the key is inserted and the biggest key of
* the node is moved there. The index node which is the parent of both
* nodes is fixed.
*
* @param node B-tree node.
* @param inskey Key to be inserted.
* @param insvalue Value to be inserted.
* @param rsubtree Right subtree of inskey.
*
* @return True if the rotation was performed, false otherwise.
*/
bool try_insert_by_rotation_to_right(btree_node_t *node, btree_key_t inskey, void *insvalue, btree_node_t *rsubtree)
{
index_t idx;
btree_node_t *rnode;
 
/*
* If this is root node, the rotation can not be done.
*/
if (ROOT_NODE(node))
return false;
idx = find_key_by_subtree(node->parent, node, false);
if (idx == node->parent->keys) {
/*
* If this node is the rightmost subtree of its parent,
* the rotation can not be done.
*/
return false;
}
rnode = node->parent->subtree[idx + 1];
if (rnode->keys < BTREE_MAX_KEYS) {
/*
* The rotaion can be done. The right sibling has free space.
*/
node_insert_key_and_rsubtree(node, inskey, insvalue, rsubtree);
rotate_from_left(node, rnode, idx);
return true;
}
 
return false;
}
 
/** Rotate in a key from the left sibling or from the index node, if this operation can be done.
*
* @param rnode Node into which to add key from its left sibling or from the index node.
*
* @return True if the rotation was performed, false otherwise.
*/
bool try_rotation_from_left(btree_node_t *rnode)
{
index_t idx;
btree_node_t *lnode;
 
/*
* If this is root node, the rotation can not be done.
*/
if (ROOT_NODE(rnode))
return false;
idx = find_key_by_subtree(rnode->parent, rnode, true);
if ((int) idx == -1) {
/*
* If this node is the leftmost subtree of its parent,
* the rotation can not be done.
*/
return false;
}
lnode = rnode->parent->subtree[idx];
if (lnode->keys > FILL_FACTOR) {
rotate_from_left(lnode, rnode, idx);
return true;
}
return false;
}
 
/** Rotate in a key from the right sibling or from the index node, if this operation can be done.
*
* @param lnode Node into which to add key from its right sibling or from the index node.
*
* @return True if the rotation was performed, false otherwise.
*/
bool try_rotation_from_right(btree_node_t *lnode)
{
index_t idx;
btree_node_t *rnode;
 
/*
* If this is root node, the rotation can not be done.
*/
if (ROOT_NODE(lnode))
return false;
idx = find_key_by_subtree(lnode->parent, lnode, false);
if (idx == lnode->parent->keys) {
/*
* If this node is the rightmost subtree of its parent,
* the rotation can not be done.
*/
return false;
}
rnode = lnode->parent->subtree[idx + 1];
if (rnode->keys > FILL_FACTOR) {
rotate_from_right(lnode, rnode, idx);
return true;
}
 
return false;
}
 
/** Print B-tree.
*
* @param t Print out B-tree.
*/
void btree_print(btree_t *t)
{
int i, depth = t->root->depth;
link_t head, *cur;
 
printf("Printing B-tree:\n");
list_initialize(&head);
list_append(&t->root->bfs_link, &head);
 
/*
* Use BFS search to print out the tree.
* Levels are distinguished from one another by node->depth.
*/
while (!list_empty(&head)) {
link_t *hlp;
btree_node_t *node;
hlp = head.next;
ASSERT(hlp != &head);
node = list_get_instance(hlp, btree_node_t, bfs_link);
list_remove(hlp);
ASSERT(node);
if (node->depth != depth) {
printf("\n");
depth = node->depth;
}
 
printf("(");
for (i = 0; i < node->keys; i++) {
printf("%lld%s", node->key[i], i < node->keys - 1 ? "," : "");
if (node->depth && node->subtree[i]) {
list_append(&node->subtree[i]->bfs_link, &head);
}
}
if (node->depth && node->subtree[i]) {
list_append(&node->subtree[i]->bfs_link, &head);
}
printf(")");
}
printf("\n");
printf("Printing list of leaves:\n");
for (cur = t->leaf_head.next; cur != &t->leaf_head; cur = cur->next) {
btree_node_t *node;
node = list_get_instance(cur, btree_node_t, leaf_link);
ASSERT(node);
 
printf("(");
for (i = 0; i < node->keys; i++)
printf("%lld%s", node->key[i], i < node->keys - 1 ? "," : "");
printf(")");
}
printf("\n");
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/adt/list.c
0,0 → 1,94
/*
* Copyright (C) 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 genericadt
* @{
*/
 
/**
* @file
* @brief Functions completing doubly linked circular list implementaion.
*
* This file contains some of the functions implementing doubly linked circular lists.
* However, this ADT is mostly implemented in @ref list.h.
*/
 
#include <adt/list.h>
 
/** Check for membership
*
* Check whether link is contained in the list head.
* The membership is defined as pointer equivalence.
*
* @param link Item to look for.
* @param head List to look in.
*
* @return true if link is contained in head, false otherwise.
*
*/
bool list_member(const link_t *link, const link_t *head)
{
bool found = false;
link_t *hlp = head->next;
while (hlp != head) {
if (hlp == link) {
found = true;
break;
}
hlp = hlp->next;
}
return found;
}
 
 
/** Concatenate two lists
*
* Concatenate lists head1 and head2, producing a single
* list head1 containing items from both (in head1, head2
* order) and empty list head2.
*
* @param head1 First list and concatenated output
* @param head2 Second list and empty output.
*
*/
void list_concat(link_t *head1, link_t *head2)
{
if (list_empty(head2))
return;
 
head2->next->prev = head1->prev;
head2->prev->next = head1;
head1->prev->next = head2->next;
head1->prev = head2->prev;
list_initialize(head2);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/ipc/ipcrsc.c
0,0 → 1,217
/*
* Copyright (C) 2006 Ondrej Palkovsky
* 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 genericipc
* @{
*/
/** @file
*/
 
/* IPC resources management
*
* The goal of this source code is to properly manage IPC resources
* and allow straight and clean clean-up procedure upon task termination.
*
* The pattern of usage of the resources is:
* - allocate empty phone slot, connect | deallocate slot
* - disconnect connected phone (some messages might be on the fly)
* - find phone in slot and send a message using phone
* - answer message to phone
* - hangup phone (the caller has hung up)
* - hangup phone (the answerbox is exiting)
*
* Locking strategy
*
* - To use a phone, disconnect a phone etc., the phone must be
* first locked and then checked that it is connected
* - To connect an allocated phone it need not be locked (assigning
* pointer is atomic on all platforms)
*
* - To find an empty phone slot, the TASK must be locked
* - To answer a message, the answerbox must be locked
* - The locking of phone and answerbox is done at the ipc_ level.
* It is perfectly correct to pass unconnected phone to these functions
* and proper reply will be generated.
*
* Locking order
*
* - first phone, then answerbox
* + Easy locking on calls
* - Very hard traversing list of phones when disconnecting because
* the phones may disconnect during traversal of list of connected phones.
* The only possibility is try_lock with restart of list traversal.
*
* Destroying is less frequent, this approach is taken.
*
* Phone call
*
* *** Connect_me_to ***
* The caller sends IPC_M_CONNECT_ME_TO to an answerbox. The server
* receives 'phoneid' of the connecting phone as an ARG3. If it answers
* with RETVAL=0, the phonecall is accepted, otherwise it is refused.
*
* *** Connect_to_me ***
* The caller sends IPC_M_CONNECT_TO_ME, with special
* The server receives an automatically
* opened phoneid. If it accepts (RETVAL=0), it can use the phoneid
* immediately.
* Possible race condition can arise, when the client receives messages
* from new connection before getting response for connect_to_me message.
* Userspace should implement handshake protocol that would control it.
*
* Phone hangup
*
* *** The caller hangs up (sys_ipc_hangup) ***
* - The phone is disconnected (no more messages can be sent over this phone),
* all in-progress messages are correctly handled. The anwerbox receives
* IPC_M_PHONE_HUNGUP call from the phone that hung up. When all async
* calls are answered, the phone is deallocated.
*
* *** The answerbox hangs up (ipc_answer(EHANGUP))
* - The phone is disconnected. EHANGUP response code is sent
* to the calling task. All new calls through this phone
* get a EHUNGUP error code, the task is expected to
* send an sys_ipc_hangup after cleaning up it's internal structures.
*
* Call forwarding
*
* The call can be forwarded, so that the answer to call is passed directly
* to the original sender. However, this poses special problems regarding
* routing of hangup messages.
*
* sys_ipc_hangup -> IPC_M_PHONE_HUNGUP
* - this message CANNOT be forwarded
*
* EHANGUP during forward
* - The *forwarding* phone will be closed, EFORWARD is sent to receiver.
*
* EHANGUP, ENOENT during forward
* - EFORWARD is sent to the receiver, ipc_forward returns error code EFORWARD
*
* Cleanup strategy
*
* 1) Disconnect all our phones ('ipc_phone_hangup').
*
* 2) Disconnect all phones connected to answerbox.
*
* 3) Answer all messages in 'calls' and 'dispatched_calls' queues with
* appropriate error code (EHANGUP, EFORWARD).
*
* 4) Wait for all async answers to arrive and dispose of them.
*
*/
 
#include <synch/spinlock.h>
#include <ipc/ipc.h>
#include <arch.h>
#include <proc/task.h>
#include <ipc/ipcrsc.h>
#include <debug.h>
 
/** Find call_t * in call table according to callid
*
* TODO: Some speedup (hash table?)
* @return NULL on not found, otherwise pointer to call structure
*/
call_t * get_call(unative_t callid)
{
link_t *lst;
call_t *call, *result = NULL;
 
spinlock_lock(&TASK->answerbox.lock);
for (lst = TASK->answerbox.dispatched_calls.next;
lst != &TASK->answerbox.dispatched_calls; lst = lst->next) {
call = list_get_instance(lst, call_t, link);
if ((unative_t)call == callid) {
result = call;
break;
}
}
spinlock_unlock(&TASK->answerbox.lock);
return result;
}
 
/** Allocate new phone slot in current TASK structure */
int phone_alloc(void)
{
int i;
 
spinlock_lock(&TASK->lock);
for (i=0; i < IPC_MAX_PHONES; i++) {
if (TASK->phones[i].state == IPC_PHONE_HUNGUP && \
atomic_get(&TASK->phones[i].active_calls) == 0)
TASK->phones[i].state = IPC_PHONE_FREE;
 
if (TASK->phones[i].state == IPC_PHONE_FREE) {
TASK->phones[i].state = IPC_PHONE_CONNECTING;
break;
}
}
spinlock_unlock(&TASK->lock);
 
if (i >= IPC_MAX_PHONES)
return -1;
return i;
}
 
static void phone_deallocp(phone_t *phone)
{
ASSERT(phone->state == IPC_PHONE_CONNECTING);
/* atomic operation */
phone->state = IPC_PHONE_FREE;
}
 
/** Free slot from a disconnected phone
*
* All already sent messages will be correctly processed
*/
void phone_dealloc(int phoneid)
{
phone_deallocp(&TASK->phones[phoneid]);
}
 
/** Connect phone to a given answerbox
*
* @param phoneid The slot that will be connected
*
* The procedure _enforces_ that the user first marks the phone
* busy (e.g. via phone_alloc) and then connects the phone, otherwise
* race condition may appear.
*/
void phone_connect(int phoneid, answerbox_t *box)
{
phone_t *phone = &TASK->phones[phoneid];
ASSERT(phone->state == IPC_PHONE_CONNECTING);
ipc_phone_connect(phone, box);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/ipc/sysipc.c
0,0 → 1,596
/*
* Copyright (C) 2006 Ondrej Palkovsky
* 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 genericipc
* @{
*/
/** @file
*/
 
#include <arch.h>
#include <proc/task.h>
#include <proc/thread.h>
#include <errno.h>
#include <memstr.h>
#include <debug.h>
#include <ipc/ipc.h>
#include <ipc/sysipc.h>
#include <ipc/irq.h>
#include <ipc/ipcrsc.h>
#include <arch/interrupt.h>
#include <print.h>
#include <syscall/copy.h>
#include <security/cap.h>
#include <mm/as.h>
 
#define GET_CHECK_PHONE(phone,phoneid,err) { \
if (phoneid > IPC_MAX_PHONES) { err; } \
phone = &TASK->phones[phoneid]; \
}
 
#define STRUCT_TO_USPACE(dst,src) copy_to_uspace(dst,src,sizeof(*(src)))
 
/** Return true if the method is a system method */
static inline int is_system_method(unative_t method)
{
if (method <= IPC_M_LAST_SYSTEM)
return 1;
return 0;
}
 
/** Return true if the message with this method is forwardable
*
* - some system messages may be forwarded, for some of them
* it is useless
*/
static inline int is_forwardable(unative_t method)
{
if (method == IPC_M_PHONE_HUNGUP || method == IPC_M_AS_AREA_SEND \
|| method == IPC_M_AS_AREA_RECV)
return 0; /* This message is meant only for the receiver */
return 1;
}
 
/****************************************************/
/* Functions that preprocess answer before sending
* it to the recepient
*/
 
/** Return true if the caller (ipc_answer) should save
* the old call contents for answer_preprocess
*/
static inline int answer_need_old(call_t *call)
{
if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_TO_ME)
return 1;
if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_ME_TO)
return 1;
if (IPC_GET_METHOD(call->data) == IPC_M_AS_AREA_SEND)
return 1;
if (IPC_GET_METHOD(call->data) == IPC_M_AS_AREA_RECV)
return 1;
return 0;
}
 
/** Interpret process answer as control information
*
* This function is called directly after sys_ipc_answer
*/
static inline int answer_preprocess(call_t *answer, ipc_data_t *olddata)
{
int phoneid;
 
if (IPC_GET_RETVAL(answer->data) == EHANGUP) {
/* In case of forward, hangup the forwared phone,
* not the originator
*/
spinlock_lock(&answer->data.phone->lock);
spinlock_lock(&TASK->answerbox.lock);
if (answer->data.phone->state == IPC_PHONE_CONNECTED) {
list_remove(&answer->data.phone->link);
answer->data.phone->state = IPC_PHONE_SLAMMED;
}
spinlock_unlock(&TASK->answerbox.lock);
spinlock_unlock(&answer->data.phone->lock);
}
 
if (!olddata)
return 0;
 
if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_TO_ME) {
phoneid = IPC_GET_ARG3(*olddata);
if (IPC_GET_RETVAL(answer->data)) {
/* The connection was not accepted */
phone_dealloc(phoneid);
} else {
/* The connection was accepted */
phone_connect(phoneid,&answer->sender->answerbox);
/* Set 'phone identification' as arg3 of response */
IPC_SET_ARG3(answer->data, (unative_t)&TASK->phones[phoneid]);
}
} else if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_ME_TO) {
/* If the users accepted call, connect */
if (!IPC_GET_RETVAL(answer->data)) {
ipc_phone_connect((phone_t *)IPC_GET_ARG3(*olddata),
&TASK->answerbox);
}
} else if (IPC_GET_METHOD(*olddata) == IPC_M_AS_AREA_SEND) {
if (!IPC_GET_RETVAL(answer->data)) { /* Accepted, handle as_area receipt */
ipl_t ipl;
int rc;
as_t *as;
ipl = interrupts_disable();
spinlock_lock(&answer->sender->lock);
as = answer->sender->as;
spinlock_unlock(&answer->sender->lock);
interrupts_restore(ipl);
rc = as_area_share(as, IPC_GET_ARG1(*olddata), IPC_GET_ARG2(*olddata),
AS, IPC_GET_ARG1(answer->data), IPC_GET_ARG3(*olddata));
IPC_SET_RETVAL(answer->data, rc);
return rc;
}
} else if (IPC_GET_METHOD(*olddata) == IPC_M_AS_AREA_RECV) {
if (!IPC_GET_RETVAL(answer->data)) {
ipl_t ipl;
as_t *as;
int rc;
ipl = interrupts_disable();
spinlock_lock(&answer->sender->lock);
as = answer->sender->as;
spinlock_unlock(&answer->sender->lock);
interrupts_restore(ipl);
rc = as_area_share(AS, IPC_GET_ARG1(answer->data), IPC_GET_ARG2(*olddata),
as, IPC_GET_ARG1(*olddata), IPC_GET_ARG2(answer->data));
IPC_SET_RETVAL(answer->data, rc);
}
}
return 0;
}
 
/** Called before the request is sent
*
* @return 0 - no error, -1 - report error to user
*/
static int request_preprocess(call_t *call)
{
int newphid;
size_t size;
 
switch (IPC_GET_METHOD(call->data)) {
case IPC_M_CONNECT_ME_TO:
newphid = phone_alloc();
if (newphid < 0)
return ELIMIT;
/* Set arg3 for server */
IPC_SET_ARG3(call->data, (unative_t)&TASK->phones[newphid]);
call->flags |= IPC_CALL_CONN_ME_TO;
call->private = newphid;
break;
case IPC_M_AS_AREA_SEND:
size = as_get_size(IPC_GET_ARG1(call->data));
if (!size) {
return EPERM;
}
IPC_SET_ARG2(call->data, size);
break;
default:
break;
}
return 0;
}
 
/****************************************************/
/* Functions called to process received call/answer
* before passing to uspace
*/
 
/** Do basic kernel processing of received call answer */
static void process_answer(call_t *call)
{
if (IPC_GET_RETVAL(call->data) == EHANGUP && \
call->flags & IPC_CALL_FORWARDED)
IPC_SET_RETVAL(call->data, EFORWARD);
 
if (call->flags & IPC_CALL_CONN_ME_TO) {
if (IPC_GET_RETVAL(call->data))
phone_dealloc(call->private);
else
IPC_SET_ARG3(call->data, call->private);
}
}
 
/** Do basic kernel processing of received call request
*
* @return 0 - the call should be passed to userspace, 1 - ignore call
*/
static int process_request(answerbox_t *box,call_t *call)
{
int phoneid;
 
if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_TO_ME) {
phoneid = phone_alloc();
if (phoneid < 0) { /* Failed to allocate phone */
IPC_SET_RETVAL(call->data, ELIMIT);
ipc_answer(box,call);
return -1;
}
IPC_SET_ARG3(call->data, phoneid);
}
return 0;
}
 
/** Send a call over IPC, wait for reply, return to user
*
* @return Call identification, returns -1 on fatal error,
-2 on 'Too many async request, handle answers first
*/
unative_t sys_ipc_call_sync_fast(unative_t phoneid, unative_t method,
unative_t arg1, ipc_data_t *data)
{
call_t call;
phone_t *phone;
int res;
 
GET_CHECK_PHONE(phone, phoneid, return ENOENT);
 
ipc_call_static_init(&call);
IPC_SET_METHOD(call.data, method);
IPC_SET_ARG1(call.data, arg1);
 
if (!(res=request_preprocess(&call))) {
ipc_call_sync(phone, &call);
process_answer(&call);
} else
IPC_SET_RETVAL(call.data, res);
STRUCT_TO_USPACE(&data->args, &call.data.args);
 
return 0;
}
 
/** Synchronous IPC call allowing to send whole message */
unative_t sys_ipc_call_sync(unative_t phoneid, ipc_data_t *question,
ipc_data_t *reply)
{
call_t call;
phone_t *phone;
int res;
int rc;
 
ipc_call_static_init(&call);
rc = copy_from_uspace(&call.data.args, &question->args, sizeof(call.data.args));
if (rc != 0)
return (unative_t) rc;
 
GET_CHECK_PHONE(phone, phoneid, return ENOENT);
 
if (!(res=request_preprocess(&call))) {
ipc_call_sync(phone, &call);
process_answer(&call);
} else
IPC_SET_RETVAL(call.data, res);
 
rc = STRUCT_TO_USPACE(&reply->args, &call.data.args);
if (rc != 0)
return rc;
 
return 0;
}
 
/** Check that the task did not exceed allowed limit
*
* @return 0 - Limit OK, -1 - limit exceeded
*/
static int check_call_limit(void)
{
if (atomic_preinc(&TASK->active_calls) > IPC_MAX_ASYNC_CALLS) {
atomic_dec(&TASK->active_calls);
return -1;
}
return 0;
}
 
/** Send an asynchronous call over ipc
*
* @return Call identification, returns -1 on fatal error,
-2 on 'Too many async request, handle answers first
*/
unative_t sys_ipc_call_async_fast(unative_t phoneid, unative_t method,
unative_t arg1, unative_t arg2)
{
call_t *call;
phone_t *phone;
int res;
 
if (check_call_limit())
return IPC_CALLRET_TEMPORARY;
 
GET_CHECK_PHONE(phone, phoneid, return IPC_CALLRET_FATAL);
 
call = ipc_call_alloc(0);
IPC_SET_METHOD(call->data, method);
IPC_SET_ARG1(call->data, arg1);
IPC_SET_ARG2(call->data, arg2);
IPC_SET_ARG3(call->data, 0);
 
if (!(res=request_preprocess(call)))
ipc_call(phone, call);
else
ipc_backsend_err(phone, call, res);
 
return (unative_t) call;
}
 
/** Synchronous IPC call allowing to send whole message
*
* @return The same as sys_ipc_call_async
*/
unative_t sys_ipc_call_async(unative_t phoneid, ipc_data_t *data)
{
call_t *call;
phone_t *phone;
int res;
int rc;
 
if (check_call_limit())
return IPC_CALLRET_TEMPORARY;
 
GET_CHECK_PHONE(phone, phoneid, return IPC_CALLRET_FATAL);
 
call = ipc_call_alloc(0);
rc = copy_from_uspace(&call->data.args, &data->args, sizeof(call->data.args));
if (rc != 0) {
ipc_call_free(call);
return (unative_t) rc;
}
if (!(res=request_preprocess(call)))
ipc_call(phone, call);
else
ipc_backsend_err(phone, call, res);
 
return (unative_t) call;
}
 
/** Forward received call to another destination
*
* The arg1 and arg2 are changed in the forwarded message
*
* Warning: If implementing non-fast version, make sure that
* arg3 is not rewritten for certain system IPC
*/
unative_t sys_ipc_forward_fast(unative_t callid, unative_t phoneid,
unative_t method, unative_t arg1)
{
call_t *call;
phone_t *phone;
 
call = get_call(callid);
if (!call)
return ENOENT;
 
call->flags |= IPC_CALL_FORWARDED;
 
GET_CHECK_PHONE(phone, phoneid, {
IPC_SET_RETVAL(call->data, EFORWARD);
ipc_answer(&TASK->answerbox, call);
return ENOENT;
});
 
if (!is_forwardable(IPC_GET_METHOD(call->data))) {
IPC_SET_RETVAL(call->data, EFORWARD);
ipc_answer(&TASK->answerbox, call);
return EPERM;
}
 
/* Userspace is not allowed to change method of system methods
* on forward, allow changing ARG1 and ARG2 by means of method and arg1
*/
if (is_system_method(IPC_GET_METHOD(call->data))) {
if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_TO_ME)
phone_dealloc(IPC_GET_ARG3(call->data));
 
IPC_SET_ARG1(call->data, method);
IPC_SET_ARG2(call->data, arg1);
} else {
IPC_SET_METHOD(call->data, method);
IPC_SET_ARG1(call->data, arg1);
}
 
return ipc_forward(call, phone, &TASK->answerbox);
}
 
/** Send IPC answer */
unative_t sys_ipc_answer_fast(unative_t callid, unative_t retval,
unative_t arg1, unative_t arg2)
{
call_t *call;
ipc_data_t saved_data;
int saveddata = 0;
int rc;
 
/* Do not answer notification callids */
if (callid & IPC_CALLID_NOTIFICATION)
return 0;
 
call = get_call(callid);
if (!call)
return ENOENT;
 
if (answer_need_old(call)) {
memcpy(&saved_data, &call->data, sizeof(call->data));
saveddata = 1;
}
 
IPC_SET_RETVAL(call->data, retval);
IPC_SET_ARG1(call->data, arg1);
IPC_SET_ARG2(call->data, arg2);
rc = answer_preprocess(call, saveddata ? &saved_data : NULL);
 
ipc_answer(&TASK->answerbox, call);
return rc;
}
 
/** Send IPC answer */
unative_t sys_ipc_answer(unative_t callid, ipc_data_t *data)
{
call_t *call;
ipc_data_t saved_data;
int saveddata = 0;
int rc;
 
/* Do not answer notification callids */
if (callid & IPC_CALLID_NOTIFICATION)
return 0;
 
call = get_call(callid);
if (!call)
return ENOENT;
 
if (answer_need_old(call)) {
memcpy(&saved_data, &call->data, sizeof(call->data));
saveddata = 1;
}
rc = copy_from_uspace(&call->data.args, &data->args,
sizeof(call->data.args));
if (rc != 0)
return rc;
 
rc = answer_preprocess(call, saveddata ? &saved_data : NULL);
ipc_answer(&TASK->answerbox, call);
 
return rc;
}
 
/** Hang up the phone
*
*/
unative_t sys_ipc_hangup(int phoneid)
{
phone_t *phone;
 
GET_CHECK_PHONE(phone, phoneid, return ENOENT);
 
if (ipc_phone_hangup(phone))
return -1;
 
return 0;
}
 
/** Wait for incoming ipc call or answer
*
* @param calldata Pointer to buffer where the call/answer data is stored
* @param usec Timeout. See waitq_sleep_timeout() for explanation.
* @param flags Select mode of sleep operation. See waitq_sleep_timeout() for explanation.
*
* @return Callid, if callid & 1, then the call is answer
*/
unative_t sys_ipc_wait_for_call(ipc_data_t *calldata, uint32_t usec, int flags)
{
call_t *call;
 
restart:
call = ipc_wait_for_call(&TASK->answerbox, usec, flags | SYNCH_FLAGS_INTERRUPTIBLE);
if (!call)
return 0;
 
if (call->flags & IPC_CALL_NOTIF) {
ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC));
 
/* Set in_phone_hash to the interrupt counter */
call->data.phone = (void *)call->private;
STRUCT_TO_USPACE(calldata, &call->data);
 
ipc_call_free(call);
return ((unative_t)call) | IPC_CALLID_NOTIFICATION;
}
 
if (call->flags & IPC_CALL_ANSWERED) {
process_answer(call);
 
ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC));
 
atomic_dec(&TASK->active_calls);
 
if (call->flags & IPC_CALL_DISCARD_ANSWER) {
ipc_call_free(call);
goto restart;
}
 
STRUCT_TO_USPACE(&calldata->args, &call->data.args);
ipc_call_free(call);
 
return ((unative_t)call) | IPC_CALLID_ANSWERED;
}
 
if (process_request(&TASK->answerbox, call))
goto restart;
 
/* Include phone address('id') of the caller in the request,
* copy whole call->data, not only call->data.args */
if (STRUCT_TO_USPACE(calldata, &call->data)) {
return 0;
}
return (unative_t)call;
}
 
/** Connect irq handler to task */
unative_t sys_ipc_register_irq(int irq, irq_code_t *ucode)
{
if (!(cap_get(TASK) & CAP_IRQ_REG))
return EPERM;
 
if (irq >= IRQ_COUNT || irq <= -IPC_IRQ_RESERVED_VIRTUAL)
return (unative_t) ELIMIT;
irq_ipc_bind_arch(irq);
 
return ipc_irq_register(&TASK->answerbox, irq, ucode);
}
 
/* Disconnect irq handler from task */
unative_t sys_ipc_unregister_irq(int irq)
{
if (!(cap_get(TASK) & CAP_IRQ_REG))
return EPERM;
 
if (irq >= IRQ_COUNT || irq <= -IPC_IRQ_RESERVED_VIRTUAL)
return (unative_t) ELIMIT;
 
ipc_irq_unregister(&TASK->answerbox, irq);
 
return 0;
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/ipc/ipc.c
0,0 → 1,534
/*
* Copyright (C) 2006 Ondrej Palkovsky
* 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 genericipc
* @{
*/
/** @file
*/
 
/* Lock ordering
*
* First the answerbox, then the phone
*/
 
#include <synch/spinlock.h>
#include <synch/waitq.h>
#include <synch/synch.h>
#include <ipc/ipc.h>
#include <errno.h>
#include <mm/slab.h>
#include <arch.h>
#include <proc/task.h>
#include <memstr.h>
#include <debug.h>
 
#include <print.h>
#include <proc/thread.h>
#include <arch/interrupt.h>
#include <ipc/irq.h>
 
/* Open channel that is assigned automatically to new tasks */
answerbox_t *ipc_phone_0 = NULL;
 
static slab_cache_t *ipc_call_slab;
 
/* Initialize new call */
static void _ipc_call_init(call_t *call)
{
memsetb((uintptr_t)call, sizeof(*call), 0);
call->callerbox = &TASK->answerbox;
call->sender = TASK;
}
 
/** Allocate & initialize call structure
*
* The call is initialized, so that the reply will be directed
* to TASK->answerbox
*
* @param flags Parameters for slab_alloc (ATOMIC, etc.)
*/
call_t * ipc_call_alloc(int flags)
{
call_t *call;
 
call = slab_alloc(ipc_call_slab, flags);
_ipc_call_init(call);
 
return call;
}
 
/** Initialize allocated call */
void ipc_call_static_init(call_t *call)
{
_ipc_call_init(call);
call->flags |= IPC_CALL_STATIC_ALLOC;
}
 
/** Deallocate call stracuture */
void ipc_call_free(call_t *call)
{
slab_free(ipc_call_slab, call);
}
 
/** Initialize answerbox structure
*/
void ipc_answerbox_init(answerbox_t *box)
{
spinlock_initialize(&box->lock, "ipc_box_lock");
spinlock_initialize(&box->irq_lock, "ipc_box_irqlock");
waitq_initialize(&box->wq);
list_initialize(&box->connected_phones);
list_initialize(&box->calls);
list_initialize(&box->dispatched_calls);
list_initialize(&box->answers);
list_initialize(&box->irq_notifs);
box->task = TASK;
}
 
/** Connect phone to answerbox */
void ipc_phone_connect(phone_t *phone, answerbox_t *box)
{
spinlock_lock(&phone->lock);
 
phone->state = IPC_PHONE_CONNECTED;
phone->callee = box;
 
spinlock_lock(&box->lock);
list_append(&phone->link, &box->connected_phones);
spinlock_unlock(&box->lock);
 
spinlock_unlock(&phone->lock);
}
 
/** Initialize phone structure and connect phone to answerbox
*/
void ipc_phone_init(phone_t *phone)
{
spinlock_initialize(&phone->lock, "phone_lock");
phone->callee = NULL;
phone->state = IPC_PHONE_FREE;
atomic_set(&phone->active_calls, 0);
}
 
/** Helper function to facilitate synchronous calls */
void ipc_call_sync(phone_t *phone, call_t *request)
{
answerbox_t sync_box;
 
ipc_answerbox_init(&sync_box);
 
/* We will receive data on special box */
request->callerbox = &sync_box;
 
ipc_call(phone, request);
ipc_wait_for_call(&sync_box, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE);
}
 
/** Answer message that was not dispatched and is not entered in
* any queue
*/
static void _ipc_answer_free_call(call_t *call)
{
answerbox_t *callerbox = call->callerbox;
 
call->flags |= IPC_CALL_ANSWERED;
 
spinlock_lock(&callerbox->lock);
list_append(&call->link, &callerbox->answers);
spinlock_unlock(&callerbox->lock);
waitq_wakeup(&callerbox->wq, 0);
}
 
/** Answer message, that is in callee queue
*
* @param box Answerbox that is answering the message
* @param call Modified request that is being sent back
*/
void ipc_answer(answerbox_t *box, call_t *call)
{
/* Remove from active box */
spinlock_lock(&box->lock);
list_remove(&call->link);
spinlock_unlock(&box->lock);
/* Send back answer */
_ipc_answer_free_call(call);
}
 
/** Simulate sending back a message
*
* Most errors are better handled by forming a normal backward
* message and sending it as a normal answer.
*/
void ipc_backsend_err(phone_t *phone, call_t *call, unative_t err)
{
call->data.phone = phone;
atomic_inc(&phone->active_calls);
IPC_SET_RETVAL(call->data, err);
_ipc_answer_free_call(call);
}
 
/* Unsafe unchecking ipc_call */
static void _ipc_call(phone_t *phone, answerbox_t *box, call_t *call)
{
if (! (call->flags & IPC_CALL_FORWARDED)) {
atomic_inc(&phone->active_calls);
call->data.phone = phone;
}
 
spinlock_lock(&box->lock);
list_append(&call->link, &box->calls);
spinlock_unlock(&box->lock);
waitq_wakeup(&box->wq, 0);
}
 
/** Send a asynchronous request using phone to answerbox
*
* @param phone Phone connected to answerbox.
* @param call Structure representing the call.
*/
int ipc_call(phone_t *phone, call_t *call)
{
answerbox_t *box;
 
spinlock_lock(&phone->lock);
if (phone->state != IPC_PHONE_CONNECTED) {
spinlock_unlock(&phone->lock);
if (call->flags & IPC_CALL_FORWARDED) {
IPC_SET_RETVAL(call->data, EFORWARD);
_ipc_answer_free_call(call);
} else {
if (phone->state == IPC_PHONE_HUNGUP)
ipc_backsend_err(phone, call, EHANGUP);
else
ipc_backsend_err(phone, call, ENOENT);
}
return ENOENT;
}
box = phone->callee;
_ipc_call(phone, box, call);
spinlock_unlock(&phone->lock);
return 0;
}
 
/** Disconnect phone from answerbox
*
* This call leaves the phone in HUNGUP state. The change to 'free' is done
* lazily later.
*
* @param phone Phone to be hung up
*
* @return 0 - phone disconnected, -1 - the phone was already disconnected
*/
int ipc_phone_hangup(phone_t *phone)
{
answerbox_t *box;
call_t *call;
spinlock_lock(&phone->lock);
if (phone->state == IPC_PHONE_FREE || phone->state ==IPC_PHONE_HUNGUP \
|| phone->state == IPC_PHONE_CONNECTING) {
spinlock_unlock(&phone->lock);
return -1;
}
box = phone->callee;
if (phone->state != IPC_PHONE_SLAMMED) {
/* Remove myself from answerbox */
spinlock_lock(&box->lock);
list_remove(&phone->link);
spinlock_unlock(&box->lock);
 
if (phone->state != IPC_PHONE_SLAMMED) {
call = ipc_call_alloc(0);
IPC_SET_METHOD(call->data, IPC_M_PHONE_HUNGUP);
call->flags |= IPC_CALL_DISCARD_ANSWER;
_ipc_call(phone, box, call);
}
}
 
phone->state = IPC_PHONE_HUNGUP;
spinlock_unlock(&phone->lock);
 
return 0;
}
 
/** Forwards call from one answerbox to a new one
*
* @param call Call to be redirected.
* @param newphone Phone to target answerbox.
* @param oldbox Old answerbox
* @return 0 on forward ok, error code, if there was error
*
* - the return value serves only as an information for the forwarder,
* the original caller is notified automatically with EFORWARD
*/
int ipc_forward(call_t *call, phone_t *newphone, answerbox_t *oldbox)
{
spinlock_lock(&oldbox->lock);
list_remove(&call->link);
spinlock_unlock(&oldbox->lock);
 
return ipc_call(newphone, call);
}
 
 
/** Wait for phone call
*
* @param box Answerbox expecting the call.
* @param usec Timeout in microseconds. See documentation for waitq_sleep_timeout() for
* decription of its special meaning.
* @param flags Select mode of sleep operation. See documentation for waitq_sleep_timeout()i
* for description of its special meaning.
* @return Recived message address
* - to distinguish between call and answer, look at call->flags
*/
call_t * ipc_wait_for_call(answerbox_t *box, uint32_t usec, int flags)
{
call_t *request;
ipl_t ipl;
int rc;
 
restart:
rc = waitq_sleep_timeout(&box->wq, usec, flags);
if (SYNCH_FAILED(rc))
return NULL;
spinlock_lock(&box->lock);
if (!list_empty(&box->irq_notifs)) {
ipl = interrupts_disable();
spinlock_lock(&box->irq_lock);
 
request = list_get_instance(box->irq_notifs.next, call_t, link);
list_remove(&request->link);
 
spinlock_unlock(&box->irq_lock);
interrupts_restore(ipl);
} else if (!list_empty(&box->answers)) {
/* Handle asynchronous answers */
request = list_get_instance(box->answers.next, call_t, link);
list_remove(&request->link);
atomic_dec(&request->data.phone->active_calls);
} else if (!list_empty(&box->calls)) {
/* Handle requests */
request = list_get_instance(box->calls.next, call_t, link);
list_remove(&request->link);
/* Append request to dispatch queue */
list_append(&request->link, &box->dispatched_calls);
} else {
/* This can happen regularly after ipc_cleanup */
spinlock_unlock(&box->lock);
goto restart;
}
spinlock_unlock(&box->lock);
return request;
}
 
/** Answer all calls from list with EHANGUP msg */
static void ipc_cleanup_call_list(link_t *lst)
{
call_t *call;
 
while (!list_empty(lst)) {
call = list_get_instance(lst->next, call_t, link);
list_remove(&call->link);
 
IPC_SET_RETVAL(call->data, EHANGUP);
_ipc_answer_free_call(call);
}
}
 
/** Cleans up all IPC communication of the current task
*
* Note: ipc_hangup sets returning answerbox to TASK->answerbox, you
* have to change it as well if you want to cleanup other current then current.
*/
void ipc_cleanup(void)
{
int i;
call_t *call;
phone_t *phone;
 
/* Disconnect all our phones ('ipc_phone_hangup') */
for (i=0;i < IPC_MAX_PHONES; i++)
ipc_phone_hangup(&TASK->phones[i]);
 
/* Disconnect all connected irqs */
ipc_irq_cleanup(&TASK->answerbox);
 
/* Disconnect all phones connected to our answerbox */
restart_phones:
spinlock_lock(&TASK->answerbox.lock);
while (!list_empty(&TASK->answerbox.connected_phones)) {
phone = list_get_instance(TASK->answerbox.connected_phones.next,
phone_t, link);
if (! spinlock_trylock(&phone->lock)) {
spinlock_unlock(&TASK->answerbox.lock);
goto restart_phones;
}
/* Disconnect phone */
ASSERT(phone->state == IPC_PHONE_CONNECTED);
phone->state = IPC_PHONE_SLAMMED;
list_remove(&phone->link);
 
spinlock_unlock(&phone->lock);
}
 
/* Answer all messages in 'calls' and 'dispatched_calls' queues */
ipc_cleanup_call_list(&TASK->answerbox.dispatched_calls);
ipc_cleanup_call_list(&TASK->answerbox.calls);
spinlock_unlock(&TASK->answerbox.lock);
/* Wait for all async answers to arrive */
while (1) {
/* Go through all phones, until all are FREE... */
/* Locking not needed, no one else should modify
* it, when we are in cleanup */
for (i=0;i < IPC_MAX_PHONES; i++) {
if (TASK->phones[i].state == IPC_PHONE_HUNGUP && \
atomic_get(&TASK->phones[i].active_calls) == 0)
TASK->phones[i].state = IPC_PHONE_FREE;
/* Just for sure, we might have had some
* IPC_PHONE_CONNECTING phones */
if (TASK->phones[i].state == IPC_PHONE_CONNECTED)
ipc_phone_hangup(&TASK->phones[i]);
/* If the hangup succeeded, it has sent a HANGUP
* message, the IPC is now in HUNGUP state, we
* wait for the reply to come */
if (TASK->phones[i].state != IPC_PHONE_FREE)
break;
}
/* Voila, got into cleanup */
if (i == IPC_MAX_PHONES)
break;
call = ipc_wait_for_call(&TASK->answerbox, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE);
ASSERT((call->flags & IPC_CALL_ANSWERED) || (call->flags & IPC_CALL_NOTIF));
ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC));
atomic_dec(&TASK->active_calls);
ipc_call_free(call);
}
}
 
 
/** Initilize ipc subsystem */
void ipc_init(void)
{
ipc_call_slab = slab_cache_create("ipc_call",
sizeof(call_t),
0,
NULL, NULL, 0);
ipc_irq_make_table(IRQ_COUNT);
}
 
 
/** Kconsole - list answerbox contents */
void ipc_print_task(task_id_t taskid)
{
task_t *task;
int i;
call_t *call;
link_t *tmp;
spinlock_lock(&tasks_lock);
task = task_find_by_id(taskid);
if (task)
spinlock_lock(&task->lock);
spinlock_unlock(&tasks_lock);
if (!task)
return;
 
/* Print opened phones & details */
printf("PHONE:\n");
for (i=0; i < IPC_MAX_PHONES;i++) {
spinlock_lock(&task->phones[i].lock);
if (task->phones[i].state != IPC_PHONE_FREE) {
printf("%d: ",i);
switch (task->phones[i].state) {
case IPC_PHONE_CONNECTING:
printf("connecting ");
break;
case IPC_PHONE_CONNECTED:
printf("connected to: %p ",
task->phones[i].callee);
break;
case IPC_PHONE_SLAMMED:
printf("slammed by: %p ",
task->phones[i].callee);
break;
case IPC_PHONE_HUNGUP:
printf("hung up - was: %p ",
task->phones[i].callee);
break;
default:
break;
}
printf("active: %d\n", atomic_get(&task->phones[i].active_calls));
}
spinlock_unlock(&task->phones[i].lock);
}
 
 
/* Print answerbox - calls */
spinlock_lock(&task->answerbox.lock);
printf("ABOX - CALLS:\n");
for (tmp=task->answerbox.calls.next; tmp != &task->answerbox.calls;tmp = tmp->next) {
call = list_get_instance(tmp, call_t, link);
printf("Callid: %p Srctask:%lld M:%d A1:%d A2:%d A3:%d Flags:%x\n",call,
call->sender->taskid, IPC_GET_METHOD(call->data), IPC_GET_ARG1(call->data),
IPC_GET_ARG2(call->data), IPC_GET_ARG3(call->data), call->flags);
}
/* Print answerbox - calls */
printf("ABOX - DISPATCHED CALLS:\n");
for (tmp=task->answerbox.dispatched_calls.next;
tmp != &task->answerbox.dispatched_calls;
tmp = tmp->next) {
call = list_get_instance(tmp, call_t, link);
printf("Callid: %p Srctask:%lld M:%d A1:%d A2:%d A3:%d Flags:%x\n",call,
call->sender->taskid, IPC_GET_METHOD(call->data), IPC_GET_ARG1(call->data),
IPC_GET_ARG2(call->data), IPC_GET_ARG3(call->data), call->flags);
}
/* Print answerbox - calls */
printf("ABOX - ANSWERS:\n");
for (tmp=task->answerbox.answers.next; tmp != &task->answerbox.answers; tmp = tmp->next) {
call = list_get_instance(tmp, call_t, link);
printf("Callid:%p M:%d A1:%d A2:%d A3:%d Flags:%x\n",call,
IPC_GET_METHOD(call->data), IPC_GET_ARG1(call->data),
IPC_GET_ARG2(call->data), IPC_GET_ARG3(call->data), call->flags);
}
 
spinlock_unlock(&task->answerbox.lock);
spinlock_unlock(&task->lock);
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/ipc/irq.c
0,0 → 1,337
/*
* Copyright (C) 2006 Ondrej Palkovsky
* 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 genericipc
* @{
*/
/**
* @file
* @brief IRQ notification framework.
*
* This framework allows applications to register to receive a notification
* when interrupt is detected. The application may provide a simple 'top-half'
* handler as part of its registration, which can perform simple operations
* (read/write port/memory, add information to notification ipc message).
*
* The structure of a notification message is as follows:
* - METHOD: interrupt number
* - ARG1: payload modified by a 'top-half' handler
* - ARG2: payload
* - ARG3: payload
* - in_phone_hash: interrupt counter (may be needed to assure correct order
* in multithreaded drivers)
*/
 
#include <arch.h>
#include <mm/slab.h>
#include <errno.h>
#include <ipc/ipc.h>
#include <ipc/irq.h>
#include <atomic.h>
#include <syscall/copy.h>
#include <console/console.h>
 
typedef struct {
SPINLOCK_DECLARE(lock);
answerbox_t *box;
irq_code_t *code;
atomic_t counter;
} ipc_irq_t;
 
 
static ipc_irq_t *irq_conns = NULL;
static int irq_conns_size;
 
#include <print.h>
/* Execute code associated with IRQ notification */
static void code_execute(call_t *call, irq_code_t *code)
{
int i;
unative_t dstval = 0;
if (!code)
return;
for (i=0; i < code->cmdcount;i++) {
switch (code->cmds[i].cmd) {
case CMD_MEM_READ_1:
dstval = *((uint8_t *)code->cmds[i].addr);
break;
case CMD_MEM_READ_2:
dstval = *((uint16_t *)code->cmds[i].addr);
break;
case CMD_MEM_READ_4:
dstval = *((uint32_t *)code->cmds[i].addr);
break;
case CMD_MEM_READ_8:
dstval = *((uint64_t *)code->cmds[i].addr);
break;
case CMD_MEM_WRITE_1:
*((uint8_t *)code->cmds[i].addr) = code->cmds[i].value;
break;
case CMD_MEM_WRITE_2:
*((uint16_t *)code->cmds[i].addr) = code->cmds[i].value;
break;
case CMD_MEM_WRITE_4:
*((uint32_t *)code->cmds[i].addr) = code->cmds[i].value;
break;
case CMD_MEM_WRITE_8:
*((uint64_t *)code->cmds[i].addr) = code->cmds[i].value;
break;
#if defined(ia32) || defined(amd64)
case CMD_PORT_READ_1:
dstval = inb((long)code->cmds[i].addr);
break;
case CMD_PORT_WRITE_1:
outb((long)code->cmds[i].addr, code->cmds[i].value);
break;
#endif
#if defined(ia64)
case CMD_IA64_GETCHAR:
dstval = _getc(&ski_uconsole);
break;
#endif
#if defined(ppc32)
case CMD_PPC32_GETCHAR:
dstval = cuda_get_scancode();
break;
#endif
default:
break;
}
if (code->cmds[i].dstarg && code->cmds[i].dstarg < 4) {
call->data.args[code->cmds[i].dstarg] = dstval;
}
}
}
 
static void code_free(irq_code_t *code)
{
if (code) {
free(code->cmds);
free(code);
}
}
 
static irq_code_t * code_from_uspace(irq_code_t *ucode)
{
irq_code_t *code;
irq_cmd_t *ucmds;
int rc;
 
code = malloc(sizeof(*code), 0);
rc = copy_from_uspace(code, ucode, sizeof(*code));
if (rc != 0) {
free(code);
return NULL;
}
if (code->cmdcount > IRQ_MAX_PROG_SIZE) {
free(code);
return NULL;
}
ucmds = code->cmds;
code->cmds = malloc(sizeof(code->cmds[0]) * (code->cmdcount), 0);
rc = copy_from_uspace(code->cmds, ucmds, sizeof(code->cmds[0]) * (code->cmdcount));
if (rc != 0) {
free(code->cmds);
free(code);
return NULL;
}
 
return code;
}
 
/** Unregister task from irq */
void ipc_irq_unregister(answerbox_t *box, int irq)
{
ipl_t ipl;
int mq = irq + IPC_IRQ_RESERVED_VIRTUAL;
 
ipl = interrupts_disable();
spinlock_lock(&irq_conns[mq].lock);
if (irq_conns[mq].box == box) {
irq_conns[mq].box = NULL;
code_free(irq_conns[mq].code);
irq_conns[mq].code = NULL;
}
 
spinlock_unlock(&irq_conns[mq].lock);
interrupts_restore(ipl);
}
 
/** Register an answerbox as a receiving end of interrupts notifications */
int ipc_irq_register(answerbox_t *box, int irq, irq_code_t *ucode)
{
ipl_t ipl;
irq_code_t *code;
int mq = irq + IPC_IRQ_RESERVED_VIRTUAL;
 
ASSERT(irq_conns);
 
if (ucode) {
code = code_from_uspace(ucode);
if (!code)
return EBADMEM;
} else
code = NULL;
 
ipl = interrupts_disable();
spinlock_lock(&irq_conns[mq].lock);
 
if (irq_conns[mq].box) {
spinlock_unlock(&irq_conns[mq].lock);
interrupts_restore(ipl);
code_free(code);
return EEXISTS;
}
irq_conns[mq].box = box;
irq_conns[mq].code = code;
atomic_set(&irq_conns[mq].counter, 0);
spinlock_unlock(&irq_conns[mq].lock);
interrupts_restore(ipl);
 
return 0;
}
 
/** Add call to proper answerbox queue
*
* Assume irq_conns[mq].lock is locked */
static void send_call(int mq, call_t *call)
{
spinlock_lock(&irq_conns[mq].box->irq_lock);
list_append(&call->link, &irq_conns[mq].box->irq_notifs);
spinlock_unlock(&irq_conns[mq].box->irq_lock);
waitq_wakeup(&irq_conns[mq].box->wq, 0);
}
 
/** Send notification message
*
*/
void ipc_irq_send_msg(int irq, unative_t a1, unative_t a2, unative_t a3)
{
call_t *call;
int mq = irq + IPC_IRQ_RESERVED_VIRTUAL;
 
spinlock_lock(&irq_conns[mq].lock);
 
if (irq_conns[mq].box) {
call = ipc_call_alloc(FRAME_ATOMIC);
if (!call) {
spinlock_unlock(&irq_conns[mq].lock);
return;
}
call->flags |= IPC_CALL_NOTIF;
IPC_SET_METHOD(call->data, irq);
IPC_SET_ARG1(call->data, a1);
IPC_SET_ARG2(call->data, a2);
IPC_SET_ARG3(call->data, a3);
/* Put a counter to the message */
call->private = atomic_preinc(&irq_conns[mq].counter);
send_call(mq, call);
}
spinlock_unlock(&irq_conns[mq].lock);
}
 
/** Notify task that an irq had occurred.
*
* We expect interrupts to be disabled
*/
void ipc_irq_send_notif(int irq)
{
call_t *call;
int mq = irq + IPC_IRQ_RESERVED_VIRTUAL;
 
ASSERT(irq_conns);
spinlock_lock(&irq_conns[mq].lock);
 
if (irq_conns[mq].box) {
call = ipc_call_alloc(FRAME_ATOMIC);
if (!call) {
spinlock_unlock(&irq_conns[mq].lock);
return;
}
call->flags |= IPC_CALL_NOTIF;
/* Put a counter to the message */
call->private = atomic_preinc(&irq_conns[mq].counter);
/* Set up args */
IPC_SET_METHOD(call->data, irq);
 
/* Execute code to handle irq */
code_execute(call, irq_conns[mq].code);
send_call(mq, call);
}
spinlock_unlock(&irq_conns[mq].lock);
}
 
 
/** Initialize table of interrupt handlers
*
* @param irqcount Count of required hardware IRQs to be supported
*/
void ipc_irq_make_table(int irqcount)
{
int i;
 
irqcount += IPC_IRQ_RESERVED_VIRTUAL;
 
irq_conns_size = irqcount;
irq_conns = malloc(irqcount * (sizeof(*irq_conns)), 0);
for (i=0; i < irqcount; i++) {
spinlock_initialize(&irq_conns[i].lock, "irq_ipc_lock");
irq_conns[i].box = NULL;
irq_conns[i].code = NULL;
}
}
 
/** Disconnect all irq's notifications
*
* @todo It may be better to do some linked list, so that
* we wouldn't need to go through whole array every cleanup
*/
void ipc_irq_cleanup(answerbox_t *box)
{
int i;
ipl_t ipl;
for (i=0; i < irq_conns_size; i++) {
ipl = interrupts_disable();
spinlock_lock(&irq_conns[i].lock);
if (irq_conns[i].box == box)
irq_conns[i].box = NULL;
spinlock_unlock(&irq_conns[i].lock);
interrupts_restore(ipl);
}
}
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/smp/ipi.c
0,0 → 1,70
/*
* 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 generic
* @{
*/
 
/**
* @file
* @brief Generic IPI interface.
*/
#ifdef CONFIG_SMP
 
#include <smp/ipi.h>
#include <config.h>
 
 
/** Broadcast IPI message
*
* Broadcast IPI message to all CPUs.
*
* @param ipi Message to broadcast.
*
* @bug The decision whether to actually send the IPI must be based
* on a different criterion. The current version has
* problems when some of the detected CPUs are marked
* disabled in machine configuration.
*/
void ipi_broadcast(int ipi)
{
/*
* Provisions must be made to avoid sending IPI:
* - before all CPU's were configured to accept the IPI
* - if there is only one CPU but the kernel was compiled with CONFIG_SMP
*/
 
if ((config.cpu_active > 1) && (config.cpu_active == config.cpu_count))
ipi_broadcast_arch(ipi);
}
 
#endif /* CONFIG_SMP */
 
/** @}
*/
/tags/0.2.0.3/kernel/generic/src/preempt/preemption.c
0,0 → 1,60
/*
* 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 generic
* @{
*/
 
/**
* @file preemption.c
* @brief Preemption control.
*/
#include <preemption.h>
#include <arch.h>
#include <arch/asm.h>
#include <arch/barrier.h>
#include <debug.h>
 
/** Increment preemption disabled counter. */
void preemption_disable(void)
{
THE->preemption_disabled++;
memory_barrier();
}
 
/** Decrement preemption disabled counter. */
void preemption_enable(void)
{
ASSERT(THE->preemption_disabled);
memory_barrier();
THE->preemption_disabled--;
}
 
/** @}
*/
/tags/0.2.0.3/kernel/kernel.config
0,0 → 1,132
## General configuration directives
 
# Architecture
@ "amd64" AMD64/Intel EM64T
@ "ia32" Intel IA-32
@ "ia64" Intel IA-64
@ "mips32" MIPS 32-bit
@ "ppc32" PowerPC 32-bit
@ "ppc64" PowerPC 64-bit
@ "sparc64" Sun UltraSPARC 64-bit
@ "xen32" Xen 32-bit
! ARCH (choice)
 
# Compiler
@ "cross" Cross-compiler
@ "native" Native
! COMPILER (choice)
 
# CPU type
@ "pentium4" Pentium 4
@ "pentium3" Pentium 3
@ "athlon-xp" Athlon XP
@ "athlon-mp" Athlon MP
@ "prescott" Prescott
! [ARCH=ia32|ARCH=xen32] MACHINE (choice)
 
# CPU type
@ "opteron" Opteron
! [ARCH=amd64] MACHINE (choice)
 
# Machine type
@ "msim" MSIM Simulator
@ "simics" Virtutech Simics simulator
@ "lgxemul" GXEmul Little Endian
@ "bgxemul" GXEmul Big Endian
@ "indy" SGI Indy
! [ARCH=mips32] MACHINE (choice)
 
# Framebuffer support
! [(ARCH=mips32&MACHINE=lgxemul)|(ARCH=mips32&MACHINE=bgxemul)|(ARCH=ia32)|(ARCH=amd64)] CONFIG_FB (y/n)
 
# Framebuffer width
@ "640"
@ "800"
@ "1024"
@ "1152"
@ "1280"
@ "1400"
@ "1440"
@ "1600"
@ "2048"
! [(ARCH=ia32|ARCH=amd64)&CONFIG_FB=y] CONFIG_VESA_WIDTH (choice)
 
# Framebuffer height
@ "480"
@ "600"
@ "768"
@ "852"
@ "900"
@ "960"
@ "1024"
@ "1050"
@ "1200"
@ "1536"
! [(ARCH=ia32|ARCH=amd64)&CONFIG_FB=y] CONFIG_VESA_HEIGHT (choice)
 
# Framebuffer depth
@ "8"
@ "16"
@ "24"
! [(ARCH=ia32|ARCH=amd64)&CONFIG_FB=y] CONFIG_VESA_BPP (choice)
 
# Support for SMP
! [ARCH=ia32|ARCH=amd64|ARCH=xen32] CONFIG_SMP (y/n)
 
# Improved support for hyperthreading
! [(ARCH=ia32|ARCH=amd64|ARCH=xen32)&CONFIG_SMP=y] CONFIG_HT (y/n)
 
# Simics BIOS AP boot fix
! [(ARCH=ia32|ARCH=amd64)&CONFIG_SMP=y] CONFIG_SIMICS_FIX (y/n)
 
# Lazy FPU context switching
! [(ARCH=mips32&MACHINE!=msim&MACHINE!=simics)|ARCH=amd64|ARCH=ia32|ARCH=ia64|ARCH=xen32] CONFIG_FPU_LAZY (y/n)
 
# Power off on halt
! [ARCH=ppc32] CONFIG_POWEROFF (n/y)
 
## Debugging configuration directives
 
# General debuging and assert checking
! CONFIG_DEBUG (y/n)
 
# Deadlock detection support for spinlocks
! [CONFIG_DEBUG=y&CONFIG_SMP=y] CONFIG_DEBUG_SPINLOCK (y/n)
 
# Watchpoint on rewriting AS with zero
! [CONFIG_DEBUG=y&(ARCH=amd64|ARCH=ia32|ARCH=xen32)] CONFIG_DEBUG_AS_WATCHPOINT (y/n)
 
# Save all interrupt registers
! [CONFIG_DEBUG=y&(ARCH=amd64|ARCH=mips32|ARCH=ia32|ARCH=xen32)] CONFIG_DEBUG_ALLREGS (y/n)
 
# Use VHPT
! [ARCH=ia64] CONFIG_VHPT (n/y)
 
## Run-time configuration directives
 
# Kernel test type
@ "" No test
@ "atomic/atomic1" Test of atomic operations.
@ "btree/btree1" B-tree test.
@ "synch/rwlock1" Read write test 1
@ "synch/rwlock2" Read write test 2
@ "synch/rwlock3" Read write test 3
@ "synch/rwlock4" Read write test 4
@ "synch/rwlock5" Read write test 5
@ "synch/semaphore1" Semaphore test 1
@ "synch/semaphore2" Sempahore test 2
@ [ARCH=ia32|ARCH=amd64|ARCH=ia64|ARCH=xen32] "fpu/fpu1" Intel FPU test 1
@ [ARCH=ia32|ARCH=amd64|ARCH=xen32] "fpu/sse1" Intel SSE test 1
@ [ARCH=mips32&MACHINE!=msim&MACHINE!=simics] "fpu/mips1" MIPS FPU test 1
@ "print/print1" Printf test 1
@ "thread/thread1" Thread test 1
@ "mm/mapping1" Mapping test 1
@ "mm/falloc1" Frame Allocation test 1
@ "mm/falloc2" Frame Allocation test 2
@ "mm/slab1" SLAB test1 - No CPU cache
@ "mm/slab2" SLAB test2 - SMP CPU cache
@ "fault/fault1" Write to NULL (maybe page fault)
@ "sysinfo" Sysinfo fill and dump test
@ [ARCH=ia64] "mm/purge1" Itanium TLB purge test
@ [ARCH=mips32] "debug/mips1" MIPS breakpoint-debug test
! CONFIG_TEST (choice)
/tags/0.2.0.3/kernel/tools/sparc64/gencontext.c
0,0 → 1,54
#include <stdio.h>
#include <stdint.h>
 
typedef uint64_t uint64_t;
typedef uint64_t ipl_t;
typedef uint64_t uintptr_t;
 
#define __sparc64_TYPES_H__
#define __ALIGN_H__
 
#include "../../arch/sparc64/include/stack.h"
#include "../../arch/sparc64/include/context.h"
 
#define FILENAME "../../arch/sparc64/include/context_offset.h"
 
int main(void)
{
FILE *f;
struct context *pctx = NULL;
 
f = fopen(FILENAME,"w");
if (!f) {
perror(FILENAME);
return 1;
}
 
fprintf(f, "/* This file is automatically generated by %s. */\n", __FILE__);
 
fprintf(f,"/* struct context */\n");
fprintf(f,"#define OFFSET_SP 0x%x\n", ((int) &pctx->sp) - (int) pctx);
fprintf(f,"#define OFFSET_PC 0x%x\n", ((int) &pctx->pc) - (int) pctx);
fprintf(f,"#define OFFSET_I0 0x%x\n", ((int) &pctx->i0) - (int) pctx);
fprintf(f,"#define OFFSET_I1 0x%x\n", ((int) &pctx->i1) - (int) pctx);
fprintf(f,"#define OFFSET_I2 0x%x\n", ((int) &pctx->i2) - (int) pctx);
fprintf(f,"#define OFFSET_I3 0x%x\n", ((int) &pctx->i3) - (int) pctx);
fprintf(f,"#define OFFSET_I4 0x%x\n", ((int) &pctx->i4) - (int) pctx);
fprintf(f,"#define OFFSET_I5 0x%x\n", ((int) &pctx->i5) - (int) pctx);
fprintf(f,"#define OFFSET_FP 0x%x\n", ((int) &pctx->fp) - (int) pctx);
fprintf(f,"#define OFFSET_I7 0x%x\n", ((int) &pctx->i7) - (int) pctx);
fprintf(f,"#define OFFSET_L0 0x%x\n", ((int) &pctx->l0) - (int) pctx);
fprintf(f,"#define OFFSET_L1 0x%x\n", ((int) &pctx->l1) - (int) pctx);
fprintf(f,"#define OFFSET_L2 0x%x\n", ((int) &pctx->l2) - (int) pctx);
fprintf(f,"#define OFFSET_L3 0x%x\n", ((int) &pctx->l3) - (int) pctx);
fprintf(f,"#define OFFSET_L4 0x%x\n", ((int) &pctx->l4) - (int) pctx);
fprintf(f,"#define OFFSET_L5 0x%x\n", ((int) &pctx->l5) - (int) pctx);
fprintf(f,"#define OFFSET_L6 0x%x\n", ((int) &pctx->l6) - (int) pctx);
fprintf(f,"#define OFFSET_L7 0x%x\n", ((int) &pctx->l7) - (int) pctx);
fprintf(f,"#define OFFSET_CLEANWIN 0x%x\n", ((int) &pctx->cleanwin) - (int) pctx);
 
fclose(f);
 
return 0;
}
/tags/0.2.0.3/kernel/tools/ppc32/gencontext.c
0,0 → 1,81
#include <stdio.h>
#include <stdint.h>
 
typedef uint32_t uint32_t;
typedef uint64_t uint64_t;
typedef uint32_t ipl_t;
typedef uint32_t uintptr_t;
 
#define __ppc32_TYPES_H__
#include "../../arch/ppc32/include/context.h"
#include "../../arch/ppc32/include/fpu_context.h"
 
#define FILENAME "../../arch/ppc32/include/context_offset.h"
 
int main(void)
{
FILE *f;
struct context *pctx = NULL;
struct fpu_context *fpctx = NULL;
 
f = fopen(FILENAME,"w");
if (!f) {
perror(FILENAME);
return 1;
}
 
fprintf(f, "/* This file is automatically generated by %s. */\n", __FILE__);
 
fprintf(f,"/* struct context */\n");
 
fprintf(f,"#define OFFSET_SP 0x%x\n", ((int) &pctx->sp) - (int) pctx);
fprintf(f,"#define OFFSET_PC 0x%x\n", ((int) &pctx->pc) - (int) pctx);
fprintf(f,"#define OFFSET_R2 0x%x\n", ((int) &pctx->r2) - (int) pctx);
fprintf(f,"#define OFFSET_R13 0x%x\n", ((int) &pctx->r13) - (int) pctx);
fprintf(f,"#define OFFSET_R14 0x%x\n", ((int) &pctx->r14) - (int) pctx);
fprintf(f,"#define OFFSET_R15 0x%x\n", ((int) &pctx->r15) - (int) pctx);
fprintf(f,"#define OFFSET_R16 0x%x\n", ((int) &pctx->r16) - (int) pctx);
fprintf(f,"#define OFFSET_R17 0x%x\n", ((int) &pctx->r17) - (int) pctx);
fprintf(f,"#define OFFSET_R18 0x%x\n", ((int) &pctx->r18) - (int) pctx);
fprintf(f,"#define OFFSET_R19 0x%x\n", ((int) &pctx->r19) - (int) pctx);
fprintf(f,"#define OFFSET_R20 0x%x\n", ((int) &pctx->r20) - (int) pctx);
fprintf(f,"#define OFFSET_R21 0x%x\n", ((int) &pctx->r21) - (int) pctx);
fprintf(f,"#define OFFSET_R22 0x%x\n", ((int) &pctx->r22) - (int) pctx);
fprintf(f,"#define OFFSET_R23 0x%x\n", ((int) &pctx->r23) - (int) pctx);
fprintf(f,"#define OFFSET_R24 0x%x\n", ((int) &pctx->r24) - (int) pctx);
fprintf(f,"#define OFFSET_R25 0x%x\n", ((int) &pctx->r25) - (int) pctx);
fprintf(f,"#define OFFSET_R26 0x%x\n", ((int) &pctx->r26) - (int) pctx);
fprintf(f,"#define OFFSET_R27 0x%x\n", ((int) &pctx->r27) - (int) pctx);
fprintf(f,"#define OFFSET_R28 0x%x\n", ((int) &pctx->r28) - (int) pctx);
fprintf(f,"#define OFFSET_R29 0x%x\n", ((int) &pctx->r29) - (int) pctx);
fprintf(f,"#define OFFSET_R30 0x%x\n", ((int) &pctx->r30) - (int) pctx);
fprintf(f,"#define OFFSET_R31 0x%x\n", ((int) &pctx->r31) - (int) pctx);
fprintf(f,"#define OFFSET_CR 0x%x\n", ((int) &pctx->cr) - (int) pctx);
fprintf(f,"\n");
 
fprintf(f,"#define OFFSET_FR14 0x%x\n", ((int) &fpctx->fr14) - (int) fpctx);
fprintf(f,"#define OFFSET_FR15 0x%x\n", ((int) &fpctx->fr15) - (int) fpctx);
fprintf(f,"#define OFFSET_FR16 0x%x\n", ((int) &fpctx->fr16) - (int) fpctx);
fprintf(f,"#define OFFSET_FR17 0x%x\n", ((int) &fpctx->fr17) - (int) fpctx);
fprintf(f,"#define OFFSET_FR18 0x%x\n", ((int) &fpctx->fr18) - (int) fpctx);
fprintf(f,"#define OFFSET_FR19 0x%x\n", ((int) &fpctx->fr19) - (int) fpctx);
fprintf(f,"#define OFFSET_FR20 0x%x\n", ((int) &fpctx->fr20) - (int) fpctx);
fprintf(f,"#define OFFSET_FR21 0x%x\n", ((int) &fpctx->fr21) - (int) fpctx);
fprintf(f,"#define OFFSET_FR22 0x%x\n", ((int) &fpctx->fr22) - (int) fpctx);
fprintf(f,"#define OFFSET_FR23 0x%x\n", ((int) &fpctx->fr23) - (int) fpctx);
fprintf(f,"#define OFFSET_FR24 0x%x\n", ((int) &fpctx->fr24) - (int) fpctx);
fprintf(f,"#define OFFSET_FR25 0x%x\n", ((int) &fpctx->fr25) - (int) fpctx);
fprintf(f,"#define OFFSET_FR26 0x%x\n", ((int) &fpctx->fr26) - (int) fpctx);
fprintf(f,"#define OFFSET_FR27 0x%x\n", ((int) &fpctx->fr27) - (int) fpctx);
fprintf(f,"#define OFFSET_FR28 0x%x\n", ((int) &fpctx->fr28) - (int) fpctx);
fprintf(f,"#define OFFSET_FR29 0x%x\n", ((int) &fpctx->fr29) - (int) fpctx);
fprintf(f,"#define OFFSET_FR30 0x%x\n", ((int) &fpctx->fr30) - (int) fpctx);
fprintf(f,"#define OFFSET_FR31 0x%x\n", ((int) &fpctx->fr31) - (int) fpctx);
fprintf(f,"#define OFFSET_FPSCR 0x%x\n", ((int) &fpctx->fpscr) - (int) fpctx);
fclose(f);
 
return 0;
}
/tags/0.2.0.3/kernel/tools/amd64/gencontext.c
0,0 → 1,43
#include <stdio.h>
#include <stdint.h>
 
typedef uint64_t uint64_t;
typedef uint64_t ipl_t;
typedef uint64_t uintptr_t;
 
#define __amd64_TYPES_H__
#include "../../arch/amd64/include/context.h"
 
#define FILENAME "../../arch/amd64/include/context_offset.h"
 
int main(void)
{
FILE *f;
struct context ctx;
struct context *pctx = &ctx;
 
struct interrupt_context ictx;
struct interrupt_context *ipctx = &ictx;
 
f = fopen(FILENAME,"w");
if (!f) {
perror(FILENAME);
return 1;
}
 
fprintf(f, "/* This file is automatically generated by %s. */\n", __FILE__);
 
fprintf(f,"#define OFFSET_SP 0x%x\n", ((int) &pctx->sp) - (int) pctx);
fprintf(f,"#define OFFSET_PC 0x%x\n", ((int) &pctx->pc) - (int) pctx);
fprintf(f,"#define OFFSET_RBX 0x%x\n", ((int) &pctx->rbx) - (int) pctx);
fprintf(f,"#define OFFSET_RBP 0x%x\n", ((int) &pctx->rbp) - (int) pctx);
fprintf(f,"#define OFFSET_R12 0x%x\n", ((int) &pctx->r12) - (int) pctx);
fprintf(f,"#define OFFSET_R13 0x%x\n", ((int) &pctx->r13) - (int) pctx);
fprintf(f,"#define OFFSET_R14 0x%x\n", ((int) &pctx->r14) - (int) pctx);
fprintf(f,"#define OFFSET_R15 0x%x\n", ((int) &pctx->r15) - (int) pctx);
fprintf(f,"#define OFFSET_IPL 0x%x\n", ((int) &pctx->ipl) - (int) pctx);
 
fclose(f);
 
return 0;
}
/tags/0.2.0.3/kernel/tools/amd64/decpt.py
0,0 → 1,25
#!/usr/bin/env python
"""
Decode 64-bit address into components
"""
import sys
 
def main():
if len(sys.argv) != 2 or not sys.argv[1].startswith('0x'):
print "%s 0x..." % sys.argv[0]
sys.exit(1)
address = int(sys.argv[1],16)
offset = address & 0xfff
ptl3 = (address >> 12) & 0x1ff
ptl2 = (address >> 21) & 0x1ff
ptl1 = (address >> 30) & 0x1ff
ptl0 = (address >> 39) & 0x1ff
print "Ptl0: %3d" % ptl0
print "Ptl1: %3d" % ptl1
print "Ptl2: %3d" % ptl2
print "Ptl3: %3d" % ptl3
print "Offset: 0x%x" % offset
 
if __name__ == '__main__':
main()
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/tools/ppc64/gencontext.c
0,0 → 1,81
#include <stdio.h>
#include <stdint.h>
 
typedef uint32_t uint32_t;
typedef uint64_t uint64_t;
typedef uint64_t ipl_t;
typedef uint64_t uintptr_t;
 
#define __ppc64_TYPES_H__
#include "../../arch/ppc64/include/context.h"
#include "../../arch/ppc64/include/fpu_context.h"
 
#define FILENAME "../../arch/ppc64/include/context_offset.h"
 
int main(void)
{
FILE *f;
struct context *pctx = NULL;
struct fpu_context *fpctx = NULL;
 
f = fopen(FILENAME,"w");
if (!f) {
perror(FILENAME);
return 1;
}
 
fprintf(f, "/* This file is automatically generated by %s. */\n", __FILE__);
 
fprintf(f,"/* struct context */\n");
 
fprintf(f,"#define OFFSET_SP 0x%x\n", ((int) &pctx->sp) - (int) pctx);
fprintf(f,"#define OFFSET_PC 0x%x\n", ((int) &pctx->pc) - (int) pctx);
fprintf(f,"#define OFFSET_R2 0x%x\n", ((int) &pctx->r2) - (int) pctx);
fprintf(f,"#define OFFSET_R13 0x%x\n", ((int) &pctx->r13) - (int) pctx);
fprintf(f,"#define OFFSET_R14 0x%x\n", ((int) &pctx->r14) - (int) pctx);
fprintf(f,"#define OFFSET_R15 0x%x\n", ((int) &pctx->r15) - (int) pctx);
fprintf(f,"#define OFFSET_R16 0x%x\n", ((int) &pctx->r16) - (int) pctx);
fprintf(f,"#define OFFSET_R17 0x%x\n", ((int) &pctx->r17) - (int) pctx);
fprintf(f,"#define OFFSET_R18 0x%x\n", ((int) &pctx->r18) - (int) pctx);
fprintf(f,"#define OFFSET_R19 0x%x\n", ((int) &pctx->r19) - (int) pctx);
fprintf(f,"#define OFFSET_R20 0x%x\n", ((int) &pctx->r20) - (int) pctx);
fprintf(f,"#define OFFSET_R21 0x%x\n", ((int) &pctx->r21) - (int) pctx);
fprintf(f,"#define OFFSET_R22 0x%x\n", ((int) &pctx->r22) - (int) pctx);
fprintf(f,"#define OFFSET_R23 0x%x\n", ((int) &pctx->r23) - (int) pctx);
fprintf(f,"#define OFFSET_R24 0x%x\n", ((int) &pctx->r24) - (int) pctx);
fprintf(f,"#define OFFSET_R25 0x%x\n", ((int) &pctx->r25) - (int) pctx);
fprintf(f,"#define OFFSET_R26 0x%x\n", ((int) &pctx->r26) - (int) pctx);
fprintf(f,"#define OFFSET_R27 0x%x\n", ((int) &pctx->r27) - (int) pctx);
fprintf(f,"#define OFFSET_R28 0x%x\n", ((int) &pctx->r28) - (int) pctx);
fprintf(f,"#define OFFSET_R29 0x%x\n", ((int) &pctx->r29) - (int) pctx);
fprintf(f,"#define OFFSET_R30 0x%x\n", ((int) &pctx->r30) - (int) pctx);
fprintf(f,"#define OFFSET_R31 0x%x\n", ((int) &pctx->r31) - (int) pctx);
fprintf(f,"#define OFFSET_CR 0x%x\n", ((int) &pctx->cr) - (int) pctx);
fprintf(f,"\n");
 
fprintf(f,"#define OFFSET_FR14 0x%x\n", ((int) &fpctx->fr14) - (int) fpctx);
fprintf(f,"#define OFFSET_FR15 0x%x\n", ((int) &fpctx->fr15) - (int) fpctx);
fprintf(f,"#define OFFSET_FR16 0x%x\n", ((int) &fpctx->fr16) - (int) fpctx);
fprintf(f,"#define OFFSET_FR17 0x%x\n", ((int) &fpctx->fr17) - (int) fpctx);
fprintf(f,"#define OFFSET_FR18 0x%x\n", ((int) &fpctx->fr18) - (int) fpctx);
fprintf(f,"#define OFFSET_FR19 0x%x\n", ((int) &fpctx->fr19) - (int) fpctx);
fprintf(f,"#define OFFSET_FR20 0x%x\n", ((int) &fpctx->fr20) - (int) fpctx);
fprintf(f,"#define OFFSET_FR21 0x%x\n", ((int) &fpctx->fr21) - (int) fpctx);
fprintf(f,"#define OFFSET_FR22 0x%x\n", ((int) &fpctx->fr22) - (int) fpctx);
fprintf(f,"#define OFFSET_FR23 0x%x\n", ((int) &fpctx->fr23) - (int) fpctx);
fprintf(f,"#define OFFSET_FR24 0x%x\n", ((int) &fpctx->fr24) - (int) fpctx);
fprintf(f,"#define OFFSET_FR25 0x%x\n", ((int) &fpctx->fr25) - (int) fpctx);
fprintf(f,"#define OFFSET_FR26 0x%x\n", ((int) &fpctx->fr26) - (int) fpctx);
fprintf(f,"#define OFFSET_FR27 0x%x\n", ((int) &fpctx->fr27) - (int) fpctx);
fprintf(f,"#define OFFSET_FR28 0x%x\n", ((int) &fpctx->fr28) - (int) fpctx);
fprintf(f,"#define OFFSET_FR29 0x%x\n", ((int) &fpctx->fr29) - (int) fpctx);
fprintf(f,"#define OFFSET_FR30 0x%x\n", ((int) &fpctx->fr30) - (int) fpctx);
fprintf(f,"#define OFFSET_FR31 0x%x\n", ((int) &fpctx->fr31) - (int) fpctx);
fprintf(f,"#define OFFSET_FPSCR 0x%x\n", ((int) &fpctx->fpscr) - (int) fpctx);
fclose(f);
 
return 0;
}
/tags/0.2.0.3/kernel/tools/mips32/gencontext.c
0,0 → 1,84
#include <stdio.h>
#include <stdint.h>
 
typedef uint32_t uint32_t;
typedef uint32_t ipl_t;
typedef uint32_t uintptr_t;
 
#define __mips32_TYPES_H__
#include "../../arch/mips32/include/context.h"
#include "../../arch/mips32/include/exception.h"
 
#define FILENAME "../../arch/mips32/include/context_offset.h"
 
int main(void)
{
FILE *f;
struct context *pctx = NULL;
struct exception_regdump *edmp = NULL;
 
f = fopen(FILENAME,"w");
if (!f) {
perror(FILENAME);
return 1;
}
 
fprintf(f, "/* This file is automatically generated by %s. */\n", __FILE__);
 
fprintf(f,"/* struct context */\n");
 
fprintf(f,"#define OFFSET_SP 0x%x\n", ((int) &pctx->sp) - (int) pctx);
fprintf(f,"#define OFFSET_PC 0x%x\n", ((int) &pctx->pc) - (int) pctx);
fprintf(f,"#define OFFSET_S0 0x%x\n", ((int) &pctx->s0) - (int) pctx);
fprintf(f,"#define OFFSET_S1 0x%x\n", ((int) &pctx->s1) - (int) pctx);
fprintf(f,"#define OFFSET_S2 0x%x\n", ((int) &pctx->s2) - (int) pctx);
fprintf(f,"#define OFFSET_S3 0x%x\n", ((int) &pctx->s3) - (int) pctx);
fprintf(f,"#define OFFSET_S4 0x%x\n", ((int) &pctx->s4) - (int) pctx);
fprintf(f,"#define OFFSET_S5 0x%x\n", ((int) &pctx->s5) - (int) pctx);
fprintf(f,"#define OFFSET_S6 0x%x\n", ((int) &pctx->s6) - (int) pctx);
fprintf(f,"#define OFFSET_S7 0x%x\n", ((int) &pctx->s7) - (int) pctx);
fprintf(f,"#define OFFSET_S8 0x%x\n", ((int) &pctx->s8) - (int) pctx);
fprintf(f,"#define OFFSET_GP 0x%x\n", ((int) &pctx->gp) - (int) pctx);
 
fprintf(f,"\n\n/* struct register_dump */\n");
fprintf(f,"#define EOFFSET_AT 0x%x\n", ((int) &edmp->at) - (int) edmp);
fprintf(f,"#define EOFFSET_V0 0x%x\n", ((int) &edmp->v0) - (int) edmp);
fprintf(f,"#define EOFFSET_V1 0x%x\n", ((int) &edmp->v1) - (int) edmp);
fprintf(f,"#define EOFFSET_A0 0x%x\n", ((int) &edmp->a0) - (int) edmp);
fprintf(f,"#define EOFFSET_A1 0x%x\n", ((int) &edmp->a1) - (int) edmp);
fprintf(f,"#define EOFFSET_A2 0x%x\n", ((int) &edmp->a2) - (int) edmp);
fprintf(f,"#define EOFFSET_A3 0x%x\n", ((int) &edmp->a3) - (int) edmp);
fprintf(f,"#define EOFFSET_T0 0x%x\n", ((int) &edmp->t0) - (int) edmp);
fprintf(f,"#define EOFFSET_T1 0x%x\n", ((int) &edmp->t1) - (int) edmp);
fprintf(f,"#define EOFFSET_T2 0x%x\n", ((int) &edmp->t2) - (int) edmp);
fprintf(f,"#define EOFFSET_T3 0x%x\n", ((int) &edmp->t3) - (int) edmp);
fprintf(f,"#define EOFFSET_T4 0x%x\n", ((int) &edmp->t4) - (int) edmp);
fprintf(f,"#define EOFFSET_T5 0x%x\n", ((int) &edmp->t5) - (int) edmp);
fprintf(f,"#define EOFFSET_T6 0x%x\n", ((int) &edmp->t6) - (int) edmp);
fprintf(f,"#define EOFFSET_T7 0x%x\n", ((int) &edmp->t7) - (int) edmp);
fprintf(f,"#define EOFFSET_S0 0x%x\n", ((int) &edmp->s0) - (int) edmp);
fprintf(f,"#define EOFFSET_S1 0x%x\n", ((int) &edmp->s1) - (int) edmp);
fprintf(f,"#define EOFFSET_S2 0x%x\n", ((int) &edmp->s2) - (int) edmp);
fprintf(f,"#define EOFFSET_S3 0x%x\n", ((int) &edmp->s3) - (int) edmp);
fprintf(f,"#define EOFFSET_S4 0x%x\n", ((int) &edmp->s4) - (int) edmp);
fprintf(f,"#define EOFFSET_S5 0x%x\n", ((int) &edmp->s5) - (int) edmp);
fprintf(f,"#define EOFFSET_S6 0x%x\n", ((int) &edmp->s6) - (int) edmp);
fprintf(f,"#define EOFFSET_S7 0x%x\n", ((int) &edmp->s7) - (int) edmp);
fprintf(f,"#define EOFFSET_T8 0x%x\n", ((int) &edmp->t8) - (int) edmp);
fprintf(f,"#define EOFFSET_T9 0x%x\n", ((int) &edmp->t9) - (int) edmp);
fprintf(f,"#define EOFFSET_GP 0x%x\n", ((int) &edmp->gp) - (int) edmp);
fprintf(f,"#define EOFFSET_SP 0x%x\n", ((int) &edmp->sp) - (int) edmp);
fprintf(f,"#define EOFFSET_S8 0x%x\n", ((int) &edmp->s8) - (int) edmp);
fprintf(f,"#define EOFFSET_RA 0x%x\n", ((int) &edmp->ra) - (int) edmp);
fprintf(f,"#define EOFFSET_LO 0x%x\n", ((int) &edmp->lo) - (int) edmp);
fprintf(f,"#define EOFFSET_HI 0x%x\n", ((int) &edmp->hi) - (int) edmp);
fprintf(f,"#define EOFFSET_STATUS 0x%x\n", ((int) &edmp->status) - (int) edmp);
fprintf(f,"#define EOFFSET_EPC 0x%x\n", ((int) &edmp->epc) - (int) edmp);
 
fprintf(f,"#define REGISTER_SPACE %d\n", sizeof(*edmp));
 
fclose(f);
 
return 0;
}
/tags/0.2.0.3/kernel/tools/ia32/decpt.py
0,0 → 1,21
#!/usr/bin/env python
"""
Decode 32-bit address into PTE components
"""
import sys
 
def main():
if len(sys.argv) != 2 or not sys.argv[1].startswith('0x'):
print "%s 0x..." % sys.argv[0]
sys.exit(1)
address = int(sys.argv[1],16)
offset = address & 0xfff
ptl1 = (address >> 12) & 0x3ff
ptl0 = (address >> 22) & 0x3ff
print "Ptl0: %3d" % ptl0
print "Ptl1: %3d" % ptl1
print "Offset: 0x%x" % offset
 
if __name__ == '__main__':
main()
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/tools/genmap.py
0,0 → 1,87
#!/usr/bin/env python
 
import sys
import struct
import re
 
MAXSTRING=63
symtabfmt = "<Q%ds" % (MAXSTRING+1)
 
 
funcline = re.compile(r'([0-9a-f]+)\s+[lg]\s+.\s+\.text\s+([0-9a-f]+)\s+(.*)$')
bssline = re.compile(r'([0-9a-f]+)\s+[lg]\s+[a-zA-Z]\s+\.bss\s+([0-9a-f]+)\s+(.*)$')
dataline = re.compile(r'([0-9a-f]+)\s+[lg]\s+[a-zA-Z]\s+\.data\s+([0-9a-f]+)\s+(.*)$')
fileexp = re.compile(r'([^\s]+):\s+file format')
def read_obdump(inp):
funcs = {}
data = {}
bss ={}
fname = ''
for line in inp:
line = line.strip()
res = funcline.match(line)
if res:
funcs.setdefault(fname,[]).append((int(res.group(1),16),
res.group(3)))
continue
res = bssline.match(line)
if res:
start = int(res.group(1),16)
end = int(res.group(2),16)
if end:
bss.setdefault(fname,[]).append((start,res.group(3)))
res = dataline.match(line)
if res:
start = int(res.group(1),16)
end = int(res.group(2),16)
if end:
data.setdefault(fname,[]).append((start,res.group(3)))
res = fileexp.match(line)
if res:
fname = res.group(1)
continue
 
return {
'text' : funcs,
'bss' : bss,
'data' : data
}
 
startfile = re.compile(r'\.(text|bss|data)\s+(0x[0-9a-f]+)\s+0x[0-9a-f]+\s+(.*)$')
def generate(kmapf, obmapf, out):
obdump = read_obdump(obmapf)
 
def sorter(x,y):
return cmp(x[0],y[0])
 
for line in kmapf:
line = line.strip()
res = startfile.match(line)
 
if res and obdump[res.group(1)].has_key(res.group(3)):
offset = int(res.group(2),16)
fname = res.group(3)
symbols = obdump[res.group(1)][fname]
symbols.sort(sorter)
for addr,symbol in symbols:
value = fname + ':' + symbol
data = struct.pack(symtabfmt,addr+offset,value[:MAXSTRING])
out.write(data)
out.write(struct.pack(symtabfmt,0,''))
 
def main():
if len(sys.argv) != 4:
print "Usage: %s <kernel.map> <nm dump> <output.bin>" % sys.argv[0]
sys.exit(1)
 
kmapf = open(sys.argv[1],'r')
obmapf = open(sys.argv[2],'r')
out = open(sys.argv[3],'w')
generate(kmapf,obmapf,out)
kmapf.close()
obmapf.close()
out.close()
 
if __name__ == '__main__':
main()
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/0.2.0.3/kernel/Makefile
0,0 → 1,266
#
# Copyright (C) 2005 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 configuration
#
 
-include ../version
-include Makefile.config
 
## Common compiler flags
#
 
DEFS = -D$(ARCH) -DARCH=\"$(ARCH)\" -DRELEASE=\"$(RELEASE)\" "-DNAME=\"$(NAME)\"" -DKERNEL
CFLAGS = -fno-builtin -fomit-frame-pointer -Wall -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -nostdlib -nostdinc -Igeneric/include/
LFLAGS = -M
AFLAGS =
 
ifdef REVISION
DEFS += "-DREVISION=\"$(REVISION)\""
endif
 
ifdef TIMESTAMP
DEFS += "-DTIMESTAMP=\"$(TIMESTAMP)\""
endif
 
## Setup kernel configuration
#
 
-include arch/$(ARCH)/Makefile.inc
-include genarch/Makefile.inc
 
ifeq ($(CONFIG_DEBUG),y)
DEFS += -DCONFIG_DEBUG
endif
 
ifeq ($(CONFIG_DEBUG_SPINLOCK),y)
DEFS += -DCONFIG_DEBUG_SPINLOCK
endif
 
ifeq ($(CONFIG_DEBUG_AS_WATCHPOINT),y)
DEFS += -DCONFIG_DEBUG_AS_WATCHPOINT
endif
 
ifeq ($(CONFIG_FPU_LAZY),y)
DEFS += -DCONFIG_FPU_LAZY
endif
 
ifeq ($(CONFIG_DEBUG_ALLREGS),y)
DEFS += -DCONFIG_DEBUG_ALLREGS
endif
 
ifeq ($(CONFIG_VHPT),y)
DEFS += -DCONFIG_VHPT
endif
 
ifeq ($(CONFIG_POWEROFF),y)
DEFS += -DCONFIG_POWEROFF
endif
 
ifeq ($(CONFIG_FB),y)
ifeq ($(ARCH),ia32)
DEFS += -DCONFIG_VESA_WIDTH=$(CONFIG_VESA_WIDTH)
DEFS += -DCONFIG_VESA_HEIGHT=$(CONFIG_VESA_HEIGHT)
DEFS += -DCONFIG_VESA_BPP=$(CONFIG_VESA_BPP)
endif
ifeq ($(ARCH),amd64)
DEFS += -DCONFIG_VESA_WIDTH=$(CONFIG_VESA_WIDTH)
DEFS += -DCONFIG_VESA_HEIGHT=$(CONFIG_VESA_HEIGHT)
DEFS += -DCONFIG_VESA_BPP=$(CONFIG_VESA_BPP)
endif
ifeq ($(ARCH),xen32)
DEFS += -DCONFIG_VESA_WIDTH=$(CONFIG_VESA_WIDTH)
DEFS += -DCONFIG_VESA_HEIGHT=$(CONFIG_VESA_HEIGHT)
DEFS += -DCONFIG_VESA_BPP=$(CONFIG_VESA_BPP)
endif
endif
 
## Toolchain configuration
#
 
ifeq ($(COMPILER),native)
CC = gcc
AS = as
LD = ld
OBJCOPY = objcopy
OBJDUMP = objdump
else
CC = $(TOOLCHAIN_DIR)/$(TARGET)-gcc
AS = $(TOOLCHAIN_DIR)/$(TARGET)-as
LD = $(TOOLCHAIN_DIR)/$(TARGET)-ld
OBJCOPY = $(TOOLCHAIN_DIR)/$(TARGET)-objcopy
OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump
endif
 
## Generic kernel sources
#
 
GENERIC_SOURCES = \
generic/src/adt/bitmap.c \
generic/src/adt/btree.c \
generic/src/adt/hash_table.c \
generic/src/adt/list.c \
generic/src/console/chardev.c \
generic/src/console/console.c \
generic/src/console/kconsole.c \
generic/src/console/klog.c \
generic/src/console/cmd.c \
generic/src/cpu/cpu.c \
generic/src/ddi/ddi.c \
generic/src/interrupt/interrupt.c \
generic/src/main/main.c \
generic/src/main/kinit.c \
generic/src/main/uinit.c \
generic/src/main/version.c \
generic/src/proc/scheduler.c \
generic/src/proc/thread.c \
generic/src/proc/task.c \
generic/src/proc/the.c \
generic/src/syscall/syscall.c \
generic/src/syscall/copy.c \
generic/src/mm/buddy.c \
generic/src/mm/frame.c \
generic/src/mm/page.c \
generic/src/mm/tlb.c \
generic/src/mm/as.c \
generic/src/mm/backend_anon.c \
generic/src/mm/backend_elf.c \
generic/src/mm/backend_phys.c \
generic/src/mm/slab.c \
generic/src/lib/func.c \
generic/src/lib/memstr.c \
generic/src/lib/sort.c \
generic/src/lib/elf.c \
generic/src/printf/printf_core.c \
generic/src/printf/printf.c \
generic/src/printf/sprintf.c \
generic/src/printf/snprintf.c \
generic/src/printf/vprintf.c \
generic/src/printf/vsprintf.c \
generic/src/printf/vsnprintf.c \
generic/src/debug/symtab.c \
generic/src/time/clock.c \
generic/src/time/timeout.c \
generic/src/time/delay.c \
generic/src/preempt/preemption.c \
generic/src/synch/spinlock.c \
generic/src/synch/condvar.c \
generic/src/synch/rwlock.c \
generic/src/synch/mutex.c \
generic/src/synch/semaphore.c \
generic/src/synch/waitq.c \
generic/src/synch/futex.c \
generic/src/smp/ipi.c \
generic/src/ipc/ipc.c \
generic/src/ipc/sysipc.c \
generic/src/ipc/ipcrsc.c \
generic/src/ipc/irq.c \
generic/src/security/cap.c \
generic/src/sysinfo/sysinfo.c
 
## Test sources
#
 
ifneq ($(CONFIG_TEST),)
DEFS += -DCONFIG_TEST
GENERIC_SOURCES += test/$(CONFIG_TEST)/test.c
endif
 
GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES)))
ARCH_OBJECTS := $(addsuffix .o,$(basename $(ARCH_SOURCES)))
GENARCH_OBJECTS := $(addsuffix .o,$(basename $(GENARCH_SOURCES)))
 
.PHONY: all build config distclean clean archlinks depend disasm
 
all:
../tools/config.py kernel.config default $(ARCH) $(COMPILER) $(CONFIG_DEBUG) $(MACHINE)
$(MAKE) -C . build
 
build: kernel.bin disasm
 
config:
-rm Makefile.depend
tools/config.py kernel.config
 
-include Makefile.depend
 
distclean: clean
-rm Makefile.config
 
clean:
-rm -f kernel.bin kernel.raw kernel.map kernel.map.pre kernel.objdump kernel.disasm generic/src/debug/real_map.bin Makefile.depend* generic/include/arch generic/include/genarch arch/$(ARCH)/_link.ld
find generic/src/ arch/*/src/ genarch/src/ test/ -name '*.o' -follow -exec rm \{\} \;
for arch in arch/* ; do \
[ -e $$arch/_link.ld ] && rm $$arch/_link.ld 2>/dev/null ; \
done ; exit 0
 
archlinks:
ln -sfn ../../arch/$(ARCH)/include/ generic/include/arch
ln -sfn ../../genarch/include/ generic/include/genarch
 
depend: archlinks
-makedepend $(DEFS) $(CFLAGS) -f - $(ARCH_SOURCES) $(GENARCH_SOURCES) $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null
 
arch/$(ARCH)/_link.ld: arch/$(ARCH)/_link.ld.in
$(CC) $(DEFS) $(CFLAGS) -D__ASM__ -E -x c $< | grep -v "^\#" > $@
 
generic/src/debug/real_map.bin: depend arch/$(ARCH)/_link.ld $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS)
$(OBJCOPY) -I binary -O $(BFD_NAME) -B $(BFD_ARCH) --prefix-sections=symtab Makefile generic/src/debug/empty_map.o
$(LD) -T arch/$(ARCH)/_link.ld $(LFLAGS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) generic/src/debug/empty_map.o -o $@ -Map kernel.map.pre
$(OBJDUMP) -t $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) > kernel.objdump
tools/genmap.py kernel.map.pre kernel.objdump generic/src/debug/real_map.bin
# Do it once again, this time to get correct even the symbols
# on architectures, that have bss after symtab
$(OBJCOPY) -I binary -O $(BFD_NAME) -B $(BFD_ARCH) --prefix-sections=symtab generic/src/debug/real_map.bin generic/src/debug/sizeok_map.o
$(LD) -T arch/$(ARCH)/_link.ld $(LFLAGS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) generic/src/debug/sizeok_map.o -o $@ -Map kernel.map.pre
$(OBJDUMP) -t $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) > kernel.objdump
tools/genmap.py kernel.map.pre kernel.objdump generic/src/debug/real_map.bin
 
generic/src/debug/real_map.o: generic/src/debug/real_map.bin
$(OBJCOPY) -I binary -O $(BFD_NAME) -B $(BFD_ARCH) --prefix-sections=symtab $< $@
 
kernel.raw: depend arch/$(ARCH)/_link.ld $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) generic/src/debug/real_map.o
$(LD) -T arch/$(ARCH)/_link.ld $(LFLAGS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) generic/src/debug/real_map.o -o $@ -Map kernel.map
 
kernel.bin: kernel.raw
$(OBJCOPY) -O $(BFD) kernel.raw kernel.bin
 
disasm: kernel.raw
$(OBJDUMP) -d kernel.raw > kernel.disasm
 
%.o: %.S
$(CC) $(DEFS) $(CFLAGS) -D__ASM__ -c $< -o $@
 
%.o: %.s
$(AS) $(AFLAGS) $< -o $@
 
%.o: %.c
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
/tags/0.2.0.3/kernel/genarch/include/fb/fb.h
0,0 → 1,48
/*
* Copyright (C) 2006 Ondrej Palkovsky
* 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 genarch
* @{
*/
/** @file
*/
 
#ifndef _FB_H_
#define _FB_H_
 
#include <typedefs.h>
#include <arch/types.h>
 
extern spinlock_t fb_lock;
void fb_init(uintptr_t addr, unsigned int x, unsigned int y, unsigned int bpp, unsigned int scan);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/genarch/include/fb/font-8x16.h
0,0 → 1,47
/*
* Copyright (C) 2005 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 genarch
* @{
*/
/** @file
*/
 
#ifndef __FONT_8X16_H__
#define __FONT_8X16_H__
 
#define FONT_GLIPHS 256
#define FONT_SCANLINES 16
 
extern unsigned char fb_font[FONT_GLIPHS * FONT_SCANLINES];
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/genarch/include/mm/page_pt.h
0,0 → 1,121
/*
* 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 genarchmm
* @{
*/
/** @file
*/
 
/*
* This is the generic 4-level page table interface.
* Architectures that use hierarchical page tables
* are supposed to implement *_ARCH macros.
*/
 
#ifdef CONFIG_PAGE_PT
 
#ifndef __PAGE_PT_H__
#define __PAGE_PT_H__
 
#include <arch/types.h>
#include <typedefs.h>
#include <mm/page.h>
 
/*
* Number of entries in each level.
*/
#define PTL0_ENTRIES PTL0_ENTRIES_ARCH
#define PTL1_ENTRIES PTL1_ENTRIES_ARCH
#define PTL2_ENTRIES PTL2_ENTRIES_ARCH
#define PTL3_ENTRIES PTL3_ENTRIES_ARCH
 
/*
* These macros process vaddr and extract those portions
* of it that function as indices to respective page tables.
*/
#define PTL0_INDEX(vaddr) PTL0_INDEX_ARCH(vaddr)
#define PTL1_INDEX(vaddr) PTL1_INDEX_ARCH(vaddr)
#define PTL2_INDEX(vaddr) PTL2_INDEX_ARCH(vaddr)
#define PTL3_INDEX(vaddr) PTL3_INDEX_ARCH(vaddr)
 
#define SET_PTL0_ADDRESS(ptl0) SET_PTL0_ADDRESS_ARCH(ptl0)
 
/*
* These macros traverse the 4-level tree of page tables,
* each descending by one level.
*/
#define GET_PTL1_ADDRESS(ptl0, i) GET_PTL1_ADDRESS_ARCH(ptl0, i)
#define GET_PTL2_ADDRESS(ptl1, i) GET_PTL2_ADDRESS_ARCH(ptl1, i)
#define GET_PTL3_ADDRESS(ptl2, i) GET_PTL3_ADDRESS_ARCH(ptl2, i)
#define GET_FRAME_ADDRESS(ptl3, i) GET_FRAME_ADDRESS_ARCH(ptl3, i)
 
/*
* These macros are provided to change shape of the 4-level
* tree of page tables on respective level.
*/
#define SET_PTL1_ADDRESS(ptl0, i, a) SET_PTL1_ADDRESS_ARCH(ptl0, i, a)
#define SET_PTL2_ADDRESS(ptl1, i, a) SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
#define SET_PTL3_ADDRESS(ptl2, i, a) SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
#define SET_FRAME_ADDRESS(ptl3, i, a) SET_FRAME_ADDRESS_ARCH(ptl3, i, a)
 
/*
* These macros are provided to query various flags within the page tables.
*/
#define GET_PTL1_FLAGS(ptl0, i) GET_PTL1_FLAGS_ARCH(ptl0, i)
#define GET_PTL2_FLAGS(ptl1, i) GET_PTL2_FLAGS_ARCH(ptl1, i)
#define GET_PTL3_FLAGS(ptl2, i) GET_PTL3_FLAGS_ARCH(ptl2, i)
#define GET_FRAME_FLAGS(ptl3, i) GET_FRAME_FLAGS_ARCH(ptl3, i)
 
/*
* These macros are provided to set/clear various flags within the page tables.
*/
#define SET_PTL1_FLAGS(ptl0, i, x) SET_PTL1_FLAGS_ARCH(ptl0, i, x)
#define SET_PTL2_FLAGS(ptl1, i, x) SET_PTL2_FLAGS_ARCH(ptl1, i, x)
#define SET_PTL3_FLAGS(ptl2, i, x) SET_PTL3_FLAGS_ARCH(ptl2, i, x)
#define SET_FRAME_FLAGS(ptl3, i, x) SET_FRAME_FLAGS_ARCH(ptl3, i, x)
 
#define PTE_VALID(p) PTE_VALID_ARCH((p))
#define PTE_PRESENT(p) PTE_PRESENT_ARCH((p))
#define PTE_GET_FRAME(p) PTE_GET_FRAME_ARCH((p))
#define PTE_READABLE(p) 1
#define PTE_WRITABLE(p) PTE_WRITABLE_ARCH((p))
#define PTE_EXECUTABLE(p) PTE_EXECUTABLE_ARCH((p))
 
extern page_mapping_operations_t pt_mapping_operations;
 
extern void page_mapping_insert_pt(as_t *as, uintptr_t page, uintptr_t frame, int flags);
extern pte_t *page_mapping_find_pt(as_t *as, uintptr_t page);
 
#endif
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/genarch/include/mm/page_ht.h
0,0 → 1,92
/*
* 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 genarchmm
* @{
*/
/** @file
*/
 
/*
* This is the generic page hash table interface.
*/
 
#ifdef CONFIG_PAGE_HT
 
#ifndef __PAGE_HT_H__
#define __PAGE_HT_H__
 
#include <mm/page.h>
#include <typedefs.h>
#include <arch/types.h>
#include <adt/list.h>
#include <adt/hash_table.h>
 
#define PAGE_HT_KEYS 2
#define KEY_AS 0
#define KEY_PAGE 1
 
#define PAGE_HT_ENTRIES_BITS 13
#define PAGE_HT_ENTRIES (1<<PAGE_HT_ENTRIES_BITS)
 
#define PTE_VALID(pte) ((pte) != NULL)
#define PTE_PRESENT(pte) ((pte)->p != 0)
#define PTE_GET_FRAME(pte) ((pte)->frame)
#define PTE_READABLE(pte) 1
#define PTE_WRITABLE(pte) ((pte)->w != 0)
#define PTE_EXECUTABLE(pte) ((pte)->x != 0)
 
#define SET_PTL0_ADDRESS(x)
 
struct pte {
link_t link; /**< Page hash table link. */
as_t *as; /**< Address space. */
uintptr_t page; /**< Virtual memory page. */
uintptr_t frame; /**< Physical memory frame. */
unsigned g : 1; /**< Global page. */
unsigned x : 1; /**< Execute. */
unsigned w : 1; /**< Writable. */
unsigned k : 1; /**< Kernel privileges required. */
unsigned c : 1; /**< Cacheable. */
unsigned a : 1; /**< Accessed. */
unsigned d : 1; /**< Dirty. */
unsigned p : 1; /**< Present. */
};
 
extern page_mapping_operations_t ht_mapping_operations;
extern mutex_t page_ht_lock;
extern hash_table_t page_ht;
extern hash_table_operations_t ht_operations;
 
#endif
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/genarch/include/mm/as_ht.h
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 genarchmm
* @{
*/
/** @file
*/
 
#ifndef __AS_HT_H__
#define __AS_HT_H__
 
#include <mm/as.h>
 
extern as_operations_t as_ht_operations;
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/genarch/include/mm/asid_fifo.h
0,0 → 1,44
/*
* 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 genarchmm
* @{
*/
/** @file
*/
 
#ifndef __ASID_FIFO_H__
#define __ASID_FIFO_H__
 
extern void asid_fifo_init(void);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/genarch/include/mm/as_pt.h
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 genarchmm
* @{
*/
/** @file
*/
 
#ifndef __AS_PT_H__
#define __AS_PT_H__
 
#include <mm/as.h>
 
extern as_operations_t as_pt_operations;
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/genarch/include/acpi/acpi.h
0,0 → 1,95
/*
* 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 genarch
* @{
*/
/** @file
*/
 
#ifndef __ACPI_H__
#define __ACPI_H__
 
#include <arch/types.h>
 
/* Root System Description Pointer */
struct acpi_rsdp {
uint8_t signature[8];
uint8_t checksum;
uint8_t oemid[6];
uint8_t revision;
uint32_t rsdt_address;
uint32_t length;
uint64_t xsdt_address;
uint32_t ext_checksum;
uint8_t reserved[3];
} __attribute__ ((packed));
 
/* System Description Table Header */
struct acpi_sdt_header {
uint8_t signature[4];
uint32_t length;
uint8_t revision;
uint8_t checksum;
uint8_t oemid[6];
uint8_t oem_table_id[8];
uint32_t oem_revision;
uint32_t creator_id;
uint32_t creator_revision;
} __attribute__ ((packed));;
 
struct acpi_signature_map {
uint8_t *signature;
struct acpi_sdt_header **sdt_ptr;
char *description;
};
 
/* Root System Description Table */
struct acpi_rsdt {
struct acpi_sdt_header header;
uint32_t entry[];
} __attribute__ ((packed));;
 
/* Extended System Description Table */
struct acpi_xsdt {
struct acpi_sdt_header header;
uint64_t entry[];
} __attribute__ ((packed));;
 
extern struct acpi_rsdp *acpi_rsdp;
extern struct acpi_rsdt *acpi_rsdt;
extern struct acpi_xsdt *acpi_xsdt;
 
extern void acpi_init(void);
extern int acpi_sdt_check(uint8_t *sdt);
 
#endif /* __ACPI_H__ */
 
/** @}
*/
 
/tags/0.2.0.3/kernel/genarch/include/acpi/madt.h
0,0 → 1,150
/*
* 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 genarch
* @{
*/
/** @file
*/
 
#ifndef __MADT_H__
#define __MADT_H__
 
#include <genarch/acpi/acpi.h>
#include <arch/smp/apic.h>
#include <arch/smp/smp.h>
 
#define MADT_L_APIC 0
#define MADT_IO_APIC 1
#define MADT_INTR_SRC_OVRD 2
#define MADT_NMI_SRC 3
#define MADT_L_APIC_NMI 4
#define MADT_L_APIC_ADDR_OVRD 5
#define MADT_IO_SAPIC 6
#define MADT_L_SAPIC 7
#define MADT_PLATFORM_INTR_SRC 8
#define MADT_RESERVED_SKIP_BEGIN 9
#define MADT_RESERVED_SKIP_END 127
#define MADT_RESERVED_OEM_BEGIN 128
 
struct madt_apic_header {
uint8_t type;
uint8_t length;
} __attribute__ ((packed));
 
 
/* Multiple APIC Description Table */
struct acpi_madt {
struct acpi_sdt_header header;
uint32_t l_apic_address;
uint32_t flags;
struct madt_apic_header apic_header[];
} __attribute__ ((packed));
 
struct madt_l_apic {
struct madt_apic_header header;
uint8_t acpi_id;
uint8_t apic_id;
uint32_t flags;
} __attribute__ ((packed));
 
struct madt_io_apic {
struct madt_apic_header header;
uint8_t io_apic_id;
uint8_t reserved;
uint32_t io_apic_address;
uint32_t global_intr_base;
} __attribute__ ((packed));
 
struct madt_intr_src_ovrd {
struct madt_apic_header header;
uint8_t bus;
uint8_t source;
uint32_t global_int;
uint16_t flags;
} __attribute__ ((packed));
 
struct madt_nmi_src {
struct madt_apic_header header;
uint16_t flags;
uint32_t global_intr;
} __attribute__ ((packed));
 
struct madt_l_apic_nmi {
struct madt_apic_header header;
uint8_t acpi_id;
uint16_t flags;
uint8_t l_apic_lint;
} __attribute__ ((packed));
 
struct madt_l_apic_addr_ovrd {
struct madt_apic_header header;
uint16_t reserved;
uint64_t l_apic_address;
} __attribute__ ((packed));
 
struct madt_io_sapic {
struct madt_apic_header header;
uint8_t io_apic_id;
uint8_t reserved;
uint32_t global_intr_base;
uint64_t io_apic_address;
} __attribute__ ((packed));
 
struct madt_l_sapic {
struct madt_apic_header header;
uint8_t acpi_id;
uint8_t sapic_id;
uint8_t sapic_eid;
uint8_t reserved[3];
uint32_t flags;
uint32_t acpi_processor_uid_value;
uint8_t acpi_processor_uid_str[1];
} __attribute__ ((packed));
 
struct madt_platform_intr_src {
struct madt_apic_header header;
uint16_t flags;
uint8_t intr_type;
uint8_t processor_id;
uint8_t processor_eid;
uint8_t io_sapic_vector;
uint32_t global_intr;
uint32_t platform_intr_src_flags;
} __attribute__ ((packed));
 
extern struct acpi_madt *acpi_madt;
extern struct smp_config_operations madt_config_operations;
 
extern void acpi_madt_parse(void);
 
#endif /* __MADT_H__ */
 
/** @}
*/
 
/tags/0.2.0.3/kernel/genarch/include/i8042/i8042.h
0,0 → 1,62
/*
* 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 genarch
* @{
*/
/** @file
*/
 
#ifndef __I8042_H__
#define __I8042_H__
 
/** Scancodes. */
#define SC_ESC 0x01
#define SC_BACKSPACE 0x0e
#define SC_LSHIFT 0x2a
#define SC_RSHIFT 0x36
#define SC_CAPSLOCK 0x3a
#define SC_SPEC_ESCAPE 0xe0
#define SC_LEFTARR 0x4b
#define SC_RIGHTARR 0x4d
#define SC_UPARR 0x48
#define SC_DOWNARR 0x50
#define SC_DELETE 0x53
#define SC_HOME 0x47
#define SC_END 0x4f
 
extern void i8042_init(void);
extern void i8042_poll(void);
extern void i8042_grab(void);
extern void i8042_release(void);
 
#endif
 
/** @}
*/
 
/tags/0.2.0.3/kernel/genarch/include/softint/division.h
0,0 → 1,70
/*
* Copyright (C) 2006 Josef Cejka
* 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 genarch
* @{
*/
/** @file
*/
 
#ifndef __SOFTINT_DIVISION_H__
#define __SOFTINT_DIVISION_H__
 
 
/* 32bit integer division */
int __divsi3(int a, int b);
 
/* 64bit integer division */
long long __divdi3(long long a, long long b);
 
/* 32bit unsigned integer division */
unsigned int __udivsi3(unsigned int a, unsigned int b);
 
/* 64bit unsigned integer division */
unsigned long long __udivdi3(unsigned long long a, unsigned long long b);
 
/* 32bit remainder of the signed division */
int __modsi3(int a, int b);
 
/* 64bit remainder of the signed division */
long long __moddi3(long long a, long long b);
 
/* 32bit remainder of the unsigned division */
unsigned int __umodsi3(unsigned int a, unsigned int b);
 
/* 64bit remainder of the unsigned division */
unsigned long long __umoddi3(unsigned long long a, unsigned long long b);
 
unsigned long long __udivmoddi3(unsigned long long a, unsigned long long b, unsigned long long *c);
 
#endif
 
 
/** @}
*/
 
/tags/0.2.0.3/kernel/genarch/Makefile.inc
0,0 → 1,71
# Copyright (C) 2005 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.
#
 
## Accepted configuration directives
#
 
ifeq ($(CONFIG_ACPI),y)
GENARCH_SOURCES += \
genarch/src/acpi/acpi.c \
genarch/src/acpi/madt.c
endif
ifeq ($(CONFIG_PAGE_PT),y)
GENARCH_SOURCES += \
genarch/src/mm/page_pt.c \
genarch/src/mm/as_pt.c
endif
ifeq ($(CONFIG_PAGE_HT),y)
GENARCH_SOURCES += \
genarch/src/mm/page_ht.c \
genarch/src/mm/as_ht.c
endif
ifeq ($(CONFIG_ASID),y)
GENARCH_SOURCES += \
genarch/src/mm/asid.c
endif
ifeq ($(CONFIG_ASID_FIFO),y)
GENARCH_SOURCES += \
genarch/src/mm/asid_fifo.c
endif
ifeq ($(CONFIG_SOFTINT),y)
GENARCH_SOURCES += \
genarch/src/softint/division.c
endif
 
## Framebuffer
ifeq ($(CONFIG_FB),y)
GENARCH_SOURCES += \
genarch/src/fb/font-8x16.c \
genarch/src/fb/fb.c
DEFS += -DCONFIG_FB
endif
 
## i8042 controller
ifeq ($(CONFIG_I8042),y)
GENARCH_SOURCES += \
genarch/src/i8042/i8042.c
endif
/tags/0.2.0.3/kernel/genarch/src/fb/fb.c
0,0 → 1,423
/*
* Copyright (C) 2006 Ondrej Palkovsky
* 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 genarch
* @{
*/
/** @file
*/
 
#include <genarch/fb/font-8x16.h>
#include <genarch/fb/fb.h>
#include <console/chardev.h>
#include <console/console.h>
#include <sysinfo/sysinfo.h>
#include <mm/slab.h>
#include <align.h>
#include <panic.h>
#include <memstr.h>
#include <config.h>
#include <bitops.h>
#include <print.h>
 
#include "helenos.xbm"
 
SPINLOCK_INITIALIZE(fb_lock);
 
static uint8_t *fbaddress = NULL;
 
static uint8_t *blankline = NULL;
static uint8_t *dbbuffer = NULL; /* Buffer for fast scrolling console */
static int dboffset;
 
static unsigned int xres = 0;
static unsigned int yres = 0;
static unsigned int scanline = 0;
static unsigned int bitspp = 0;
static unsigned int pixelbytes = 0;
 
static unsigned int position = 0;
static unsigned int columns = 0;
static unsigned int rows = 0;
 
 
#define COL_WIDTH 8
#define ROW_BYTES (scanline * FONT_SCANLINES)
 
#define BGCOLOR 0x000080
#define FGCOLOR 0xffff00
#define LOGOCOLOR 0x2020b0
 
#define RED(x, bits) ((x >> (16 + 8 - bits)) & ((1 << bits) - 1))
#define GREEN(x, bits) ((x >> (8 + 8 - bits)) & ((1 << bits) - 1))
#define BLUE(x, bits) ((x >> (8 - bits)) & ((1 << bits) - 1))
 
#define POINTPOS(x, y) ((y) * scanline + (x) * pixelbytes)
 
/***************************************************************/
/* Pixel specific fuctions */
 
static void (*rgb2scr)(void *, int);
static int (*scr2rgb)(void *);
 
/* Conversion routines between different color representations */
static void rgb_4byte(void *dst, int rgb)
{
*(int *)dst = rgb;
}
 
static int byte4_rgb(void *src)
{
return (*(int *)src) & 0xffffff;
}
 
static void rgb_3byte(void *dst, int rgb)
{
uint8_t *scr = dst;
#if (defined(BIG_ENDIAN) || defined(FB_BIG_ENDIAN))
scr[0] = RED(rgb, 8);
scr[1] = GREEN(rgb, 8);
scr[2] = BLUE(rgb, 8);
#else
scr[2] = RED(rgb, 8);
scr[1] = GREEN(rgb, 8);
scr[0] = BLUE(rgb, 8);
#endif
}
 
static int byte3_rgb(void *src)
{
uint8_t *scr = src;
#if (defined(BIG_ENDIAN) || defined(FB_BIG_ENDIAN))
return scr[0] << 16 | scr[1] << 8 | scr[2];
#else
return scr[2] << 16 | scr[1] << 8 | scr[0];
#endif
}
 
/** 16-bit depth (5:6:5) */
static void rgb_2byte(void *dst, int rgb)
{
/* 5-bit, 6-bits, 5-bits */
*((uint16_t *)(dst)) = RED(rgb, 5) << 11 | GREEN(rgb, 6) << 5 | BLUE(rgb, 5);
}
 
/** 16-bit depth (5:6:5) */
static int byte2_rgb(void *src)
{
int color = *(uint16_t *)(src);
return (((color >> 11) & 0x1f) << (16 + 3)) | (((color >> 5) & 0x3f) << (8 + 2)) | ((color & 0x1f) << 3);
}
 
/** Put pixel - 8-bit depth (3:2:3) */
static void rgb_1byte(void *dst, int rgb)
{
*(uint8_t *)dst = RED(rgb, 3) << 5 | GREEN(rgb, 2) << 3 | BLUE(rgb, 3);
}
 
/** Return pixel color - 8-bit depth (3:2:3) */
static int byte1_rgb(void *src)
{
int color = *(uint8_t *)src;
return (((color >> 5) & 0x7) << (16 + 5)) | (((color >> 3) & 0x3) << (8 + 6)) | ((color & 0x7) << 5);
}
 
static void putpixel(unsigned int x, unsigned int y, int color)
{
(*rgb2scr)(&fbaddress[POINTPOS(x,y)],color);
 
if (dbbuffer) {
int dline = (y + dboffset) % yres;
(*rgb2scr)(&dbbuffer[POINTPOS(x,dline)],color);
}
}
 
/** Get pixel from viewport */
static int getpixel(unsigned int x, unsigned int y)
{
if (dbbuffer) {
int dline = (y + dboffset) % yres;
return (*scr2rgb)(&dbbuffer[POINTPOS(x,dline)]);
}
return (*scr2rgb)(&fbaddress[POINTPOS(x,y)]);
}
 
 
/** Fill screen with background color */
static void clear_screen(void)
{
unsigned int y;
 
for (y = 0; y < yres; y++) {
memcpy(&fbaddress[scanline*y], blankline, xres*pixelbytes);
if (dbbuffer)
memcpy(&dbbuffer[scanline*y], blankline, xres*pixelbytes);
}
}
 
 
/** Scroll screen one row up */
static void scroll_screen(void)
{
uint8_t *lastline = &fbaddress[(rows - 1) * ROW_BYTES];
int firstsz;
 
if (dbbuffer) {
memcpy(&dbbuffer[dboffset*scanline], blankline, FONT_SCANLINES*scanline);
dboffset = (dboffset + FONT_SCANLINES) % yres;
firstsz = yres-dboffset;
 
memcpy(fbaddress, &dbbuffer[scanline*dboffset], firstsz*scanline);
memcpy(&fbaddress[firstsz*scanline], dbbuffer, dboffset*scanline);
} else {
memcpy((void *) fbaddress, (void *) &fbaddress[ROW_BYTES], scanline * yres - ROW_BYTES);
/* Clear last row */
memcpy((void *) lastline, (void *) blankline, ROW_BYTES);
}
}
 
 
static void invert_pixel(unsigned int x, unsigned int y)
{
putpixel(x, y, ~getpixel(x, y));
}
 
 
/** Draw one line of glyph at a given position */
static void draw_glyph_line(unsigned int glline, unsigned int x, unsigned int y)
{
unsigned int i;
 
for (i = 0; i < 8; i++)
if (glline & (1 << (7 - i))) {
putpixel(x + i, y, FGCOLOR);
} else
putpixel(x + i, y, BGCOLOR);
}
 
/***************************************************************/
/* Character-console functions */
 
/** Draw character at given position */
static void draw_glyph(uint8_t glyph, unsigned int col, unsigned int row)
{
unsigned int y;
 
for (y = 0; y < FONT_SCANLINES; y++)
draw_glyph_line(fb_font[glyph * FONT_SCANLINES + y], col * COL_WIDTH, row * FONT_SCANLINES + y);
}
 
/** Invert character at given position */
static void invert_char(unsigned int col, unsigned int row)
{
unsigned int x;
unsigned int y;
 
for (x = 0; x < COL_WIDTH; x++)
for (y = 0; y < FONT_SCANLINES; y++)
invert_pixel(col * COL_WIDTH + x, row * FONT_SCANLINES + y);
}
 
/** Draw character at default position */
static void draw_char(char chr)
{
draw_glyph(chr, position % columns, position / columns);
}
 
static void draw_logo(unsigned int startx, unsigned int starty)
{
unsigned int x;
unsigned int y;
unsigned int byte;
unsigned int rowbytes;
 
rowbytes = (helenos_width - 1) / 8 + 1;
 
for (y = 0; y < helenos_height; y++)
for (x = 0; x < helenos_width; x++) {
byte = helenos_bits[rowbytes * y + x / 8];
byte >>= x % 8;
if (byte & 1)
putpixel(startx + x, starty + y, LOGOCOLOR);
}
}
 
/***************************************************************/
/* Stdout specific functions */
 
static void invert_cursor(void)
{
invert_char(position % columns, position / columns);
}
 
/** Print character to screen
*
* Emulate basic terminal commands
*/
static void fb_putchar(chardev_t *dev, char ch)
{
spinlock_lock(&fb_lock);
switch (ch) {
case '\n':
invert_cursor();
position += columns;
position -= position % columns;
break;
case '\r':
invert_cursor();
position -= position % columns;
break;
case '\b':
invert_cursor();
if (position % columns)
position--;
break;
case '\t':
invert_cursor();
do {
draw_char(' ');
position++;
} while ((position % 8) && position < columns * rows);
break;
default:
draw_char(ch);
position++;
}
if (position >= columns * rows) {
position -= columns;
scroll_screen();
}
invert_cursor();
spinlock_unlock(&fb_lock);
}
 
static chardev_t framebuffer;
static chardev_operations_t fb_ops = {
.write = fb_putchar,
};
 
 
/** Initialize framebuffer as a chardev output device
*
* @param addr Physical address of the framebuffer
* @param x Screen width in pixels
* @param y Screen height in pixels
* @param bpp Bits per pixel (8, 16, 24, 32)
* @param scan Bytes per one scanline
*
*/
void fb_init(uintptr_t addr, unsigned int x, unsigned int y, unsigned int bpp, unsigned int scan)
{
switch (bpp) {
case 8:
rgb2scr = rgb_1byte;
scr2rgb = byte1_rgb;
pixelbytes = 1;
break;
case 16:
rgb2scr = rgb_2byte;
scr2rgb = byte2_rgb;
pixelbytes = 2;
break;
case 24:
rgb2scr = rgb_3byte;
scr2rgb = byte3_rgb;
pixelbytes = 3;
break;
case 32:
rgb2scr = rgb_4byte;
scr2rgb = byte4_rgb;
pixelbytes = 4;
break;
default:
panic("Unsupported bpp");
}
unsigned int fbsize = scan * y;
/* Map the framebuffer */
fbaddress = (uint8_t *) hw_map((uintptr_t) addr, fbsize);
xres = x;
yres = y;
bitspp = bpp;
scanline = scan;
rows = y / FONT_SCANLINES;
columns = x / COL_WIDTH;
 
sysinfo_set_item_val("fb", NULL, true);
sysinfo_set_item_val("fb.kind", NULL, 1);
sysinfo_set_item_val("fb.width", NULL, xres);
sysinfo_set_item_val("fb.height", NULL, yres);
sysinfo_set_item_val("fb.bpp", NULL, bpp);
sysinfo_set_item_val("fb.scanline", NULL, scan);
sysinfo_set_item_val("fb.address.physical", NULL, addr);
 
/* Allocate double buffer */
int totsize = scanline * yres;
int pages = SIZE2FRAMES(totsize);
int order;
if (pages == 1)
order = 0;
else
order = fnzb(pages-1)+1;
 
dbbuffer = frame_alloc(order,FRAME_ATOMIC | FRAME_KA);
if (!dbbuffer)
printf("Failed to allocate scroll buffer.\n");
dboffset = 0;
 
/* Initialized blank line */
blankline = (uint8_t *) malloc(ROW_BYTES, FRAME_ATOMIC);
if (!blankline)
panic("Failed to allocate blank line for framebuffer.");
for (y=0; y < FONT_SCANLINES; y++)
for (x=0; x < xres; x++)
(*rgb2scr)(&blankline[POINTPOS(x,y)],BGCOLOR);
 
clear_screen();
 
/* Update size of screen to match text area */
yres = rows * FONT_SCANLINES;
 
draw_logo(xres - helenos_width, 0);
invert_cursor();
 
chardev_initialize("fb", &framebuffer, &fb_ops);
stdout = &framebuffer;
}
 
/** @}
*/
/tags/0.2.0.3/kernel/genarch/src/fb/font-8x16.c
0,0 → 1,4651
/*
* Copyright (C) 2005 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 genarch
* @{
*/
/** @file
*/
 
#include <genarch/fb/font-8x16.h>
 
unsigned char fb_font[FONT_GLIPHS * FONT_SCANLINES] = {
 
/* 0 0x00 '^@' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 1 0x01 '^A' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x81, /* 10000001 */
0xa5, /* 10100101 */
0x81, /* 10000001 */
0x81, /* 10000001 */
0xbd, /* 10111101 */
0x99, /* 10011001 */
0x81, /* 10000001 */
0x81, /* 10000001 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 2 0x02 '^B' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0xff, /* 11111111 */
0xdb, /* 11011011 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xc3, /* 11000011 */
0xe7, /* 11100111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 3 0x03 '^C' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x6c, /* 01101100 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0x7c, /* 01111100 */
0x38, /* 00111000 */
0x10, /* 00010000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 4 0x04 '^D' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x7c, /* 01111100 */
0xfe, /* 11111110 */
0x7c, /* 01111100 */
0x38, /* 00111000 */
0x10, /* 00010000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 5 0x05 '^E' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x3c, /* 00111100 */
0xe7, /* 11100111 */
0xe7, /* 11100111 */
0xe7, /* 11100111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 6 0x06 '^F' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x7e, /* 01111110 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 7 0x07 '^G' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 8 0x08 '^H' */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xe7, /* 11100111 */
0xc3, /* 11000011 */
0xc3, /* 11000011 */
0xe7, /* 11100111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
 
/* 9 0x09 '^I' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0x42, /* 01000010 */
0x42, /* 01000010 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 10 0x0a '^J' */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xc3, /* 11000011 */
0x99, /* 10011001 */
0xbd, /* 10111101 */
0xbd, /* 10111101 */
0x99, /* 10011001 */
0xc3, /* 11000011 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
 
/* 11 0x0b '^K' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1e, /* 00011110 */
0x0e, /* 00001110 */
0x1a, /* 00011010 */
0x32, /* 00110010 */
0x78, /* 01111000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x78, /* 01111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 12 0x0c '^L' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 13 0x0d '^M' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3f, /* 00111111 */
0x33, /* 00110011 */
0x3f, /* 00111111 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x70, /* 01110000 */
0xf0, /* 11110000 */
0xe0, /* 11100000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 14 0x0e '^N' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7f, /* 01111111 */
0x63, /* 01100011 */
0x7f, /* 01111111 */
0x63, /* 01100011 */
0x63, /* 01100011 */
0x63, /* 01100011 */
0x63, /* 01100011 */
0x67, /* 01100111 */
0xe7, /* 11100111 */
0xe6, /* 11100110 */
0xc0, /* 11000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 15 0x0f '^O' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xdb, /* 11011011 */
0x3c, /* 00111100 */
0xe7, /* 11100111 */
0x3c, /* 00111100 */
0xdb, /* 11011011 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 16 0x10 '^P' */
0x00, /* 00000000 */
0x80, /* 10000000 */
0xc0, /* 11000000 */
0xe0, /* 11100000 */
0xf0, /* 11110000 */
0xf8, /* 11111000 */
0xfe, /* 11111110 */
0xf8, /* 11111000 */
0xf0, /* 11110000 */
0xe0, /* 11100000 */
0xc0, /* 11000000 */
0x80, /* 10000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 17 0x11 '^Q' */
0x00, /* 00000000 */
0x02, /* 00000010 */
0x06, /* 00000110 */
0x0e, /* 00001110 */
0x1e, /* 00011110 */
0x3e, /* 00111110 */
0xfe, /* 11111110 */
0x3e, /* 00111110 */
0x1e, /* 00011110 */
0x0e, /* 00001110 */
0x06, /* 00000110 */
0x02, /* 00000010 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 18 0x12 '^R' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 19 0x13 '^S' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 20 0x14 '^T' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7f, /* 01111111 */
0xdb, /* 11011011 */
0xdb, /* 11011011 */
0xdb, /* 11011011 */
0x7b, /* 01111011 */
0x1b, /* 00011011 */
0x1b, /* 00011011 */
0x1b, /* 00011011 */
0x1b, /* 00011011 */
0x1b, /* 00011011 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 21 0x15 '^U' */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0x60, /* 01100000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x0c, /* 00001100 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 22 0x16 '^V' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 23 0x17 '^W' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 24 0x18 '^X' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 25 0x19 '^Y' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 26 0x1a '^Z' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0xfe, /* 11111110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 27 0x1b '^[' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xfe, /* 11111110 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 28 0x1c '^\' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 29 0x1d '^]' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x28, /* 00101000 */
0x6c, /* 01101100 */
0xfe, /* 11111110 */
0x6c, /* 01101100 */
0x28, /* 00101000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 30 0x1e '^^' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x38, /* 00111000 */
0x7c, /* 01111100 */
0x7c, /* 01111100 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 31 0x1f '^_' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0x7c, /* 01111100 */
0x7c, /* 01111100 */
0x38, /* 00111000 */
0x38, /* 00111000 */
0x10, /* 00010000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 32 0x20 ' ' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 33 0x21 '!' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x3c, /* 00111100 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 34 0x22 '"' */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x24, /* 00100100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 35 0x23 '#' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0xfe, /* 11111110 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0xfe, /* 11111110 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 36 0x24 '$' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc2, /* 11000010 */
0xc0, /* 11000000 */
0x7c, /* 01111100 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x86, /* 10000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 37 0x25 '%' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc2, /* 11000010 */
0xc6, /* 11000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xc6, /* 11000110 */
0x86, /* 10000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 38 0x26 '&' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 39 0x27 ''' */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 40 0x28 '(' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 41 0x29 ')' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 42 0x2a '*' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0xff, /* 11111111 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 43 0x2b '+' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 44 0x2c ',' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 45 0x2d '-' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 46 0x2e '.' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 47 0x2f '/' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x02, /* 00000010 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xc0, /* 11000000 */
0x80, /* 10000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 48 0x30 '0' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 49 0x31 '1' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x38, /* 00111000 */
0x78, /* 01111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 50 0x32 '2' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 51 0x33 '3' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x3c, /* 00111100 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 52 0x34 '4' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x0c, /* 00001100 */
0x1c, /* 00011100 */
0x3c, /* 00111100 */
0x6c, /* 01101100 */
0xcc, /* 11001100 */
0xfe, /* 11111110 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x1e, /* 00011110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 53 0x35 '5' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xfc, /* 11111100 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 54 0x36 '6' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x60, /* 01100000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xfc, /* 11111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 55 0x37 '7' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 56 0x38 '8' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 57 0x39 '9' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7e, /* 01111110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x78, /* 01111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 58 0x3a ':' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 59 0x3b ';' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 60 0x3c '<' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x06, /* 00000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 61 0x3d '=' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 62 0x3e '>' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 63 0x3f '?' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 64 0x40 '@' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xde, /* 11011110 */
0xde, /* 11011110 */
0xde, /* 11011110 */
0xdc, /* 11011100 */
0xc0, /* 11000000 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 65 0x41 'A' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 66 0x42 'B' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfc, /* 11111100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x7c, /* 01111100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0xfc, /* 11111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 67 0x43 'C' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0xc2, /* 11000010 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc2, /* 11000010 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 68 0x44 'D' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xf8, /* 11111000 */
0x6c, /* 01101100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x6c, /* 01101100 */
0xf8, /* 11111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 69 0x45 'E' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x66, /* 01100110 */
0x62, /* 01100010 */
0x68, /* 01101000 */
0x78, /* 01111000 */
0x68, /* 01101000 */
0x60, /* 01100000 */
0x62, /* 01100010 */
0x66, /* 01100110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 70 0x46 'F' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x66, /* 01100110 */
0x62, /* 01100010 */
0x68, /* 01101000 */
0x78, /* 01111000 */
0x68, /* 01101000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0xf0, /* 11110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 71 0x47 'G' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0xc2, /* 11000010 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xde, /* 11011110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x66, /* 01100110 */
0x3a, /* 00111010 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 72 0x48 'H' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 73 0x49 'I' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 74 0x4a 'J' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1e, /* 00011110 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x78, /* 01111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 75 0x4b 'K' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xe6, /* 11100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x6c, /* 01101100 */
0x78, /* 01111000 */
0x78, /* 01111000 */
0x6c, /* 01101100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0xe6, /* 11100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 76 0x4c 'L' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xf0, /* 11110000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x62, /* 01100010 */
0x66, /* 01100110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 77 0x4d 'M' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xee, /* 11101110 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0xd6, /* 11010110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 78 0x4e 'N' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xe6, /* 11100110 */
0xf6, /* 11110110 */
0xfe, /* 11111110 */
0xde, /* 11011110 */
0xce, /* 11001110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 79 0x4f 'O' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 80 0x50 'P' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfc, /* 11111100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x7c, /* 01111100 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0xf0, /* 11110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 81 0x51 'Q' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xd6, /* 11010110 */
0xde, /* 11011110 */
0x7c, /* 01111100 */
0x0c, /* 00001100 */
0x0e, /* 00001110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 82 0x52 'R' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfc, /* 11111100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x7c, /* 01111100 */
0x6c, /* 01101100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0xe6, /* 11100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 83 0x53 'S' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x60, /* 01100000 */
0x38, /* 00111000 */
0x0c, /* 00001100 */
0x06, /* 00000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 84 0x54 'T' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x7e, /* 01111110 */
0x5a, /* 01011010 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 85 0x55 'U' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 86 0x56 'V' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x10, /* 00010000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 87 0x57 'W' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xfe, /* 11111110 */
0xee, /* 11101110 */
0x6c, /* 01101100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 88 0x58 'X' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x7c, /* 01111100 */
0x38, /* 00111000 */
0x38, /* 00111000 */
0x7c, /* 01111100 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 89 0x59 'Y' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 90 0x5a 'Z' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0x86, /* 10000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xc2, /* 11000010 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 91 0x5b '[' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 92 0x5c '\' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x80, /* 10000000 */
0xc0, /* 11000000 */
0xe0, /* 11100000 */
0x70, /* 01110000 */
0x38, /* 00111000 */
0x1c, /* 00011100 */
0x0e, /* 00001110 */
0x06, /* 00000110 */
0x02, /* 00000010 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 93 0x5d ']' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 94 0x5e '^' */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 95 0x5f '_' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 96 0x60 '`' */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 97 0x61 'a' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x78, /* 01111000 */
0x0c, /* 00001100 */
0x7c, /* 01111100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 98 0x62 'b' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xe0, /* 11100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x78, /* 01111000 */
0x6c, /* 01101100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 99 0x63 'c' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 100 0x64 'd' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1c, /* 00011100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x3c, /* 00111100 */
0x6c, /* 01101100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 101 0x65 'e' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 102 0x66 'f' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1c, /* 00011100 */
0x36, /* 00110110 */
0x32, /* 00110010 */
0x30, /* 00110000 */
0x78, /* 01111000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x78, /* 01111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 103 0x67 'g' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x7c, /* 01111100 */
0x0c, /* 00001100 */
0xcc, /* 11001100 */
0x78, /* 01111000 */
0x00, /* 00000000 */
 
/* 104 0x68 'h' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xe0, /* 11100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x6c, /* 01101100 */
0x76, /* 01110110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0xe6, /* 11100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 105 0x69 'i' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 106 0x6a 'j' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x00, /* 00000000 */
0x0e, /* 00001110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
 
/* 107 0x6b 'k' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xe0, /* 11100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x66, /* 01100110 */
0x6c, /* 01101100 */
0x78, /* 01111000 */
0x78, /* 01111000 */
0x6c, /* 01101100 */
0x66, /* 01100110 */
0xe6, /* 11100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 108 0x6c 'l' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 109 0x6d 'm' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xec, /* 11101100 */
0xfe, /* 11111110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 110 0x6e 'n' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xdc, /* 11011100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 111 0x6f 'o' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 112 0x70 'p' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xdc, /* 11011100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x7c, /* 01111100 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0xf0, /* 11110000 */
0x00, /* 00000000 */
 
/* 113 0x71 'q' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x7c, /* 01111100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x1e, /* 00011110 */
0x00, /* 00000000 */
 
/* 114 0x72 'r' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xdc, /* 11011100 */
0x76, /* 01110110 */
0x66, /* 01100110 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0xf0, /* 11110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 115 0x73 's' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0x60, /* 01100000 */
0x38, /* 00111000 */
0x0c, /* 00001100 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 116 0x74 't' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0xfc, /* 11111100 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x36, /* 00110110 */
0x1c, /* 00011100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 117 0x75 'u' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 118 0x76 'v' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 119 0x77 'w' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xfe, /* 11111110 */
0x6c, /* 01101100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 120 0x78 'x' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x38, /* 00111000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 121 0x79 'y' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7e, /* 01111110 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0xf8, /* 11111000 */
0x00, /* 00000000 */
 
/* 122 0x7a 'z' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xcc, /* 11001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 123 0x7b '{' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x0e, /* 00001110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x70, /* 01110000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x0e, /* 00001110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 124 0x7c '|' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 125 0x7d '}' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x70, /* 01110000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x0e, /* 00001110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x70, /* 01110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 126 0x7e '~' */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 127 0x7f '' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 128 0x80 '€' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0xc2, /* 11000010 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc2, /* 11000010 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x70, /* 01110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 129 0x81 '' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xcc, /* 11001100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 130 0x82 '‚' */
0x00, /* 00000000 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 131 0x83 'ƒ' */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x00, /* 00000000 */
0x78, /* 01111000 */
0x0c, /* 00001100 */
0x7c, /* 01111100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 132 0x84 '„' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xcc, /* 11001100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x78, /* 01111000 */
0x0c, /* 00001100 */
0x7c, /* 01111100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 133 0x85 '…' */
0x00, /* 00000000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x78, /* 01111000 */
0x0c, /* 00001100 */
0x7c, /* 01111100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 134 0x86 '†' */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x00, /* 00000000 */
0x78, /* 01111000 */
0x0c, /* 00001100 */
0x7c, /* 01111100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 135 0x87 '‡' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x18, /* 00011000 */
0x70, /* 01110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 136 0x88 'ˆ' */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 137 0x89 '‰' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 138 0x8a 'Š' */
0x00, /* 00000000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 139 0x8b '‹' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 140 0x8c 'Œ' */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 141 0x8d '' */
0x00, /* 00000000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 142 0x8e 'Ž' */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 143 0x8f '' */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 144 0x90 '' */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x66, /* 01100110 */
0x62, /* 01100010 */
0x68, /* 01101000 */
0x78, /* 01111000 */
0x68, /* 01101000 */
0x62, /* 01100010 */
0x66, /* 01100110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 145 0x91 '‘' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xec, /* 11101100 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x7e, /* 01111110 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0x6e, /* 01101110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 146 0x92 '’' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3e, /* 00111110 */
0x6c, /* 01101100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xfe, /* 11111110 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xce, /* 11001110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 147 0x93 '“' */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 148 0x94 '”' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 149 0x95 '•' */
0x00, /* 00000000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 150 0x96 '–' */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x78, /* 01111000 */
0xcc, /* 11001100 */
0x00, /* 00000000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 151 0x97 '—' */
0x00, /* 00000000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 152 0x98 '˜' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7e, /* 01111110 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x78, /* 01111000 */
0x00, /* 00000000 */
 
/* 153 0x99 '™' */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 154 0x9a 'š' */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 155 0x9b '›' */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 156 0x9c 'œ' */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x64, /* 01100100 */
0x60, /* 01100000 */
0xf0, /* 11110000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0xe6, /* 11100110 */
0xfc, /* 11111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 157 0x9d '' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 158 0x9e 'ž' */
0x00, /* 00000000 */
0xf8, /* 11111000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xf8, /* 11111000 */
0xc4, /* 11000100 */
0xcc, /* 11001100 */
0xde, /* 11011110 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 159 0x9f 'Ÿ' */
0x00, /* 00000000 */
0x0e, /* 00001110 */
0x1b, /* 00011011 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xd8, /* 11011000 */
0x70, /* 01110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 160 0xa0 ' ' */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x00, /* 00000000 */
0x78, /* 01111000 */
0x0c, /* 00001100 */
0x7c, /* 01111100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 161 0xa1 '¡' */
0x00, /* 00000000 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 162 0xa2 '¢' */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 163 0xa3 '£' */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x00, /* 00000000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 164 0xa4 '¤' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0x00, /* 00000000 */
0xdc, /* 11011100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 165 0xa5 '¥' */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xe6, /* 11100110 */
0xf6, /* 11110110 */
0xfe, /* 11111110 */
0xde, /* 11011110 */
0xce, /* 11001110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 166 0xa6 '¦' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x3e, /* 00111110 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 167 0xa7 '§' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 168 0xa8 '¨' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 169 0xa9 '©' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 170 0xaa 'ª' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 171 0xab '«' */
0x00, /* 00000000 */
0x60, /* 01100000 */
0xe0, /* 11100000 */
0x62, /* 01100010 */
0x66, /* 01100110 */
0x6c, /* 01101100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xdc, /* 11011100 */
0x86, /* 10000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x3e, /* 00111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 172 0xac '¬' */
0x00, /* 00000000 */
0x60, /* 01100000 */
0xe0, /* 11100000 */
0x62, /* 01100010 */
0x66, /* 01100110 */
0x6c, /* 01101100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x66, /* 01100110 */
0xce, /* 11001110 */
0x9a, /* 10011010 */
0x3f, /* 00111111 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 173 0xad '­' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x3c, /* 00111100 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 174 0xae '®' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x36, /* 00110110 */
0x6c, /* 01101100 */
0xd8, /* 11011000 */
0x6c, /* 01101100 */
0x36, /* 00110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 175 0xaf '¯' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xd8, /* 11011000 */
0x6c, /* 01101100 */
0x36, /* 00110110 */
0x6c, /* 01101100 */
0xd8, /* 11011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 176 0xb0 '°' */
0x11, /* 00010001 */
0x44, /* 01000100 */
0x11, /* 00010001 */
0x44, /* 01000100 */
0x11, /* 00010001 */
0x44, /* 01000100 */
0x11, /* 00010001 */
0x44, /* 01000100 */
0x11, /* 00010001 */
0x44, /* 01000100 */
0x11, /* 00010001 */
0x44, /* 01000100 */
0x11, /* 00010001 */
0x44, /* 01000100 */
0x11, /* 00010001 */
0x44, /* 01000100 */
 
/* 177 0xb1 '±' */
0x55, /* 01010101 */
0xaa, /* 10101010 */
0x55, /* 01010101 */
0xaa, /* 10101010 */
0x55, /* 01010101 */
0xaa, /* 10101010 */
0x55, /* 01010101 */
0xaa, /* 10101010 */
0x55, /* 01010101 */
0xaa, /* 10101010 */
0x55, /* 01010101 */
0xaa, /* 10101010 */
0x55, /* 01010101 */
0xaa, /* 10101010 */
0x55, /* 01010101 */
0xaa, /* 10101010 */
 
/* 178 0xb2 '²' */
0xdd, /* 11011101 */
0x77, /* 01110111 */
0xdd, /* 11011101 */
0x77, /* 01110111 */
0xdd, /* 11011101 */
0x77, /* 01110111 */
0xdd, /* 11011101 */
0x77, /* 01110111 */
0xdd, /* 11011101 */
0x77, /* 01110111 */
0xdd, /* 11011101 */
0x77, /* 01110111 */
0xdd, /* 11011101 */
0x77, /* 01110111 */
0xdd, /* 11011101 */
0x77, /* 01110111 */
 
/* 179 0xb3 '³' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 180 0xb4 '´' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xf8, /* 11111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 181 0xb5 'µ' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xf8, /* 11111000 */
0x18, /* 00011000 */
0xf8, /* 11111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 182 0xb6 '¶' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xf6, /* 11110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 183 0xb7 '·' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 184 0xb8 '¸' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xf8, /* 11111000 */
0x18, /* 00011000 */
0xf8, /* 11111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 185 0xb9 '¹' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xf6, /* 11110110 */
0x06, /* 00000110 */
0xf6, /* 11110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 186 0xba 'º' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 187 0xbb '»' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x06, /* 00000110 */
0xf6, /* 11110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 188 0xbc '¼' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xf6, /* 11110110 */
0x06, /* 00000110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 189 0xbd '½' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 190 0xbe '¾' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xf8, /* 11111000 */
0x18, /* 00011000 */
0xf8, /* 11111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 191 0xbf '¿' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xf8, /* 11111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 192 0xc0 'À' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x1f, /* 00011111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 193 0xc1 'Á' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 194 0xc2 'Â' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 195 0xc3 'Ã' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x1f, /* 00011111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 196 0xc4 'Ä' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 197 0xc5 'Å' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xff, /* 11111111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 198 0xc6 'Æ' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x1f, /* 00011111 */
0x18, /* 00011000 */
0x1f, /* 00011111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 199 0xc7 'Ç' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x37, /* 00110111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 200 0xc8 'È' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x37, /* 00110111 */
0x30, /* 00110000 */
0x3f, /* 00111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 201 0xc9 'É' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3f, /* 00111111 */
0x30, /* 00110000 */
0x37, /* 00110111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 202 0xca 'Ê' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xf7, /* 11110111 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 203 0xcb 'Ë' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0xf7, /* 11110111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 204 0xcc 'Ì' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x37, /* 00110111 */
0x30, /* 00110000 */
0x37, /* 00110111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 205 0xcd 'Í' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 206 0xce 'Î' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xf7, /* 11110111 */
0x00, /* 00000000 */
0xf7, /* 11110111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 207 0xcf 'Ï' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 208 0xd0 'Ð' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 209 0xd1 'Ñ' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 210 0xd2 'Ò' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 211 0xd3 'Ó' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x3f, /* 00111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 212 0xd4 'Ô' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x1f, /* 00011111 */
0x18, /* 00011000 */
0x1f, /* 00011111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 213 0xd5 'Õ' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1f, /* 00011111 */
0x18, /* 00011000 */
0x1f, /* 00011111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 214 0xd6 'Ö' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3f, /* 00111111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 215 0xd7 '×' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xff, /* 11111111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 216 0xd8 'Ø' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xff, /* 11111111 */
0x18, /* 00011000 */
0xff, /* 11111111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 217 0xd9 'Ù' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xf8, /* 11111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 218 0xda 'Ú' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1f, /* 00011111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 219 0xdb 'Û' */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
 
/* 220 0xdc 'Ü' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
 
/* 221 0xdd 'Ý' */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
 
/* 222 0xde 'Þ' */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
 
/* 223 0xdf 'ß' */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 224 0xe0 'à' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0xdc, /* 11011100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 225 0xe1 'á' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x78, /* 01111000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xd8, /* 11011000 */
0xcc, /* 11001100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xcc, /* 11001100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 226 0xe2 'â' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 227 0xe3 'ã' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 228 0xe4 'ä' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 229 0xe5 'å' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0x70, /* 01110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 230 0xe6 'æ' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x7c, /* 01111100 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0xc0, /* 11000000 */
0x00, /* 00000000 */
 
/* 231 0xe7 'ç' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 232 0xe8 'è' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 233 0xe9 'é' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 234 0xea 'ê' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0xee, /* 11101110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 235 0xeb 'ë' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1e, /* 00011110 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x3e, /* 00111110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 236 0xec 'ì' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0xdb, /* 11011011 */
0xdb, /* 11011011 */
0xdb, /* 11011011 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 237 0xed 'í' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x03, /* 00000011 */
0x06, /* 00000110 */
0x7e, /* 01111110 */
0xdb, /* 11011011 */
0xdb, /* 11011011 */
0xf3, /* 11110011 */
0x7e, /* 01111110 */
0x60, /* 01100000 */
0xc0, /* 11000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 238 0xee 'î' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1c, /* 00011100 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x7c, /* 01111100 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x1c, /* 00011100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 239 0xef 'ï' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 240 0xf0 'ð' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 241 0xf1 'ñ' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 242 0xf2 'ò' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 243 0xf3 'ó' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 244 0xf4 'ô' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x0e, /* 00001110 */
0x1b, /* 00011011 */
0x1b, /* 00011011 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 245 0xf5 'õ' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0x70, /* 01110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 246 0xf6 'ö' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 247 0xf7 '÷' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 248 0xf8 'ø' */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 249 0xf9 'ù' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 250 0xfa 'ú' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 251 0xfb 'û' */
0x00, /* 00000000 */
0x0f, /* 00001111 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0xec, /* 11101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x3c, /* 00111100 */
0x1c, /* 00011100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 252 0xfc 'ü' */
0x00, /* 00000000 */
0x6c, /* 01101100 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 253 0xfd 'ý' */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x32, /* 00110010 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 254 0xfe 'þ' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x7e, /* 01111110 */
0x7e, /* 01111110 */
0x7e, /* 01111110 */
0x7e, /* 01111110 */
0x7e, /* 01111110 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 255 0xff 'ÿ' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
};
 
/** @}
*/
 
/tags/0.2.0.3/kernel/genarch/src/fb/helenos.xbm
0,0 → 1,163
#define helenos_width 127
#define helenos_height 120
static unsigned char helenos_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x1f, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x0f, 0x78, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x80, 0x81,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x0f, 0x00, 0x00, 0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x06,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07,
0x00, 0x00, 0x00, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x0c,
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00,
0x00, 0x00, 0x00, 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00,
0x00, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00,
0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xc0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00,
0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x80, 0xc1, 0x00, 0x00, 0x00,
0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x80,
0xc1, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xfe, 0x01, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0x83, 0x01, 0x00, 0x00,
0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00,
0x03, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0x07, 0x00, 0x00, 0x06, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x06, 0x03, 0x00, 0x00,
0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00,
0x0c, 0x02, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0x0f, 0x00, 0x00, 0x0c, 0x06, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0x00, 0x18, 0x04, 0x00, 0x00,
0x08, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00,
0x18, 0x0c, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
0xfc, 0x1f, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00,
0x80, 0x1f, 0x00, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00,
0x18, 0x02, 0x00, 0x00, 0xc0, 0x3f, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x00,
0x30, 0x18, 0x00, 0x00, 0x18, 0x06, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00,
0xf8, 0x3f, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x18, 0x06, 0x00, 0x00,
0xe0, 0x7f, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00,
0x38, 0x0c, 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00,
0xe0, 0x20, 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00,
0xf0, 0x7f, 0x00, 0x00, 0xc0, 0x78, 0x00, 0x00, 0x70, 0x08, 0x00, 0x00,
0xe0, 0xff, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0xc0, 0x7c, 0x00, 0x00,
0x70, 0x18, 0x00, 0x00, 0xe0, 0xff, 0x01, 0x00, 0xf0, 0xff, 0x00, 0x00,
0x80, 0xfd, 0x00, 0x00, 0x60, 0x3f, 0x00, 0x00, 0xc0, 0xff, 0x01, 0x00,
0xfc, 0xff, 0x01, 0x00, 0x80, 0xf9, 0x00, 0x00, 0xe0, 0x3f, 0x00, 0x00,
0xc0, 0xff, 0x01, 0x80, 0xff, 0xff, 0x01, 0x00, 0x80, 0xfb, 0x00, 0x00,
0xc0, 0x7f, 0x00, 0x00, 0xc0, 0xff, 0x03, 0xe0, 0xff, 0xff, 0x03, 0x00,
0x00, 0xf3, 0x01, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0x80, 0xff, 0x03, 0xfc,
0xff, 0xff, 0x03, 0x00, 0x00, 0xf3, 0x01, 0x00, 0xc0, 0x7f, 0x00, 0x00,
0x80, 0xff, 0x07, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0xf6, 0x03, 0x00,
0x80, 0xff, 0x00, 0x00, 0x00, 0xff, 0xe7, 0xff, 0xff, 0xff, 0x07, 0x00,
0x00, 0xe6, 0x03, 0x00, 0x80, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
0xff, 0xff, 0x07, 0x00, 0x00, 0xec, 0x07, 0x00, 0x00, 0xff, 0x01, 0x00,
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xcc, 0x07, 0x00,
0x00, 0xff, 0x01, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x7f, 0xfe, 0x0f, 0x00,
0x00, 0xdc, 0x07, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xfe, 0xff, 0xff,
0x1f, 0xfe, 0x0f, 0x00, 0x00, 0xd8, 0x0f, 0x00, 0x00, 0xfe, 0x03, 0x00,
0x00, 0xfc, 0xff, 0xff, 0x03, 0xfe, 0x1f, 0x00, 0x00, 0x98, 0x0f, 0x00,
0x00, 0xfe, 0x03, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x00, 0xfc, 0x1f, 0x00,
0x00, 0xb0, 0x1f, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0xf8, 0xff, 0x1f,
0x00, 0xfc, 0x3f, 0x00, 0x00, 0x30, 0x1f, 0x00, 0x00, 0xfc, 0x07, 0x00,
0x00, 0xf8, 0xff, 0x07, 0x00, 0xfc, 0x3f, 0x00, 0x00, 0x70, 0x1f, 0x00,
0x00, 0xfc, 0x07, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf8, 0x7f, 0x00,
0x00, 0x60, 0x3e, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xf0, 0x7f, 0x00,
0x00, 0xf8, 0x7f, 0x00, 0x00, 0xe0, 0x3e, 0x00, 0x00, 0xf8, 0x0f, 0x00,
0x00, 0xf0, 0x7f, 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0xf8, 0x7e, 0x00,
0x00, 0xf0, 0x1f, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0xf0, 0xff, 0x00,
0x00, 0xfc, 0x7c, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00, 0xe0, 0xff, 0x00,
0x00, 0xf0, 0xff, 0x00, 0x00, 0xfe, 0xfd, 0x00, 0x00, 0xf0, 0x1f, 0x00,
0x00, 0xe0, 0xff, 0x01, 0x00, 0xe0, 0xff, 0x00, 0x80, 0xff, 0xf9, 0x00,
0x00, 0xe0, 0x3f, 0x00, 0x00, 0xc0, 0xff, 0x01, 0x00, 0xe0, 0xff, 0x00,
0xc0, 0xff, 0xfb, 0x00, 0x00, 0xe0, 0x3f, 0x00, 0x00, 0xc0, 0xff, 0x03,
0x00, 0xc0, 0x7f, 0x00, 0xe0, 0xff, 0xfb, 0x01, 0x00, 0xc0, 0x7f, 0x00,
0x00, 0x80, 0xff, 0x03, 0x00, 0xc0, 0x7f, 0x00, 0xf8, 0xff, 0xf7, 0x01,
0x00, 0xc0, 0x7f, 0x00, 0x00, 0x80, 0xff, 0x03, 0x00, 0x80, 0x3f, 0x00,
0xfc, 0xff, 0xf7, 0x03, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0x80, 0xff, 0x07,
0x00, 0x00, 0x00, 0x00, 0xfe, 0xef, 0xe7, 0x03, 0x00, 0x80, 0xff, 0x00,
0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x80, 0xff, 0xdf, 0xef, 0x07,
0x00, 0x80, 0xff, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0xc0,
0xff, 0xdf, 0xef, 0x07, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xff, 0x0f,
0x00, 0x00, 0x00, 0xe0, 0xff, 0xcf, 0xcf, 0x07, 0x00, 0x00, 0xff, 0x01,
0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0xf0, 0x7f, 0xc3, 0xcf, 0x0f,
0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0xfc,
0xff, 0xe0, 0xcf, 0x0f, 0x00, 0x00, 0xfe, 0x03, 0x00, 0x00, 0xfc, 0x1f,
0x00, 0x00, 0x00, 0xfe, 0xff, 0xf9, 0xc7, 0x0f, 0x00, 0x00, 0xfe, 0x03,
0x00, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xe7, 0x0f,
0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xc0, 0xff,
0xff, 0xff, 0xe7, 0x0f, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0xf8, 0x07,
0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xe3, 0x0f, 0x00, 0x00, 0xfc, 0x0f,
0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xf1, 0x0f,
0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff,
0xff, 0xff, 0xf8, 0x0f, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xfe, 0xff, 0xff, 0x3f, 0xfc, 0x0f, 0x00, 0x00, 0xf0, 0x1f,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x07, 0xfe, 0x0f,
0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff,
0xff, 0x81, 0xff, 0x07, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00,
0x00, 0xe0, 0xff, 0xff, 0x3f, 0xe0, 0xff, 0x07, 0x00, 0x00, 0xe0, 0x3f,
0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x07, 0xfc, 0xff, 0x07,
0x00, 0x00, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff,
0x80, 0xff, 0xff, 0x03, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0x00, 0x00,
0x00, 0xfe, 0xff, 0x1f, 0xf0, 0xff, 0xff, 0x01, 0x00, 0x00, 0xc0, 0x7f,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x07, 0xfe, 0xff, 0xff, 0x00,
0x00, 0x00, 0xc0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xc0,
0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x80, 0xbf, 0x00, 0x00, 0x00, 0x00,
0xe0, 0xff, 0x1f, 0xf0, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x80, 0xdf,
0x00, 0x3c, 0x00, 0x00, 0xf0, 0xff, 0x03, 0xfe, 0xff, 0xff, 0x0f, 0x00,
0x00, 0x00, 0x00, 0xcf, 0x00, 0x7e, 0x00, 0x00, 0xfc, 0x7f, 0xc0, 0xff,
0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x01, 0x7e, 0x00, 0x00,
0xfe, 0x0f, 0xf8, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97,
0x01, 0x3e, 0x00, 0x00, 0xff, 0x03, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00,
0x00, 0x00, 0x00, 0x9e, 0x03, 0x00, 0x00, 0xc0, 0x7f, 0xc0, 0xff, 0xff,
0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x03, 0x00, 0x00, 0xe0,
0x0f, 0xf8, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
0x03, 0x00, 0x00, 0xf8, 0x01, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7c, 0x06, 0x00, 0x00, 0x3f, 0xe0, 0xff, 0xff, 0xff,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x0e, 0x00, 0xe0, 0x0f,
0xfc, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
0x3c, 0x00, 0xfc, 0x01, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xf8, 0x78, 0x80, 0x3f, 0xe0, 0xff, 0xff, 0xff, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xe1, 0xff, 0x07, 0xfc,
0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
0x81, 0xff, 0x80, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0xfe, 0xff,
0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
0x0f, 0x00, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xc0, 0x3f, 0xc0, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff,
0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x1f,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x0f, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xf0, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
/tags/0.2.0.3/kernel/genarch/src/i8042/i8042.c
0,0 → 1,585
/*
* 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 genarch
* @{
*/
/**
* @file
* @brief i8042 processor driver.
*
* It takes care of low-level keyboard functions.
*/
 
#include <genarch/i8042/i8042.h>
#include <arch/drivers/i8042.h>
#include <arch/interrupt.h>
#include <cpu.h>
#include <arch/asm.h>
#include <arch.h>
#include <synch/spinlock.h>
#include <typedefs.h>
#include <console/chardev.h>
#include <console/console.h>
#include <macros.h>
#include <interrupt.h>
 
/* Keyboard commands. */
#define KBD_ENABLE 0xf4
#define KBD_DISABLE 0xf5
#define KBD_ACK 0xfa
 
/*
* 60 Write 8042 Command Byte: next data byte written to port 60h is
* placed in 8042 command register. Format:
*
* |7|6|5|4|3|2|1|0|8042 Command Byte
* | | | | | | | `---- 1=enable output register full interrupt
* | | | | | | `----- should be 0
* | | | | | `------ 1=set status register system, 0=clear
* | | | | `------- 1=override keyboard inhibit, 0=allow inhibit
* | | | `-------- disable keyboard I/O by driving clock line low
* | | `--------- disable auxiliary device, drives clock line low
* | `---------- IBM scancode translation 0=AT, 1=PC/XT
* `----------- reserved, should be 0
*/
 
#define i8042_SET_COMMAND 0x60
#define i8042_COMMAND 0x69
 
#define i8042_BUFFER_FULL_MASK 0x01
#define i8042_WAIT_MASK 0x02
#define i8042_MOUSE_DATA 0x20
 
#define SPECIAL '?'
#define KEY_RELEASE 0x80
 
/**
* These codes read from i8042 data register are silently ignored.
*/
#define IGNORE_CODE 0x7f
 
static void key_released(uint8_t sc);
static void key_pressed(uint8_t sc);
static char key_read(chardev_t *d);
 
#define PRESSED_SHIFT (1<<0)
#define PRESSED_CAPSLOCK (1<<1)
#define LOCKED_CAPSLOCK (1<<0)
 
#define ACTIVE_READ_BUFF_SIZE 16 /* Must be power of 2 */
 
static uint8_t active_read_buff[ACTIVE_READ_BUFF_SIZE];
 
SPINLOCK_INITIALIZE(keylock); /**< keylock protects keyflags and lockflags. */
static volatile int keyflags; /**< Tracking of multiple keypresses. */
static volatile int lockflags; /**< Tracking of multiple keys lockings. */
 
static void i8042_suspend(chardev_t *);
static void i8042_resume(chardev_t *);
 
static chardev_t kbrd;
static chardev_operations_t ops = {
.suspend = i8042_suspend,
.resume = i8042_resume,
.read = key_read
};
 
/** Primary meaning of scancodes. */
static char sc_primary_map[] = {
SPECIAL, /* 0x00 */
SPECIAL, /* 0x01 - Esc */
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=',
'\b', /* 0x0e - Backspace */
'\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n',
SPECIAL, /* 0x1d - LCtrl */
'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'',
'`',
SPECIAL, /* 0x2a - LShift */
'\\',
'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/',
SPECIAL, /* 0x36 - RShift */
'*',
SPECIAL, /* 0x38 - LAlt */
' ',
SPECIAL, /* 0x3a - CapsLock */
SPECIAL, /* 0x3b - F1 */
SPECIAL, /* 0x3c - F2 */
SPECIAL, /* 0x3d - F3 */
SPECIAL, /* 0x3e - F4 */
SPECIAL, /* 0x3f - F5 */
SPECIAL, /* 0x40 - F6 */
SPECIAL, /* 0x41 - F7 */
SPECIAL, /* 0x42 - F8 */
SPECIAL, /* 0x43 - F9 */
SPECIAL, /* 0x44 - F10 */
SPECIAL, /* 0x45 - NumLock */
SPECIAL, /* 0x46 - ScrollLock */
'7', '8', '9', '-',
'4', '5', '6', '+',
'1', '2', '3',
'0', '.',
SPECIAL, /* 0x54 - Alt-SysRq */
SPECIAL, /* 0x55 - F11/F12/PF1/FN */
SPECIAL, /* 0x56 - unlabelled key next to LAlt */
SPECIAL, /* 0x57 - F11 */
SPECIAL, /* 0x58 - F12 */
SPECIAL, /* 0x59 */
SPECIAL, /* 0x5a */
SPECIAL, /* 0x5b */
SPECIAL, /* 0x5c */
SPECIAL, /* 0x5d */
SPECIAL, /* 0x5e */
SPECIAL, /* 0x5f */
SPECIAL, /* 0x60 */
SPECIAL, /* 0x61 */
SPECIAL, /* 0x62 */
SPECIAL, /* 0x63 */
SPECIAL, /* 0x64 */
SPECIAL, /* 0x65 */
SPECIAL, /* 0x66 */
SPECIAL, /* 0x67 */
SPECIAL, /* 0x68 */
SPECIAL, /* 0x69 */
SPECIAL, /* 0x6a */
SPECIAL, /* 0x6b */
SPECIAL, /* 0x6c */
SPECIAL, /* 0x6d */
SPECIAL, /* 0x6e */
SPECIAL, /* 0x6f */
SPECIAL, /* 0x70 */
SPECIAL, /* 0x71 */
SPECIAL, /* 0x72 */
SPECIAL, /* 0x73 */
SPECIAL, /* 0x74 */
SPECIAL, /* 0x75 */
SPECIAL, /* 0x76 */
SPECIAL, /* 0x77 */
SPECIAL, /* 0x78 */
SPECIAL, /* 0x79 */
SPECIAL, /* 0x7a */
SPECIAL, /* 0x7b */
SPECIAL, /* 0x7c */
SPECIAL, /* 0x7d */
SPECIAL, /* 0x7e */
SPECIAL, /* 0x7f */
};
 
/** Secondary meaning of scancodes. */
static char sc_secondary_map[] = {
SPECIAL, /* 0x00 */
SPECIAL, /* 0x01 - Esc */
'!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+',
SPECIAL, /* 0x0e - Backspace */
'\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n',
SPECIAL, /* 0x1d - LCtrl */
'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"',
'~',
SPECIAL, /* 0x2a - LShift */
'|',
'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?',
SPECIAL, /* 0x36 - RShift */
'*',
SPECIAL, /* 0x38 - LAlt */
' ',
SPECIAL, /* 0x3a - CapsLock */
SPECIAL, /* 0x3b - F1 */
SPECIAL, /* 0x3c - F2 */
SPECIAL, /* 0x3d - F3 */
SPECIAL, /* 0x3e - F4 */
SPECIAL, /* 0x3f - F5 */
SPECIAL, /* 0x40 - F6 */
SPECIAL, /* 0x41 - F7 */
SPECIAL, /* 0x42 - F8 */
SPECIAL, /* 0x43 - F9 */
SPECIAL, /* 0x44 - F10 */
SPECIAL, /* 0x45 - NumLock */
SPECIAL, /* 0x46 - ScrollLock */
'7', '8', '9', '-',
'4', '5', '6', '+',
'1', '2', '3',
'0', '.',
SPECIAL, /* 0x54 - Alt-SysRq */
SPECIAL, /* 0x55 - F11/F12/PF1/FN */
SPECIAL, /* 0x56 - unlabelled key next to LAlt */
SPECIAL, /* 0x57 - F11 */
SPECIAL, /* 0x58 - F12 */
SPECIAL, /* 0x59 */
SPECIAL, /* 0x5a */
SPECIAL, /* 0x5b */
SPECIAL, /* 0x5c */
SPECIAL, /* 0x5d */
SPECIAL, /* 0x5e */
SPECIAL, /* 0x5f */
SPECIAL, /* 0x60 */
SPECIAL, /* 0x61 */
SPECIAL, /* 0x62 */
SPECIAL, /* 0x63 */
SPECIAL, /* 0x64 */
SPECIAL, /* 0x65 */
SPECIAL, /* 0x66 */
SPECIAL, /* 0x67 */
SPECIAL, /* 0x68 */
SPECIAL, /* 0x69 */
SPECIAL, /* 0x6a */
SPECIAL, /* 0x6b */
SPECIAL, /* 0x6c */
SPECIAL, /* 0x6d */
SPECIAL, /* 0x6e */
SPECIAL, /* 0x6f */
SPECIAL, /* 0x70 */
SPECIAL, /* 0x71 */
SPECIAL, /* 0x72 */
SPECIAL, /* 0x73 */
SPECIAL, /* 0x74 */
SPECIAL, /* 0x75 */
SPECIAL, /* 0x76 */
SPECIAL, /* 0x77 */
SPECIAL, /* 0x78 */
SPECIAL, /* 0x79 */
SPECIAL, /* 0x7a */
SPECIAL, /* 0x7b */
SPECIAL, /* 0x7c */
SPECIAL, /* 0x7d */
SPECIAL, /* 0x7e */
SPECIAL, /* 0x7f */
};
 
static void i8042_interrupt(int n, istate_t *istate);
static void i8042_wait(void);
 
static iroutine oldvector;
/** Initialize keyboard and service interrupts using kernel routine */
void i8042_grab(void)
{
oldvector = exc_register(VECTOR_KBD, "i8042_interrupt", (iroutine) i8042_interrupt);
i8042_wait();
i8042_command_write(i8042_SET_COMMAND);
i8042_wait();
i8042_data_write(i8042_COMMAND);
i8042_wait();
}
/** Resume the former interrupt vector */
void i8042_release(void)
{
if (oldvector)
exc_register(VECTOR_KBD, "user_interrupt", oldvector);
}
 
/** Initialize i8042. */
void i8042_init(void)
{
int i;
 
i8042_grab();
/* Prevent user from accidentaly releasing calling i8042_resume
* and disabling keyboard
*/
oldvector = NULL;
 
trap_virtual_enable_irqs(1<<IRQ_KBD);
chardev_initialize("i8042_kbd", &kbrd, &ops);
stdin = &kbrd;
 
/*
* Clear input buffer.
* Number of iterations is limited to prevent infinite looping.
*/
for (i = 0; (i8042_status_read() & i8042_BUFFER_FULL_MASK) && i < 100; i++) {
i8042_data_read();
}
}
 
/** Process i8042 interrupt.
*
* @param n Interrupt vector.
* @param istate Interrupted state.
*/
void i8042_interrupt(int n, istate_t *istate)
{
uint8_t x;
uint8_t status;
 
while (((status=i8042_status_read()) & i8042_BUFFER_FULL_MASK)) {
x = i8042_data_read();
 
if ((status & i8042_MOUSE_DATA))
continue;
 
if (x & KEY_RELEASE)
key_released(x ^ KEY_RELEASE);
else
key_pressed(x);
}
trap_virtual_eoi();
}
 
/** Wait until the controller reads its data. */
void i8042_wait(void) {
while (i8042_status_read() & i8042_WAIT_MASK) {
/* wait */
}
}
 
/** Process release of key.
*
* @param sc Scancode of the key being released.
*/
void key_released(uint8_t sc)
{
spinlock_lock(&keylock);
switch (sc) {
case SC_LSHIFT:
case SC_RSHIFT:
keyflags &= ~PRESSED_SHIFT;
break;
case SC_CAPSLOCK:
keyflags &= ~PRESSED_CAPSLOCK;
if (lockflags & LOCKED_CAPSLOCK)
lockflags &= ~LOCKED_CAPSLOCK;
else
lockflags |= LOCKED_CAPSLOCK;
break;
default:
break;
}
spinlock_unlock(&keylock);
}
 
/** Process keypress.
*
* @param sc Scancode of the key being pressed.
*/
void key_pressed(uint8_t sc)
{
char *map = sc_primary_map;
char ascii = sc_primary_map[sc];
bool shift, capslock;
bool letter = false;
 
spinlock_lock(&keylock);
switch (sc) {
case SC_LSHIFT:
case SC_RSHIFT:
keyflags |= PRESSED_SHIFT;
break;
case SC_CAPSLOCK:
keyflags |= PRESSED_CAPSLOCK;
break;
case SC_SPEC_ESCAPE:
break;
case SC_LEFTARR:
chardev_push_character(&kbrd, 0x1b);
chardev_push_character(&kbrd, 0x5b);
chardev_push_character(&kbrd, 0x44);
break;
case SC_RIGHTARR:
chardev_push_character(&kbrd, 0x1b);
chardev_push_character(&kbrd, 0x5b);
chardev_push_character(&kbrd, 0x43);
break;
case SC_UPARR:
chardev_push_character(&kbrd, 0x1b);
chardev_push_character(&kbrd, 0x5b);
chardev_push_character(&kbrd, 0x41);
break;
case SC_DOWNARR:
chardev_push_character(&kbrd, 0x1b);
chardev_push_character(&kbrd, 0x5b);
chardev_push_character(&kbrd, 0x42);
break;
case SC_HOME:
chardev_push_character(&kbrd, 0x1b);
chardev_push_character(&kbrd, 0x4f);
chardev_push_character(&kbrd, 0x48);
break;
case SC_END:
chardev_push_character(&kbrd, 0x1b);
chardev_push_character(&kbrd, 0x4f);
chardev_push_character(&kbrd, 0x46);
break;
case SC_DELETE:
chardev_push_character(&kbrd, 0x1b);
chardev_push_character(&kbrd, 0x5b);
chardev_push_character(&kbrd, 0x33);
chardev_push_character(&kbrd, 0x7e);
break;
default:
letter = is_lower(ascii);
capslock = (keyflags & PRESSED_CAPSLOCK) || (lockflags & LOCKED_CAPSLOCK);
shift = keyflags & PRESSED_SHIFT;
if (letter && capslock)
shift = !shift;
if (shift)
map = sc_secondary_map;
chardev_push_character(&kbrd, map[sc]);
break;
}
spinlock_unlock(&keylock);
}
 
/* Called from getc(). */
void i8042_resume(chardev_t *d)
{
}
 
/* Called from getc(). */
void i8042_suspend(chardev_t *d)
{
}
 
static uint8_t active_read_buff_read(void)
{
static int i=0;
i &= (ACTIVE_READ_BUFF_SIZE-1);
if(!active_read_buff[i]) {
return 0;
}
return active_read_buff[i++];
}
 
static void active_read_buff_write(uint8_t ch)
{
static int i=0;
active_read_buff[i] = ch;
i++;
i &= (ACTIVE_READ_BUFF_SIZE-1);
active_read_buff[i]=0;
}
 
 
static void active_read_key_pressed(uint8_t sc)
{
char *map = sc_primary_map;
char ascii = sc_primary_map[sc];
bool shift, capslock;
bool letter = false;
 
/*spinlock_lock(&keylock);*/
switch (sc) {
case SC_LSHIFT:
case SC_RSHIFT:
keyflags |= PRESSED_SHIFT;
break;
case SC_CAPSLOCK:
keyflags |= PRESSED_CAPSLOCK;
break;
case SC_SPEC_ESCAPE:
break;
case SC_LEFTARR:
active_read_buff_write(0x1b);
active_read_buff_write(0x5b);
active_read_buff_write(0x44);
break;
case SC_RIGHTARR:
active_read_buff_write(0x1b);
active_read_buff_write(0x5b);
active_read_buff_write(0x43);
break;
case SC_UPARR:
active_read_buff_write(0x1b);
active_read_buff_write(0x5b);
active_read_buff_write(0x41);
break;
case SC_DOWNARR:
active_read_buff_write(0x1b);
active_read_buff_write(0x5b);
active_read_buff_write(0x42);
break;
case SC_HOME:
active_read_buff_write(0x1b);
active_read_buff_write(0x4f);
active_read_buff_write(0x48);
break;
case SC_END:
active_read_buff_write(0x1b);
active_read_buff_write(0x4f);
active_read_buff_write(0x46);
break;
case SC_DELETE:
active_read_buff_write(0x1b);
active_read_buff_write(0x5b);
active_read_buff_write(0x33);
active_read_buff_write(0x7e);
break;
default:
letter = is_lower(ascii);
capslock = (keyflags & PRESSED_CAPSLOCK) || (lockflags & LOCKED_CAPSLOCK);
shift = keyflags & PRESSED_SHIFT;
if (letter && capslock)
shift = !shift;
if (shift)
map = sc_secondary_map;
active_read_buff_write(map[sc]);
break;
}
/*spinlock_unlock(&keylock);*/
 
}
 
static char key_read(chardev_t *d)
{
char ch;
 
while(!(ch = active_read_buff_read())) {
uint8_t x;
while (!(i8042_status_read() & i8042_BUFFER_FULL_MASK))
;
x = i8042_data_read();
if (x != IGNORE_CODE) {
if (x & KEY_RELEASE)
key_released(x ^ KEY_RELEASE);
else
active_read_key_pressed(x);
}
}
return ch;
}
 
/** Poll for key press and release events.
*
* This function can be used to implement keyboard polling.
*/
void i8042_poll(void)
{
uint8_t x;
 
while (((x = i8042_status_read() & i8042_BUFFER_FULL_MASK))) {
x = i8042_data_read();
if (x != IGNORE_CODE) {
if (x & KEY_RELEASE)
key_released(x ^ KEY_RELEASE);
else
key_pressed(x);
}
}
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/genarch/src/mm/page_pt.c
0,0 → 1,270
/*
* 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 genarchmm
* @{
*/
 
/**
* @file
* @brief Virtual Address Translation for hierarchical 4-level page tables.
*/
 
#include <genarch/mm/page_pt.h>
#include <mm/page.h>
#include <mm/frame.h>
#include <mm/as.h>
#include <arch/mm/page.h>
#include <arch/mm/as.h>
#include <arch/types.h>
#include <typedefs.h>
#include <arch/asm.h>
#include <memstr.h>
 
static void pt_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame, int flags);
static void pt_mapping_remove(as_t *as, uintptr_t page);
static pte_t *pt_mapping_find(as_t *as, uintptr_t page);
 
page_mapping_operations_t pt_mapping_operations = {
.mapping_insert = pt_mapping_insert,
.mapping_remove = pt_mapping_remove,
.mapping_find = pt_mapping_find
};
 
/** Map page to frame using hierarchical page tables.
*
* Map virtual address page to physical address frame
* using flags.
*
* The page table must be locked and interrupts must be disabled.
*
* @param as Address space to wich page belongs.
* @param page Virtual address of the page to be mapped.
* @param frame Physical address of memory frame to which the mapping is done.
* @param flags Flags to be used for mapping.
*/
void pt_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame, int flags)
{
pte_t *ptl0, *ptl1, *ptl2, *ptl3;
pte_t *newpt;
 
ptl0 = (pte_t *) PA2KA((uintptr_t) as->page_table);
 
if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT) {
newpt = (pte_t *)frame_alloc(ONE_FRAME, FRAME_KA);
memsetb((uintptr_t)newpt, PAGE_SIZE, 0);
SET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page), KA2PA(newpt));
SET_PTL1_FLAGS(ptl0, PTL0_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE);
}
 
ptl1 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page)));
 
if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT) {
newpt = (pte_t *)frame_alloc(ONE_FRAME, FRAME_KA);
memsetb((uintptr_t)newpt, PAGE_SIZE, 0);
SET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page), KA2PA(newpt));
SET_PTL2_FLAGS(ptl1, PTL1_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE);
}
 
ptl2 = (pte_t *) PA2KA(GET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page)));
 
if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT) {
newpt = (pte_t *)frame_alloc(ONE_FRAME, FRAME_KA);
memsetb((uintptr_t)newpt, PAGE_SIZE, 0);
SET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page), KA2PA(newpt));
SET_PTL3_FLAGS(ptl2, PTL2_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE);
}
 
ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page)));
 
SET_FRAME_ADDRESS(ptl3, PTL3_INDEX(page), frame);
SET_FRAME_FLAGS(ptl3, PTL3_INDEX(page), flags);
}
 
/** Remove mapping of page from hierarchical page tables.
*
* Remove any mapping of page within address space as.
* TLB shootdown should follow in order to make effects of
* this call visible.
*
* Empty page tables except PTL0 are freed.
*
* The page table must be locked and interrupts must be disabled.
*
* @param as Address space to wich page belongs.
* @param page Virtual address of the page to be demapped.
*/
void pt_mapping_remove(as_t *as, uintptr_t page)
{
pte_t *ptl0, *ptl1, *ptl2, *ptl3;
bool empty = true;
int i;
 
/*
* First, remove the mapping, if it exists.
*/
 
ptl0 = (pte_t *) PA2KA((uintptr_t) as->page_table);
 
if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT)
return;
 
ptl1 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page)));
 
if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT)
return;
 
ptl2 = (pte_t *) PA2KA(GET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page)));
 
if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT)
return;
 
ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page)));
 
/* Destroy the mapping. Setting to PAGE_NOT_PRESENT is not sufficient. */
memsetb((uintptr_t) &ptl3[PTL3_INDEX(page)], sizeof(pte_t), 0);
 
/*
* Second, free all empty tables along the way from PTL3 down to PTL0.
*/
/* check PTL3 */
for (i = 0; i < PTL3_ENTRIES; i++) {
if (PTE_VALID(&ptl3[i])) {
empty = false;
break;
}
}
if (empty) {
/*
* PTL3 is empty.
* Release the frame and remove PTL3 pointer from preceding table.
*/
frame_free(KA2PA((uintptr_t) ptl3));
if (PTL2_ENTRIES)
memsetb((uintptr_t) &ptl2[PTL2_INDEX(page)], sizeof(pte_t), 0);
else if (PTL1_ENTRIES)
memsetb((uintptr_t) &ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0);
else
memsetb((uintptr_t) &ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
} else {
/*
* PTL3 is not empty.
* Therefore, there must be a path from PTL0 to PTL3 and
* thus nothing to free in higher levels.
*/
return;
}
/* check PTL2, empty is still true */
if (PTL2_ENTRIES) {
for (i = 0; i < PTL2_ENTRIES; i++) {
if (PTE_VALID(&ptl2[i])) {
empty = false;
break;
}
}
if (empty) {
/*
* PTL2 is empty.
* Release the frame and remove PTL2 pointer from preceding table.
*/
frame_free(KA2PA((uintptr_t) ptl2));
if (PTL1_ENTRIES)
memsetb((uintptr_t) &ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0);
else
memsetb((uintptr_t) &ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
}
else {
/*
* PTL2 is not empty.
* Therefore, there must be a path from PTL0 to PTL2 and
* thus nothing to free in higher levels.
*/
return;
}
}
 
/* check PTL1, empty is still true */
if (PTL1_ENTRIES) {
for (i = 0; i < PTL1_ENTRIES; i++) {
if (PTE_VALID(&ptl1[i])) {
empty = false;
break;
}
}
if (empty) {
/*
* PTL1 is empty.
* Release the frame and remove PTL1 pointer from preceding table.
*/
frame_free(KA2PA((uintptr_t) ptl1));
memsetb((uintptr_t) &ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
}
}
 
}
 
/** Find mapping for virtual page in hierarchical page tables.
*
* Find mapping for virtual page.
*
* The page table must be locked and interrupts must be disabled.
*
* @param as Address space to which page belongs.
* @param page Virtual page.
*
* @return NULL if there is no such mapping; entry from PTL3 describing the mapping otherwise.
*/
pte_t *pt_mapping_find(as_t *as, uintptr_t page)
{
pte_t *ptl0, *ptl1, *ptl2, *ptl3;
 
ptl0 = (pte_t *) PA2KA((uintptr_t) as->page_table);
 
if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT)
return NULL;
 
ptl1 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page)));
 
if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT)
return NULL;
 
ptl2 = (pte_t *) PA2KA(GET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page)));
 
if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT)
return NULL;
 
ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page)));
 
return &ptl3[PTL3_INDEX(page)];
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/genarch/src/mm/as_pt.c
0,0 → 1,144
/*
* 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 genarchmm
* @{
*/
 
/**
* @file
* @brief Address space functions for 4-level hierarchical pagetables.
*/
 
#include <genarch/mm/page_pt.h>
#include <mm/page.h>
#include <mm/frame.h>
#include <mm/as.h>
#include <synch/mutex.h>
#include <arch/mm/page.h>
#include <arch/mm/as.h>
#include <arch/types.h>
#include <typedefs.h>
#include <memstr.h>
#include <arch.h>
 
static pte_t *ptl0_create(int flags);
static void ptl0_destroy(pte_t *page_table);
 
static void pt_lock(as_t *as, bool lock);
static void pt_unlock(as_t *as, bool unlock);
 
as_operations_t as_pt_operations = {
.page_table_create = ptl0_create,
.page_table_destroy = ptl0_destroy,
.page_table_lock = pt_lock,
.page_table_unlock = pt_unlock
};
 
/** Create PTL0.
*
* PTL0 of 4-level page table will be created for each address space.
*
* @param flags Flags can specify whether ptl0 is for the kernel address space.
*
* @return New PTL0.
*/
pte_t *ptl0_create(int flags)
{
pte_t *src_ptl0, *dst_ptl0;
ipl_t ipl;
 
dst_ptl0 = (pte_t *) frame_alloc(ONE_FRAME, FRAME_KA);
 
if (flags & FLAG_AS_KERNEL) {
memsetb((uintptr_t) dst_ptl0, PAGE_SIZE, 0);
} else {
uintptr_t src, dst;
/*
* Copy the kernel address space portion to new PTL0.
*/
ipl = interrupts_disable();
mutex_lock(&AS_KERNEL->lock);
src_ptl0 = (pte_t *) PA2KA((uintptr_t) AS_KERNEL->page_table);
 
src = (uintptr_t) &src_ptl0[PTL0_INDEX(KERNEL_ADDRESS_SPACE_START)];
dst = (uintptr_t) &dst_ptl0[PTL0_INDEX(KERNEL_ADDRESS_SPACE_START)];
 
memsetb((uintptr_t) dst_ptl0, PAGE_SIZE, 0);
memcpy((void *) dst, (void *) src, PAGE_SIZE - (src - (uintptr_t) src_ptl0));
mutex_unlock(&AS_KERNEL->lock);
interrupts_restore(ipl);
}
 
return (pte_t *) KA2PA((uintptr_t) dst_ptl0);
}
 
/** Destroy page table.
*
* Destroy PTL0, other levels are expected to be already deallocated.
*
* @param page_table Physical address of PTL0.
*/
void ptl0_destroy(pte_t *page_table)
{
frame_free((uintptr_t)page_table);
}
 
/** Lock page tables.
*
* Lock only the address space.
* Interrupts must be disabled.
*
* @param as Address space.
* @param lock If false, do not attempt to lock the address space.
*/
void pt_lock(as_t *as, bool lock)
{
if (lock)
mutex_lock(&as->lock);
}
 
/** Unlock page tables.
*
* Unlock the address space.
* Interrupts must be disabled.
*
* @param as Address space.
* @param unlock If false, do not attempt to unlock the address space.
*/
void pt_unlock(as_t *as, bool unlock)
{
if (unlock)
mutex_unlock(&as->lock);
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/genarch/src/mm/page_ht.c
0,0 → 1,249
/*
* 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 genarchmm
* @{
*/
 
/**
* @file
* @brief Virtual Address Translation (VAT) for global page hash table.
*/
 
#include <genarch/mm/page_ht.h>
#include <mm/page.h>
#include <arch/mm/page.h>
#include <mm/frame.h>
#include <mm/slab.h>
#include <mm/as.h>
#include <arch/mm/asid.h>
#include <arch/types.h>
#include <typedefs.h>
#include <arch/asm.h>
#include <synch/spinlock.h>
#include <arch.h>
#include <debug.h>
#include <memstr.h>
#include <adt/hash_table.h>
#include <align.h>
 
static index_t hash(unative_t key[]);
static bool compare(unative_t key[], count_t keys, link_t *item);
static void remove_callback(link_t *item);
 
static void ht_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame, int flags);
static void ht_mapping_remove(as_t *as, uintptr_t page);
static pte_t *ht_mapping_find(as_t *as, uintptr_t page);
 
/**
* This lock protects the page hash table. It must be acquired
* after address space lock and after any address space area
* locks.
*/
mutex_t page_ht_lock;
 
/**
* Page hash table.
* The page hash table may be accessed only when page_ht_lock is held.
*/
hash_table_t page_ht;
 
/** Hash table operations for page hash table. */
hash_table_operations_t ht_operations = {
.hash = hash,
.compare = compare,
.remove_callback = remove_callback
};
 
/** Page mapping operations for page hash table architectures. */
page_mapping_operations_t ht_mapping_operations = {
.mapping_insert = ht_mapping_insert,
.mapping_remove = ht_mapping_remove,
.mapping_find = ht_mapping_find
};
 
/** Compute page hash table index.
*
* @param key Array of two keys (i.e. page and address space).
*
* @return Index into page hash table.
*/
index_t hash(unative_t key[])
{
as_t *as = (as_t *) key[KEY_AS];
uintptr_t page = (uintptr_t) key[KEY_PAGE];
index_t index;
/*
* Virtual page addresses have roughly the same probability
* of occurring. Least significant bits of VPN compose the
* hash index.
*/
index = ((page >> PAGE_WIDTH) & (PAGE_HT_ENTRIES-1));
/*
* Address space structures are likely to be allocated from
* similar addresses. Least significant bits compose the
* hash index.
*/
index |= ((unative_t) as) & (PAGE_HT_ENTRIES-1);
return index;
}
 
/** Compare page hash table item with page and/or address space.
*
* @param key Array of one or two keys (i.e. page and/or address space).
* @param keys Number of keys passed.
* @param item Item to compare the keys with.
*
* @return true on match, false otherwise.
*/
bool compare(unative_t key[], count_t keys, link_t *item)
{
pte_t *t;
 
ASSERT(item);
ASSERT((keys > 0) && (keys <= PAGE_HT_KEYS));
 
/*
* Convert item to PTE.
*/
t = hash_table_get_instance(item, pte_t, link);
 
if (keys == PAGE_HT_KEYS) {
return (key[KEY_AS] == (uintptr_t) t->as) && (key[KEY_PAGE] == t->page);
} else {
return (key[KEY_AS] == (uintptr_t) t->as);
}
}
 
/** Callback on page hash table item removal.
*
* @param item Page hash table item being removed.
*/
void remove_callback(link_t *item)
{
pte_t *t;
 
ASSERT(item);
 
/*
* Convert item to PTE.
*/
t = hash_table_get_instance(item, pte_t, link);
 
free(t);
}
 
/** Map page to frame using page hash table.
*
* Map virtual address page to physical address frame
* using flags.
*
* The page table must be locked and interrupts must be disabled.
*
* @param as Address space to which page belongs.
* @param page Virtual address of the page to be mapped.
* @param frame Physical address of memory frame to which the mapping is done.
* @param flags Flags to be used for mapping.
*/
void ht_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame, int flags)
{
pte_t *t;
unative_t key[2] = { (uintptr_t) as, page = ALIGN_DOWN(page, PAGE_SIZE) };
if (!hash_table_find(&page_ht, key)) {
t = (pte_t *) malloc(sizeof(pte_t), FRAME_ATOMIC);
ASSERT(t != NULL);
 
t->g = (flags & PAGE_GLOBAL) != 0;
t->x = (flags & PAGE_EXEC) != 0;
t->w = (flags & PAGE_WRITE) != 0;
t->k = !(flags & PAGE_USER);
t->c = (flags & PAGE_CACHEABLE) != 0;
t->p = !(flags & PAGE_NOT_PRESENT);
 
t->as = as;
t->page = ALIGN_DOWN(page, PAGE_SIZE);
t->frame = ALIGN_DOWN(frame, FRAME_SIZE);
 
hash_table_insert(&page_ht, key, &t->link);
}
}
 
/** Remove mapping of page from page hash table.
*
* Remove any mapping of page within address space as.
* TLB shootdown should follow in order to make effects of
* this call visible.
*
* The page table must be locked and interrupts must be disabled.
*
* @param as Address space to wich page belongs.
* @param page Virtual address of the page to be demapped.
*/
void ht_mapping_remove(as_t *as, uintptr_t page)
{
unative_t key[2] = { (uintptr_t) as, page = ALIGN_DOWN(page, PAGE_SIZE) };
/*
* Note that removed PTE's will be freed
* by remove_callback().
*/
hash_table_remove(&page_ht, key, 2);
}
 
 
/** Find mapping for virtual page in page hash table.
*
* Find mapping for virtual page.
*
* The page table must be locked and interrupts must be disabled.
*
* @param as Address space to wich page belongs.
* @param page Virtual page.
*
* @return NULL if there is no such mapping; requested mapping otherwise.
*/
pte_t *ht_mapping_find(as_t *as, uintptr_t page)
{
link_t *hlp;
pte_t *t = NULL;
unative_t key[2] = { (uintptr_t) as, page = ALIGN_DOWN(page, PAGE_SIZE) };
hlp = hash_table_find(&page_ht, key);
if (hlp)
t = hash_table_get_instance(hlp, pte_t, link);
 
return t;
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/genarch/src/mm/as_ht.c
0,0 → 1,123
/*
* 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 genarchmm
* @{
*/
/**
* @file
* @brief Address space functions for global page hash table.
*/
 
#include <genarch/mm/as_ht.h>
#include <genarch/mm/page_ht.h>
#include <mm/as.h>
#include <mm/frame.h>
#include <arch/types.h>
#include <typedefs.h>
#include <memstr.h>
#include <adt/hash_table.h>
#include <synch/mutex.h>
 
static pte_t *ht_create(int flags);
static void ht_destroy(pte_t *page_table);
 
static void ht_lock(as_t *as, bool lock);
static void ht_unlock(as_t *as, bool unlock);
 
as_operations_t as_ht_operations = {
.page_table_create = ht_create,
.page_table_destroy = ht_destroy,
.page_table_lock = ht_lock,
.page_table_unlock = ht_unlock,
};
 
 
/** Page hash table create.
*
* The page hash table will be created only once
* and will be shared by all address spaces.
*
* @param flags Ignored.
*
* @return Returns NULL.
*/
pte_t *ht_create(int flags)
{
if (flags & FLAG_AS_KERNEL) {
hash_table_create(&page_ht, PAGE_HT_ENTRIES, 2, &ht_operations);
mutex_initialize(&page_ht_lock);
}
return NULL;
}
 
/** Destroy page table.
*
* Actually do nothing as the global page hash table is used.
*
* @param page_table This parameter is ignored.
*/
void ht_destroy(pte_t *page_table)
{
/* No-op. */
}
 
/** Lock page table.
*
* Lock address space and page hash table.
* Interrupts must be disabled.
*
* @param as Address space.
* @param lock If false, do not attempt to lock the address space.
*/
void ht_lock(as_t *as, bool lock)
{
if (lock)
mutex_lock(&as->lock);
mutex_lock(&page_ht_lock);
}
 
/** Unlock page table.
*
* Unlock address space and page hash table.
* Interrupts must be disabled.
*
* @param as Address space.
* @param unlock If false, do not attempt to lock the address space.
*/
void ht_unlock(as_t *as, bool unlock)
{
mutex_unlock(&page_ht_lock);
if (unlock)
mutex_unlock(&as->lock);
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/genarch/src/mm/asid.c
0,0 → 1,179
/*
* 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 genarchmm
* @{
*/
 
/**
* @file
* @brief ASID management.
*
* Modern processor architectures optimize TLB utilization
* by using ASIDs (a.k.a. memory contexts on sparc64 and
* region identifiers on ia64). These ASIDs help to associate
* each TLB item with an address space, thus making
* finer-grained TLB invalidation possible.
*
* Unfortunatelly, there are usually less ASIDs available than
* there can be unique as_t structures (i.e. address spaces
* recognized by the kernel).
*
* When system runs short of ASIDs, it will attempt to steal
* ASID from an address space that has not been active for
* a while.
*
* This code depends on the fact that ASIDS_ALLOCABLE
* is greater than number of supported CPUs (i.e. the
* amount of concurently active address spaces).
*
* Architectures that don't have hardware support for address
* spaces do not compile with this file.
*/
 
#include <mm/asid.h>
#include <mm/as.h>
#include <mm/tlb.h>
#include <arch/mm/asid.h>
#include <synch/spinlock.h>
#include <synch/mutex.h>
#include <arch.h>
#include <adt/list.h>
#include <debug.h>
 
/**
* asidlock protects the asids_allocated counter.
*/
SPINLOCK_INITIALIZE(asidlock);
 
static count_t asids_allocated = 0;
 
/** Allocate free address space identifier.
*
* Interrupts must be disabled and inactive_as_with_asid_lock must be held
* prior to this call
*
* @return New ASID.
*/
asid_t asid_get(void)
{
asid_t asid;
link_t *tmp;
as_t *as;
 
/*
* Check if there is an unallocated ASID.
*/
spinlock_lock(&asidlock);
if (asids_allocated == ASIDS_ALLOCABLE) {
 
/*
* All ASIDs are already allocated.
* Resort to stealing.
*/
/*
* Remove the first item on the list.
* It is guaranteed to belong to an
* inactive address space.
*/
ASSERT(!list_empty(&inactive_as_with_asid_head));
tmp = inactive_as_with_asid_head.next;
list_remove(tmp);
as = list_get_instance(tmp, as_t, inactive_as_with_asid_link);
mutex_lock_active(&as->lock);
 
/*
* Steal the ASID.
* Note that the stolen ASID is not active.
*/
asid = as->asid;
ASSERT(asid != ASID_INVALID);
 
/*
* Notify the address space from wich the ASID
* was stolen by invalidating its asid member.
*/
as->asid = ASID_INVALID;
mutex_unlock(&as->lock);
 
/*
* Get the system rid of the stolen ASID.
*/
tlb_shootdown_start(TLB_INVL_ASID, asid, 0, 0);
tlb_invalidate_asid(asid);
tlb_shootdown_finalize();
} else {
 
/*
* There is at least one unallocated ASID.
* Find it and assign it.
*/
 
asid = asid_find_free();
asids_allocated++;
 
/*
* Purge the allocated rid from TLBs.
*/
tlb_shootdown_start(TLB_INVL_ASID, asid, 0, 0);
tlb_invalidate_asid(asid);
tlb_shootdown_finalize();
}
spinlock_unlock(&asidlock);
return asid;
}
 
/** Release address space identifier.
*
* This code relies on architecture
* dependent functionality.
*
* @param asid ASID to be released.
*/
void asid_put(asid_t asid)
{
ipl_t ipl;
 
ipl = interrupts_disable();
spinlock_lock(&asidlock);
 
asids_allocated--;
asid_put_arch(asid);
spinlock_unlock(&asidlock);
interrupts_restore(ipl);
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/genarch/src/mm/asid_fifo.c
0,0 → 1,99
/*
* 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 genarchmm
* @{
*/
/**
* @file
* @brief FIFO queue ASID management.
*
* Architectures that link with this file keep the unallocated ASIDs
* in FIFO queue. The queue can be statically (e.g. mips32) or
* dynamically allocated (e.g ia64 and sparc64).
*/
 
#include <genarch/mm/asid_fifo.h>
#include <arch/mm/asid.h>
#include <mm/asid.h>
#include <typedefs.h>
#include <adt/fifo.h>
 
#define FIFO_STATIC_LIMIT 1024
#define FIFO_STATIC (ASIDS_ALLOCABLE<FIFO_STATIC_LIMIT)
 
/**
* FIFO queue containing unassigned ASIDs.
* Can be only accessed when asidlock is held.
*/
#if FIFO_STATIC
FIFO_INITIALIZE_STATIC(free_asids, asid_t, ASIDS_ALLOCABLE);
#else
FIFO_INITIALIZE_DYNAMIC(free_asids, asid_t, ASIDS_ALLOCABLE);
#endif
 
/** Initialize data structures for O(1) ASID allocation and deallocation. */
void asid_fifo_init(void)
{
int i;
 
#if (!FIFO_STATIC)
fifo_create(free_asids);
#endif
for (i = 0; i < ASIDS_ALLOCABLE; i++) {
fifo_push(free_asids, ASID_START + i);
}
}
 
/** Allocate free ASID.
*
* Allocation runs in O(1).
*
* @return Free ASID.
*/
asid_t asid_find_free(void)
{
return fifo_pop(free_asids);
}
 
/** Return ASID among free ASIDs.
*
* This operation runs in O(1).
*
* @param asid ASID being freed.
*/
void asid_put_arch(asid_t asid)
{
fifo_push(free_asids, asid);
}
 
/** @}
*/
 
/tags/0.2.0.3/kernel/genarch/src/acpi/madt.c
0,0 → 1,248
/*
* 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 genarch
* @{
*/
/**
* @file
* @brief Multiple APIC Description Table (MADT) parsing.
*/
 
#include <arch/types.h>
#include <typedefs.h>
#include <genarch/acpi/acpi.h>
#include <genarch/acpi/madt.h>
#include <arch/smp/apic.h>
#include <arch/smp/smp.h>
#include <panic.h>
#include <debug.h>
#include <config.h>
#include <print.h>
#include <mm/slab.h>
#include <memstr.h>
#include <sort.h>
 
struct acpi_madt *acpi_madt = NULL;
 
#ifdef CONFIG_SMP
 
/** Standard ISA IRQ map; can be overriden by Interrupt Source Override entries of MADT. */
int isa_irq_map[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
 
static void madt_l_apic_entry(struct madt_l_apic *la, uint32_t index);
static void madt_io_apic_entry(struct madt_io_apic *ioa, uint32_t index);
static void madt_intr_src_ovrd_entry(struct madt_intr_src_ovrd *override, uint32_t index);
static int madt_cmp(void * a, void * b);
 
struct madt_l_apic *madt_l_apic_entries = NULL;
struct madt_io_apic *madt_io_apic_entries = NULL;
 
index_t madt_l_apic_entry_index = 0;
index_t madt_io_apic_entry_index = 0;
count_t madt_l_apic_entry_cnt = 0;
count_t madt_io_apic_entry_cnt = 0;
count_t cpu_count = 0;
 
struct madt_apic_header * * madt_entries_index = NULL;
int madt_entries_index_cnt = 0;
 
char *entry[] = {
"L_APIC",
"IO_APIC",
"INTR_SRC_OVRD",
"NMI_SRC",
"L_APIC_NMI",
"L_APIC_ADDR_OVRD",
"IO_SAPIC",
"L_SAPIC",
"PLATFORM_INTR_SRC"
};
 
/*
* ACPI MADT Implementation of SMP configuration interface.
*/
static count_t madt_cpu_count(void);
static bool madt_cpu_enabled(index_t i);
static bool madt_cpu_bootstrap(index_t i);
static uint8_t madt_cpu_apic_id(index_t i);
static int madt_irq_to_pin(int irq);
 
struct smp_config_operations madt_config_operations = {
.cpu_count = madt_cpu_count,
.cpu_enabled = madt_cpu_enabled,
.cpu_bootstrap = madt_cpu_bootstrap,
.cpu_apic_id = madt_cpu_apic_id,
.irq_to_pin = madt_irq_to_pin
};
 
count_t madt_cpu_count(void)
{
return madt_l_apic_entry_cnt;
}
 
bool madt_cpu_enabled(index_t i)
{
ASSERT(i < madt_l_apic_entry_cnt);
return ((struct madt_l_apic *) madt_entries_index[madt_l_apic_entry_index + i])->flags & 0x1;
 
}
 
bool madt_cpu_bootstrap(index_t i)
{
ASSERT(i < madt_l_apic_entry_cnt);
return ((struct madt_l_apic *) madt_entries_index[madt_l_apic_entry_index + i])->apic_id == l_apic_id();
}
 
uint8_t madt_cpu_apic_id(index_t i)
{
ASSERT(i < madt_l_apic_entry_cnt);
return ((struct madt_l_apic *) madt_entries_index[madt_l_apic_entry_index + i])->apic_id;
}
 
int madt_irq_to_pin(int irq)
{
ASSERT(irq < sizeof(isa_irq_map)/sizeof(int));
return isa_irq_map[irq];
}
 
int madt_cmp(void * a, void * b)
{
return
(((struct madt_apic_header *) a)->type > ((struct madt_apic_header *) b)->type) ?
1 :
((((struct madt_apic_header *) a)->type < ((struct madt_apic_header *) b)->type) ? -1 : 0);
}
void acpi_madt_parse(void)
{
struct madt_apic_header *end = (struct madt_apic_header *) (((uint8_t *) acpi_madt) + acpi_madt->header.length);
struct madt_apic_header *h;
l_apic = (uint32_t *) (unative_t) acpi_madt->l_apic_address;
 
/* calculate madt entries */
for (h = &acpi_madt->apic_header[0]; h < end; h = (struct madt_apic_header *) (((uint8_t *) h) + h->length)) {
madt_entries_index_cnt++;
}
 
/* create madt apic entries index array */
madt_entries_index = (struct madt_apic_header * *) malloc(madt_entries_index_cnt * sizeof(struct madt_apic_header * *), FRAME_ATOMIC);
if (!madt_entries_index)
panic("Memory allocation error.");
 
uint32_t index = 0;
 
for (h = &acpi_madt->apic_header[0]; h < end; h = (struct madt_apic_header *) (((uint8_t *) h) + h->length)) {
madt_entries_index[index++] = h;
}
 
/* Quicksort MADT index structure */
qsort(madt_entries_index, madt_entries_index_cnt, sizeof(uintptr_t), &madt_cmp);
 
/* Parse MADT entries */
for (index = 0; index < madt_entries_index_cnt - 1; index++) {
h = madt_entries_index[index];
switch (h->type) {
case MADT_L_APIC:
madt_l_apic_entry((struct madt_l_apic *) h, index);
break;
case MADT_IO_APIC:
madt_io_apic_entry((struct madt_io_apic *) h, index);
break;
case MADT_INTR_SRC_OVRD:
madt_intr_src_ovrd_entry((struct madt_intr_src_ovrd *) h, index);
break;
case MADT_NMI_SRC:
case MADT_L_APIC_NMI:
case MADT_L_APIC_ADDR_OVRD:
case MADT_IO_SAPIC:
case MADT_L_SAPIC:
case MADT_PLATFORM_INTR_SRC:
printf("MADT: skipping %s entry (type=%zd)\n", entry[h->type], h->type);
break;
 
default:
if (h->type >= MADT_RESERVED_SKIP_BEGIN && h->type <= MADT_RESERVED_SKIP_END) {
printf("MADT: skipping reserved entry (type=%zd)\n", h->type);
}
if (h->type >= MADT_RESERVED_OEM_BEGIN) {
printf("MADT: skipping OEM entry (type=%zd)\n", h->type);
}
break;
}
}
 
if (cpu_count)
config.cpu_count = cpu_count;
}
 
void madt_l_apic_entry(struct madt_l_apic *la, uint32_t index)
{
if (!madt_l_apic_entry_cnt++) {
madt_l_apic_entry_index = index;
}
if (!(la->flags & 0x1)) {
/* Processor is unusable, skip it. */
return;
}
cpu_count++;
apic_id_mask |= 1<<la->apic_id;
}
 
void madt_io_apic_entry(struct madt_io_apic *ioa, uint32_t index)
{
if (!madt_io_apic_entry_cnt++) {
/* remember index of the first io apic entry */
madt_io_apic_entry_index = index;
io_apic = (uint32_t *) (unative_t) ioa->io_apic_address;
} else {
/* currently not supported */
return;
}
}
 
void madt_intr_src_ovrd_entry(struct madt_intr_src_ovrd *override, uint32_t index)
{
ASSERT(override->source < sizeof(isa_irq_map)/sizeof(int));
printf("MADT: ignoring %s entry: bus=%zd, source=%zd, global_int=%zd, flags=%#hx\n",
entry[override->header.type], override->bus, override->source,
override->global_int, override->flags);
}
 
#endif /* CONFIG_SMP */
 
/** @}
*/
 
/tags/0.2.0.3/kernel/genarch/src/acpi/acpi.c
0,0 → 1,189
/*
* 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 genarch
* @{
*/
 
/**
* @file
* @brief Advanced Configuration and Power Interface (ACPI) initialization.
*/
#include <genarch/acpi/acpi.h>
#include <genarch/acpi/madt.h>
#include <arch/bios/bios.h>
#include <mm/as.h>
#include <mm/page.h>
#include <print.h>
 
#define RSDP_SIGNATURE "RSD PTR "
#define RSDP_REVISION_OFFS 15
 
struct acpi_rsdp *acpi_rsdp = NULL;
struct acpi_rsdt *acpi_rsdt = NULL;
struct acpi_xsdt *acpi_xsdt = NULL;
 
struct acpi_signature_map signature_map[] = {
{ (uint8_t *)"APIC", (void *) &acpi_madt, "Multiple APIC Description Table" }
};
 
static int rsdp_check(uint8_t *rsdp) {
struct acpi_rsdp *r = (struct acpi_rsdp *) rsdp;
uint8_t sum = 0;
int i;
for (i=0; i<20; i++)
sum += rsdp[i];
if (sum)
return 0; /* bad checksum */
 
if (r->revision == 0)
return 1; /* ACPI 1.0 */
for (; i<r->length; i++)
sum += rsdp[i];
return !sum;
}
 
int acpi_sdt_check(uint8_t *sdt)
{
struct acpi_sdt_header *h = (struct acpi_sdt_header *) sdt;
uint8_t sum = 0;
int i;
 
for (i=0; i<h->length; i++)
sum += sdt[i];
return !sum;
}
 
static void map_sdt(struct acpi_sdt_header *sdt)
{
page_mapping_insert(AS_KERNEL, (uintptr_t) sdt, (uintptr_t) sdt, PAGE_NOT_CACHEABLE);
map_structure((uintptr_t) sdt, sdt->length);
}
 
static void configure_via_rsdt(void)
{
int i, j, cnt = (acpi_rsdt->header.length - sizeof(struct acpi_sdt_header))/sizeof(uint32_t);
for (i=0; i<cnt; i++) {
for (j=0; j<sizeof(signature_map)/sizeof(struct acpi_signature_map); j++) {
struct acpi_sdt_header *h = (struct acpi_sdt_header *) (unative_t) acpi_rsdt->entry[i];
map_sdt(h);
if (*((uint32_t *) &h->signature[0])==*((uint32_t *) &signature_map[j].signature[0])) {
if (!acpi_sdt_check((uint8_t *) h))
goto next;
*signature_map[j].sdt_ptr = h;
printf("%#zx: ACPI %s\n", *signature_map[j].sdt_ptr, signature_map[j].description);
}
}
next:
;
}
}
 
static void configure_via_xsdt(void)
{
int i, j, cnt = (acpi_xsdt->header.length - sizeof(struct acpi_sdt_header))/sizeof(uint64_t);
for (i=0; i<cnt; i++) {
for (j=0; j<sizeof(signature_map)/sizeof(struct acpi_signature_map); j++) {
struct acpi_sdt_header *h = (struct acpi_sdt_header *) ((uintptr_t) acpi_rsdt->entry[i]);
 
map_sdt(h);
if (*((uint32_t *) &h->signature[0])==*((uint32_t *) &signature_map[j].signature[0])) {
if (!acpi_sdt_check((uint8_t *) h))
goto next;
*signature_map[j].sdt_ptr = h;
printf("%#zx: ACPI %s\n", *signature_map[j].sdt_ptr, signature_map[j].description);
}
}
next:
;
}
 
}
 
void acpi_init(void)
{
uint8_t *addr[2] = { NULL, (uint8_t *) PA2KA(0xe0000) };
int i, j, length[2] = { 1024, 128*1024 };
uint64_t *sig = (uint64_t *) RSDP_SIGNATURE;
 
/*
* Find Root System Description Pointer
* 1. search first 1K of EBDA
* 2. search 128K starting at 0xe0000
*/
 
addr[0] = (uint8_t *) PA2KA(ebda);
for (i = (ebda ? 0 : 1); i < 2; i++) {
for (j = 0; j < length[i]; j += 16) {
if (*((uint64_t *) &addr[i][j]) == *sig && rsdp_check(&addr[i][j])) {
acpi_rsdp = (struct acpi_rsdp *) &addr[i][j];
goto rsdp_found;
}
}
}
 
return;
 
rsdp_found:
printf("%#zx: ACPI Root System Description Pointer\n", acpi_rsdp);
 
acpi_rsdt = (struct acpi_rsdt *) (unative_t) acpi_rsdp->rsdt_address;
if (acpi_rsdp->revision) acpi_xsdt = (struct acpi_xsdt *) ((uintptr_t) acpi_rsdp->xsdt_address);
 
if (acpi_rsdt) map_sdt((struct acpi_sdt_header *) acpi_rsdt);
if (acpi_xsdt) map_sdt((struct acpi_sdt_header *) acpi_xsdt);
 
if (acpi_rsdt && !acpi_sdt_check((uint8_t *) acpi_rsdt)) {
printf("RSDT: %s\n", "bad checksum");
return;
}
if (acpi_xsdt && !acpi_sdt_check((uint8_t *) acpi_xsdt)) {
printf("XSDT: %s\n", "bad checksum");
return;
}
 
if (acpi_xsdt) configure_via_xsdt();
else if (acpi_rsdt) configure_via_rsdt();
 
}
 
 
/** @}
*/
 
/tags/0.2.0.3/kernel/genarch/src/softint/division.c
0,0 → 1,198
/*
* Copyright (C) 2006 Josef Cejka
* 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 genarch
* @{
*/
/** @file
*/
 
#include <genarch/softint/division.h>
 
#define ABSVAL(x) ( (x) > 0 ? (x) : -(x))
#define SGN(x) ( (x) >= 0 ? 1 : 0 )
static unsigned int divandmod32(unsigned int a, unsigned int b, unsigned int *remainder)
{
unsigned int result;
int steps = sizeof(unsigned int) * 8;
*remainder = 0;
result = 0;
if (b == 0) {
/* FIXME: division by zero */
return 0;
}
if ( a < b) {
*remainder = a;
return 0;
}
 
for ( ; steps > 0; steps--) {
/* shift one bit to remainder */
*remainder = ( (*remainder) << 1) | (( a >> 31) & 0x1);
result <<= 1;
if (*remainder >= b) {
*remainder -= b;
result |= 0x1;
}
a <<= 1;
}
 
return result;
}
 
 
static unsigned long long divandmod64(unsigned long long a, unsigned long long b, unsigned long long *remainder)
{
unsigned long long result;
int steps = sizeof(unsigned long long) * 8;
*remainder = 0;
result = 0;
if (b == 0) {
/* FIXME: division by zero */
return 0;
}
if ( a < b) {
*remainder = a;
return 0;
}
 
for ( ; steps > 0; steps--) {
/* shift one bit to remainder */
*remainder = ( (*remainder) << 1) | ((a >> 63) & 0x1);
result <<= 1;
if (*remainder >= b) {
*remainder -= b;
result |= 0x1;
}
a <<= 1;
}
 
return result;
}
 
/* 32bit integer division */
int __divsi3(int a, int b)
{
unsigned int rem;
int result;
result = (int)divandmod32(ABSVAL(a), ABSVAL(b), &rem);
 
if ( SGN(a) == SGN(b)) return result;
return -result;
}
 
/* 64bit integer division */
long long __divdi3(long long a, long long b)
{
unsigned long long rem;
long long result;
result = (long long)divandmod64(ABSVAL(a), ABSVAL(b), &rem);
 
if ( SGN(a) == SGN(b)) return result;
return -result;
}
 
/* 32bit unsigned integer division */
unsigned int __udivsi3(unsigned int a, unsigned int b)
{
unsigned int rem;
return divandmod32(a, b, &rem);
}
 
/* 64bit unsigned integer division */
unsigned long long __udivdi3(unsigned long long a, unsigned long long b)
{
unsigned long long rem;
return divandmod64(a, b, &rem);
}
 
/* 32bit remainder of the signed division */
int __modsi3(int a, int b)
{
unsigned int rem;
divandmod32(a, b, &rem);
/* if divident is negative, remainder must be too */
if (!(SGN(a))) {
return -((int)rem);
}
return (int)rem;
}
 
/* 64bit remainder of the signed division */
long long __moddi3(long long a,long long b)
{
unsigned long long rem;
divandmod64(a, b, &rem);
/* if divident is negative, remainder must be too */
if (!(SGN(a))) {
return -((long long)rem);
}
return (long long)rem;
}
 
/* 32bit remainder of the unsigned division */
unsigned int __umodsi3(unsigned int a, unsigned int b)
{
unsigned int rem;
divandmod32(a, b, &rem);
return rem;
}
 
/* 64bit remainder of the unsigned division */
unsigned long long __umoddi3(unsigned long long a, unsigned long long b)
{
unsigned long long rem;
divandmod64(a, b, &rem);
return rem;
}
 
unsigned long long __udivmoddi3(unsigned long long a, unsigned long long b, unsigned long long *c)
{
return divandmod64(a, b, c);
}
 
 
 
/** @}
*/
 
/tags/0.2.0.3/kernel/test/synch/rwlock4/test.c
0,0 → 1,163
/*
* 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.
*/
 
#include <test.h>
#include <arch.h>
#include <atomic.h>
#include <print.h>
#include <proc/thread.h>
#include <arch/types.h>
#include <arch/context.h>
#include <context.h>
#include <panic.h>
 
#include <synch/waitq.h>
#include <synch/rwlock.h>
#include <synch/synch.h>
#include <synch/spinlock.h>
 
#define READERS 50
#define WRITERS 50
 
static rwlock_t rwlock;
 
SPINLOCK_INITIALIZE(lock);
 
static waitq_t can_start;
 
uint32_t seed = 0xdeadbeef;
 
static uint32_t random(uint32_t max);
 
static void writer(void *arg);
static void reader(void *arg);
static void failed(void);
 
uint32_t random(uint32_t max)
{
uint32_t rc;
 
spinlock_lock(&lock);
rc = seed % max;
seed = (((seed<<2) ^ (seed>>2)) * 487) + rc;
spinlock_unlock(&lock);
return rc;
}
 
 
void writer(void *arg)
{
int rc, to;
thread_detach(THREAD);
waitq_sleep(&can_start);
 
to = random(40000);
printf("cpu%d, tid %d w+ (%d)\n", CPU->id, THREAD->tid, to);
rc = rwlock_write_lock_timeout(&rwlock, to);
if (SYNCH_FAILED(rc)) {
printf("cpu%d, tid %d w!\n", CPU->id, THREAD->tid);
return;
};
printf("cpu%d, tid %d w=\n", CPU->id, THREAD->tid);
 
if (rwlock.readers_in) panic("Oops.");
thread_usleep(random(1000000));
if (rwlock.readers_in) panic("Oops.");
 
rwlock_write_unlock(&rwlock);
printf("cpu%d, tid %d w-\n", CPU->id, THREAD->tid);
}
 
void reader(void *arg)
{
int rc, to;
thread_detach(THREAD);
waitq_sleep(&can_start);
to = random(2000);
printf("cpu%d, tid %d r+ (%d)\n", CPU->id, THREAD->tid, to);
rc = rwlock_read_lock_timeout(&rwlock, to);
if (SYNCH_FAILED(rc)) {
printf("cpu%d, tid %d r!\n", CPU->id, THREAD->tid);
return;
}
printf("cpu%d, tid %d r=\n", CPU->id, THREAD->tid);
thread_usleep(30000);
rwlock_read_unlock(&rwlock);
printf("cpu%d, tid %d r-\n", CPU->id, THREAD->tid);
}
 
void failed(void)
{
printf("Test failed prematurely.\n");
thread_exit();
}
 
void test(void)
{
context_t ctx;
uint32_t i, k;
printf("Read/write locks test #4\n");
waitq_initialize(&can_start);
rwlock_initialize(&rwlock);
 
for (; ;) {
thread_t *thrd;
context_save(&ctx);
printf("sp=%#x, readers_in=%d\n", ctx.sp, rwlock.readers_in);
k = random(7) + 1;
printf("Creating %d readers\n", k);
for (i=0; i<k; i++) {
thrd = thread_create(reader, NULL, TASK, 0, "reader");
if (thrd)
thread_ready(thrd);
else
failed();
}
 
k = random(5) + 1;
printf("Creating %d writers\n", k);
for (i=0; i<k; i++) {
thrd = thread_create(writer, NULL, TASK, 0, "writer");
if (thrd)
thread_ready(thrd);
else
failed();
}
thread_usleep(20000);
waitq_wakeup(&can_start, WAKEUP_ALL);
}
 
}
/tags/0.2.0.3/kernel/test/synch/semaphore2/test.c
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.
*/
 
#include <test.h>
#include <arch.h>
#include <atomic.h>
#include <print.h>
#include <proc/thread.h>
#include <arch/types.h>
#include <arch/context.h>
 
#include <synch/waitq.h>
#include <synch/semaphore.h>
#include <synch/synch.h>
#include <synch/spinlock.h>
 
static semaphore_t sem;
 
SPINLOCK_INITIALIZE(lock);
 
static waitq_t can_start;
 
uint32_t seed = 0xdeadbeef;
 
static uint32_t random(uint32_t max);
 
static void consumer(void *arg);
static void failed(void);
 
uint32_t random(uint32_t max)
{
uint32_t rc;
 
spinlock_lock(&lock);
rc = seed % max;
seed = (((seed<<2) ^ (seed>>2)) * 487) + rc;
spinlock_unlock(&lock);
return rc;
}
 
 
void consumer(void *arg)
{
int rc, to;
thread_detach(THREAD);
waitq_sleep(&can_start);
to = random(20000);
printf("cpu%d, tid %d down+ (%d)\n", CPU->id, THREAD->tid, to);
rc = semaphore_down_timeout(&sem, to);
if (SYNCH_FAILED(rc)) {
printf("cpu%d, tid %d down!\n", CPU->id, THREAD->tid);
return;
}
printf("cpu%d, tid %d down=\n", CPU->id, THREAD->tid);
thread_usleep(random(30000));
semaphore_up(&sem);
printf("cpu%d, tid %d up\n", CPU->id, THREAD->tid);
}
 
void failed(void)
{
printf("Test failed prematurely.\n");
thread_exit();
}
 
void test(void)
{
uint32_t i, k;
printf("Semaphore test #2\n");
waitq_initialize(&can_start);
semaphore_initialize(&sem, 5);
 
for (; ;) {
thread_t *thrd;
k = random(7) + 1;
printf("Creating %d consumers\n", k);
for (i=0; i<k; i++) {
thrd = thread_create(consumer, NULL, TASK, 0, "consumer");
if (thrd)
thread_ready(thrd);
else
failed();
}
thread_usleep(20000);
waitq_wakeup(&can_start, WAKEUP_ALL);
}
 
}
/tags/0.2.0.3/kernel/test/synch/rwlock2/test.c
0,0 → 1,94
/*
* 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.
*/
 
#include <test.h>
#include <arch.h>
#include <atomic.h>
#include <print.h>
#include <proc/thread.h>
 
#include <synch/rwlock.h>
 
#define READERS 50
#define WRITERS 50
 
static rwlock_t rwlock;
 
static void writer(void *arg);
static void failed(void);
 
void writer(void *arg)
{
 
thread_detach(THREAD);
 
printf("Trying to lock rwlock for writing....\n");
 
rwlock_write_lock(&rwlock);
rwlock_write_unlock(&rwlock);
printf("Trying to lock rwlock for reading....\n");
rwlock_read_lock(&rwlock);
rwlock_read_unlock(&rwlock);
printf("Test passed.\n");
}
 
void failed()
{
printf("Test failed prematurely.\n");
thread_exit();
}
 
void test(void)
{
thread_t *thrd;
printf("Read/write locks test #2\n");
rwlock_initialize(&rwlock);
 
rwlock_read_lock(&rwlock);
rwlock_read_lock(&rwlock);
rwlock_read_lock(&rwlock);
rwlock_read_lock(&rwlock);
thrd = thread_create(writer, NULL, TASK, 0, "writer");
if (thrd)
thread_ready(thrd);
else
failed();
 
 
thread_sleep(1);
rwlock_read_unlock(&rwlock);
rwlock_read_unlock(&rwlock);
rwlock_read_unlock(&rwlock);
rwlock_read_unlock(&rwlock);
 
}
/tags/0.2.0.3/kernel/test/synch/rwlock3/test.c
0,0 → 1,93
/*
* 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.
*/
 
#include <test.h>
#include <arch.h>
#include <atomic.h>
#include <print.h>
#include <proc/thread.h>
 
#include <synch/rwlock.h>
 
#define READERS 50
#define WRITERS 50
 
static rwlock_t rwlock;
 
static void reader(void *arg);
static void failed(void);
 
void reader(void *arg)
{
thread_detach(THREAD);
 
printf("cpu%d, tid %d: trying to lock rwlock for reading....\n", CPU->id, THREAD->tid);
rwlock_read_lock(&rwlock);
rwlock_read_unlock(&rwlock);
printf("cpu%d, tid %d: success\n", CPU->id, THREAD->tid);
 
printf("cpu%d, tid %d: trying to lock rwlock for writing....\n", CPU->id, THREAD->tid);
 
rwlock_write_lock(&rwlock);
rwlock_write_unlock(&rwlock);
printf("cpu%d, tid %d: success\n", CPU->id, THREAD->tid);
printf("Test passed.\n");
 
}
 
void failed(void)
{
printf("Test failed prematurely.\n");
thread_exit();
}
 
void test(void)
{
int i;
thread_t *thrd;
printf("Read/write locks test #3\n");
rwlock_initialize(&rwlock);
 
rwlock_write_lock(&rwlock);
for (i=0; i<4; i++) {
thrd = thread_create(reader, NULL, TASK, 0, "reader");
if (thrd)
thread_ready(thrd);
else
failed();
}
 
 
thread_sleep(1);
rwlock_write_unlock(&rwlock);
}
/tags/0.2.0.3/kernel/test/synch/semaphore1/test.c
0,0 → 1,132
/*
* 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.
*/
 
#include <test.h>
#include <arch.h>
#include <atomic.h>
#include <print.h>
#include <proc/thread.h>
 
#include <synch/waitq.h>
#include <synch/semaphore.h>
 
#define AT_ONCE 3
#define PRODUCERS 50
#define CONSUMERS 50
 
static semaphore_t sem;
 
static waitq_t can_start;
static atomic_t items_produced;
static atomic_t items_consumed;
 
static void consumer(void *arg);
static void producer(void *arg);
static void failed(void);
 
void producer(void *arg)
{
thread_detach(THREAD);
 
waitq_sleep(&can_start);
semaphore_down(&sem);
atomic_inc(&items_produced);
thread_usleep(250);
semaphore_up(&sem);
}
 
void consumer(void *arg)
{
thread_detach(THREAD);
waitq_sleep(&can_start);
semaphore_down(&sem);
atomic_inc(&items_consumed);
thread_usleep(500);
semaphore_up(&sem);
}
 
void failed(void)
{
printf("Test failed prematurely.\n");
thread_exit();
}
 
void test(void)
{
int i, j, k;
int consumers, producers;
printf("Semaphore test #1\n");
waitq_initialize(&can_start);
semaphore_initialize(&sem, AT_ONCE);
 
 
for (i=1; i<=3; i++) {
thread_t *thrd;
 
atomic_set(&items_produced, 0);
atomic_set(&items_consumed, 0);
consumers = i * CONSUMERS;
producers = (4-i) * PRODUCERS;
printf("Creating %d consumers and %d producers...", consumers, producers);
for (j=0; j<(CONSUMERS+PRODUCERS)/2; j++) {
for (k=0; k<i; k++) {
thrd = thread_create(consumer, NULL, TASK, 0, "consumer");
if (thrd)
thread_ready(thrd);
else
failed();
}
for (k=0; k<(4-i); k++) {
thrd = thread_create(producer, NULL, TASK, 0, "producer");
if (thrd)
thread_ready(thrd);
else
failed();
}
}
 
printf("ok\n");
 
thread_sleep(1);
waitq_wakeup(&can_start, WAKEUP_ALL);
while (items_consumed.count != consumers || items_produced.count != producers) {
printf("%d consumers remaining, %d producers remaining\n", consumers - items_consumed.count, producers - items_produced.count);
thread_sleep(1);
}
}
printf("Test passed.\n");
}
/tags/0.2.0.3/kernel/test/synch/rwlock5/test.c
0,0 → 1,128
/*
* 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.
*/
 
#include <test.h>
#include <arch.h>
#include <atomic.h>
#include <print.h>
#include <proc/thread.h>
 
#include <synch/waitq.h>
#include <synch/rwlock.h>
 
#define READERS 50
#define WRITERS 50
 
static rwlock_t rwlock;
 
static waitq_t can_start;
static atomic_t items_read;
static atomic_t items_written;
 
static void writer(void *arg);
static void reader(void *arg);
static void failed(void);
 
void writer(void *arg)
{
thread_detach(THREAD);
 
waitq_sleep(&can_start);
 
rwlock_write_lock(&rwlock);
atomic_inc(&items_written);
rwlock_write_unlock(&rwlock);
}
 
void reader(void *arg)
{
thread_detach(THREAD);
 
waitq_sleep(&can_start);
rwlock_read_lock(&rwlock);
atomic_inc(&items_read);
rwlock_read_unlock(&rwlock);
}
 
void failed(void)
{
printf("Test failed prematurely.\n");
thread_exit();
}
 
void test(void)
{
int i, j, k;
count_t readers, writers;
printf("Read/write locks test #5\n");
waitq_initialize(&can_start);
rwlock_initialize(&rwlock);
for (i=1; i<=3; i++) {
thread_t *thrd;
 
atomic_set(&items_read, 0);
atomic_set(&items_written, 0);
 
readers = i*READERS;
writers = (4-i)*WRITERS;
 
printf("Creating %ld readers and %ld writers...", readers, writers);
for (j=0; j<(READERS+WRITERS)/2; j++) {
for (k=0; k<i; k++) {
thrd = thread_create(reader, NULL, TASK, 0, "reader");
if (thrd)
thread_ready(thrd);
else
failed();
}
for (k=0; k<(4-i); k++) {
thrd = thread_create(writer, NULL, TASK, 0, "writer");
if (thrd)
thread_ready(thrd);
else
failed();
}
}
 
printf("ok\n");
 
thread_sleep(1);
waitq_wakeup(&can_start, WAKEUP_ALL);
while (items_read.count != readers || items_written.count != writers) {
printf("%zd readers remaining, %zd writers remaining, readers_in=%zd\n", readers - items_read.count, writers - items_written.count, rwlock.readers_in);
thread_usleep(100000);
}
}
printf("Test passed.\n");
}
/tags/0.2.0.3/kernel/test/synch/rwlock1/test.c
0,0 → 1,78
/*
* 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.
*/
 
#include <test.h>
#include <arch.h>
#include <atomic.h>
#include <print.h>
#include <proc/thread.h>
 
#include <synch/waitq.h>
#include <synch/rwlock.h>
 
#define READERS 50
#define WRITERS 50
 
static rwlock_t rwlock;
 
void test(void)
{
printf("Read/write locks test #1\n");
 
rwlock_initialize(&rwlock);
 
rwlock_write_lock(&rwlock);
rwlock_write_unlock(&rwlock);
 
rwlock_read_lock(&rwlock);
rwlock_read_lock(&rwlock);
rwlock_read_lock(&rwlock);
rwlock_read_lock(&rwlock);
rwlock_read_lock(&rwlock);
 
rwlock_read_unlock(&rwlock);
rwlock_read_unlock(&rwlock);
rwlock_read_unlock(&rwlock);
rwlock_read_unlock(&rwlock);
rwlock_read_unlock(&rwlock);
rwlock_write_lock(&rwlock);
rwlock_write_unlock(&rwlock);
 
rwlock_read_lock(&rwlock);
rwlock_read_unlock(&rwlock);
 
rwlock_write_lock(&rwlock);
rwlock_write_unlock(&rwlock);
 
rwlock_read_lock(&rwlock);
rwlock_read_unlock(&rwlock);
 
printf("Test passed.\n");
}
/tags/0.2.0.3/kernel/test/mm/falloc1/test.c
0,0 → 1,92
/*
* Copyright (C) 2006 Sergey Bondari
* 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 <print.h>
#include <test.h>
#include <mm/page.h>
#include <mm/frame.h>
#include <mm/slab.h>
#include <arch/mm/page.h>
#include <arch/types.h>
#include <debug.h>
#include <align.h>
 
#define MAX_FRAMES 1024
#define MAX_ORDER 8
#define TEST_RUNS 2
 
void test(void) {
uintptr_t * frames = (uintptr_t *) malloc(MAX_FRAMES*sizeof(uintptr_t), 0);
int results[MAX_ORDER+1];
int i, order, run;
int allocated;
 
ASSERT(TEST_RUNS > 1);
ASSERT(frames != NULL)
 
for (run = 0; run < TEST_RUNS; run++) {
for (order = 0; order <= MAX_ORDER; order++) {
printf("Allocating %d frames blocks ... ", 1 << order);
allocated = 0;
for (i = 0; i < MAX_FRAMES >> order; i++) {
frames[allocated] = (uintptr_t) frame_alloc(order, FRAME_ATOMIC | FRAME_KA);
if (ALIGN_UP(frames[allocated], FRAME_SIZE << order) != frames[allocated]) {
panic("Test failed. Block at address %p (size %dK) is not aligned\n", frames[allocated], (FRAME_SIZE << order) >> 10);
}
if (frames[allocated]) {
allocated++;
} else {
printf("done. ");
break;
}
}
printf("%d blocks allocated.\n", allocated);
if (run) {
if (results[order] != allocated) {
panic("Test failed. Frame leak possible.\n");
}
} else
results[order] = allocated;
printf("Deallocating ... ");
for (i = 0; i < allocated; i++) {
frame_free(KA2PA(frames[i]));
}
printf("done.\n");
}
}
 
free(frames);
printf("Test passed.\n");
}
 
/tags/0.2.0.3/kernel/test/mm/falloc2/test.c
0,0 → 1,123
/*
* Copyright (C) 2006 Sergey Bondari
* 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 <print.h>
#include <test.h>
#include <mm/page.h>
#include <mm/frame.h>
#include <mm/slab.h>
#include <arch/mm/page.h>
#include <arch/types.h>
#include <atomic.h>
#include <debug.h>
#include <proc/thread.h>
#include <memstr.h>
#include <arch.h>
 
#define MAX_FRAMES 256
#define MAX_ORDER 8
 
#define THREAD_RUNS 1
#define THREADS 8
 
static void falloc(void * arg);
static void failed(void);
 
static atomic_t thread_count;
 
void falloc(void * arg)
{
int order, run, allocated, i;
uint8_t val = THREAD->tid % THREADS;
index_t k;
uintptr_t * frames = (uintptr_t *) malloc(MAX_FRAMES * sizeof(uintptr_t), FRAME_ATOMIC);
ASSERT(frames != NULL);
thread_detach(THREAD);
 
for (run = 0; run < THREAD_RUNS; run++) {
for (order = 0; order <= MAX_ORDER; order++) {
printf("Thread #%d (cpu%d): Allocating %d frames blocks ... \n", THREAD->tid, CPU->id, 1 << order);
allocated = 0;
for (i = 0; i < (MAX_FRAMES >> order); i++) {
frames[allocated] = (uintptr_t)frame_alloc(order, FRAME_ATOMIC | FRAME_KA);
if (frames[allocated]) {
memsetb(frames[allocated], FRAME_SIZE << order, val);
allocated++;
} else {
break;
}
}
printf("Thread #%d (cpu%d): %d blocks allocated.\n", THREAD->tid, CPU->id, allocated);
 
printf("Thread #%d (cpu%d): Deallocating ... \n", THREAD->tid, CPU->id);
for (i = 0; i < allocated; i++) {
for (k = 0; k <= ((FRAME_SIZE << order) - 1); k++) {
if (((uint8_t *) frames[i])[k] != val) {
printf("Thread #%d (cpu%d): Unexpected data (%d) in block %p offset %#zx\n", THREAD->tid, CPU->id, ((char *) frames[i])[k], frames[i], k);
failed();
}
}
frame_free(KA2PA(frames[i]));
}
printf("Thread #%d (cpu%d): Finished run.\n", THREAD->tid, CPU->id);
}
}
free(frames);
printf("Thread #%d (cpu%d): Exiting\n", THREAD->tid, CPU->id);
atomic_dec(&thread_count);
}
 
 
void failed(void)
{
panic("Test failed.\n");
}
 
 
void test(void)
{
int i;
 
atomic_set(&thread_count, THREADS);
for (i = 0; i < THREADS; i++) {
thread_t * thrd;
thrd = thread_create(falloc, NULL, TASK, 0, "falloc");
if (thrd)
thread_ready(thrd);
else
failed();
}
while (thread_count.count)
;
 
printf("Test passed.\n");
}
/tags/0.2.0.3/kernel/test/mm/slab1/test.c
0,0 → 1,160
/*
* Copyright (C) 2006 Ondrej Palkovsky
* 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 <test.h>
#include <mm/slab.h>
#include <print.h>
#include <proc/thread.h>
#include <arch.h>
#include <panic.h>
#include <memstr.h>
 
#define VAL_COUNT 1024
 
void * data[VAL_COUNT];
 
static void testit(int size, int count)
{
slab_cache_t *cache;
int i;
printf("Creating cache, object size: %d.\n", size);
cache = slab_cache_create("test_cache", size, 0, NULL, NULL,
SLAB_CACHE_NOMAGAZINE);
printf("Allocating %d items...", count);
for (i=0; i < count; i++) {
data[i] = slab_alloc(cache, 0);
memsetb((uintptr_t)data[i], size, 0);
}
printf("done.\n");
printf("Freeing %d items...", count);
for (i=0; i < count; i++) {
slab_free(cache, data[i]);
}
printf("done.\n");
 
printf("Allocating %d items...", count);
for (i=0; i < count; i++) {
data[i] = slab_alloc(cache, 0);
memsetb((uintptr_t)data[i], size, 0);
}
printf("done.\n");
 
printf("Freeing %d items...", count/2);
for (i=count-1; i >= count/2; i--) {
slab_free(cache, data[i]);
}
printf("done.\n");
 
printf("Allocating %d items...", count/2);
for (i=count/2; i < count; i++) {
data[i] = slab_alloc(cache, 0);
memsetb((uintptr_t)data[i], size, 0);
}
printf("done.\n");
printf("Freeing %d items...", count);
for (i=0; i < count; i++) {
slab_free(cache, data[i]);
}
printf("done.\n");
slab_cache_destroy(cache);
 
printf("Test complete.\n");
}
 
static void testsimple(void)
{
testit(100, VAL_COUNT);
testit(200, VAL_COUNT);
testit(1024, VAL_COUNT);
testit(2048, 512);
testit(4000, 128);
testit(8192, 128);
testit(16384, 128);
testit(16385, 128);
}
 
 
#define THREADS 6
#define THR_MEM_COUNT 1024
#define THR_MEM_SIZE 128
 
void * thr_data[THREADS][THR_MEM_COUNT];
slab_cache_t *thr_cache;
semaphore_t thr_sem;
 
static void slabtest(void *data)
{
int offs = (int)(unative_t) data;
int i,j;
thread_detach(THREAD);
printf("Starting thread #%d...\n",THREAD->tid);
for (j=0; j<10; j++) {
for (i=0; i<THR_MEM_COUNT; i++)
thr_data[offs][i] = slab_alloc(thr_cache,0);
for (i=0; i<THR_MEM_COUNT/2; i++)
slab_free(thr_cache, thr_data[offs][i]);
for (i=0; i< THR_MEM_COUNT/2; i++)
thr_data[offs][i] = slab_alloc(thr_cache, 0);
for (i=0; i<THR_MEM_COUNT;i++)
slab_free(thr_cache, thr_data[offs][i]);
}
printf("Thread #%d finished\n", THREAD->tid);
semaphore_up(&thr_sem);
}
 
static void testthreads(void)
{
thread_t *t;
int i;
 
thr_cache = slab_cache_create("thread_cache", THR_MEM_SIZE, 0,
NULL, NULL,
SLAB_CACHE_NOMAGAZINE);
semaphore_initialize(&thr_sem,0);
for (i=0; i<THREADS; i++) {
if (!(t = thread_create(slabtest, (void *)(unative_t)i, TASK, 0, "slabtest")))
panic("could not create thread\n");
thread_ready(t);
}
 
for (i=0; i<THREADS; i++)
semaphore_down(&thr_sem);
slab_cache_destroy(thr_cache);
printf("Test complete.\n");
}
 
void test(void)
{
testsimple();
testthreads();
}
/tags/0.2.0.3/kernel/test/mm/purge1/test.c
0,0 → 1,85
/*
* 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.
*/
#include <print.h>
#include <test.h>
#include <mm/page.h>
#include <mm/frame.h>
#include <mm/as.h>
#include <arch/mm/page.h>
#include <arch/mm/tlb.h>
#include <arch/types.h>
#include <debug.h>
 
 
extern void tlb_invalidate_all(void);
extern void tlb_invalidate_pages(asid_t asid, uintptr_t va, count_t cnt);
void test(void)
{
tlb_entry_t entryi;
tlb_entry_t entryd;
 
int i;
entryd.word[0] = 0;
entryd.word[1] = 0;
entryd.p = true; /* present */
entryd.ma = MA_WRITEBACK;
entryd.a = true; /* already accessed */
entryd.d = true; /* already dirty */
entryd.pl = PL_KERNEL;
entryd.ar = AR_READ | AR_WRITE;
entryd.ppn = 0;
entryd.ps = PAGE_WIDTH;
 
 
entryi.word[0] = 0;
entryi.word[1] = 0;
entryi.p = true; /* present */
entryi.ma = MA_WRITEBACK;
entryi.a = true; /* already accessed */
entryi.d = true; /* already dirty */
entryi.pl = PL_KERNEL;
entryi.ar = AR_READ | AR_EXECUTE;
entryi.ppn = 0;
entryi.ps = PAGE_WIDTH;
 
for(i=0;i<100;i++)
{
itc_mapping_insert(0+i*(1<<PAGE_WIDTH),8,entryi);
dtc_mapping_insert(0+i*(1<<PAGE_WIDTH),9,entryd);
}
 
tlb_invalidate_pages(8,0x0c000,14);
/*tlb_invalidate_all();*/
}
/tags/0.2.0.3/kernel/test/mm/slab2/test.c
0,0 → 1,221
/*
* Copyright (C) 2006 Ondrej Palkovsky
* 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 <test.h>
#include <mm/slab.h>
#include <print.h>
#include <proc/thread.h>
#include <arch.h>
#include <panic.h>
#include <mm/frame.h>
#include <memstr.h>
#include <synch/condvar.h>
#include <synch/mutex.h>
 
#define ITEM_SIZE 256
 
/** Fill memory with 2 caches, when allocation fails,
* free one of the caches. We should have everything in magazines,
* now allocation should clean magazines and allow for full allocation.
*/
static void totalmemtest(void)
{
slab_cache_t *cache1;
slab_cache_t *cache2;
int i;
 
void *data1, *data2;
void *olddata1=NULL, *olddata2=NULL;
cache1 = slab_cache_create("cache1_tst", ITEM_SIZE, 0, NULL, NULL, 0);
cache2 = slab_cache_create("cache2_tst", ITEM_SIZE, 0, NULL, NULL, 0);
 
printf("Allocating...");
/* Use atomic alloc, so that we find end of memory */
do {
data1 = slab_alloc(cache1, FRAME_ATOMIC);
data2 = slab_alloc(cache2, FRAME_ATOMIC);
if (!data1 || !data2) {
if (data1)
slab_free(cache1,data1);
if (data2)
slab_free(cache2,data2);
break;
}
memsetb((uintptr_t)data1, ITEM_SIZE, 0);
memsetb((uintptr_t)data2, ITEM_SIZE, 0);
*((void **)data1) = olddata1;
*((void **)data2) = olddata2;
olddata1 = data1;
olddata2 = data2;
}while(1);
printf("done.\n");
/* We do not have memory - now deallocate cache2 */
printf("Deallocating cache2...");
while (olddata2) {
data2 = *((void **)olddata2);
slab_free(cache2, olddata2);
olddata2 = data2;
}
printf("done.\n");
 
printf("Allocating to cache1...\n");
for (i=0; i<30; i++) {
data1 = slab_alloc(cache1, FRAME_ATOMIC);
if (!data1) {
panic("Incorrect memory size - use another test.");
}
memsetb((uintptr_t)data1, ITEM_SIZE, 0);
*((void **)data1) = olddata1;
olddata1 = data1;
}
while (1) {
data1 = slab_alloc(cache1, FRAME_ATOMIC);
if (!data1) {
break;
}
memsetb((uintptr_t)data1, ITEM_SIZE, 0);
*((void **)data1) = olddata1;
olddata1 = data1;
}
printf("Deallocating cache1...");
while (olddata1) {
data1 = *((void **)olddata1);
slab_free(cache1, olddata1);
olddata1 = data1;
}
printf("done.\n");
slab_print_list();
slab_cache_destroy(cache1);
slab_cache_destroy(cache2);
}
 
slab_cache_t *thr_cache;
semaphore_t thr_sem;
condvar_t thread_starter;
mutex_t starter_mutex;
 
#define THREADS 8
 
static void slabtest(void *priv)
{
void *data=NULL, *new;
 
thread_detach(THREAD);
 
mutex_lock(&starter_mutex);
condvar_wait(&thread_starter,&starter_mutex);
mutex_unlock(&starter_mutex);
printf("Starting thread #%d...\n",THREAD->tid);
 
/* Alloc all */
printf("Thread #%d allocating...\n", THREAD->tid);
while (1) {
/* Call with atomic to detect end of memory */
new = slab_alloc(thr_cache, FRAME_ATOMIC);
if (!new)
break;
*((void **)new) = data;
data = new;
}
printf("Thread #%d releasing...\n", THREAD->tid);
while (data) {
new = *((void **)data);
*((void **)data) = NULL;
slab_free(thr_cache, data);
data = new;
}
printf("Thread #%d allocating...\n", THREAD->tid);
while (1) {
/* Call with atomic to detect end of memory */
new = slab_alloc(thr_cache, FRAME_ATOMIC);
if (!new)
break;
*((void **)new) = data;
data = new;
}
printf("Thread #%d releasing...\n", THREAD->tid);
while (data) {
new = *((void **)data);
*((void **)data) = NULL;
slab_free(thr_cache, data);
data = new;
}
 
 
printf("Thread #%d finished\n", THREAD->tid);
slab_print_list();
semaphore_up(&thr_sem);
}
 
 
static void multitest(int size)
{
/* Start 8 threads that just allocate as much as possible,
* then release everything, then again allocate, then release
*/
thread_t *t;
int i;
 
printf("Running stress test with size %d\n", size);
condvar_initialize(&thread_starter);
mutex_initialize(&starter_mutex);
 
thr_cache = slab_cache_create("thread_cache", size, 0,
NULL, NULL,
0);
semaphore_initialize(&thr_sem,0);
for (i=0; i<THREADS; i++) {
if (!(t = thread_create(slabtest, NULL, TASK, 0, "slabtest")))
panic("could not create thread\n");
thread_ready(t);
}
thread_sleep(1);
condvar_broadcast(&thread_starter);
 
for (i=0; i<THREADS; i++)
semaphore_down(&thr_sem);
slab_cache_destroy(thr_cache);
printf("Stress test complete.\n");
}
 
void test(void)
{
printf("Running reclaim single-thread test .. pass1\n");
totalmemtest();
printf("Running reclaim single-thread test .. pass2\n");
totalmemtest();
printf("Reclaim test OK.\n");
 
multitest(128);
multitest(2048);
multitest(8192);
printf("All done.\n");
}
/tags/0.2.0.3/kernel/test/mm/mapping1/test.c
0,0 → 1,85
/*
* 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.
*/
#include <print.h>
#include <test.h>
#include <mm/page.h>
#include <mm/frame.h>
#include <mm/as.h>
#include <arch/mm/page.h>
#include <arch/types.h>
#include <debug.h>
 
#define PAGE0 0x10000000
#define PAGE1 (PAGE0+PAGE_SIZE)
 
#define VALUE0 0x01234567
#define VALUE1 0x89abcdef
 
void test(void)
{
uintptr_t frame0, frame1;
uint32_t v0, v1;
 
printf("Memory management test mapping #1\n");
 
frame0 = frame_alloc(ONE_FRAME, FRAME_KA);
frame1 = frame_alloc(ONE_FRAME, FRAME_KA);
 
printf("Writing %#x to physical address %p.\n", VALUE0, KA2PA(frame0));
*((uint32_t *) frame0) = VALUE0;
printf("Writing %#x to physical address %p.\n", VALUE1, KA2PA(frame1));
*((uint32_t *) frame1) = VALUE1;
printf("Mapping virtual address %p to physical address %p.\n", PAGE0, KA2PA(frame0));
page_mapping_insert(AS_KERNEL, PAGE0, KA2PA(frame0), PAGE_PRESENT | PAGE_WRITE);
printf("Mapping virtual address %p to physical address %p.\n", PAGE1, KA2PA(frame1));
page_mapping_insert(AS_KERNEL, PAGE1, KA2PA(frame1), PAGE_PRESENT | PAGE_WRITE);
printf("Value at virtual address %p is %#x.\n", PAGE0, v0 = *((uint32_t *) PAGE0));
printf("Value at virtual address %p is %#x.\n", PAGE1, v1 = *((uint32_t *) PAGE1));
ASSERT(v0 == VALUE0);
ASSERT(v1 == VALUE1);
 
printf("Writing %#x to virtual address %p.\n", 0, PAGE0);
*((uint32_t *) PAGE0) = 0;
printf("Writing %#x to virtual address %p.\n", 0, PAGE1);
*((uint32_t *) PAGE1) = 0;
 
v0 = *((uint32_t *) PAGE0);
v1 = *((uint32_t *) PAGE1);
printf("Value at virtual address %p is %#x.\n", PAGE0, *((uint32_t *) PAGE0));
printf("Value at virtual address %p is %#x.\n", PAGE1, *((uint32_t *) PAGE1));
 
ASSERT(v0 == 0);
ASSERT(v1 == 0);
printf("Test passed.\n");
}
/tags/0.2.0.3/kernel/test/fpu/mips1/test.c
0,0 → 1,136
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 <print.h>
#include <debug.h>
#include <panic.h>
 
#include <test.h>
#include <atomic.h>
#include <proc/thread.h>
#include <time/delay.h>
 
#include <arch.h>
 
#define THREADS 50
#define DELAY 10000L
#define ATTEMPTS 5
 
static atomic_t threads_ok;
static waitq_t can_start;
 
static void testit1(void *data)
{
int i;
int arg __attribute__((aligned(16))) = (int)((unative_t) data);
int after_arg __attribute__((aligned(16)));
 
thread_detach(THREAD);
waitq_sleep(&can_start);
 
for (i = 0; i<ATTEMPTS; i++) {
__asm__ volatile (
"mtc1 %0,$1"
:"=r"(arg)
);
 
delay(DELAY);
__asm__ volatile (
"mfc1 %0, $1"
:"=r"(after_arg)
);
if(arg != after_arg)
panic("General reg tid%d: arg(%d) != %d\n",
THREAD->tid, arg, after_arg);
}
 
atomic_inc(&threads_ok);
}
 
static void testit2(void *data)
{
int i;
int arg __attribute__((aligned(16))) = (int)((unative_t) data);
int after_arg __attribute__((aligned(16)));
 
thread_detach(THREAD);
 
waitq_sleep(&can_start);
 
for (i = 0; i<ATTEMPTS; i++) {
__asm__ volatile (
"mtc1 %0,$1"
:"=r"(arg)
);
 
scheduler();
__asm__ volatile (
"mfc1 %0,$1"
:"=r"(after_arg)
);
if(arg != after_arg)
panic("General reg tid%d: arg(%d) != %d\n",
THREAD->tid, arg, after_arg);
}
 
atomic_inc(&threads_ok);
}
 
 
void test(void)
{
thread_t *t;
int i;
 
waitq_initialize(&can_start);
 
printf("MIPS test #1\n");
printf("Creating %d threads... ", THREADS);
 
for (i=0; i<THREADS/2; i++) {
if (!(t = thread_create(testit1, (void *)((unative_t)i*2), TASK, 0, "testit1")))
panic("could not create thread\n");
thread_ready(t);
if (!(t = thread_create(testit2, (void *)((unative_t)i*2+1), TASK, 0, "testit2")))
panic("could not create thread\n");
thread_ready(t);
}
 
printf("ok\n");
thread_sleep(1);
waitq_wakeup(&can_start, WAKEUP_ALL);
 
while (atomic_get(&threads_ok) != THREADS)
;
printf("Test passed.\n");
}
/tags/0.2.0.3/kernel/test/fpu/fpu1/test.c
0,0 → 1,178
/*
* Copyright (C) 2005 Jakub Vana
* 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.
*/
 
#include <print.h>
#include <debug.h>
#include <panic.h>
 
#include <test.h>
#include <atomic.h>
#include <proc/thread.h>
 
#include <arch.h>
#include <arch/arch.h>
 
#define THREADS 150*2
#define ATTEMPTS 100
 
#define E_10e8 271828182
#define PI_10e8 314159265
 
 
#ifdef __ia32_ARCH_H__
static inline double sqrt(double x) { double v; __asm__ ("fsqrt\n" : "=t" (v) : "0" (x)); return v; }
#endif
 
#ifdef __amd64_ARCH_H__
static inline double sqrt(double x) { double v; __asm__ ("fsqrt\n" : "=t" (v) : "0" (x)); return v; }
#endif
 
#ifdef __ia64_ARCH_H__
static inline long double sqrt(long double a)
{
long double x = 1;
long double lx = 0;
 
if(a<0.00000000000000001) return 0;
while(x!=lx)
{
lx=x;
x=(x+(a/x))/2;
}
return x;
}
#endif
 
 
 
static atomic_t threads_ok;
static waitq_t can_start;
 
static void e(void *data)
{
int i;
double e,d,le,f;
 
thread_detach(THREAD);
 
waitq_sleep(&can_start);
 
for (i = 0; i<ATTEMPTS; i++) {
le=-1;
e=0;
f=1;
 
for(d=1;e!=le;d*=f,f+=1) {
le=e;
e=e+1/d;
}
 
if((int)(100000000*e)!=E_10e8)
panic("tid%d: e*10e8=%zd should be %zd\n", THREAD->tid, (unative_t) (100000000*e),(unative_t) E_10e8);
}
 
printf("tid%d: e*10e8=%zd should be %zd\n", THREAD->tid, (unative_t) (100000000*e),(unative_t) E_10e8);
atomic_inc(&threads_ok);
}
 
static void pi(void *data)
{
 
#ifdef __ia64_ARCH_H__
#undef PI_10e8
#define PI_10e8 3141592
#endif
 
 
int i;
double lpi, pi;
double n, ab, ad;
thread_detach(THREAD);
 
waitq_sleep(&can_start);
 
 
for (i = 0; i<ATTEMPTS; i++) {
lpi = -1;
pi = 0;
 
for (n=2, ab = sqrt(2); lpi != pi; n *= 2, ab = ad) {
double sc, cd;
 
sc = sqrt(1 - (ab*ab/4));
cd = 1 - sc;
ad = sqrt(ab*ab/4 + cd*cd);
lpi = pi;
pi = 2 * n * ad;
}
 
#ifdef __ia64_ARCH_H__
if((int)(1000000*pi)!=PI_10e8)
panic("tid%d: pi*10e8=%zd should be %zd\n", THREAD->tid, (unative_t) (1000000*pi),(unative_t) (PI_10e8/100));
#else
if((int)(100000000*pi)!=PI_10e8)
panic("tid%d: pi*10e8=%zd should be %zd\n", THREAD->tid, (unative_t) (100000000*pi),(unative_t) PI_10e8);
#endif
 
}
 
printf("tid%d: pi*10e8=%zd should be %zd\n", THREAD->tid, (unative_t) (100000000*pi),(unative_t) PI_10e8);
atomic_inc(&threads_ok);
}
 
void test(void)
{
thread_t *t;
int i;
 
waitq_initialize(&can_start);
 
printf("FPU test #1\n");
printf("Creating %d threads... ", THREADS);
 
for (i=0; i<THREADS/2; i++) {
if (!(t = thread_create(e, NULL, TASK, 0, "e")))
panic("could not create thread\n");
thread_ready(t);
if (!(t = thread_create(pi, NULL, TASK, 0, "pi")))
panic("could not create thread\n");
thread_ready(t);
}
printf("ok\n");
thread_sleep(1);
waitq_wakeup(&can_start, WAKEUP_ALL);
 
while (atomic_get(&threads_ok) != THREADS)
;
printf("Test passed.\n");
}
/tags/0.2.0.3/kernel/test/fpu/sse1/test.c
0,0 → 1,136
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 <print.h>
#include <debug.h>
#include <panic.h>
 
#include <test.h>
#include <atomic.h>
#include <proc/thread.h>
#include <time/delay.h>
 
#include <arch.h>
 
#define THREADS 50
#define DELAY 10000L
#define ATTEMPTS 5
 
static atomic_t threads_ok;
static waitq_t can_start;
 
static void testit1(void *data)
{
int i;
int arg __attribute__((aligned(16))) = (int)((unative_t) data);
int after_arg __attribute__((aligned(16)));
 
thread_detach(THREAD);
waitq_sleep(&can_start);
 
for (i = 0; i<ATTEMPTS; i++) {
__asm__ volatile (
"movlpd %0, %%xmm2"
:"=m"(arg)
);
 
delay(DELAY);
__asm__ volatile (
"movlpd %%xmm2, %0"
:"=m"(after_arg)
);
if(arg != after_arg)
panic("tid%d: arg(%d) != %d\n",
THREAD->tid, arg, after_arg);
}
 
atomic_inc(&threads_ok);
}
 
static void testit2(void *data)
{
int i;
int arg __attribute__((aligned(16))) = (int)((unative_t) data);
int after_arg __attribute__((aligned(16)));
 
thread_detach(THREAD);
waitq_sleep(&can_start);
 
for (i = 0; i<ATTEMPTS; i++) {
__asm__ volatile (
"movlpd %0, %%xmm2"
:"=m"(arg)
);
 
scheduler();
__asm__ volatile (
"movlpd %%xmm2, %0"
:"=m"(after_arg)
);
if(arg != after_arg)
panic("tid%d: arg(%d) != %d\n",
THREAD->tid, arg, after_arg);
}
 
atomic_inc(&threads_ok);
}
 
 
void test(void)
{
thread_t *t;
int i;
 
waitq_initialize(&can_start);
 
printf("SSE test #1\n");
printf("Creating %d threads... ", THREADS);
 
for (i=0; i<THREADS/2; i++) {
if (!(t = thread_create(testit1, (void *)((unative_t)i*2), TASK, 0, "testit1")))
panic("could not create thread\n");
thread_ready(t);
if (!(t = thread_create(testit2, (void *)((unative_t)i*2+1), TASK, 0, "testit2")))
panic("could not create thread\n");
thread_ready(t);
}
 
printf("ok\n");
thread_sleep(1);
waitq_wakeup(&can_start, WAKEUP_ALL);
 
while (atomic_get(&threads_ok) != THREADS)
;
printf("Test passed.\n");
}
/tags/0.2.0.3/kernel/test/sysinfo/test.c
0,0 → 1,55
/*
* Copyright (C) 2005 Jakub Vana
* 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 <print.h>
#include <debug.h>
#include <panic.h>
 
#include <test.h>
#include <sysinfo/sysinfo.h>
/*
static unative_t counter(sysinfo_item_t *root)
{
static unative_t i=0;
return i++;
}*/
 
void test(void)
{
/* sysinfo_set_item_val("Ahoj.lidi.uaaaa",NULL,9);
sysinfo_set_item_val("Ahoj.lidi.ubbbb",NULL,15);
sysinfo_set_item_val("Ahoj.lidi",NULL,64);
sysinfo_set_item_function("Ahoj",NULL,counter);
sysinfo_dump(NULL,0);
sysinfo_set_item_val("Ahoj.lidi.ubbbb",NULL,75);
sysinfo_dump(NULL,0);
sysinfo_dump(NULL,0);
sysinfo_dump(NULL,0);*/
sysinfo_dump(NULL,0);
}
/tags/0.2.0.3/kernel/test/print/print1/test.c
0,0 → 1,71
/*
* Copyright (C) 2005 Josef Cejka
* 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 <print.h>
#include <test.h>
 
#define BUFFER_SIZE 32
 
void test(void)
{
int retval;
unative_t nat = 0x12345678u;
char buffer[BUFFER_SIZE];
printf(" Printf test \n");
printf(" text 10.8s %*.*s \n", 5, 3, "text");
printf(" very long text 10.8s %10.8s \n", "very long text");
printf(" text 8.10s %8.10s \n", "text");
printf(" very long text 8.10s %8.10s \n", "very long text");
 
printf(" char: c '%c', 3.2c '%3.2c', -3.2c '%-3.2c', 2.3c '%2.3c', -2.3c '%-2.3c' \n",'a', 'b', 'c', 'd', 'e' );
printf(" int: d '%d', 3.2d '%3.2d', -3.2d '%-3.2d', 2.3d '%2.3d', -2.3d '%-2.3d' \n",1, 1, 1, 1, 1 );
printf(" -int: d '%d', 3.2d '%3.2d', -3.2d '%-3.2d', 2.3d '%2.3d', -2.3d '%-2.3d' \n",-1, -1, -1, -1, -1 );
printf(" 0xint: x '%#x', 5.3x '%#5.3x', -5.3x '%#-5.3x', 3.5x '%#3.5x', -3.5x '%#-3.5x' \n",17, 17, 17, 17, 17 );
 
printf("'%#llx' 64bit, '%#x' 32bit, '%#hhx' 8bit, '%#hx' 16bit, unative_t '%#zx'. '%#llx' 64bit and '%s' string.\n", 0x1234567887654321ll, 0x12345678, 0x12, 0x1234, nat, 0x1234567887654321ull, "Lovely string" );
printf(" Print to NULL '%s'\n",NULL);
 
retval = snprintf(buffer, BUFFER_SIZE, "Short text without parameters.");
printf("Result is: '%s', retval = %d\n", buffer, retval);
 
retval = snprintf(buffer, BUFFER_SIZE, "Very very very long text without parameters.");
printf("Result is: '%s', retval = %d\n", buffer, retval);
printf("Print short text to %d char long buffer via snprintf.\n", BUFFER_SIZE);
retval = snprintf(buffer, BUFFER_SIZE, "Short %s", "text");
printf("Result is: '%s', retval = %d\n", buffer, retval);
printf("Print long text to %d char long buffer via snprintf.\n", BUFFER_SIZE);
retval = snprintf(buffer, BUFFER_SIZE, "Very long %s. This text`s length is more than %d. We are interested in the result.", "text" , BUFFER_SIZE);
printf("Result is: '%s', retval = %d\n", buffer, retval);
return;
}
/tags/0.2.0.3/kernel/test/thread/thread1/test.c
0,0 → 1,67
/*
* Copyright (C) 2005 Jakub Vana
* 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.
*/
 
#include <print.h>
#include <debug.h>
#include <panic.h>
 
#include <test.h>
#include <atomic.h>
#include <proc/thread.h>
 
#include <arch.h>
 
#define THREADS 5
 
static void threadtest(void *data)
{
 
thread_detach(THREAD);
 
while(1)
{
while (1)
;
printf("%d\n",(int)(THREAD->tid));
scheduler();
}
}
 
void test(void)
{
thread_t *t;
int i;
 
for (i=0; i<THREADS; i++) {
if (!(t = thread_create(threadtest, NULL, TASK, 0, "threadtest")))
panic("could not create thread\n");
thread_ready(t);
}
printf("ok\n");
}
/tags/0.2.0.3/kernel/test/btree/btree1/test.c
0,0 → 1,159
/*
* 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.
*/
 
#include <test.h>
#include <print.h>
#include <adt/btree.h>
#include <debug.h>
 
void *data = (void *) 0xdeadbeef;
 
void test(void)
{
btree_t t;
int i;
 
btree_create(&t);
 
printf("Inserting keys.\n");
btree_insert(&t, 19, data, NULL);
btree_insert(&t, 20, data, NULL);
btree_insert(&t, 21, data, NULL);
btree_insert(&t, 0, data, NULL);
btree_insert(&t, 25, data, NULL);
btree_insert(&t, 22, data, NULL);
btree_insert(&t, 26, data, NULL);
btree_insert(&t, 23, data, NULL);
btree_insert(&t, 24, data, NULL);
btree_insert(&t, 5, data, NULL);
btree_insert(&t, 1, data, NULL);
btree_insert(&t, 4, data, NULL);
btree_insert(&t, 28, data, NULL);
btree_insert(&t, 29, data, NULL);
btree_insert(&t, 7, data, NULL);
btree_insert(&t, 8, data, NULL);
btree_insert(&t, 9, data, NULL);
btree_insert(&t, 17, data, NULL);
btree_insert(&t, 18, data, NULL);
btree_insert(&t, 2, data, NULL);
btree_insert(&t, 3, data, NULL);
btree_insert(&t, 6, data, NULL);
btree_insert(&t, 10, data, NULL);
btree_insert(&t, 11, data, NULL);
btree_insert(&t, 12, data, NULL);
btree_insert(&t, 13, data, NULL);
btree_insert(&t, 14, data, NULL);
btree_insert(&t, 15, data, NULL);
btree_insert(&t, 16, data, NULL);
btree_insert(&t, 27, data, NULL);
 
for (i = 30; i < 50; i++)
btree_insert(&t, i, data, NULL);
for (i = 100; i >= 50; i--)
btree_insert(&t, i, data, NULL);
 
btree_print(&t);
printf("Removing keys.\n");
btree_remove(&t, 50, NULL);
btree_remove(&t, 49, NULL);
btree_remove(&t, 51, NULL);
btree_remove(&t, 46, NULL);
btree_remove(&t, 45, NULL);
btree_remove(&t, 48, NULL);
btree_remove(&t, 53, NULL);
btree_remove(&t, 47, NULL);
btree_remove(&t, 52, NULL);
btree_remove(&t, 54, NULL);
btree_remove(&t, 65, NULL);
btree_remove(&t, 60, NULL);
btree_remove(&t, 99, NULL);
btree_remove(&t, 97, NULL);
btree_remove(&t, 57, NULL);
btree_remove(&t, 58, NULL);
btree_remove(&t, 61, NULL);
btree_remove(&t, 64, NULL);
btree_remove(&t, 56, NULL);
btree_remove(&t, 41, NULL);
 
for (i = 5; i < 20; i++)
btree_remove(&t, i, NULL);
 
btree_remove(&t, 2, NULL);
btree_remove(&t, 43, NULL);
btree_remove(&t, 22, NULL);
btree_remove(&t, 100, NULL);
btree_remove(&t, 98, NULL);
btree_remove(&t, 96, NULL);
btree_remove(&t, 66, NULL);
btree_remove(&t, 1, NULL);
 
for (i = 70; i < 90; i++)
btree_remove(&t, i, NULL);
 
btree_remove(&t, 20, NULL);
btree_remove(&t, 0, NULL);
btree_remove(&t, 40, NULL);
btree_remove(&t, 3, NULL);
btree_remove(&t, 4, NULL);
btree_remove(&t, 21, NULL);
btree_remove(&t, 44, NULL);
btree_remove(&t, 55, NULL);
btree_remove(&t, 62, NULL);
btree_remove(&t, 26, NULL);
btree_remove(&t, 27, NULL);
btree_remove(&t, 28, NULL);
btree_remove(&t, 29, NULL);
btree_remove(&t, 30, NULL);
btree_remove(&t, 31, NULL);
btree_remove(&t, 32, NULL);
btree_remove(&t, 33, NULL);
btree_remove(&t, 93, NULL);
btree_remove(&t, 95, NULL);
btree_remove(&t, 94, NULL);
btree_remove(&t, 69, NULL);
btree_remove(&t, 68, NULL);
btree_remove(&t, 92, NULL);
btree_remove(&t, 91, NULL);
btree_remove(&t, 67, NULL);
btree_remove(&t, 63, NULL);
btree_remove(&t, 90, NULL);
btree_remove(&t, 59, NULL);
btree_remove(&t, 23, NULL);
btree_remove(&t, 24, NULL);
btree_remove(&t, 25, NULL);
btree_remove(&t, 37, NULL);
btree_remove(&t, 38, NULL);
btree_remove(&t, 42, NULL);
btree_remove(&t, 39, NULL);
btree_remove(&t, 34, NULL);
btree_remove(&t, 35, NULL);
btree_remove(&t, 36, NULL);
 
btree_print(&t);
}
/tags/0.2.0.3/kernel/test/debug/mips1/test.c
0,0 → 1,50
/*
* Copyright (C) 2005 Ondrej Palkovsky
* 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 <print.h>
#include <debug.h>
#include <panic.h>
 
#include <test.h>
#include <atomic.h>
#include <proc/thread.h>
#include <time/delay.h>
 
#include <arch.h>
 
 
void test(void)
{
printf("MIPS debug test #1\n");
 
printf("You should enter kconsole debug mode now.\n");
 
asm __volatile__ ("break");
 
printf("Test passed.\n");
}
/tags/0.2.0.3/kernel/test/fault/fault1/test.c
0,0 → 1,46
/*
* Copyright (C) 2005 Jakub Vana
* 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.
*/
 
#include <print.h>
#include <debug.h>
#include <panic.h>
 
#include <test.h>
#include <atomic.h>
#include <proc/thread.h>
 
#include <arch.h>
 
 
void test(void)
{
 
((int *)(0))[1]=0;
 
}
/tags/0.2.0.3/kernel/test/atomic/atomic1/test.c
0,0 → 1,56
/*
* 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.
*/
 
#include <test.h>
#include <print.h>
#include <atomic.h>
#include <debug.h>
 
void test(void)
{
atomic_t a;
 
atomic_set(&a, 10);
printf("Testing atomic_set() and atomic_get().\n");
ASSERT(atomic_get(&a) == 10);
printf("Testing atomic_postinc()\n");
ASSERT(atomic_postinc(&a) == 10);
ASSERT(atomic_get(&a) == 11);
printf("Testing atomic_postdec()\n");
ASSERT(atomic_postdec(&a) == 11);
ASSERT(atomic_get(&a) == 10);
printf("Testing atomic_preinc()\n");
ASSERT(atomic_preinc(&a) == 11);
ASSERT(atomic_get(&a) == 11);
printf("Testing atomic_predec()\n");
ASSERT(atomic_postdec(&a) == 11);
ASSERT(atomic_get(&a) == 10);
 
printf("Test passed.\n");
return;
}
/tags/0.2.0.3/kernel/doc/arch/amd64
0,0 → 1,35
amd64 port
==========
 
The fifth port, amd64 port, was originally written by Ondrej Palkovsky.
The goal is to support AMD64 and Intel Extended Memory 64 Technology PC's.
The port makes use of portable parts of ia32.
Both uniprocessors and multiprocessors are supported.
The kernel runs on real hardware and in simulators too.
 
HARDWARE REQUIREMENTS
o AMD64 architecture processor
o Intel Extended Memory 64 Technology processor
 
CPU
o Intel Xeon with Intel Extended Memory 64 Technology
o AMD Athlon 64
 
SMP COMPATIBILITY
o Bochs 2.2.1 - 2.2.6
o 2x-8x AMD64 CPU
o Simics 2.2.19
o 2x-15x AMD hammer CPU
o QEMU 0.8.0 - QEMU 0.8.1
o 2x-15x CPU
o HP ProLiant ML350 (HyperThreading)
 
EMULATORS AND VIRTUALIZERS
o Bochs 2.2.6
o Simics 2.2.19
o QEMU 0.8.1
 
TOOLCHAIN REQUIREMENTS
o binutils 2.16, 2.16.1
o gcc 4.0.1, 4.1.0, 4.1.1
o older versions may do as well, but are now obsoleted
/tags/0.2.0.3/kernel/doc/arch/ia64
0,0 → 1,16
ia64 port
=========
 
ia64 port is the third port of SPARTAN originally written by Jakub Jermar.
It is still in its early stages. It runs on HP Ski simulator of IA-64 architecture.
 
HARDWARE REQUIREMENTS
o no real hardware supported
 
EMULATORS AND VIRTUALIZERS
o ski
 
TOOLCHAIN REQUIREMENTS
o binutils 2.15, 2.16, 2.16.1
o gcc 4.0.0, 4.0.1, 4.1.0, 4.1.1
o older versions may do as well, but are now obsoleted
/tags/0.2.0.3/kernel/doc/arch/ppc32
0,0 → 1,16
ppc32 port
==========
 
ppc32 port is the fourth port of SPARTAN, originally written by Martin Decky.
The goal is to support 32-bit PowerPC architecture.
So far, it runs only in emulator.
 
HARDWARE REQUIREMENTS
o no real hardware supported
 
EMULATORS AND VIRTUALIZERS
o PearPC
 
TOOLCHAIN REQUIREMENTS
o binutils 2.16
o gcc 4.0.1, 4.1.0, 4.1.1
/tags/0.2.0.3/kernel/doc/arch/mips32
0,0 → 1,24
mips32 port
===========
 
mips32 is the second port of SPARTAN kernel originally written by Jakub Jermar.
It was first developed to run on MIPS R4000 32-bit simulator.
Now it can run on real hardware as well.
It can be compiled and run either as little- or big-endian.
 
HARDWARE REQUIREMENTS
o SGI Indy R4600
o emulated MIPS 4K CPU
 
CPU
o QED R4600
 
EMULATORS AND VIRTUALIZERS
o msim 1.2.8
o gxemul - both big and little endian
o simics 2.2.19
 
TOOLCHAIN REQUIREMENTS
o binutils 2.16, 2.16.1
o gcc 4.0.1, 4.1.0, 4.1.1
o older versions may do as well, but are now obsoleted
/tags/0.2.0.3/kernel/doc/arch/ia32
0,0 → 1,40
ia32 port
=========
 
ia32 port is the oldest and the most advanced one.
It was originally written by Jakub Jermar.
It is meant to support ordinary PC's based on IA-32 architecture.
Both uniprocessor and multiprocessor modes are supported.
It runs both in emulated environment and on real hardware.
 
HARDWARE REQUIREMENTS
o IA-32 processor (Pentium and successors)
 
SMP COMPATIBILITY
o Bochs 2.0.2 - Bochs 2.2.6
o 2x-8x 686 CPU
o Simics 2.0.28 - Simics 2.2.19
o 2x-15x Pentium 4 CPU
o VMware Workstation 5.5
o 2x CPU
o QEMU 0.8.0 - QEMU 0.8.1
o 2x-15x CPU
o ASUS P/I-P65UP5 + ASUS C-P55T2D REV. 1.41
o 2x 200Mhz Pentium CPU
o ASUS PCH-DL
o 2x 3000Mhz Pentium 4 Xeon (HT) CPU
o MSI K7D Master-L
o 2x 2100MHz Athlon MP CPU
o ECS 865PE-A REV : 2.0
o 1x 2800MHz Pentium 4 Prescott (HT) CPU
 
EMULATORS AND VIRTUALIZERS
o Bochs 2.0.2 - Bochs 2.2.6
o VMware Workstation 4, VMware Workstation 5, VMware Workstation 5.5
o Simics 2.2.19
o QEMU 0.8.0 - QEMU 0.8.1
 
TOOLCHAIN REQUIREMENTS
o binutils 2.15, 2.16, 2.16.1
o gcc 3.3.5, 4.0.1, 4.1.0, 4.1.1
o older versions may do as well, but are now obsoleted
/tags/0.2.0.3/kernel/doc/arch/sparc64
0,0 → 1,8
sparc64 port
============
 
Currently, this porting effort is subject to
Jakub Jermar's work on his master thesis.
 
The goal is to provide support for UltraSPARC
implementation of SPARC V9 architecture.
/tags/0.2.0.3/kernel/doc/doxygroups.h
0,0 → 1,390
 
/* Definitions of modules and its relations for generating Doxygen documentation */
 
/** @defgroup genericadt Data types
* @ingroup kernel
*/
 
/** @defgroup main Kernel initialization
* @ingroup others
*/
 
/** @defgroup genericconsole Kernel console
* @ingroup others
*/
 
/**
* @defgroup time Time management
* @ingroup kernel
*/
 
/**
* @defgroup proc Scheduling
* @ingroup kernel
*/
/** @defgroup genericproc generic
* @ingroup proc
*/
/**
* @cond amd64
* @defgroup amd64proc amd64
* @ingroup proc
* @endcond
*/
 
/**
* @cond ia32
* @defgroup ia32proc ia32
* @ingroup proc
* @endcond
*/
 
/**
* @cond ia64
* @defgroup ia64proc ia64
* @ingroup proc
* @endcond
*/
 
/**
* @cond mips32
* @defgroup mips32proc mips32
* @ingroup proc
* @endcond
*/
 
/**
* @cond ppc32
* @defgroup ppc32proc ppc32
* @ingroup proc
* @endcond
*/
 
/**
* @cond ppc64
* @defgroup ppc64proc ppc64
* @ingroup proc
* @endcond
*/
 
/**
* @cond sparc64
* @defgroup sparc64proc sparc64
* @ingroup proc
* @endcond
*/
 
 
/** @defgroup sync Synchronization
* @ingroup kernel
*/
 
 
/** @defgroup mm Memory management
* @ingroup kernel
*/
/**
* @defgroup genericmm generic
* @ingroup mm
*/
/**
* @defgroup genarchmm genarch
* @ingroup mm
*/
/**
* @cond amd64
* @defgroup amd64mm amd64
* @ingroup mm
* @endcond
*/
/**
* @cond ia32
* @defgroup ia32mm ia32
* @ingroup mm
* @endcond
*/
/**
* @cond ia64
* @defgroup ia64mm ia64
* @ingroup mm
* @endcond
*/
/**
* @cond mips32
* @defgroup mips32mm mips32
* @ingroup mm
* @endcond
*/
/**
* @cond ppc32
* @defgroup ppc32mm ppc32
* @ingroup mm
* @endcond
*/
/**
* @cond ppc64
* @defgroup ppc64mm ppc64
* @ingroup mm
* @endcond
*/
/**
* @cond sparc64
* @defgroup sparc64mm sparc64
* @ingroup mm
* @endcond
*/
 
/** @defgroup genericipc IPC
* @ingroup kernel
*/
/** @defgroup genericklog KLog
* @brief Kernel logging facility
* @ingroup genericconsole
*/
 
 
/** @defgroup ddi Device Driver Interface
* @ingroup kernel
*/
 
/** @defgroup genericddi generic
* @ingroup ddi
*/
 
/**
* @cond amd64
* @defgroup amd64ddi amd64
* @ingroup ddi
* @endcond
*/
 
/**
* @cond ia32
* @defgroup ia32ddi ia32
* @ingroup ddi
* @endcond
*/
 
/**
* @cond ia64
* @defgroup ia64ddi ia64
* @ingroup ddi
* @endcond
*/
 
/**
* @cond mips32
* @defgroup mips32ddi mips32
* @ingroup ddi
* @endcond
*/
 
/**
* @cond ppc32
* @defgroup ppc32ddi ppc32
* @ingroup ddi
* @endcond
*/
 
/**
* @cond ppc64
* @defgroup ppc64ddi ppc64
* @ingroup ddi
* @endcond
*/
 
/**
* @cond sparc64
* @defgroup sparc64ddi sparc64
* @ingroup ddi
* @endcond
*/
 
/** @defgroup debug Debugging
* @ingroup others
*/
/** @defgroup genericdebug generic
* @ingroup debug
*/
/**
* @cond amd64
* @defgroup amd64debug ia32/amd64
* @ingroup debug
* @endcond
*/
 
/**
* @cond ia32
* @defgroup amd64debug ia32/amd64
* @ingroup debug
* @endcond
*/
 
/**
* @cond ia64
* @defgroup ia64debug ia64
* @ingroup debug
* @endcond
*/
 
/**
* @cond mips32
* @defgroup mips32debug mips32
* @ingroup debug
* @endcond
*/
 
/**
* @cond ppc32
* @defgroup ppc32debug ppc32
* @ingroup debug
* @endcond
*/
 
/**
* @cond ppc64
* @defgroup ppc64debug ppc64
* @ingroup debug
* @endcond
*/
 
/**
* @cond sparc64
* @defgroup sparc64debug sparc64
* @ingroup debug
* @endcond
*/
 
/** @defgroup interrupt Interrupt handling and dispatching
* @ingroup kernel
*/
/**
* @defgroup genericinterrupt generic
* @ingroup interrupt
*/
 
/**
* @cond amd64
* @defgroup amd64interrupt amd64
* @ingroup interrupt
* @endcond
*/
 
/**
* @cond ia32
* @defgroup ia32interrupt ia32
* @ingroup interrupt
* @endcond
*/
 
/**
* @cond ia64
* @defgroup ia64interrupt ia64
* @ingroup interrupt
* @endcond
*/
 
/**
* @cond mips32
* @defgroup mips32interrupt mips32
* @ingroup interrupt
* @endcond
*/
 
/**
* @cond ppc32
* @defgroup ppc32interrupt ppc32
* @ingroup interrupt
* @endcond
*/
 
/**
* @cond ppc64
* @defgroup ppc64interrupt ppc64
* @ingroup interrupt
* @endcond
*/
 
/**
* @cond sparc64
* @defgroup sparc64interrupt sparc64
* @ingroup interrupt
* @endcond
*/
 
 
/** @defgroup others Miscellanea
* @ingroup kernel
*/
/** @defgroup generic generic
* @ingroup others
*/
 
/** @defgroup genarch genarch
* @ingroup others
*/
/**
* @cond amd64
* @defgroup amd64 amd64
* @ingroup others
* @endcond
*/
 
/**
* @cond ia32
* @defgroup ia32 ia32
* @ingroup others
* @endcond
*/
 
/**
* @cond ia64
* @defgroup ia64 ia64
* @ingroup others
* @endcond
*/
 
/**
* @cond mips32
* @defgroup mips32 mips32
* @ingroup others
* @endcond
*/
 
/**
* @cond ppc32
* @defgroup ppc32 ppc32
* @ingroup others
* @endcond
*/
 
/**
* @cond ppc64
* @defgroup ppc64 ppc64
* @ingroup others
* @endcond
*/
 
/**
* @cond sparc64
* @defgroup sparc64 sparc64
* @ingroup others
* @endcond
*/
/tags/0.2.0.3/kernel/doc/BUGS_FOUND
0,0 → 1,23
During development of this operating system, there were found bugs in:
 
Simics
======
- ia32 BIOS rewrites memory during AP start in SMP environment (#3351)
- ia32 Simics does not report #GP when EFER.NXE is 0 and finds NX page (#4214)
- incorrect MIPS instructions MSUB, MSUBU
 
Bochs
=====
- FXSAVE/FXRSTOR not working correctly with XMM registers (patch #1282033)
 
Msim
====
- Incorrect interpretation of lwl/lwr/swl/swr instructions
- Omitted excMod case in write_proc_mem()
- Incorrect signed multiplication
 
Gcc
===
- Incorrect generation of unaligned data access instructions
(lwl/lwr/swl/swr) when using mipsel- target and -EB(big endian)
compilation, -O2 (#23824)
/tags/0.2.0.3/kernel/doc/mm
0,0 → 1,87
Memory management
=================
 
1. Virtual Address Translation
 
1.1 Hierarchical 4-level per address space page tables
 
SPARTAN kernel deploys generic interface for 4-level page tables
for these architectures: amd64, ia32, mips32 and ppc32. In this
setting, page tables are hierarchical and are not shared by
address spaces (i.e. one set of page tables per address space).
 
 
VADDR
+-----------------------------------------------------------------------------+
| PTL0_INDEX | PTL1_INDEX | PTL2_INDEX | PTL3_INDEX | OFFSET |
+-----------------------------------------------------------------------------+
 
 
PTL0 PTL1 PTL2 PTL3
+--------+ +--------+ +--------+ +--------+
| | | | | PTL3 | -----\ | |
| | | | +--------+ | | |
| | +--------+ | | | | |
| | | PTL2 | -----\ | | | | |
| | +--------+ | | | | | |
| | | | | | | | +--------+
+--------+ | | | | | | | FRAME |
| PTL1 | -----\ | | | | | | +--------+
+--------+ | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
+--------+ \----> +--------+ \----> +--------+ \----> +--------+
^
|
|
+--------+
| PTL0 |
+--------+
 
 
PTL0 Page Table Level 0 (Page Directory)
PTL1 Page Table Level 1
PTL2 Page Table Level 2
PTL3 Page Table Level 3
 
PTL0_INDEX Index into PTL0
PTL1_INDEX Index into PTL1
PTL2_INDEX Index into PTL2
PTL3_INDEX Index into PTL3
 
VADDR Virtual address for which mapping is looked up
FRAME Physical address of memory frame to which VADDR is mapped
 
 
On architectures whose hardware has fewer levels, PTL2 and, if need be, PTL1 are
left out. TLB-only architectures are to define custom format for software page
tables.
 
1.2 Single global page hash table
 
Generic page hash table interface is deployed on 64-bit architectures without
implied hardware support for hierarchical page tables, i.e. ia64 and sparc64.
There is only one global page hash table in the system shared by all address
spaces.
 
 
2. Memory allocators
 
2.1 General allocator
 
'malloc' function accepts flags as a second argument. The flags are directly
passed to the underlying frame_alloc function.
 
1) If the flags parameter contains FRAME_ATOMIC, the allocator will not sleep.
The allocator CAN return NULL, when memory is not directly available.
The caller MUST check if NULL was not returned
 
2) If the flags parameter does not contain FRAME_ATOMIC, the allocator
will never return NULL, but it CAN sleep indefinitely. The caller
does not have to check the return value.
 
3) The maximum size that can be allocated using malloc is 128K
 
Rules 1) and 2) apply to slab_alloc as well. Using SLAB allocator
to allocate too large values is not recommended.
 
/tags/0.2.0.3/kernel/doc/AUTHORS
0,0 → 1,7
Jakub Jermar <jermar@helenos.eu>
Ondrej Palkovsky <palkovsky@helenos.eu>
Martin Decky <decky@helenos.eu>
Jakub Vana <vana@helenos.eu>
Josef Cejka <cejka@helenos.eu>
Sergey Bondari <bondari@helenos.eu>
 
/tags/0.2.0.3/kernel/doc/build
0,0 → 1,14
Following make targets are supported:
 
make, make all
- Check configuration, build
 
make config
- Start kernel configuration program
 
make clean
- Clean build temporary files
 
make distclean
- Clean everything including configuration
 
/tags/0.2.0.3/kernel/doc/synchronization
0,0 → 1,29
 
SPINNING LOCKS
spinlock_lock, spinlock_trylock, spinlock_unlock
+------------+
| spinlock_t |
+------------+
 
WAIT QUEUES
waitq_sleep_timeout, waitq_wakeup
+---------+
| waitq_t |
+---------+
/ \
SEMAPHORES / \ CONDITION VARIABLES
semaphore_down_timeout, semaphore_up condvar_wait_timeout, condvar_signal
+--------------+ / \ +-----------+
| semaphore_t |<-+ +->| condvar_t |
+--------------+ +-----------+
| ^
| |
| +------+
V /
MUTEXES / READERS/WRITERS LOCKS
mutex_lock_timeout, mutex_unlock rwlock_reader/writer_lock_timeout, rwlock_unlock
+---------+ / +----------+
| mutex_t |------------------------------->| rwlock_t |
+---------+ / +----------+
| /
+------------------------+