/tags/0.2.0/kernel/trunk/kernel.config |
---|
File deleted |
/tags/0.2.0/kernel/trunk/doc/BUGS_FOUND |
---|
File deleted |
/tags/0.2.0/kernel/trunk/doc/arch/ppc32 |
---|
File deleted |
/tags/0.2.0/kernel/trunk/doc/arch/amd64 |
---|
File deleted |
/tags/0.2.0/kernel/trunk/doc/arch/mips32 |
---|
File deleted |
/tags/0.2.0/kernel/trunk/doc/arch/ia32 |
---|
File deleted |
/tags/0.2.0/kernel/trunk/doc/arch/sparc64 |
---|
File deleted |
/tags/0.2.0/kernel/trunk/doc/arch/ia64 |
---|
File deleted |
/tags/0.2.0/kernel/trunk/doc/build |
---|
File deleted |
/tags/0.2.0/kernel/trunk/doc/synchronization |
---|
File deleted |
/tags/0.2.0/kernel/trunk/doc/AUTHORS |
---|
File deleted |
/tags/0.2.0/kernel/trunk/doc/mm |
---|
File deleted |
/tags/0.2.0/kernel/trunk/genarch/include/ofw/ofw.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/genarch/include/ofw/memory_init.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/genarch/include/acpi/madt.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/genarch/include/acpi/acpi.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/genarch/include/softint/division.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/genarch/include/i8042/i8042.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/genarch/include/fb/font-8x16.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/genarch/include/fb/fb.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/genarch/include/mm/as_ht.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/genarch/include/mm/page_pt.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/genarch/include/mm/asid_fifo.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/genarch/include/mm/as_pt.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/genarch/include/mm/page_ht.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/genarch/Makefile.inc |
---|
File deleted |
/tags/0.2.0/kernel/trunk/genarch/src/fb/helenos.xbm |
---|
File deleted |
/tags/0.2.0/kernel/trunk/genarch/src/fb/fb.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/genarch/src/fb/font-8x16.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/genarch/src/mm/page_ht.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/genarch/src/mm/as_ht.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/genarch/src/mm/page_pt.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/genarch/src/mm/asid.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/genarch/src/mm/asid_fifo.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/genarch/src/mm/as_pt.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/genarch/src/ofw/ofw.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/genarch/src/ofw/memory_init.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/genarch/src/acpi/madt.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/genarch/src/acpi/acpi.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/genarch/src/softint/division.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/genarch/src/i8042/i8042.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/fpu_context.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/main/kinit.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/main/version.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/main/uinit.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/byteorder.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/bitops.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/sysinfo/sysinfo.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/elf.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/memstr.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/atomic.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/printf/printf_core.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/arch.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/test.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/security/cap.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/preemption.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/typedefs.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/mm/buddy.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/mm/frame.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/mm/page.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/mm/asid.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/mm/slab.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/mm/tlb.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/mm/as.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/stdarg.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/macros.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/debug.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/cpu.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/sort.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/panic.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/userspace.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/func.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/interrupt.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/synch/mutex.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/synch/spinlock.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/synch/semaphore.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/synch/synch.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/synch/waitq.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/synch/futex.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/synch/condvar.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/synch/rwlock.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/symtab.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/stackarg.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/config.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/putchar.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/time/timeout.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/time/clock.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/time/delay.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/smp/smp.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/smp/ipi.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/ddi/ddi.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/ddi/ddi_arg.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/console/kconsole.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/console/console.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/console/cmd.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/console/klog.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/console/chardev.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/proc/task.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/proc/thread.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/proc/uarg.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/proc/scheduler.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/adt/btree.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/adt/fifo.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/adt/hash_table.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/adt/list.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/adt/bitmap.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/syscall/sysarg64.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/syscall/copy.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/syscall/syscall.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/context.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/errno.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/ipc/sysipc.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/ipc/ipc.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/ipc/irq.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/ipc/ipcrsc.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/align.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/include/print.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/time/timeout.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/time/clock.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/time/delay.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/smp/ipi.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/ddi/ddi.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/console/console.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/console/cmd.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/console/klog.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/console/chardev.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/console/kconsole.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/printf/printf.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/printf/snprintf.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/printf/sprintf.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/printf/vprintf.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/printf/vsnprintf.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/printf/printf_core.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/printf/vsprintf.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/proc/thread.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/proc/scheduler.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/proc/the.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/proc/task.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/lib/sort.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/lib/memstr.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/lib/func.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/lib/elf.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/security/cap.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/adt/hash_table.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/adt/list.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/adt/bitmap.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/adt/btree.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/mm/page.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/mm/backend_elf.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/mm/slab.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/mm/tlb.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/mm/backend_anon.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/mm/as.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/mm/buddy.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/mm/backend_phys.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/mm/frame.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/syscall/syscall.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/syscall/copy.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/ipc/sysipc.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/ipc/irq.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/ipc/ipc.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/ipc/ipcrsc.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/preempt/preemption.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/synch/condvar.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/synch/rwlock.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/synch/mutex.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/synch/spinlock.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/synch/semaphore.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/synch/waitq.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/synch/futex.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/main/kinit.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/main/main.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/main/version.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/main/uinit.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/debug/symtab.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/cpu/cpu.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/sysinfo/sysinfo.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/generic/src/interrupt/interrupt.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/_link.ld.in |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/elf.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/memstr.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/arg.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/atomic.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/arch.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/proc/thread.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/proc/task.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/boot/boot.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/trap/exception.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/trap/mmu.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/trap/trap.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/trap/regwin.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/trap/interrupt.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/trap/trap_table.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/faddr.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/asm.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/mm/as.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/mm/frame.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/mm/memory_init.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/mm/page.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/mm/tte.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/mm/mmu.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/mm/asid.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/mm/tlb.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/context.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/register.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/debug.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/barrier.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/cpu.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/drivers/i8042.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/drivers/fb.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/drivers/tick.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/context_offset.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/interrupt.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/fpu_context.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/byteorder.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/console.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/types.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/include/stack.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/Makefile.inc |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/src/asm.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/src/sparc64.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/src/proc/scheduler.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/src/console.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/src/context.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/src/trap/trap.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/src/trap/interrupt.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/src/trap/trap_table.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/src/trap/exception.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/src/cpu/cpu.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/src/mm/frame.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/src/mm/memory_init.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/src/mm/page.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/src/mm/tlb.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/src/mm/as.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/src/panic.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/src/dummy.s |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/src/drivers/tick.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/src/drivers/i8042.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/src/start.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/sparc64/src/ddi/ddi.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/_link.ld.in |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/include/types.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/include/stack.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/include/elf.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/include/memstr.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/include/arg.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/include/atomic.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/include/arch.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/include/proc/thread.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/include/proc/task.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/include/faddr.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/include/asm.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/include/mm/frame.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/include/mm/memory_init.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/include/mm/page.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/include/mm/asid.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/include/mm/vhpt.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/include/mm/tlb.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/include/mm/as.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/include/context.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/include/register.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/include/debug.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/include/barrier.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/include/pal/pal.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/include/cpu.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/include/drivers/it.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/include/interrupt.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/include/fpu_context.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/include/byteorder.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/include/ski/ski.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/Makefile.inc |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/src/ddi/ddi.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/src/asm.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/src/ivt.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/src/proc/scheduler.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/src/ia64.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/src/context.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/src/ski/ski.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/src/cpu/cpu.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/src/putchar.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/src/mm/frame.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/src/mm/page.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/src/mm/tlb.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/src/mm/vhpt.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/src/mm/as.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/src/dummy.s |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/src/interrupt.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/src/drivers/it.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/src/start.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia64/src/fpu_context.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/include/fpu_context.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/include/exception.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/include/byteorder.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/include/cpuid.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/include/types.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/include/elf.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/include/memstr.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/include/arg.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/include/atomic.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/include/arch.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/include/proc/task.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/include/proc/thread.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/include/boot/boot.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/include/faddr.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/include/asm.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/include/mm/asid.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/include/mm/tlb.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/include/mm/as.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/include/mm/frame.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/include/mm/memory_init.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/include/mm/page.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/include/context.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/include/debug.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/include/barrier.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/include/cpu.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/include/drivers/pic.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/include/drivers/cuda.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/include/context_offset.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/include/asm/regname.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/include/interrupt.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/Makefile.inc |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/src/drivers/pic.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/src/drivers/cuda.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/src/exception.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/src/fpu_context.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/src/ddi/ddi.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/src/asm.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/src/proc/scheduler.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/src/boot/boot.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/src/context.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/src/debug/panic.s |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/src/cpu/cpu.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/src/ppc32.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/src/mm/frame.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/src/mm/memory_init.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/src/mm/page.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/src/mm/tlb.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/src/mm/as.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/src/dummy.s |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/src/interrupt.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc32/_link.ld.in |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/src/mm/tlb.c |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/arch/amd64/src/mm/as.c |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/arch/amd64/src/mm/frame.c |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/arch/amd64/src/mm/memory_init.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/src/mm/page.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/src/userspace.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/src/interrupt.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/src/drivers |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/arch/amd64/src/fpu_context.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/src/context.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/src/cpu/cpu.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/src/syscall.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/src/bios |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/arch/amd64/src/amd64.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/src/pm.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/src/delay.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/src/smp/apic.c |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/arch/amd64/src/smp/mps.c |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/arch/amd64/src/smp/smp.c |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/arch/amd64/src/smp/ap.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/src/smp/ipi.c |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/arch/amd64/src/ddi/ddi.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/src/asm_utils.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/src/boot/boot.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/src/proc/thread.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/src/proc/scheduler.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/src/proc/task.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/src/debugger.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/_link.ld.in |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/include/byteorder.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/include/types.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/include/cpuid.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/include/elf.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/include/bios |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/arch/amd64/include/memstr.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/include/smp |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/arch/amd64/include/arg.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/include/ddi/ddi.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/include/syscall.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/include/pm.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/include/atomic.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/include/arch.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/include/proc/task.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/include/proc/thread.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/include/boot/memmap.h |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/arch/amd64/include/boot/boot.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/include/faddr.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/include/asm.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/include/mm/frame.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/include/mm/memory_init.h |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/arch/amd64/include/mm/page.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/include/mm/ptl.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/include/mm/asid.h |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/arch/amd64/include/mm/tlb.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/include/mm/as.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/include/debugger.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/include/context.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/include/barrier.h |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/arch/amd64/include/debug.h |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/arch/amd64/include/cpu.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/include/drivers/ega.h |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/arch/amd64/include/drivers/vesa.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/include/drivers/i8259.h |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/arch/amd64/include/drivers/i8042.h |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/arch/amd64/include/drivers/i8254.h |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/arch/amd64/include/context_offset.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/include/interrupt.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/amd64/include/fpu_context.h |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/arch/amd64/Makefile.inc |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/src/asm.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/src/proc/scheduler.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/src/boot/boot.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/src/context.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/src/debug/panic.s |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/src/cpu/cpu.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/src/mm/frame.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/src/mm/memory_init.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/src/mm/page.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/src/mm/tlb.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/src/mm/as.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/src/dummy.s |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/src/interrupt.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/src/ppc64.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/src/exception.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/src/fpu_context.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/src/ddi/ddi.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/_link.ld.in |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/include/cpuid.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/include/types.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/include/elf.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/include/memstr.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/include/arg.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/include/atomic.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/include/arch.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/include/proc/task.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/include/proc/thread.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/include/boot/boot.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/include/faddr.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/include/asm.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/include/mm/page.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/include/mm/asid.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/include/mm/tlb.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/include/mm/as.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/include/mm/frame.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/include/mm/memory_init.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/include/context.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/include/debug.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/include/barrier.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/include/cpu.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/include/context_offset.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/include/asm/regname.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/include/interrupt.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/include/fpu_context.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/include/exception.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/include/byteorder.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ppc64/Makefile.inc |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/_link.ld.in |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/barrier.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/debug.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/cpu.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/drivers/serial.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/drivers/msim.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/drivers/arc.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/asm/boot.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/asm/regname.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/context_offset.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/interrupt.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/fpu_context.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/exception.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/byteorder.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/console.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/cache.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/types.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/stack.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/elf.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/memstr.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/arg.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/atomic.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/arch.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/proc/task.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/proc/thread.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/faddr.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/asm.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/cp0.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/mm/page.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/mm/asid.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/mm/tlb.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/mm/as.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/mm/frame.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/mm/memory_init.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/debugger.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/include/context.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/Makefile.inc |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/src/debugger.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/src/mm/page.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/src/mm/tlb.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/src/mm/as.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/src/mm/frame.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/src/interrupt.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/src/drivers/msim.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/src/drivers/arc.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/src/drivers/serial.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/src/fpu_context.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/src/exception.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/src/asm.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/src/console.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/src/cache.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/src/context.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/src/cpu/cpu.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/src/panic.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/src/dummy.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/src/start.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/src/mips32.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/mips32/src/ddi/ddi.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/byteorder.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/types.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/cpuid.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/elf.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/bios/bios.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/memstr.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/smp/apic.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/smp/smp.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/smp/mps.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/smp/ap.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/arg.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/ddi/ddi.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/pm.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/atomic.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/arch.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/proc/task.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/proc/thread.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/boot/boot.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/boot/memmap.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/faddr.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/asm.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/mm/frame.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/mm/memory_init.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/mm/page.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/mm/asid.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/mm/tlb.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/mm/as.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/debugger.h |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/arch/ia32/include/context.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/debug.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/barrier.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/cpu.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/drivers/i8042.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/drivers/i8254.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/drivers/ega.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/drivers/vesa.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/drivers/i8259.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/interrupt.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/include/fpu_context.h |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/Makefile.inc |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/mm/tlb.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/mm/as.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/mm/frame.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/mm/memory_init.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/mm/page.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/userspace.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/atomic.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/interrupt.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/drivers/i8254.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/drivers/ega.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/drivers/vesa.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/drivers/i8259.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/ia32.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/fpu_context.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/asm.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/context.s |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/debug/panic.s |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/cpu/cpu.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/bios/bios.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/pm.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/delay.s |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/smp/mps.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/smp/smp.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/smp/ap.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/smp/ipi.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/smp/apic.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/ddi/ddi.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/boot/boot.S |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/proc/task.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/proc/thread.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/proc/scheduler.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/arch/ia32/src/debugger.c |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/arch/ia32/_link.ld.in |
---|
File deleted |
/tags/0.2.0/kernel/trunk/Makefile |
---|
File deleted |
/tags/0.2.0/kernel/trunk/test/synch/rwlock1/test.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/test/synch/rwlock2/test.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/test/synch/semaphore1/test.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/test/synch/rwlock3/test.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/test/synch/semaphore2/test.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/test/synch/rwlock4/test.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/test/synch/rwlock5/test.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/test/debug/mips1/test.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/test/thread/thread1/test.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/test/mm/mapping1/test.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/test/mm/falloc1/test.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/test/mm/falloc2/test.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/test/mm/slab1/test.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/test/mm/slab2/test.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/test/mm/purge1/test.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/test/fpu/fpu1/test.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/test/fpu/sse1/test.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/test/fpu/mips1/test.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/test/sysinfo/test.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/test/fault/fault1/test.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/test/atomic/atomic1/test.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/test/print/print1/test.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/test/btree/btree1/test.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/contrib/arch/ia64/vmaxlma.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/contrib/toolchain/toolchain.ppc32.sh |
---|
File deleted |
Property changes: |
Deleted: svn:executable |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/contrib/toolchain/toolchain.amd64.sh |
---|
File deleted |
Property changes: |
Deleted: svn:executable |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/contrib/toolchain/toolchain.ppc64.sh |
---|
File deleted |
Property changes: |
Deleted: svn:executable |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/contrib/toolchain/toolchain.ia32.sh |
---|
File deleted |
Property changes: |
Deleted: svn:executable |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/contrib/toolchain/toolchain.mipsel32.sh |
---|
File deleted |
Property changes: |
Deleted: svn:executable |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/contrib/toolchain/toolchain.sparc64.sh |
---|
File deleted |
Property changes: |
Deleted: svn:executable |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/contrib/toolchain/toolchain.ia64.sh |
---|
File deleted |
Property changes: |
Deleted: svn:executable |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/contrib/toolchain/toolchain.mipseb32.sh |
---|
File deleted |
Property changes: |
Deleted: svn:executable |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/contrib/conf/ski.conf |
---|
File deleted |
/tags/0.2.0/kernel/trunk/contrib/conf/gxemul.sh |
---|
File deleted |
Property changes: |
Deleted: svn:executable |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/contrib/conf/simics.conf |
---|
File deleted |
/tags/0.2.0/kernel/trunk/contrib/conf/HelenOS.amd64.simics |
---|
File deleted |
/tags/0.2.0/kernel/trunk/contrib/conf/pearpc.conf |
---|
File deleted |
/tags/0.2.0/kernel/trunk/contrib/conf/spmips.conf |
---|
File deleted |
/tags/0.2.0/kernel/trunk/contrib/conf/SPMIPS.simics |
---|
File deleted |
/tags/0.2.0/kernel/trunk/contrib/conf/vmware.conf |
---|
File deleted |
/tags/0.2.0/kernel/trunk/contrib/conf/bootindy |
---|
File deleted |
/tags/0.2.0/kernel/trunk/contrib/conf/dot.bochsrc |
---|
File deleted |
/tags/0.2.0/kernel/trunk/contrib/conf/msim.conf |
---|
File deleted |
/tags/0.2.0/kernel/trunk/contrib/conf/HelenOS.ppc32.simics |
---|
File deleted |
/tags/0.2.0/kernel/trunk/tools/amd64/decpt.py |
---|
File deleted |
Property changes: |
Deleted: svn:executable |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/tools/amd64/gencontext.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/tools/config.py |
---|
File deleted |
Property changes: |
Deleted: svn:executable |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/tools/ppc64/gencontext.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/tools/mips32/gencontext.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/tools/ia32/decpt.py |
---|
File deleted |
Property changes: |
Deleted: svn:executable |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/tools/genmap.py |
---|
File deleted |
Property changes: |
Deleted: svn:executable |
-* |
\ No newline at end of property |
/tags/0.2.0/kernel/trunk/tools/sparc64/gencontext.c |
---|
File deleted |
/tags/0.2.0/kernel/trunk/tools/ppc32/gencontext.c |
---|
File deleted |
/tags/0.2.0/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/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/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/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; |
__u32 seed = 0xdeadbeef; |
static __u32 random(__u32 max); |
static void writer(void *arg); |
static void reader(void *arg); |
static void failed(void); |
__u32 random(__u32 max) |
{ |
__u32 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; |
__u32 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/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; |
__u32 seed = 0xdeadbeef; |
static __u32 random(__u32 max); |
static void consumer(void *arg); |
static void failed(void); |
__u32 random(__u32 max) |
{ |
__u32 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) |
{ |
__u32 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/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/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/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/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 status, order, run, allocated, i; |
__u8 val = THREAD->tid % THREADS; |
index_t k; |
__address * frames = (__address *) malloc(MAX_FRAMES * sizeof(__address), 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] = PA2KA(PFN2ADDR(frame_alloc_rc(order, FRAME_ATOMIC | FRAME_KA, &status))); |
if (status == 0) { |
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 (((__u8 *) 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(ADDR2PFN(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/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((__address)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((__address)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((__address)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)(__native) 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 *)(__native)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/kernel/test/mm/slab2/test.c |
---|
0,0 → 1,219 |
/* |
* 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((__address)data1, ITEM_SIZE, 0); |
memsetb((__address)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((__address)data1, ITEM_SIZE, 0); |
*((void **)data1) = olddata1; |
olddata1 = data1; |
} |
while (1) { |
data1 = slab_alloc(cache1, FRAME_ATOMIC); |
if (!data1) { |
break; |
} |
memsetb((__address)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); |
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); |
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/kernel/test/mm/falloc1/test.c |
---|
0,0 → 1,93 |
/* |
* 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) { |
__address * frames = (__address *) malloc(MAX_FRAMES*sizeof(__address), 0); |
int results[MAX_ORDER+1]; |
int i, order, run; |
int allocated; |
int status; |
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] = PA2KA(PFN2ADDR(frame_alloc_rc(order, FRAME_ATOMIC | FRAME_KA, &status))); |
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 (status == 0) { |
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(ADDR2PFN(KA2PA(frames[i]))); |
} |
printf("done.\n"); |
} |
} |
free(frames); |
printf("Test passed.\n"); |
} |
/tags/0.2.0/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) |
{ |
__address frame0, frame1; |
__u32 v0, v1; |
printf("Memory management test mapping #1\n"); |
frame0 = PA2KA(PFN2ADDR(frame_alloc(ONE_FRAME, FRAME_KA))); |
frame1 = PA2KA(PFN2ADDR(frame_alloc(ONE_FRAME, FRAME_KA))); |
printf("Writing %#x to physical address %p.\n", VALUE0, KA2PA(frame0)); |
*((__u32 *) frame0) = VALUE0; |
printf("Writing %#x to physical address %p.\n", VALUE1, KA2PA(frame1)); |
*((__u32 *) 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 = *((__u32 *) PAGE0)); |
printf("Value at virtual address %p is %#x.\n", PAGE1, v1 = *((__u32 *) PAGE1)); |
ASSERT(v0 == VALUE0); |
ASSERT(v1 == VALUE1); |
printf("Writing %#x to virtual address %p.\n", 0, PAGE0); |
*((__u32 *) PAGE0) = 0; |
printf("Writing %#x to virtual address %p.\n", 0, PAGE1); |
*((__u32 *) PAGE1) = 0; |
v0 = *((__u32 *) PAGE0); |
v1 = *((__u32 *) PAGE1); |
printf("Value at virtual address %p is %#x.\n", PAGE0, *((__u32 *) PAGE0)); |
printf("Value at virtual address %p is %#x.\n", PAGE1, *((__u32 *) PAGE1)); |
ASSERT(v0 == 0); |
ASSERT(v1 == 0); |
printf("Test passed.\n"); |
} |
/tags/0.2.0/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, __address 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/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)((__native) 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)((__native) 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 *)((__native)i*2), TASK, 0, "testit1"))) |
panic("could not create thread\n"); |
thread_ready(t); |
if (!(t = thread_create(testit2, (void *)((__native)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/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, (__native) (100000000*e),(__native) E_10e8); |
} |
printf("tid%d: e*10e8=%zd should be %zd\n", THREAD->tid, (__native) (100000000*e),(__native) 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, (__native) (1000000*pi),(__native) (PI_10e8/100)); |
#else |
if((int)(100000000*pi)!=PI_10e8) |
panic("tid%d: pi*10e8=%zd should be %zd\n", THREAD->tid, (__native) (100000000*pi),(__native) PI_10e8); |
#endif |
} |
printf("tid%d: pi*10e8=%zd should be %zd\n", THREAD->tid, (__native) (100000000*pi),(__native) 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/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)((__native) 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)((__native) 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 *)((__native)i*2), TASK, 0, "testit1"))) |
panic("could not create thread\n"); |
thread_ready(t); |
if (!(t = thread_create(testit2, (void *)((__native)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/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; |
__native 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, __native '%#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/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 __native counter(sysinfo_item_t *root) |
{ |
static __native 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/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/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/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/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/kernel/contrib/conf/pearpc.conf |
---|
0,0 → 1,7 |
ppc_start_resolution = "800x600x32" |
pci_ide0_master_installed = 0 |
prom_bootmethod = "force" |
prom_loadfile = "image.boot" |
key_toggle_mouse_grab = "F11" |
/tags/0.2.0/kernel/contrib/conf/ski.conf |
---|
0,0 → 1,11 |
load HelenOS/boot/kernel.bin |
romload HelenOS/uspace/ns/ns 0x400000 |
romload HelenOS/uspace/init/init 0x800000 |
romload HelenOS/uspace/console/console 0xc00000 |
romload HelenOS/uspace/fb/fb 0x1000000 |
romload HelenOS/uspace/kbd/kbd 0x1400000 |
romload HelenOS/uspace/tetris/tetris 0x1800000 |
romload HelenOS/uspace/klog/klog 0x1c00000 |
romload HelenOS/uspace/ipcc/ipcc 0x2000000 |
/tags/0.2.0/kernel/contrib/conf/msim.conf |
---|
0,0 → 1,17 |
# |
# MSIM configuration script |
# |
add dcpu mips1 |
add rwm mainmem 0x0 8M load "/dev/zero" |
add rom startmem 0x1fc00000 1024k load "image.boot" |
add rwm ns 0x01000000 1M load "ns" |
add rwm kbd 0x01100000 1M load "fb" |
add rwm fb 0x01200000 1M load "kbd" |
add rwm console 0x01300000 1M load "console" |
add rwm init 0x01400000 1M load "init" |
add rwm tetris 0x01500000 1M load "tetris" |
add dprinter printer 0x10000000 |
add dkeyboard keyboard 0x10000000 2 |
/tags/0.2.0/kernel/contrib/conf/gxemul.sh |
---|
0,0 → 1,4 |
#!/bin/sh |
# Uspace addresses outside of normal memory (kernel has std. 8 or 16MB) |
# we place the pages at 24M |
gxemul $@ -E testmips -X 0x81800000:../uspace/ns/ns 0x81900000:../uspace/kbd/kbd 0x81a00000:../uspace/fb/fb 0x81b00000:../uspace/init/init 0x81c00000:../uspace/console/console 0x81d00000:../uspace/tetris/tetris kernel.bin |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/tags/0.2.0/kernel/contrib/conf/dot.bochsrc |
---|
0,0 → 1,719 |
# You may now use double quotes around pathnames, in case |
# your pathname includes spaces. |
#======================================================================= |
# CONFIG_INTERFACE |
# |
# The configuration interface is a series of menus or dialog boxes that |
# allows you to change all the settings that control Bochs's behavior. |
# There are two choices of configuration interface: a text mode version |
# called "textconfig" and a graphical version called "wx". The text |
# mode version uses stdin/stdout and is always compiled in. The graphical |
# version is only available when you use "--with-wx" on the configure |
# command. If you do not write a config_interface line, Bochs will |
# choose a default for you. |
# |
# NOTE: if you use the "wx" configuration interface, you must also use |
# the "wx" display library. |
#======================================================================= |
config_interface: textconfig |
#config_interface: wx |
#======================================================================= |
# DISPLAY_LIBRARY |
# |
# The display library is the code that displays the Bochs VGA screen. Bochs |
# has a selection of about 10 different display library implementations for |
# different platforms. If you run configure with multiple --with-* options, |
# the display_library command lets you choose which one you want to run with. |
# If you do not write a display_library line, Bochs will choose a default for |
# you. |
# |
# The choices are: |
# x use X windows interface, cross platform |
# win32 use native win32 libraries |
# carbon use Carbon library (for MacOS X) |
# beos use native BeOS libraries |
# macintosh use MacOS pre-10 |
# amigaos use native AmigaOS libraries |
# sdl use SDL library, cross platform |
# svga use SVGALIB library for Linux, allows graphics without X11 |
# term text only, uses curses/ncurses library, cross platform |
# rfb provides an interface to AT&T's VNC viewer, cross platform |
# wx use wxWindows library, cross platform |
# nogui no display at all |
# |
# NOTE: if you use the "wx" configuration interface, you must also use |
# the "wx" display library. |
#======================================================================= |
#display_library: amigaos |
#display_library: beos |
#display_library: carbon |
#display_library: macintosh |
#display_library: nogui |
#display_library: rfb |
#display_library: sdl |
#display_library: term |
#display_library: win32 |
#display_library: wx |
display_library: x |
cpu: count=8, ips=10000000 |
#======================================================================= |
# ROMIMAGE: |
# You now need to load a ROM BIOS into F0000-FFFFF. Normally, you can |
# use a precompiled BIOS in the bios/ directory of the source tree, |
# named BIOS-bochs-latest. |
# You can also use the environment variable $BXSHARE to specify the |
# location of the BIOS. |
#======================================================================= |
romimage: file=$BXSHARE/BIOS-bochs-latest, address=0xf0000 |
#romimage: file=$BXSHARE/BIOS-bochs-8-processors, address=0xf0000 |
#romimage: file=bios/P4SMT, address=0xf0000 |
#======================================================================= |
# MEGS |
# set this to the default number of Megabytes of memory you want |
# to emulate. You may also pass the '-megs xyz' option to bochs |
# |
# The default is 32MB, most OS's won't need more than that. |
#======================================================================= |
#megs: 256 |
#megs: 128 |
#megs: 64 |
megs: 32 |
#megs: 16 |
#megs: 8 |
#======================================================================= |
# OPTROMIMAGE[1-4]: |
# You may now load up to 4 optional ROM images. Be sure to use a |
# read-only area, typically between C8000 and EFFFF. These optional |
# ROM images should not overwrite the rombios (located at |
# F0000-FFFFF) and the videobios (located at C0000-C7FFF). |
# Those ROM images will be initialized by the bios if they contain |
# the right signature (0x55AA). |
# It can also be a convenient way to upload some arbitary code/data |
# in the simulation, that can be retrieved by the boot loader |
#======================================================================= |
#optromimage1: file=optionalrom.bin, address=0xd0000 |
#optromimage2: file=optionalrom.bin, address=0xd1000 |
#optromimage3: file=optionalrom.bin, address=0xd2000 |
#optromimage4: file=optionalrom.bin, address=0xd3000 |
#======================================================================= |
# VGAROMIMAGE |
# You now need to load a VGA ROM BIOS into C0000. |
#======================================================================= |
vgaromimage: $BXSHARE/VGABIOS-lgpl-latest |
#vgaromimage: bios/VGABIOS-elpin-2.40 |
#vgaromimage: $BXSHARE/VGABIOS-elpin-2.40 |
#======================================================================= |
# FLOPPYA: |
# Point this to pathname of floppy image file or device |
# This should be of a bootable floppy(image/device) if you're |
# booting from 'a'. |
# |
# You can set the initial status of the media to 'ejected' or 'inserted'. |
# floppya: 2_88=path, status=ejected (2.88M 3.5" floppy) |
# floppya: 1_44=path, status=inserted (1.44M 3.5" floppy) |
# floppya: 1_2=path, status=ejected (1.2M 5.25" floppy) |
# floppya: 720k=path, status=inserted (720K 3.5" floppy) |
# floppya: 360k=path, status=inserted (360K 5.25" floppy) |
# floppya: 320k=path, status=inserted (320K 5.25" floppy) |
# floppya: 180k=path, status=inserted (180K 5.25" floppy) |
# floppya: 160k=path, status=inserted (160K 5.25" floppy) |
# |
# The path should be the name of a disk image file. On unix, you can use |
# a raw device name such as /dev/fd0 on Linux. On WinNT and Win2k, use |
# drive letters such as a: or b: as the path. Raw floppy access is not |
# supported on Windows 95 and 98. |
#======================================================================= |
#floppya: 1_44=image.boot, status=inserted |
#floppya: 1_44=/dev/fd0, status=inserted |
#======================================================================= |
# FLOPPYB: |
# See FLOPPYA above for syntax |
#======================================================================= |
#floppyb: 1_44=b:, status=inserted |
#floppyb: 1_44=b.img, status=inserted |
#======================================================================= |
# ATA0, ATA1, ATA2, ATA3 |
# ATA controller for hard disks and cdroms |
# |
# ata[0-3]: enabled=[0|1], ioaddr1=addr, ioaddr2=addr, irq=number |
# |
# These options enables up to 4 ata channels. For each channel |
# the two base io addresses and the irq must be specified. |
# |
# ata0 is enabled by default, with ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 |
# |
# Examples: |
# ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 |
# ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15 |
# ata2: enabled=1, ioaddr1=0x1e8, ioaddr2=0x3e0, irq=11 |
# ata3: enabled=1, ioaddr1=0x168, ioaddr2=0x360, irq=9 |
#======================================================================= |
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 |
ata1: enabled=0, ioaddr1=0x170, ioaddr2=0x370, irq=15 |
ata2: enabled=0, ioaddr1=0x1e8, ioaddr2=0x3e0, irq=11 |
ata3: enabled=0, ioaddr1=0x168, ioaddr2=0x360, irq=9 |
#======================================================================= |
# ATA[0-3]-MASTER, ATA[0-3]-SLAVE |
# |
# This defines the type and characteristics of all attached ata devices: |
# type= type of attached device [disk|cdrom] |
# mode= only valid for disks [flat|concat|external|dll|sparse|vmware3] |
# mode= only valid for disks [undoable|growing|volatile] |
# path= path of the image |
# cylinders= only valid for disks |
# heads= only valid for disks |
# spt= only valid for disks |
# status= only valid for cdroms [inserted|ejected] |
# biosdetect= type of biosdetection [none|auto], only for disks on ata0 [cmos] |
# translation=type of transation of the bios, only for disks [none|lba|large|rechs|auto] |
# model= string returned by identify device command |
# journal= optional filename of the redolog for undoable and volatile disks |
# |
# Point this at a hard disk image file, cdrom iso file, or physical cdrom |
# device. To create a hard disk image, try running bximage. It will help you |
# choose the size and then suggest a line that works with it. |
# |
# In UNIX it may be possible to use a raw device as a Bochs hard disk, |
# but WE DON'T RECOMMEND IT. In Windows there is no easy way. |
# |
# In windows, the drive letter + colon notation should be used for cdroms. |
# Depending on versions of windows and drivers, you may only be able to |
# access the "first" cdrom in the system. On MacOSX, use path="drive" |
# to access the physical drive. |
# |
# The path, cylinders, heads, and spt are mandatory for type=disk |
# The path is mandatory for type=cdrom |
# |
# Default values are: |
# mode=flat, biosdetect=auto, translation=auto, model="Generic 1234" |
# |
# The biosdetect option has currently no effect on the bios |
# |
# Examples: |
# ata0-master: type=disk, mode=flat, path=10M.sample, cylinders=306, heads=4, spt=17 |
# ata0-slave: type=disk, mode=flat, path=20M.sample, cylinders=615, heads=4, spt=17 |
# ata1-master: type=disk, mode=flat, path=30M.sample, cylinders=615, heads=6, spt=17 |
# ata1-slave: type=disk, mode=flat, path=46M.sample, cylinders=940, heads=6, spt=17 |
# ata2-master: type=disk, mode=flat, path=62M.sample, cylinders=940, heads=8, spt=17 |
# ata2-slave: type=disk, mode=flat, path=112M.sample, cylinders=900, heads=15, spt=17 |
# ata3-master: type=disk, mode=flat, path=483M.sample, cylinders=1024, heads=15, spt=63 |
# ata3-slave: type=cdrom, path=iso.sample, status=inserted |
#======================================================================= |
ata0-master: type=cdrom, path="image.iso", status=inserted |
#ata0-master: type=disk, mode=flat, path="30M.sample", cylinders=615, heads=6, spt=17 |
#ata0-slave: type=cdrom, path=D:, status=inserted |
#ata0-slave: type=cdrom, path=/dev/cdrom, status=inserted |
#ata0-slave: type=cdrom, path="drive", status=inserted |
#ata0-slave: type=cdrom, path=/dev/rcd0d, status=inserted |
#======================================================================= |
# BOOT: |
# This defines your boot drive. |
# You can either boot from 'floppy', 'disk' or 'cdrom' |
# legacy 'a' and 'c' are also supported |
# Examples: |
# boot: floppy |
# boot: disk |
# boot: cdrom |
# boot: c |
# boot: a |
#======================================================================= |
boot: cdrom |
#boot: disk |
#======================================================================= |
# IPS: |
# Emulated Instructions Per Second. This is the number of IPS that bochs |
# is capable of running on your machine. Read the note in config.h |
# on how to find this. Make sure to recompile after. |
# |
# IPS is used to calibrate many time-dependent events within the bochs |
# simulation. For example, changing IPS affects the frequency of VGA |
# updates, the duration of time before a key starts to autorepeat, and |
# the measurement of BogoMips and other benchmarks. |
# |
# Examples: |
# Machine Mips |
# ________________________________________________________________ |
# 650Mhz Athlon K-7 with Linux 2.4.4/egcs-2.91.66 2 to 2.5 Mips |
# 400Mhz Pentium II with Linux 2.0.36/egcs-1.0.3 1 to 1.8 Mips |
# 166Mhz 64bit Sparc with Solaris 2.x approx 0.75 Mips |
# 200Mhz Pentium with Linux 2.x approx 0.5 Mips |
# |
#======================================================================= |
ips: 2500000 |
#======================================================================= |
# CLOCK: |
# This defines the parameters of the clock inside Bochs: |
# |
# SYNC: |
# TO BE COMPLETED (see Greg explaination in bug #536329) |
# |
# TIME0: |
# Specifies the start (boot) time of the virtual machine. Use a time |
# value as returned by the time(2) system call. If no time0 value is |
# set or if time0 equal to 1 (special case) or if time0 equal 'local', |
# the simulation will be started at the current local host time. |
# If time0 equal to 2 (special case) or if time0 equal 'utc', |
# the simulation will be started at the current utc time. |
# |
# Syntax: |
# clock: sync=[none|slowdown|realtime], time0=[timeValue|local|utc] |
# |
# Example: |
# clock: sync=none, time0=local # Now (localtime) |
# clock: sync=slowdown, time0=315529200 # Tue Jan 1 00:00:00 1980 |
# clock: sync=none, time0=631148400 # Mon Jan 1 00:00:00 1990 |
# clock: sync=realtime, time0=938581955 # Wed Sep 29 07:12:35 1999 |
# clock: sync=realtime, time0=946681200 # Sat Jan 1 00:00:00 2000 |
# clock: sync=none, time0=1 # Now (localtime) |
# clock: sync=none, time0=utc # Now (utc/gmt) |
# |
# Default value are sync=none, time0=local |
#======================================================================= |
clock: sync=none, time0=local |
#======================================================================= |
# FLOPPY_BOOTSIG_CHECK: disabled=[0|1] |
# Enables or disables the 0xaa55 signature check on boot floppies |
# Defaults to disabled=0 |
# Examples: |
# floppy_bootsig_check: disabled=0 |
# floppy_bootsig_check: disabled=1 |
#======================================================================= |
#floppy_bootsig_check: disabled=1 |
floppy_bootsig_check: disabled=1 |
#======================================================================= |
# LOG: |
# Give the path of the log file you'd like Bochs debug and misc. verbage |
# to be written to. If you really don't want it, make it /dev/null. :^( |
# |
# Examples: |
# log: ./bochs.out |
# log: /dev/tty |
#======================================================================= |
#log: /dev/null |
log: bochsout.txt |
#======================================================================= |
# LOGPREFIX: |
# This handles the format of the string prepended to each log line. |
# You may use those special tokens : |
# %t : 11 decimal digits timer tick |
# %i : 8 hexadecimal digits of cpu0 current eip |
# %e : 1 character event type ('i'nfo, 'd'ebug, 'p'anic, 'e'rror) |
# %d : 5 characters string of the device, between brackets |
# |
# Default : %t%e%d |
# Examples: |
# logprefix: %t-%e-@%i-%d |
# logprefix: %i%e%d |
#======================================================================= |
#logprefix: %t%e%d |
#======================================================================= |
# LOG CONTROLS |
# |
# Bochs now has four severity levels for event logging. |
# panic: cannot proceed. If you choose to continue after a panic, |
# don't be surprised if you get strange behavior or crashes. |
# error: something went wrong, but it is probably safe to continue the |
# simulation. |
# info: interesting or useful messages. |
# debug: messages useful only when debugging the code. This may |
# spit out thousands per second. |
# |
# For events of each level, you can choose to crash, report, or ignore. |
# TODO: allow choice based on the facility: e.g. crash on panics from |
# everything except the cdrom, and only report those. |
# |
# If you are experiencing many panics, it can be helpful to change |
# the panic action to report instead of fatal. However, be aware |
# that anything executed after a panic is uncharted territory and can |
# cause bochs to become unstable. The panic is a "graceful exit," so |
# if you disable it you may get a spectacular disaster instead. |
#======================================================================= |
panic: action=report |
error: action=report |
info: action=report |
debug: action=ignore |
#pass: action=fatal |
#======================================================================= |
# DEBUGGER_LOG: |
# Give the path of the log file you'd like Bochs to log debugger output. |
# If you really don't want it, make it /dev/null or '-'. :^( |
# |
# Examples: |
# debugger_log: ./debugger.out |
#======================================================================= |
#debugger_log: /dev/null |
#debugger_log: debugger.out |
debugger_log: - |
#======================================================================= |
# COM1: |
# This defines a serial port (UART type 16550A). You can specify a device |
# to use as com1. This can be a real serial line, or a pty. To use a pty |
# (under X/Unix), create two windows (xterms, usually). One of them will |
# run bochs, and the other will act as com1. Find out the tty the com1 |
# window using the `tty' command, and use that as the `dev' parameter. |
# Then do `sleep 1000000' in the com1 window to keep the shell from |
# messing with things, and run bochs in the other window. Serial I/O to |
# com1 (port 0x3f8) will all go to the other window. |
#======================================================================= |
#com1: enabled=1, dev=/dev/ttyp9 |
#======================================================================= |
# PARPORT1: |
# This defines a parallel (printer) port. When turned on and an output file is |
# defined the emulated printer port sends characters printed by the guest OS |
# into the output file. On some platforms a device filename can be used to |
# send the data to the real parallel port (e.g. "/dev/lp0" on Linux, "lpt1" on |
# win32 platforms). |
# |
# Examples: |
# parport1: enabled=1, file="parport.out" |
# parport1: enabled=1, file="/dev/lp0" |
# parport1: enabled=0 |
#======================================================================= |
parport1: enabled=1, file="parport.out" |
#======================================================================= |
# SB16: |
# This defines the SB16 sound emulation. It can have several of the |
# following properties. |
# All properties are in the format sb16: property=value |
# midi: The filename is where the midi data is sent. This can be a |
# device or just a file if you want to record the midi data. |
# midimode: |
# 0=no data |
# 1=output to device (system dependent. midi denotes the device driver) |
# 2=SMF file output, including headers |
# 3=output the midi data stream to the file (no midi headers and no |
# delta times, just command and data bytes) |
# wave: This is the device/file where wave output is stored |
# wavemode: |
# 0=no data |
# 1=output to device (system dependent. wave denotes the device driver) |
# 2=VOC file output, incl. headers |
# 3=output the raw wave stream to the file |
# log: The file to write the sb16 emulator messages to. |
# loglevel: |
# 0=no log |
# 1=only midi program and bank changes |
# 2=severe errors |
# 3=all errors |
# 4=all errors plus all port accesses |
# 5=all errors and port accesses plus a lot of extra info |
# dmatimer: |
# microseconds per second for a DMA cycle. Make it smaller to fix |
# non-continous sound. 750000 is usually a good value. This needs a |
# reasonably correct setting for IPS. |
# |
# For an example look at the next line: |
#======================================================================= |
#sb16: midimode=1, midi=/dev/midi00, wavemode=1, wave=/dev/dsp, loglevel=2, log=sb16.log, dmatimer=600000 |
#======================================================================= |
# VGA_UPDATE_INTERVAL: |
# Video memory is scanned for updates and screen updated every so many |
# virtual seconds. The default is 300000, about 3Hz. This is generally |
# plenty. Keep in mind that you must tweak the 'ips:' directive |
# to be as close to the number of emulated instructions-per-second |
# your workstation can do, for this to be accurate. |
# |
# Examples: |
# vga_update_interval: 250000 |
#======================================================================= |
vga_update_interval: 300000 |
# using for Winstone '98 tests |
#vga_update_interval: 100000 |
#======================================================================= |
# KEYBOARD_SERIAL_DELAY: |
# Approximate time in microseconds that it takes one character to |
# be transfered from the keyboard to controller over the serial path. |
# Examples: |
# keyboard_serial_delay: 200 |
#======================================================================= |
keyboard_serial_delay: 250 |
#======================================================================= |
# KEYBOARD_PASTE_DELAY: |
# Approximate time in microseconds between attempts to paste |
# characters to the keyboard controller. This leaves time for the |
# guest os to deal with the flow of characters. The ideal setting |
# depends on how your operating system processes characters. The |
# default of 100000 usec (.1 seconds) was chosen because it works |
# consistently in Windows. |
# |
# If your OS is losing characters during a paste, increase the paste |
# delay until it stops losing characters. |
# |
# Examples: |
# keyboard_paste_delay: 100000 |
#======================================================================= |
keyboard_paste_delay: 100000 |
#======================================================================= |
# FLOPPY_COMMAND_DELAY: |
# Time in microseconds to wait before completing some floppy commands |
# such as read/write/seek/etc, which normally have a delay associated. |
# I had this hardwired to 50,000 before. |
# |
# Examples: |
# floppy_command_delay: 50000 |
#======================================================================= |
floppy_command_delay: 500 |
#======================================================================= |
# MOUSE: |
# This option prevents Bochs from creating mouse "events" unless a mouse |
# is enabled. The hardware emulation itself is not disabled by this. |
# You can turn the mouse on by setting enabled to 1, or turn it off by |
# setting enabled to 0. Unless you have a particular reason for enabling |
# the mouse by default, it is recommended that you leave it off. |
# You can also toggle the mouse usage at runtime (middle mouse button on |
# X11 and SDL, F12 on Win32). |
# |
# Examples: |
# mouse: enabled=1 |
# mouse: enabled=0 |
#======================================================================= |
mouse: enabled=0 |
#======================================================================= |
# private_colormap: Request that the GUI create and use it's own |
# non-shared colormap. This colormap will be used |
# when in the bochs window. If not enabled, a |
# shared colormap scheme may be used. Not implemented |
# on all GUI's. |
# |
# Examples: |
# private_colormap: enabled=1 |
# private_colormap: enabled=0 |
#======================================================================= |
private_colormap: enabled=0 |
#======================================================================= |
# fullscreen: ONLY IMPLEMENTED ON AMIGA |
# Request that Bochs occupy the entire screen instead of a |
# window. |
# |
# Examples: |
# fullscreen: enabled=0 |
# fullscreen: enabled=1 |
#======================================================================= |
#fullscreen: enabled=0 |
#screenmode: name="sample" |
#======================================================================= |
# ne2k: NE2000 compatible ethernet adapter |
# |
# Examples: |
# ne2k: ioaddr=IOADDR, irq=IRQ, mac=MACADDR, ethmod=MODULE, ethdev=DEVICE, script=SCRIPT |
# |
# ioaddr, irq: You probably won't need to change ioaddr and irq, unless there |
# are IRQ conflicts. |
# |
# mac: The MAC address MUST NOT match the address of any machine on the net. |
# Also, the first byte must be an even number (bit 0 set means a multicast |
# address), and you cannot use ff:ff:ff:ff:ff:ff because that's the broadcast |
# address. For the ethertap module, you must use fe:fd:00:00:00:01. There may |
# be other restrictions too. To be safe, just use the b0:c4... address. |
# |
# ethdev: The ethdev value is the name of the network interface on your host |
# platform. On UNIX machines, you can get the name by running ifconfig. On |
# Windows machines, you must run niclist to get the name of the ethdev. |
# Niclist source code is in misc/niclist.c and it is included in Windows |
# binary releases. |
# |
# script: The script value is optionnal, and is the name of a script that |
# is executed after bochs initialize the network interface. You can use |
# this script to configure this network interface, or enable masquerading. |
# This is mainly useful for the tun/tap devices that only exist during |
# Bochs execution. The network interface name is supplied to the script |
# as first parameter |
#======================================================================= |
# ne2k: ioaddr=0x240, irq=9, mac=fe:fd:00:00:00:01, ethmod=fbsd, ethdev=en0 #macosx |
# ne2k: ioaddr=0x240, irq=9, mac=b0:c4:20:00:00:00, ethmod=fbsd, ethdev=xl0 |
# ne2k: ioaddr=0x240, irq=9, mac=b0:c4:20:00:00:00, ethmod=linux, ethdev=eth0 |
# ne2k: ioaddr=0x240, irq=9, mac=b0:c4:20:00:00:01, ethmod=win32, ethdev=MYCARD |
# ne2k: ioaddr=0x240, irq=9, mac=fe:fd:00:00:00:01, ethmod=tap, ethdev=tap0 |
# ne2k: ioaddr=0x240, irq=9, mac=fe:fd:00:00:00:01, ethmod=tuntap, ethdev=tun0, script=./tunconfig |
#======================================================================= |
# KEYBOARD_MAPPING: |
# This enables a remap of a physical localized keyboard to a |
# virtualized us keyboard, as the PC architecture expects. |
# If enabled, the keymap file must be specified. |
# |
# Examples: |
# keyboard_mapping: enabled=1, map=gui/keymaps/x11-pc-de.map |
#======================================================================= |
keyboard_mapping: enabled=0, map= |
#======================================================================= |
# KEYBOARD_TYPE: |
# Type of keyboard return by a "identify keyboard" command to the |
# keyboard controler. It must be one of "xt", "at" or "mf". |
# Defaults to "mf". It should be ok for almost everybody. A known |
# exception is french macs, that do have a "at"-like keyboard. |
# |
# Examples: |
# keyboard_type: mf |
#======================================================================= |
#keyboard_type: mf |
#======================================================================= |
# USER_SHORTCUT: |
# This defines the keyboard shortcut to be sent when you press the "user" |
# button in the headerbar. The shortcut string can be a combination of |
# these key names: "alt", "bksp", "ctrl", "del", "esc", "f1", "f4", "tab" |
# and "win". Up to 3 keys can be pressed at a time. |
# |
# Example: |
# user_shortcut: keys=ctrlaltdel |
#======================================================================= |
#user_shortcut: keys=ctrlaltdel |
#======================================================================= |
# other stuff |
#======================================================================= |
#magic_break: enabled=1 |
#cmosimage: cmos.img |
#load32bitOSImage: os=nullkernel, path=../kernel.img, iolog=../vga_io.log |
#load32bitOSImage: os=linux, path=../linux.img, iolog=../vga_io.log, initrd=../initrd.img |
#i440fxsupport: enabled=1 |
usb1: enabled=1, ioaddr=0xFF80, irq=10 |
#text_snapshot_check: enable |
#======================================================================= |
# for Macintosh, use the style of pathnames in the following |
# examples. |
# |
# vgaromimage: :bios:VGABIOS-elpin-2.40 |
# romimage: file=:bios:BIOS-bochs-latest, address=0xf0000 |
# floppya: 1_44=[fd:], status=inserted |
#======================================================================= |
#======================================================================= |
# |
# The following directives are DEPRECATED |
# Please convert them to the new syntax or remove them |
# |
#======================================================================= |
#======================================================================= |
# |
# The DISKC option is deprecated. Use ATA* options instead. |
# |
# DISKC: file=, cyl=, heads=, spt= |
# Point this at a hard disk image file. To create |
# a hard disk image, try running bximage. It will help you choose the |
# size and then suggest a diskc line that works with it. |
# |
# In UNIX it may be possible to use a raw device as a Bochs hard disk, |
# but WE DON'T RECOMMEND IT. In Windows there is no easy way. |
# |
# Examples: |
# diskc: file=10M.sample, cyl=306, heads=4, spt=17 |
# diskc: file=20M.sample, cyl=615, heads=4, spt=17 |
# diskc: file=30M.sample, cyl=615, heads=6, spt=17 |
# diskc: file=46M.sample, cyl=940, heads=6, spt=17 |
# diskc: file=62M.sample, cyl=940, heads=8, spt=17 |
# diskc: file=112M.sample, cyl=900, heads=15, spt=17 |
# diskc: file=483M.sample, cyl=1024, heads=15, spt=63 |
#======================================================================= |
#diskc: file="30M.sample", cyl=615, heads=6, spt=17 |
#======================================================================= |
# |
# The DISKD option is deprecated. Use ATA* options instead. |
# |
# DISKD: |
# See DISKC above for syntax |
# |
# NOTE: diskd and cdromd must not be used together! |
#======================================================================= |
#diskd: file="diskd.img", cyl=615, heads=6, spt=17 |
#======================================================================= |
# |
# The CDROMD option is deprecated. Use ATA* options instead. |
# |
# CDROMD: |
# |
# cdromd: dev=/dev/cdrom, status=inserted |
# cdromd: dev=/dev/cdrom, status=ejected |
# cdromd: dev=e:, status=ejected |
# |
# In windows, the drive letter + colon notation should be used for cdroms. |
# Depending on versions of windows and drivers, you may only be able to |
# access the "first" cdrom in the system. On MacOSX, use path="drive" |
# to access the physical drive. |
# |
# NOTE: diskd and cdromd must not be used together! |
#======================================================================= |
#cdromd: dev=D:, status=inserted |
#cdromd: dev=/dev/cdrom, status=inserted |
#cdromd: dev="drive", status=inserted |
#======================================================================= |
# |
# The TIME0 directive is DEPRECATED. Use the CLOCK directive instead |
# |
# TIME0: |
# Specifies the start (boot) time of the virtual machine. Use a time |
# value as returned by the time(2) system call. If no time0 value is |
# set or if time0 equal to 1 (special case), the simulation will be |
# started at the current time of the host. |
# |
# Examples: |
# time0: 1 # Now |
# time0: 315529200 # Tue Jan 1 00:00:00 1980 |
# time0: 631148400 # Mon Jan 1 00:00:00 1990 |
# time0: 938581955 # Wed Sep 29 07:12:35 1999 |
# time0: 946681200 # Sat Jan 1 00:00:00 2000 |
#======================================================================= |
#time0: 938581955 |
#======================================================================= |
# |
# The PIT directive is DEPRECATED. Use the CLOCK directive instead |
# |
# PIT: |
# The PIT is the programmable interval timer. It has an option that tries to |
# keep the PIT in sync with real time. This feature is still experimental, |
# but it may be useful if you want to prevent Bochs from running too fast, for |
# example a DOS video game. Be aware that with the realtime pit option, your |
# simulation will not be repeatable; this can a problem if you are debugging. |
#======================================================================= |
#pit: realtime=1 |
#======================================================================= |
# NEWHARDDRIVESUPPORT: enabled=[0|1] |
# The old harddrive code is not maintened any more. |
# Default value is enabled=1 |
#======================================================================= |
#newharddrivesupport: enabled=1 |
/tags/0.2.0/kernel/contrib/conf/HelenOS.amd64.simics |
---|
0,0 → 1,57 |
# |
# Simics 3.0 AMD64 configuration |
# |
$num_cpus = 2 |
$cpu_class = "x86-hammer" |
$freq_mhz = 50 |
add-directory "%simics%/targets/x86-440bx/images" |
import-isa-components |
import-pci-components |
import-std-components |
import-x86-components |
$system = (create-x86-apic-system memory_megs = 256 |
rtc_time = "2006-03-12 10:00:00 UTC" |
break_on_reboot = 1 |
bios = "rombios-2.65.2.3") |
$count = 0 |
$create_command = ("create-" + $cpu_class + "-cpu") |
while $count < $num_cpus { |
$cpu[$count] = ($create_command cpu_frequency = $freq_mhz) |
$system.connect ("cpu" + $count) $cpu[$count] |
$count += 1 |
} |
$nb = (create-north-bridge-443bx-agp) |
$vga = (create-agp-voodoo3) |
$nb.connect agp-slot0 $vga |
$sb = (create-south-bridge-piix4) |
$sio = (create-std-super-io) |
$cdrom = (create-std-ide-cdrom) |
$console = (create-std-graphics-console) |
$console.connect mouse $sio mse-console |
$console.connect keyboard $sio kbd-console |
$console.connect $vga |
$system.connect chipset $nb |
$system.connect interrupt $sb |
$system.connect reset $sio |
$nb.connect pci-slot7 $sb |
$sb.connect $sio |
$sb.connect ide0-slave $cdrom |
instantiate-components |
run-python-file "%simics%/home/scripts/cdrom_bootloader.py" |
@install_cdrom_bootloader((conf.cpu0,)) |
new-file-cdrom "image.iso" image |
cd0.insert image |
/tags/0.2.0/kernel/contrib/conf/simics.conf |
---|
0,0 → 1,25 |
# Test machine features |
# - Standard PC system |
# - 256 Mb memory |
# - 40 MHz processor(s) |
# - AM79C960 NIC (ISA Lance) |
# - Voodoo3 PCI graphics device |
@num_processors = 2 |
#@num_processors = 1 |
@if not "cpu_class" in dir(): cpu_class = "x86-hammer" |
@if not "clock_freq_mhz" in dir(): clock_freq_mhz = 40 |
@if not "memory_megs" in dir(): memory_megs = 256 |
@if not "cdrom_image" in dir(): cdrom_image = "image.iso" |
@if not "use_voodoo3_pci" in dir(): use_voodoo3_pci = 1 |
@if not "use_voodoo3_agp" in dir(): use_voodoo3_agp = 0 |
run-command-file ../x86-test-machine/pc-common.simics |
run-python-file ../scripts/cdrom_bootloader.py |
@install_cdrom_bootloader((conf.cpu0,)) |
@if cdrom_image != None: |
eval_cli_line("new-file-cdrom %s image" % cdrom_image) |
eval_cli_line("cd0.insert image") |
/tags/0.2.0/kernel/contrib/conf/HelenOS.ppc32.simics |
---|
0,0 → 1,32 |
# |
# Simics 3.0 PPC32 simple configuration |
# |
$cpu_class = "ppc750" |
$freq_mhz = 50 |
$image = "image.boot" |
$image_offset = -0x7a000000 |
add-directory "%simics%/targets/ppc64-simple/images" |
import-std-components |
import-ppc-simple-components |
$system = (create-ppc-simple cpu_class = $cpu_class |
cpu_frequency = $freq_mhz |
memory_megs = 256) |
$cpu = ($system.get-component-object "cpu") |
$system.connect uart0 (create-std-text-console) |
instantiate-components |
$start = (load-binary $image $image_offset) |
$cpu->msr = ($cpu->msr | (1 << 13) | (1 << 5) | (1 << 4)) |
$cpu.set-pc $start - $image_offset |
@itlb = conf.cpu0.itlb |
@itlb[0] = [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0]] |
@conf.cpu0.itlb = itlb |
/tags/0.2.0/kernel/contrib/conf/spmips.conf |
---|
0,0 → 1,263 |
OBJECT cpu0 TYPE mips-4kc { |
freq-mhz: 10 |
queue: cpu0 |
physical-memory: phys-mem0 |
} |
OBJECT phys-mem0 TYPE memory-space { |
map: ((0x18000020, pic0, 0, 0x20, 1), |
(0x18000021, pic0, 0, 0x21, 1), |
(0x180000a0, pic0, 0, 0xa0, 1), |
(0x180000a1, pic0, 0, 0xa1, 1), |
(0x180004d0, pic0, 0, 0x4d0, 1), |
(0x180004d1, pic0, 0, 0x4d1, 1), |
(0x18000070, rtc0, 0, 0, 1), |
(0x18000071, rtc0, 0, 1, 1), |
(0x180003f8, tty0, 0, 0, 1), |
(0x180003f9, tty0, 0, 1, 1), |
(0x180003fa, tty0, 0, 2, 1), |
(0x180003fb, tty0, 0, 3, 1), |
(0x180003fc, tty0, 0, 4, 1), |
(0x180003fd, tty0, 0, 5, 1), |
(0x180003fe, tty0, 0, 6, 1), |
(0x180003ff, tty0, 0, 7, 1), |
(0x1c000000, hfs0, 0, 0, 16), |
(0x01000000, initmem0, 0, 0, 0x100000)) |
} |
OBJECT cbus-space TYPE memory-space { |
map: ((0x1f000000, malta0, 0, 0, 0xc00000), |
(0x1fc00000, rom0, 0, 0, 0x400000)) |
} |
OBJECT memory0 TYPE ram { |
image: memory0-image |
} |
OBJECT memory0-image TYPE image { |
queue: cpu0 |
size: 0x08000000 |
} |
OBJECT initmem0 TYPE ram { |
image: initmem0-image |
} |
OBJECT initmem0-image TYPE image { |
queue: cpu0 |
size: 0x100000 |
files: (("../../../uspace/init/init", "ro", 0,0)) |
} |
OBJECT rom0 TYPE rom { |
image: rom0-image |
} |
OBJECT rom0-image TYPE image { |
queue: cpu0 |
size: 0x00400000 |
} |
OBJECT tty0 TYPE NS16550 { |
irq-dev: pic0 |
irq-level: 4 |
queue: cpu0 |
console: con0 |
recorder: rec0 |
} |
OBJECT pic0 TYPE i8259x2 { |
queue: cpu0 |
irq-dev: gt64120-0 |
# It seems like Linux expects the master 8259 to have VBA 0. |
# Maybe that would be set up by YAMON? |
vba: (0, 1) |
} |
OBJECT con0 TYPE xterm-console { |
title: "mips32-test-machine" |
bg-color: "black" |
fg-color: "green" |
queue: cpu0 |
device: tty0 |
output-timeout: 120 |
} |
OBJECT rtc0 TYPE DS12887 { |
irq-dev: pic0 |
irq-level: 8 |
queue: cpu0 |
} |
OBJECT malta0 TYPE malta { |
console: display0 |
} |
OBJECT display0 TYPE xterm-console { |
title: "MALTA Display" |
bg-color: "black" |
fg-color: "red" |
width: 8 |
height: 1 |
scrollbar: 0 |
x11-font: "-*-*-*-r-*-*-*-240-*-*-m-*-*-*" |
win32-font: "Lucida Console:Bold:48" |
queue: cpu0 |
output-timeout: 120 |
} |
# PCI buses |
OBJECT pci-bus0 TYPE pci-bus { |
queue: cpu0 |
bridge: gt64120-0-pci-0-0 |
interrupt: gt64120-0-pci-0-0 |
conf-space: pci-bus0-conf-space |
memory-space: pci-bus0-memory-space |
io-space: pci-bus0-io-space |
pci-devices: ((0, 0, gt64120-0-pci-0-0), |
(0, 1, gt64120-0-pci-0-1)) |
} |
OBJECT pci-bus0-conf-space TYPE memory-space { |
queue: cpu0 |
} |
OBJECT pci-bus1-conf-space TYPE memory-space { |
queue: cpu0 |
} |
OBJECT pci-bus0-memory-space TYPE memory-space { |
queue: cpu0 |
} |
OBJECT pci-bus1 TYPE pci-bus { |
queue: cpu0 |
bridge: gt64120-0-pci-1-0 |
interrupt: gt64120-0-pci-1-0 |
conf-space: pci-bus1-conf-space |
memory-space: pci-bus1-memory-space |
io-space: pci-bus1-io-space |
pci-devices: ((0, 0, gt64120-0-pci-1-0), |
(0, 1, gt64120-0-pci-1-1)) |
} |
OBJECT pci-bus1-memory-space TYPE memory-space { |
queue: cpu0 |
} |
OBJECT pci-bus0-io-space TYPE memory-space { |
queue: cpu0 |
} |
OBJECT pci-bus1-io-space TYPE memory-space { |
queue: cpu0 |
} |
# GT64120 chipset |
OBJECT gt64120-0 TYPE GT64120 { |
queue: cpu0 |
cpu-mem: phys-mem0 |
pci-0-0: gt64120-0-pci-0-0 |
pci-0-1: gt64120-0-pci-0-1 |
pci-1-0: gt64120-0-pci-1-0 |
pci-1-1: gt64120-0-pci-1-1 |
scs0: memory0 |
cs3: cbus-space |
bootcs: cbus-space |
pci-0-conf: pci-bus0-conf-space |
pci-0-io: pci-bus0-io-space |
pci-0-memory: pci-bus0-memory-space |
pci-1-conf: pci-bus1-conf-space |
pci-1-io: pci-bus1-io-space |
pci-1-memory: pci-bus1-memory-space |
irq-dev: cpu0 |
irq-level: 2 |
# Little endian |
cpu_interface_configuration: 0x00041000 |
# Map 128MB RAM. |
scs10-high-decode-address: 0x40 |
scs0-low-decode-address: 0x0 |
scs0-high-decode-address: 0x7f |
# Map the internal registers at 0x1be00000. |
internal-space-decode: 0xdf |
# Disable host-PCI mappings |
pci-0-io-high-decode-address: 0 |
pci-0-io-low-decode-address: 1 |
pci-0-io-remap: 1 |
pci-0-memory-0-high-decode-address: 0 |
pci-0-memory-0-low-decode-address: 1 |
pci-0-memory-0-remap: 1 |
pci-0-memory-1-high-decode-address: 0 |
pci-0-memory-1-low-decode-address: 1 |
pci-0-memory-1-remap: 1 |
pci-1-io-high-decode-address: 0 |
pci-1-io-low-decode-address: 1 |
pci-1-io-remap: 1 |
pci-1-memory-0-high-decode-address: 0 |
pci-1-memory-0-low-decode-address: 1 |
pci-1-memory-0-remap: 1 |
pci-1-memory-1-high-decode-address: 0 |
pci-1-memory-1-low-decode-address: 1 |
pci-1-memory-1-remap: 1 |
# Disable PCI-host mappings |
pci-0-base-address-registers-enable: 0x1ff |
pci-1-base-address-registers-enable: 0x1ff |
} |
OBJECT gt64120-0-pci-0-0 TYPE GT64120-pci { |
queue: cpu0 |
gt64120: gt64120-0 |
bridge-num: 0 |
function-num: 0 |
pci-bus: pci-bus0 |
} |
OBJECT gt64120-0-pci-0-1 TYPE GT64120-pci { |
queue: cpu0 |
gt64120: gt64120-0 |
bridge-num: 0 |
function-num: 1 |
pci-bus: pci-bus0 |
} |
OBJECT gt64120-0-pci-1-0 TYPE GT64120-pci { |
queue: cpu0 |
gt64120: gt64120-0 |
bridge-num: 1 |
function-num: 0 |
pci-bus: pci-bus1 |
} |
OBJECT gt64120-0-pci-1-1 TYPE GT64120-pci { |
queue: cpu0 |
gt64120: gt64120-0 |
bridge-num: 1 |
function-num: 1 |
pci-bus: pci-bus1 |
} |
# Various |
OBJECT rec0 TYPE recorder { |
} |
OBJECT hfs0 TYPE hostfs { |
} |
OBJECT sim TYPE sim { |
handle-outside-memory: 1 |
} |
/tags/0.2.0/kernel/contrib/conf/bootindy |
---|
0,0 → 1,2 |
Without this the indy will not boot |
echo 1 > /proc/sys/net/ipv4/ip_no_pmtu_disc |
/tags/0.2.0/kernel/contrib/conf/SPMIPS.simics |
---|
0,0 → 1,14 |
run-python-file ../scripts/extrapath.py |
add-directory ../../import/mips |
read-configuration spmips.conf |
set-pc (cpu0.load-binary ../../../SPARTAN/kernel.bin) |
# Setup uart to use 8 bits |
@conf.tty0.lcr = 0xf; |
# Set date |
rtc0.set-date-time 2001 01 01 01 01 01 |
@century = 20 |
@ignore=SIM_set_attribute_idx(conf.rtc0, "nvram", 0x32, century) |
/tags/0.2.0/kernel/contrib/conf/vmware.conf |
---|
0,0 → 1,15 |
#!/opt/vmware/bin/vmware |
config.version = "8" |
virtualHW.version = "4" |
scsi0.present = "FALSE" |
memsize = "96" |
ide0:0.present = "FALSE" |
ide1:0.present = "FALSE" |
floppy0.startConnected = "TRUE" |
floppy0.fileType = "file" |
floppy0.fileName = "image.bin" |
sound.present = "FALSE" |
displayName = "HelenOS" |
guestOS = "other" |
nvram = "HelenOS.nvram" |
isolation.tools.hgfs.disable = "TRUE" |
/tags/0.2.0/kernel/contrib/toolchain/toolchain.ia64.sh |
---|
0,0 → 1,93 |
#!/bin/bash |
# Cross-Compiler Toolchain for ${PLATFORM} |
# by Martin Decky <martin@decky.cz> |
# |
# GPL'ed, copyleft |
# |
check_error() { |
if [ "$1" -ne "0" ]; then |
echo |
echo "Script failed: $2" |
exit |
fi |
} |
BINUTILS_VERSION="2.16.1" |
GCC_VERSION="4.1.1" |
INCLUDES="ia64-pc-gnu-linux_includes.tar.bz2" |
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz" |
GCC="gcc-core-${GCC_VERSION}.tar.bz2" |
INCLUDES_SOURCE="http://download.decky.cz/" |
BINUTILS_SOURCE="ftp://ftp.gnu.org/gnu/binutils/" |
GCC_SOURCE="ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/" |
PLATFORM="ia64" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-pc-linux-gnu" |
HOST="i686-pc-linux-gnu" |
PREFIX="/usr/local/${PLATFORM}" |
INCLUDESDIR="${WORKDIR}/include" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
OBJDIR="${WORKDIR}/gcc-obj" |
echo ">>> Downloading tarballs" |
if [ ! -f "${INCLUDES}" ]; then |
wget -c "${INCLUDES_SOURCE}${INCLUDES}" |
check_error $? "Error downloading includes." |
fi |
if [ ! -f "${BINUTILS}" ]; then |
wget -c "${BINUTILS_SOURCE}${BINUTILS}" |
check_error $? "Error downloading binutils." |
fi |
if [ ! -f "${GCC}" ]; then |
wget -c "${GCC_SOURCE}${GCC}" |
check_error $? "Error downloading GCC." |
fi |
echo ">>> Creating destionation directory" |
if [ ! -d "${PREFIX}" ]; then |
mkdir -p "${PREFIX}" |
test -d "${PREFIX}" |
check_error $? "Unable to create ${PREFIX}." |
fi |
echo ">>> Creating GCC work directory" |
if [ ! -d "${OBJDIR}" ]; then |
mkdir -p "${OBJDIR}" |
test -d "${OBJDIR}" |
check_error $? "Unable to create ${OBJDIR}." |
fi |
echo ">>> Unpacking tarballs" |
tar -xvjf "${INCLUDES}" |
check_error $? "Error unpacking includes." |
tar -xvzf "${BINUTILS}" |
check_error $? "Error unpacking binutils." |
tar -xvjf "${GCC}" |
check_error $? "Error unpacking GCC." |
echo ">>> Compiling and installing binutils" |
cd "${BINUTILSDIR}" |
check_error $? "Change directory failed." |
./configure "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls" |
check_error $? "Error configuring binutils." |
make all install |
check_error $? "Error compiling/installing binutils." |
echo ">>> Compiling and installing GCC" |
cd "${OBJDIR}" |
check_error $? "Change directory failed." |
"${GCCDIR}/configure" "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c --disable-multilib --disable-libgcj "--with-headers=${INCLUDESDIR}" --disable-shared |
check_error $? "Error configuring GCC." |
PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc |
check_error $? "Error compiling/installing GCC." |
echo |
echo ">>> Cross-compiler for ${TARGET} installed." |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/tags/0.2.0/kernel/contrib/toolchain/toolchain.ppc32.sh |
---|
0,0 → 1,84 |
#!/bin/bash |
# Cross-Compiler Toolchain for ${PLATFORM} |
# by Martin Decky <martin@decky.cz> |
# |
# GPL'ed, copyleft |
# |
check_error() { |
if [ "$1" -ne "0" ]; then |
echo |
echo "Script failed: $2" |
exit |
fi |
} |
BINUTILS_VERSION="2.16.1" |
GCC_VERSION="4.1.1" |
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz" |
GCC="gcc-core-${GCC_VERSION}.tar.bz2" |
BINUTILS_SOURCE="ftp://ftp.gnu.org/gnu/binutils/" |
GCC_SOURCE="ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/" |
PLATFORM="ppc" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-linux-gnu" |
HOST="i686-pc-linux-gnu" |
PREFIX="/usr/local/${PLATFORM}" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
OBJDIR="${WORKDIR}/gcc-obj" |
echo ">>> Downloading tarballs" |
if [ ! -f "${BINUTILS}" ]; then |
wget -c "${BINUTILS_SOURCE}${BINUTILS}" |
check_error $? "Error downloading binutils." |
fi |
if [ ! -f "${GCC}" ]; then |
wget -c "${GCC_SOURCE}${GCC}" |
check_error $? "Error downloading GCC." |
fi |
echo ">>> Creating destionation directory" |
if [ ! -d "${PREFIX}" ]; then |
mkdir -p "${PREFIX}" |
test -d "${PREFIX}" |
check_error $? "Unable to create ${PREFIX}." |
fi |
echo ">>> Creating GCC work directory" |
if [ ! -d "${OBJDIR}" ]; then |
mkdir -p "${OBJDIR}" |
test -d "${OBJDIR}" |
check_error $? "Unable to create ${OBJDIR}." |
fi |
echo ">>> Unpacking tarballs" |
tar -xvzf "${BINUTILS}" |
check_error $? "Error unpacking binutils." |
tar -xvjf "${GCC}" |
check_error $? "Error unpacking GCC." |
echo ">>> Compiling and installing binutils" |
cd "${BINUTILSDIR}" |
check_error $? "Change directory failed." |
./configure "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls" |
check_error $? "Error configuring binutils." |
make all install |
check_error $? "Error compiling/installing binutils." |
echo ">>> Compiling and installing GCC" |
cd "${OBJDIR}" |
check_error $? "Change directory failed." |
"${GCCDIR}/configure" "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c --disable-multilib --disable-libgcj --without-headers --disable-shared |
check_error $? "Error configuring GCC." |
PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc |
check_error $? "Error compiling/installing GCC." |
echo |
echo ">>> Cross-compiler for ${TARGET} installed." |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/tags/0.2.0/kernel/contrib/toolchain/toolchain.amd64.sh |
---|
0,0 → 1,84 |
#!/bin/bash |
# Cross-Compiler Toolchain for ${PLATFORM} |
# by Martin Decky <martin@decky.cz> |
# |
# GPL'ed, copyleft |
# |
check_error() { |
if [ "$1" -ne "0" ]; then |
echo |
echo "Script failed: $2" |
exit |
fi |
} |
BINUTILS_VERSION="2.16.1" |
GCC_VERSION="4.1.1" |
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz" |
GCC="gcc-core-${GCC_VERSION}.tar.bz2" |
BINUTILS_SOURCE="ftp://ftp.gnu.org/gnu/binutils/" |
GCC_SOURCE="ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/" |
PLATFORM="amd64" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-linux-gnu" |
HOST="i686-pc-linux-gnu" |
PREFIX="/usr/local/${PLATFORM}" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
OBJDIR="${WORKDIR}/gcc-obj" |
echo ">>> Downloading tarballs" |
if [ ! -f "${BINUTILS}" ]; then |
wget -c "${BINUTILS_SOURCE}${BINUTILS}" |
check_error $? "Error downloading binutils." |
fi |
if [ ! -f "${GCC}" ]; then |
wget -c "${GCC_SOURCE}${GCC}" |
check_error $? "Error downloading GCC." |
fi |
echo ">>> Creating destionation directory" |
if [ ! -d "${PREFIX}" ]; then |
mkdir -p "${PREFIX}" |
test -d "${PREFIX}" |
check_error $? "Unable to create ${PREFIX}." |
fi |
echo ">>> Creating GCC work directory" |
if [ ! -d "${OBJDIR}" ]; then |
mkdir -p "${OBJDIR}" |
test -d "${OBJDIR}" |
check_error $? "Unable to create ${OBJDIR}." |
fi |
echo ">>> Unpacking tarballs" |
tar -xvzf "${BINUTILS}" |
check_error $? "Error unpacking binutils." |
tar -xvjf "${GCC}" |
check_error $? "Error unpacking GCC." |
echo ">>> Compiling and installing binutils" |
cd "${BINUTILSDIR}" |
check_error $? "Change directory failed." |
./configure "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls" |
check_error $? "Error configuring binutils." |
make all install |
check_error $? "Error compiling/installing binutils." |
echo ">>> Compiling and installing GCC" |
cd "${OBJDIR}" |
check_error $? "Change directory failed." |
"${GCCDIR}/configure" "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c --disable-multilib --disable-libgcj --without-headers --disable-shared |
check_error $? "Error configuring GCC." |
PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc |
check_error $? "Error compiling/installing GCC." |
echo |
echo ">>> Cross-compiler for ${TARGET} installed." |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/tags/0.2.0/kernel/contrib/toolchain/toolchain.ppc64.sh |
---|
0,0 → 1,84 |
#!/bin/bash |
# Cross-Compiler Toolchain for ${PLATFORM} |
# by Martin Decky <martin@decky.cz> |
# |
# GPL'ed, copyleft |
# |
check_error() { |
if [ "$1" -ne "0" ]; then |
echo |
echo "Script failed: $2" |
exit |
fi |
} |
BINUTILS_VERSION="2.16.1" |
GCC_VERSION="4.1.1" |
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz" |
GCC="gcc-core-${GCC_VERSION}.tar.bz2" |
BINUTILS_SOURCE="ftp://ftp.gnu.org/gnu/binutils/" |
GCC_SOURCE="ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/" |
PLATFORM="ppc64" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-linux-gnu" |
HOST="i686-pc-linux-gnu" |
PREFIX="/usr/local/${PLATFORM}" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
OBJDIR="${WORKDIR}/gcc-obj" |
echo ">>> Downloading tarballs" |
if [ ! -f "${BINUTILS}" ]; then |
wget -c "${BINUTILS_SOURCE}${BINUTILS}" |
check_error $? "Error downloading binutils." |
fi |
if [ ! -f "${GCC}" ]; then |
wget -c "${GCC_SOURCE}${GCC}" |
check_error $? "Error downloading GCC." |
fi |
echo ">>> Creating destionation directory" |
if [ ! -d "${PREFIX}" ]; then |
mkdir -p "${PREFIX}" |
test -d "${PREFIX}" |
check_error $? "Unable to create ${PREFIX}." |
fi |
echo ">>> Creating GCC work directory" |
if [ ! -d "${OBJDIR}" ]; then |
mkdir -p "${OBJDIR}" |
test -d "${OBJDIR}" |
check_error $? "Unable to create ${OBJDIR}." |
fi |
echo ">>> Unpacking tarballs" |
tar -xvzf "${BINUTILS}" |
check_error $? "Error unpacking binutils." |
tar -xvjf "${GCC}" |
check_error $? "Error unpacking GCC." |
echo ">>> Compiling and installing binutils" |
cd "${BINUTILSDIR}" |
check_error $? "Change directory failed." |
./configure "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls" |
check_error $? "Error configuring binutils." |
make all install |
check_error $? "Error compiling/installing binutils." |
echo ">>> Compiling and installing GCC" |
cd "${OBJDIR}" |
check_error $? "Change directory failed." |
"${GCCDIR}/configure" "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c --disable-multilib --disable-libgcj --without-headers --disable-shared |
check_error $? "Error configuring GCC." |
PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc |
check_error $? "Error compiling/installing GCC." |
echo |
echo ">>> Cross-compiler for ${TARGET} installed." |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/tags/0.2.0/kernel/contrib/toolchain/toolchain.ia32.sh |
---|
0,0 → 1,84 |
#!/bin/bash |
# Cross-Compiler Toolchain for ${PLATFORM} |
# by Martin Decky <martin@decky.cz> |
# |
# GPL'ed, copyleft |
# |
check_error() { |
if [ "$1" -ne "0" ]; then |
echo |
echo "Script failed: $2" |
exit |
fi |
} |
BINUTILS_VERSION="2.16.1" |
GCC_VERSION="4.1.1" |
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz" |
GCC="gcc-core-${GCC_VERSION}.tar.bz2" |
BINUTILS_SOURCE="ftp://ftp.gnu.org/gnu/binutils/" |
GCC_SOURCE="ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/" |
PLATFORM="i686" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-pc-linux-gnu" |
HOST="i686-pc-linux-gnu" |
PREFIX="/usr/local/${PLATFORM}" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
OBJDIR="${WORKDIR}/gcc-obj" |
echo ">>> Downloading tarballs" |
if [ ! -f "${BINUTILS}" ]; then |
wget -c "${BINUTILS_SOURCE}${BINUTILS}" |
check_error $? "Error downloading binutils." |
fi |
if [ ! -f "${GCC}" ]; then |
wget -c "${GCC_SOURCE}${GCC}" |
check_error $? "Error downloading GCC." |
fi |
echo ">>> Creating destionation directory" |
if [ ! -d "${PREFIX}" ]; then |
mkdir -p "${PREFIX}" |
test -d "${PREFIX}" |
check_error $? "Unable to create ${PREFIX}." |
fi |
echo ">>> Creating GCC work directory" |
if [ ! -d "${OBJDIR}" ]; then |
mkdir -p "${OBJDIR}" |
test -d "${OBJDIR}" |
check_error $? "Unable to create ${OBJDIR}." |
fi |
echo ">>> Unpacking tarballs" |
tar -xvzf "${BINUTILS}" |
check_error $? "Error unpacking binutils." |
tar -xvjf "${GCC}" |
check_error $? "Error unpacking GCC." |
echo ">>> Compiling and installing binutils" |
cd "${BINUTILSDIR}" |
check_error $? "Change directory failed." |
./configure "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls" |
check_error $? "Error configuring binutils." |
make all install |
check_error $? "Error compiling/installing binutils." |
echo ">>> Compiling and installing GCC" |
cd "${OBJDIR}" |
check_error $? "Change directory failed." |
"${GCCDIR}/configure" "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c --disable-multilib --disable-libgcj --without-headers --disable-shared |
check_error $? "Error configuring GCC." |
PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc |
check_error $? "Error compiling/installing GCC." |
echo |
echo ">>> Cross-compiler for ${TARGET} installed." |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/tags/0.2.0/kernel/contrib/toolchain/toolchain.mipsel32.sh |
---|
0,0 → 1,84 |
#!/bin/bash |
# Cross-Compiler Toolchain for ${PLATFORM} |
# by Martin Decky <martin@decky.cz> |
# |
# GPL'ed, copyleft |
# |
check_error() { |
if [ "$1" -ne "0" ]; then |
echo |
echo "Script failed: $2" |
exit |
fi |
} |
BINUTILS_VERSION="2.16.1" |
GCC_VERSION="4.1.1" |
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz" |
GCC="gcc-core-${GCC_VERSION}.tar.bz2" |
BINUTILS_SOURCE="ftp://ftp.gnu.org/gnu/binutils/" |
GCC_SOURCE="ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/" |
PLATFORM="mipsel" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-linux-gnu" |
HOST="i686-pc-linux-gnu" |
PREFIX="/usr/local/${PLATFORM}" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
OBJDIR="${WORKDIR}/gcc-obj" |
echo ">>> Downloading tarballs" |
if [ ! -f "${BINUTILS}" ]; then |
wget -c "${BINUTILS_SOURCE}${BINUTILS}" |
check_error $? "Error downloading binutils." |
fi |
if [ ! -f "${GCC}" ]; then |
wget -c "${GCC_SOURCE}${GCC}" |
check_error $? "Error downloading GCC." |
fi |
echo ">>> Creating destionation directory" |
if [ ! -d "${PREFIX}" ]; then |
mkdir -p "${PREFIX}" |
test -d "${PREFIX}" |
check_error $? "Unable to create ${PREFIX}." |
fi |
echo ">>> Creating GCC work directory" |
if [ ! -d "${OBJDIR}" ]; then |
mkdir -p "${OBJDIR}" |
test -d "${OBJDIR}" |
check_error $? "Unable to create ${OBJDIR}." |
fi |
echo ">>> Unpacking tarballs" |
tar -xvzf "${BINUTILS}" |
check_error $? "Error unpacking binutils." |
tar -xvjf "${GCC}" |
check_error $? "Error unpacking GCC." |
echo ">>> Compiling and installing binutils" |
cd "${BINUTILSDIR}" |
check_error $? "Change directory failed." |
./configure "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls" |
check_error $? "Error configuring binutils." |
make all install |
check_error $? "Error compiling/installing binutils." |
echo ">>> Compiling and installing GCC" |
cd "${OBJDIR}" |
check_error $? "Change directory failed." |
"${GCCDIR}/configure" "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c --disable-multilib --disable-libgcj --without-headers --disable-shared |
check_error $? "Error configuring GCC." |
PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc |
check_error $? "Error compiling/installing GCC." |
echo |
echo ">>> Cross-compiler for ${TARGET} installed." |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/tags/0.2.0/kernel/contrib/toolchain/toolchain.sparc64.sh |
---|
0,0 → 1,84 |
#!/bin/bash |
# Cross-Compiler Toolchain for ${PLATFORM} |
# by Martin Decky <martin@decky.cz> |
# |
# GPL'ed, copyleft |
# |
check_error() { |
if [ "$1" -ne "0" ]; then |
echo |
echo "Script failed: $2" |
exit |
fi |
} |
BINUTILS_VERSION="2.16.1" |
GCC_VERSION="4.1.1" |
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz" |
GCC="gcc-core-${GCC_VERSION}.tar.bz2" |
BINUTILS_SOURCE="ftp://ftp.gnu.org/gnu/binutils/" |
GCC_SOURCE="ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/" |
PLATFORM="sparc64" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-linux-gnu" |
HOST="i686-pc-linux-gnu" |
PREFIX="/usr/local/${PLATFORM}" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
OBJDIR="${WORKDIR}/gcc-obj" |
echo ">>> Downloading tarballs" |
if [ ! -f "${BINUTILS}" ]; then |
wget -c "${BINUTILS_SOURCE}${BINUTILS}" |
check_error $? "Error downloading binutils." |
fi |
if [ ! -f "${GCC}" ]; then |
wget -c "${GCC_SOURCE}${GCC}" |
check_error $? "Error downloading GCC." |
fi |
echo ">>> Creating destionation directory" |
if [ ! -d "${PREFIX}" ]; then |
mkdir -p "${PREFIX}" |
test -d "${PREFIX}" |
check_error $? "Unable to create ${PREFIX}." |
fi |
echo ">>> Creating GCC work directory" |
if [ ! -d "${OBJDIR}" ]; then |
mkdir -p "${OBJDIR}" |
test -d "${OBJDIR}" |
check_error $? "Unable to create ${OBJDIR}." |
fi |
echo ">>> Unpacking tarballs" |
tar -xvzf "${BINUTILS}" |
check_error $? "Error unpacking binutils." |
tar -xvjf "${GCC}" |
check_error $? "Error unpacking GCC." |
echo ">>> Compiling and installing binutils" |
cd "${BINUTILSDIR}" |
check_error $? "Change directory failed." |
./configure "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls" |
check_error $? "Error configuring binutils." |
make all install |
check_error $? "Error compiling/installing binutils." |
echo ">>> Compiling and installing GCC" |
cd "${OBJDIR}" |
check_error $? "Change directory failed." |
"${GCCDIR}/configure" "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c --disable-multilib --disable-libgcj --without-headers --disable-shared |
check_error $? "Error configuring GCC." |
PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc |
check_error $? "Error compiling/installing GCC." |
echo |
echo ">>> Cross-compiler for ${TARGET} installed." |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/tags/0.2.0/kernel/contrib/toolchain/toolchain.mipseb32.sh |
---|
0,0 → 1,84 |
#!/bin/bash |
# Cross-Compiler Toolchain for ${PLATFORM} |
# by Martin Decky <martin@decky.cz> |
# |
# GPL'ed, copyleft |
# |
check_error() { |
if [ "$1" -ne "0" ]; then |
echo |
echo "Script failed: $2" |
exit |
fi |
} |
BINUTILS_VERSION="2.16.1" |
GCC_VERSION="4.1.1" |
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz" |
GCC="gcc-core-${GCC_VERSION}.tar.bz2" |
BINUTILS_SOURCE="ftp://ftp.gnu.org/gnu/binutils/" |
GCC_SOURCE="ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/" |
PLATFORM="mips" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-sgi-irix5" |
HOST="i686-pc-linux-gnu" |
PREFIX="/usr/local/${PLATFORM}" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
OBJDIR="${WORKDIR}/gcc-obj" |
echo ">>> Downloading tarballs" |
if [ ! -f "${BINUTILS}" ]; then |
wget -c "${BINUTILS_SOURCE}${BINUTILS}" |
check_error $? "Error downloading binutils." |
fi |
if [ ! -f "${GCC}" ]; then |
wget -c "${GCC_SOURCE}${GCC}" |
check_error $? "Error downloading GCC." |
fi |
echo ">>> Creating destionation directory" |
if [ ! -d "${PREFIX}" ]; then |
mkdir -p "${PREFIX}" |
test -d "${PREFIX}" |
check_error $? "Unable to create ${PREFIX}." |
fi |
echo ">>> Creating GCC work directory" |
if [ ! -d "${OBJDIR}" ]; then |
mkdir -p "${OBJDIR}" |
test -d "${OBJDIR}" |
check_error $? "Unable to create ${OBJDIR}." |
fi |
echo ">>> Unpacking tarballs" |
tar -xvzf "${BINUTILS}" |
check_error $? "Error unpacking binutils." |
tar -xvjf "${GCC}" |
check_error $? "Error unpacking GCC." |
echo ">>> Compiling and installing binutils" |
cd "${BINUTILSDIR}" |
check_error $? "Change directory failed." |
./configure "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls" |
check_error $? "Error configuring binutils." |
make all install |
check_error $? "Error compiling/installing binutils." |
echo ">>> Compiling and installing GCC" |
cd "${OBJDIR}" |
check_error $? "Change directory failed." |
"${GCCDIR}/configure" "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c --disable-multilib --disable-libgcj --without-headers --disable-shared |
check_error $? "Error configuring GCC." |
PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc |
check_error $? "Error compiling/installing GCC." |
echo |
echo ">>> Cross-compiler for ${TARGET} installed." |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/tags/0.2.0/kernel/contrib/arch/ia64/vmaxlma.c |
---|
0,0 → 1,75 |
/* |
* Swap VMA and LMA in ELF header. |
* |
* by Jakub Jermar <jermar@itbs.cz> |
* |
* GPL'ed, copyleft |
*/ |
/* |
* HP's IA-64 simulator Ski seems to confuse VMA and LMA in the ELF header. |
* Instead of using LMA, Ski loads sections at their VMA addresses. |
* This short program provides a workaround for this bug by simply |
* swapping VMA and LMA in the ELF header of the executable. |
* |
* Note that after applying this workaround, you will be able to load |
* ELF objects with different VMA and LMA in Ski, but the executable |
* will become wronged for other potential uses. |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <sys/types.h> |
#include <sys/stat.h> |
#include <sys/mman.h> |
#include <unistd.h> |
#include <fcntl.h> |
void syntax(char *prg) |
{ |
printf("%s ELF-file\n", prg); |
exit(1); |
} |
void error(char *msg) |
{ |
printf("Error: %s\n", msg); |
exit(2); |
} |
#define ELF_VMA (0x50/sizeof(unsigned long long)) |
#define ELF_LMA (0x58/sizeof(unsigned long long)) |
#define ELF_ENTRY (0x18/sizeof(unsigned long long)) |
#define LENGTH 0x98 |
int main(int argc, char *argv[]) |
{ |
int fd; |
unsigned long long vma, lma,entry; |
unsigned long long *elf; |
if (argc != 2) |
syntax(argv[0]); |
fd = open(argv[1], O_RDWR); |
if (fd == -1) |
error("open failed"); |
elf = mmap(NULL, LENGTH, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); |
if ((void *) elf == (void *) -1) |
error("map failed"); |
lma = elf[ELF_LMA]; |
elf[ELF_VMA] = lma; |
entry = lma; |
elf[ELF_ENTRY] = entry; |
if (munmap(elf, LENGTH) == -1) |
error("munmap failed"); |
if (close(fd) == -1) |
error("close failed"); |
return 0; |
} |
/tags/0.2.0/kernel/tools/config.py |
---|
0,0 → 1,494 |
#!/usr/bin/env python |
""" |
Kernel configuration script |
""" |
import sys |
import os |
import re |
import commands |
INPUT = 'kernel.config' |
OUTPUT = 'Makefile.config' |
TMPOUTPUT = 'Makefile.config.tmp' |
class DefaultDialog: |
"Wrapper dialog that tries to return default values" |
def __init__(self, dlg): |
self.dlg = dlg |
def set_title(self,text): |
self.dlg.set_title(text) |
def yesno(self, text, default=None): |
if default is not None: |
return default |
return self.dlg.yesno(text, default) |
def noyes(self, text, default=None): |
if default is not None: |
return default |
return self.dlg.noyes(text, default) |
def choice(self, text, choices, defopt=None): |
if defopt is not None: |
return choices[defopt][0] |
return self.dlg.choice(text, choices, defopt) |
class NoDialog: |
def __init__(self): |
self.printed = None |
self.title = 'HelenOS Configuration' |
def print_title(self): |
if not self.printed: |
sys.stdout.write("\n*** %s ***\n" % self.title) |
self.printed = True |
def set_title(self, text): |
self.title = text |
self.printed = False |
def noyes(self, text, default=None): |
if not default: |
default = 'n' |
return self.yesno(text, default) |
def yesno(self, text, default=None): |
self.print_title() |
if default != 'n': |
default = 'y' |
while 1: |
sys.stdout.write("%s (y/n)[%s]: " % (text,default)) |
inp = sys.stdin.readline() |
if not inp: |
raise EOFError |
inp = inp.strip().lower() |
if not inp: |
return default |
if inp == 'y': |
return 'y' |
elif inp == 'n': |
return 'n' |
def _print_choice(self, text, choices, defopt): |
sys.stdout.write('%s:\n' % text) |
for i,(text,descr) in enumerate(choices): |
sys.stdout.write('\t%2d. %s\n' % (i, descr)) |
if defopt is not None: |
sys.stdout.write('Enter choice number[%d]: ' % defopt) |
else: |
sys.stdout.write('Enter choice number: ') |
def menu(self, text, choices, button, defopt=None): |
self.title = 'Main menu' |
menu = [] |
for key, descr in choices: |
txt = key + (45-len(key))*' ' + ': ' + descr |
menu.append((key, txt)) |
return self.choice(text, [button] + menu) |
def choice(self, text, choices, defopt=None): |
self.print_title() |
while 1: |
self._print_choice(text, choices, defopt) |
inp = sys.stdin.readline() |
if not inp: |
raise EOFError |
if not inp.strip(): |
if defopt is not None: |
return choices[defopt][0] |
continue |
try: |
number = int(inp.strip()) |
except ValueError: |
continue |
if number < 0 or number >= len(choices): |
continue |
return choices[number][0] |
def eof_checker(fnc): |
def wrapper(self, *args, **kw): |
try: |
return fnc(self, *args, **kw) |
except EOFError: |
return getattr(self.bckdialog,fnc.func_name)(*args, **kw) |
return wrapper |
class Dialog(NoDialog): |
def __init__(self): |
NoDialog.__init__(self) |
self.dlgcmd = os.environ.get('DIALOG','dialog') |
self.title = '' |
self.backtitle = 'HelenOS Kernel Configuration' |
if os.system('%s --print-maxsize >/dev/null 2>&1' % self.dlgcmd) != 0: |
raise NotImplementedError |
self.bckdialog = NoDialog() |
def set_title(self,text): |
self.title = text |
self.bckdialog.set_title(text) |
def calldlg(self,*args,**kw): |
"Wrapper for calling 'dialog' program" |
indesc, outdesc = os.pipe() |
pid = os.fork() |
if not pid: |
os.close(2) |
os.dup(outdesc) |
os.close(indesc) |
dlgargs = [self.dlgcmd,'--title',self.title, |
'--backtitle', self.backtitle] |
for key,val in kw.items(): |
dlgargs.append('--'+key) |
dlgargs.append(val) |
dlgargs += args |
os.execlp(self.dlgcmd,*dlgargs) |
os.close(outdesc) |
try: |
errout = os.fdopen(indesc,'r') |
data = errout.read() |
errout.close() |
pid,status = os.wait() |
except: |
os.system('reset') # Reset terminal |
raise |
if not os.WIFEXITED(status): |
os.system('reset') # Reset terminal |
raise EOFError |
status = os.WEXITSTATUS(status) |
if status == 255: |
raise EOFError |
return status,data |
def yesno(self, text, default=None): |
if text[-1] not in ('?',':'): |
text = text + ':' |
width = '50' |
height = '5' |
if len(text) < 48: |
text = ' '*int(((48-len(text))/2)) + text |
else: |
width = '0' |
height = '0' |
if default == 'n': |
res,data = self.calldlg('--defaultno','--yesno',text,height,width) |
else: |
res,data = self.calldlg('--yesno',text,height,width) |
if res == 0: |
return 'y' |
return 'n' |
yesno = eof_checker(yesno) |
def menu(self, text, choices, button, defopt=None): |
self.title = 'Main menu' |
text = text + ':' |
width = '70' |
height = str(8 + len(choices)) |
args = [] |
for key,val in choices: |
args.append(key) |
args.append(val) |
kw = {} |
if defopt: |
kw['default-item'] = choices[defopt][0] |
res,data = self.calldlg('--ok-label','Change', |
'--extra-label',button[1], |
'--extra-button', |
'--menu',text,height,width, |
str(len(choices)),*args,**kw) |
if res == 3: |
return button[0] |
if res == 1: # Cancel |
sys.exit(1) |
elif res: |
print data |
raise EOFError |
return data |
menu = eof_checker(menu) |
def choice(self, text, choices, defopt=None): |
text = text + ':' |
width = '50' |
height = str(8 + len(choices)) |
args = [] |
for key,val in choices: |
args.append(key) |
args.append(val) |
kw = {} |
if defopt: |
kw['default-item'] = choices[defopt][0] |
res,data = self.calldlg('--nocancel','--menu',text,height,width, |
str(len(choices)),*args, **kw) |
if res: |
print data |
raise EOFError |
return data |
choice = eof_checker(choice) |
def read_defaults(fname,defaults): |
"Read saved values from last configuration run" |
f = file(fname,'r') |
for line in f: |
res = re.match(r'^(?:#!# )?([^#]\w*)\s*=\s*(.*?)\s*$', line) |
if res: |
defaults[res.group(1)] = res.group(2) |
f.close() |
def check_condition(text, defaults, asked_names): |
seen_vars = [ x[0] for x in asked_names ] |
ctype = 'cnf' |
if ')|' in text or '|(' in text: |
ctype = 'dnf' |
if ctype == 'cnf': |
conds = text.split('&') |
else: |
conds = text.split('|') |
for cond in conds: |
if cond.startswith('(') and cond.endswith(')'): |
cond = cond[1:-1] |
inside = check_inside(cond, defaults, ctype, seen_vars) |
if ctype == 'cnf' and not inside: |
return False |
if ctype == 'dnf' and inside: |
return True |
if ctype == 'cnf': |
return True |
return False |
def check_inside(text, defaults, ctype, seen_vars): |
""" |
Check that the condition specified on input line is True |
only CNF is supported |
""" |
if ctype == 'cnf': |
conds = text.split('|') |
else: |
conds = text.split('&') |
for cond in conds: |
res = re.match(r'^(.*?)(!?=)(.*)$', cond) |
if not res: |
raise RuntimeError("Invalid condition: %s" % cond) |
condname = res.group(1) |
oper = res.group(2) |
condval = res.group(3) |
if condname not in seen_vars: |
varval = '' |
## raise RuntimeError("Variable %s not defined before being asked." %\ |
## condname) |
elif not defaults.has_key(condname): |
raise RuntimeError("Condition var %s does not exist: %s" % \ |
(condname,text)) |
else: |
varval = defaults[condname] |
if ctype == 'cnf': |
if oper == '=' and condval == varval: |
return True |
if oper == '!=' and condval != varval: |
return True |
else: |
if oper== '=' and condval != varval: |
return False |
if oper== '!=' and condval == varval: |
return False |
if ctype=='cnf': |
return False |
return True |
def parse_config(input, output, dlg, defaults={}, askonly=None): |
"Parse configuration file and create Makefile.config on the fly" |
def ask_the_question(dialog): |
"Ask question based on the type of variables to ask" |
# This is quite a hack, this thingy is written just to |
# have access to local variables.. |
if vartype == 'y/n': |
return dialog.yesno(comment, default) |
elif vartype == 'n/y': |
return dialog.noyes(comment, default) |
elif vartype == 'choice': |
defopt = None |
if default is not None: |
for i,(key,val) in enumerate(choices): |
if key == default: |
defopt = i |
break |
return dialog.choice(comment, choices, defopt) |
else: |
raise RuntimeError("Bad method: %s" % vartype) |
f = file(input, 'r') |
outf = file(output, 'w') |
outf.write('#########################################\n') |
outf.write('## AUTO-GENERATED FILE, DO NOT EDIT!!! ##\n') |
outf.write('#########################################\n\n') |
asked_names = [] |
comment = '' |
default = None |
choices = [] |
for line in f: |
if line.startswith('%'): |
res = re.match(r'^%\s*(?:\[(.*?)\])?\s*(.*)$', line) |
if not res: |
raise RuntimeError('Invalid command: %s' % line) |
if res.group(1): |
if not check_condition(res.group(1), defaults, |
asked_names): |
continue |
args = res.group(2).strip().split(' ') |
cmd = args[0].lower() |
args = args[1:] |
if cmd == 'saveas': |
outf.write('%s = %s\n' % (args[1],defaults[args[0]])) |
elif cmd == 'shellcmd': |
varname = args[0] |
args = args[1:] |
for i,arg in enumerate(args): |
if arg.startswith('$'): |
args[i] = defaults[arg[1:]] |
data,status = commands.getstatusoutput(' '.join(args)) |
if status: |
raise RuntimeError('Error running: %s' % ' '.join(args)) |
outf.write('%s = %s\n' % (varname,data.strip())) |
continue |
if line.startswith('!'): |
# Ask a question |
res = re.search(r'!\s*(?:\[(.*?)\])?\s*([^\s]+)\s*\((.*)\)\s*$', line) |
if not res: |
raise RuntimeError("Weird line: %s" % line) |
varname = res.group(2) |
vartype = res.group(3) |
default = defaults.get(varname,None) |
if res.group(1): |
if not check_condition(res.group(1), defaults, |
asked_names): |
if default is not None: |
outf.write('#!# %s = %s\n' % (varname, default)) |
# Clear cumulated values |
comment = '' |
default = None |
choices = [] |
continue |
asked_names.append((varname,comment)) |
if default is None or not askonly or askonly == varname: |
default = ask_the_question(dlg) |
else: |
default = ask_the_question(DefaultDialog(dlg)) |
outf.write('%s = %s\n' % (varname, default)) |
# Remeber the selected value |
defaults[varname] = default |
# Clear cumulated values |
comment = '' |
default = None |
choices = [] |
continue |
if line.startswith('@'): |
# Add new line into the 'choice array' |
res = re.match(r'@\s*(?:\[(.*?)\])?\s*"(.*?)"\s*(.*)$', line) |
if not res: |
raise RuntimeError("Bad line: %s" % line) |
if res.group(1): |
if not check_condition(res.group(1),defaults, |
asked_names): |
continue |
choices.append((res.group(2), res.group(3))) |
continue |
# All other things print to output file |
outf.write(line) |
if re.match(r'^#[^#]', line): |
# Last comment before question will be displayed to the user |
comment = line[1:].strip() |
elif line.startswith('## '): |
# Set title of the dialog window |
dlg.set_title(line[2:].strip()) |
outf.write('\n') |
outf.write('REVISION = %s\n' % commands.getoutput('svnversion . 2> /dev/null')) |
outf.write('TIMESTAMP = %s\n' % commands.getoutput('date "+%Y-%m-%d %H:%M:%S"')) |
outf.close() |
f.close() |
return asked_names |
def main(): |
defaults = {} |
try: |
dlg = Dialog() |
except NotImplementedError: |
dlg = NoDialog() |
if len(sys.argv) >= 2 and sys.argv[1]=='default': |
defmode = True |
else: |
defmode = False |
# Default run will update the configuration file |
# with newest options |
if os.path.exists(OUTPUT): |
read_defaults(OUTPUT, defaults) |
# Get ARCH from command line if specified |
if len(sys.argv) >= 3: |
defaults['ARCH'] = sys.argv[2] |
# Dry run only with defaults |
varnames = parse_config(INPUT, TMPOUTPUT, DefaultDialog(dlg), defaults) |
# If not in default mode, present selection of all possibilities |
if not defmode: |
defopt = 0 |
while 1: |
# varnames contains variable names that were in the |
# last question set |
choices = [ (x[1],defaults[x[0]]) for x in varnames ] |
res = dlg.menu('Configuration',choices,('save','Save'),defopt) |
if res == 'save': |
parse_config(INPUT, TMPOUTPUT, DefaultDialog(dlg), defaults) |
break |
# transfer description back to varname |
for i,(vname,descr) in enumerate(varnames): |
if res == descr: |
defopt = i |
break |
# Ask the user a simple question, produce output |
# as if the user answered all the other questions |
# with default answer |
varnames = parse_config(INPUT, TMPOUTPUT, dlg, defaults, |
askonly=varnames[i][0]) |
if os.path.exists(OUTPUT): |
os.unlink(OUTPUT) |
os.rename(TMPOUTPUT, OUTPUT) |
if not defmode and dlg.yesno('Rebuild kernel?') == 'y': |
os.execlp('make','make','clean','build') |
if __name__ == '__main__': |
main() |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/tags/0.2.0/kernel/tools/ppc64/gencontext.c |
---|
0,0 → 1,81 |
#include <stdio.h> |
#include <stdint.h> |
typedef uint32_t __u32; |
typedef uint64_t __u64; |
typedef __u64 ipl_t; |
typedef __u64 __address; |
#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/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/kernel/tools/amd64/gencontext.c |
---|
0,0 → 1,43 |
#include <stdio.h> |
#include <stdint.h> |
typedef uint64_t __u64; |
typedef __u64 ipl_t; |
typedef __u64 __address; |
#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/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/kernel/tools/sparc64/gencontext.c |
---|
0,0 → 1,54 |
#include <stdio.h> |
#include <stdint.h> |
typedef uint64_t __u64; |
typedef __u64 ipl_t; |
typedef __u64 __address; |
#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/kernel/tools/ppc32/gencontext.c |
---|
0,0 → 1,81 |
#include <stdio.h> |
#include <stdint.h> |
typedef uint32_t __u32; |
typedef uint64_t __u64; |
typedef __u32 ipl_t; |
typedef __u32 __address; |
#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/kernel/tools/mips32/gencontext.c |
---|
0,0 → 1,84 |
#include <stdio.h> |
#include <stdint.h> |
typedef uint32_t __u32; |
typedef __u32 ipl_t; |
typedef __u32 __address; |
#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/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/kernel/kernel.config |
---|
0,0 → 1,147 |
## 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 |
! ARCH (choice) |
# IA32 Compiler |
@ "cross" Cross-compiler |
@ "native" Native |
! [ARCH=ia32] IA32_COMPILER (choice) |
% [ARCH=ia32] SAVEAS IA32_COMPILER COMPILER |
# AMD64 Compiler |
@ "cross" Cross-compiler |
@ "native" Native |
! [ARCH=amd64] AMD64_COMPILER (choice) |
% [ARCH=amd64] SAVEAS AMD64_COMPILER COMPILER |
# Compiler |
@ "cross" Cross-compiler |
@ "native" Native |
! [(ARCH!=amd64)&(ARCH!=ia32)] OTHER_COMPILER (choice) |
% [(ARCH!=amd64)&(ARCH!=ia32)] SAVEAS OTHER_COMPILER COMPILER |
# CPU type |
@ "pentium4" Pentium 4 |
@ "pentium3" Pentium 3 |
@ "athlon-xp" Athlon XP |
@ "athlon-mp" Athlon MP |
@ "prescott" Prescott |
! [ARCH=ia32] IA32_CPU (choice) |
# MIPS Machine Type |
@ "msim" MSIM Simulator |
@ "simics" Virtutech Simics simulator |
@ "lgxemul" GXEmul Little Endian |
@ "bgxemul" GXEmul Big Endian |
@ "indy" SGI Indy |
! [ARCH=mips32] MIPS_MACHINE (choice) |
# Framebuffer support |
! [(ARCH=mips32&MIPS_MACHINE=lgxemul)|(ARCH=mips32&MIPS_MACHINE=bgxemul)|(ARCH=ia32)|(ARCH=amd64)] CONFIG_FB (y/n) |
# Framebuffer width |
@ "320" |
@ "640" |
@ "800" |
@ "1024" |
@ "1152" |
@ "1280" |
@ "1400" |
@ "1440" |
@ "1600" |
@ "2048" |
! [(ARCH=ia32|ARCH=amd64)&CONFIG_FB=y] CONFIG_VESA_WIDTH (choice) |
# Framebuffer height |
@ "200" |
@ "240" |
@ "400" |
@ "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] CONFIG_SMP (y/n) |
# Improved support for hyperthreading |
! [(ARCH=ia32|ARCH=amd64)&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&MIPS_MACHINE!=msim&MIPS_MACHINE!=simics)|ARCH=amd64|ARCH=ia32|ARCH=ia64] CONFIG_FPU_LAZY (y/n) |
# Power off on halt |
! [ARCH=ppc32] CONFIG_POWEROFF (y/n) |
## 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)] CONFIG_DEBUG_AS_WATCHPOINT (y/n) |
# Save all interrupt registers |
! [CONFIG_DEBUG=y&(ARCH=amd64|ARCH=mips32|ARCH=ia32)] CONFIG_DEBUG_ALLREGS (y/n) |
# Use VHPT |
! [ARCH=ia64] CONFIG_VHPT (y/n) |
## 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] "fpu/fpu1" Intel fpu test 1 |
@ [ARCH=ia32|ARCH=amd64] "fpu/sse1" Intel Sse test 1 |
@ [ARCH=mips32&MIPS_MACHINE!=msim&MIPS_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/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/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/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/kernel/doc/arch/amd64 |
---|
0,0 → 1,34 |
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 |
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/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/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/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/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/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/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/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 | |
+---------+ / +----------+ |
| / |
+------------------------+ |
/tags/0.2.0/kernel/genarch/src/mm/asid.c |
---|
0,0 → 1,171 |
/* |
* 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. |
*/ |
/** |
* @file asid.c |
* @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/kernel/genarch/src/mm/as_ht.c |
---|
0,0 → 1,115 |
/* |
* 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. |
*/ |
/** |
* @file as_ht.c |
* @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/kernel/genarch/src/mm/as_pt.c |
---|
0,0 → 1,136 |
/* |
* 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. |
*/ |
/** |
* @file as_pt.c |
* @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 *) PA2KA(PFN2ADDR(frame_alloc(ONE_FRAME, FRAME_KA | FRAME_PANIC))); |
if (flags & FLAG_AS_KERNEL) { |
memsetb((__address) dst_ptl0, PAGE_SIZE, 0); |
} else { |
__address src, dst; |
/* |
* Copy the kernel address space portion to new PTL0. |
*/ |
ipl = interrupts_disable(); |
mutex_lock(&AS_KERNEL->lock); |
src_ptl0 = (pte_t *) PA2KA((__address) AS_KERNEL->page_table); |
src = (__address) &src_ptl0[PTL0_INDEX(KERNEL_ADDRESS_SPACE_START)]; |
dst = (__address) &dst_ptl0[PTL0_INDEX(KERNEL_ADDRESS_SPACE_START)]; |
memsetb((__address) dst_ptl0, PAGE_SIZE, 0); |
memcpy((void *) dst, (void *) src, PAGE_SIZE - (src - (__address) src_ptl0)); |
mutex_unlock(&AS_KERNEL->lock); |
interrupts_restore(ipl); |
} |
return (pte_t *) KA2PA((__address) 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(ADDR2PFN((__address) 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/kernel/genarch/src/mm/page_ht.c |
---|
0,0 → 1,241 |
/* |
* 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. |
*/ |
/** |
* @file page_ht.c |
* @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(__native key[]); |
static bool compare(__native key[], count_t keys, link_t *item); |
static void remove_callback(link_t *item); |
static void ht_mapping_insert(as_t *as, __address page, __address frame, int flags); |
static void ht_mapping_remove(as_t *as, __address page); |
static pte_t *ht_mapping_find(as_t *as, __address 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(__native key[]) |
{ |
as_t *as = (as_t *) key[KEY_AS]; |
__address page = (__address) 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 |= ((__native) 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(__native 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] == (__address) t->as) && (key[KEY_PAGE] == t->page); |
} else { |
return (key[KEY_AS] == (__address) 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, __address page, __address frame, int flags) |
{ |
pte_t *t; |
__native key[2] = { (__address) 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, __address page) |
{ |
__native key[2] = { (__address) 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, __address page) |
{ |
link_t *hlp; |
pte_t *t = NULL; |
__native key[2] = { (__address) 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/kernel/genarch/src/mm/page_pt.c |
---|
0,0 → 1,262 |
/* |
* 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. |
*/ |
/** |
* @file page_pt.c |
* @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, __address page, __address frame, int flags); |
static void pt_mapping_remove(as_t *as, __address page); |
static pte_t *pt_mapping_find(as_t *as, __address 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, __address page, __address frame, int flags) |
{ |
pte_t *ptl0, *ptl1, *ptl2, *ptl3; |
__address newpt; |
ptl0 = (pte_t *) PA2KA((__address) as->page_table); |
if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT) { |
newpt = PA2KA(PFN2ADDR(frame_alloc(ONE_FRAME, FRAME_KA))); |
memsetb(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 = PA2KA(PFN2ADDR(frame_alloc(ONE_FRAME, FRAME_KA))); |
memsetb(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 = PA2KA(PFN2ADDR(frame_alloc(ONE_FRAME, FRAME_KA))); |
memsetb(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, __address page) |
{ |
pte_t *ptl0, *ptl1, *ptl2, *ptl3; |
bool empty = true; |
int i; |
/* |
* First, remove the mapping, if it exists. |
*/ |
ptl0 = (pte_t *) PA2KA((__address) 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((__address) &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(ADDR2PFN(KA2PA((__address) ptl3))); |
if (PTL2_ENTRIES) |
memsetb((__address) &ptl2[PTL2_INDEX(page)], sizeof(pte_t), 0); |
else if (PTL1_ENTRIES) |
memsetb((__address) &ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0); |
else |
memsetb((__address) &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(ADDR2PFN(KA2PA((__address) ptl2))); |
if (PTL1_ENTRIES) |
memsetb((__address) &ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0); |
else |
memsetb((__address) &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(ADDR2PFN(KA2PA((__address) ptl1))); |
memsetb((__address) &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, __address page) |
{ |
pte_t *ptl0, *ptl1, *ptl2, *ptl3; |
ptl0 = (pte_t *) PA2KA((__address) 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/kernel/genarch/src/mm/asid_fifo.c |
---|
0,0 → 1,91 |
/* |
* 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. |
*/ |
/** |
* @file asid_fifo.c |
* @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/kernel/genarch/src/i8042/i8042.c |
---|
0,0 → 1,568 |
/* |
* 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 <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> |
/** |
* i8042 processor driver. |
* It takes care of low-level keyboard functions. |
*/ |
/** 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 0x49 |
#define i8042_BUFFER_FULL_MASK 0x01 |
#define i8042_WAIT_MASK 0x02 |
#define SPECIAL '?' |
#define KEY_RELEASE 0x80 |
/** |
* These codes read from i8042 data register are silently ignored. |
*/ |
#define IGNORE_CODE 0x7f |
static void key_released(__u8 sc); |
static void key_pressed(__u8 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 __u8 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 stack Interrupted stack. |
*/ |
void i8042_interrupt(int n, istate_t *istate) |
{ |
__u8 x; |
trap_virtual_eoi(); |
x = i8042_data_read(); |
if (x & KEY_RELEASE) |
key_released(x ^ KEY_RELEASE); |
else |
key_pressed(x); |
} |
/** 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(__u8 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(__u8 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 __u8 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(__u8 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(__u8 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())) { |
__u8 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 |
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) |
{ |
__u8 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/kernel/genarch/src/fb/fb.c |
---|
0,0 → 1,377 |
/* |
* 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 <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 "helenos.xbm" |
SPINLOCK_INITIALIZE(fb_lock); |
static __u8 *fbaddress = NULL; |
static __u8 *blankline = NULL; |
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 (*putpixel)(unsigned int x, unsigned int y, int color); |
static int (*getpixel)(unsigned int x, unsigned int y); |
/** Put pixel - 24-bit depth, 1 free byte */ |
static void putpixel_4byte(unsigned int x, unsigned int y, int color) |
{ |
*((__u32 *)(fbaddress + POINTPOS(x, y))) = color; |
} |
/** Return pixel color - 24-bit depth, 1 free byte */ |
static int getpixel_4byte(unsigned int x, unsigned int y) |
{ |
return *((__u32 *)(fbaddress + POINTPOS(x, y))) & 0xffffff; |
} |
/** Put pixel - 24-bit depth */ |
static void putpixel_3byte(unsigned int x, unsigned int y, int color) |
{ |
unsigned int startbyte = POINTPOS(x, y); |
#if (defined(BIG_ENDIAN) || defined(FB_BIG_ENDIAN)) |
fbaddress[startbyte] = RED(color, 8); |
fbaddress[startbyte + 1] = GREEN(color, 8); |
fbaddress[startbyte + 2] = BLUE(color, 8); |
#else |
fbaddress[startbyte + 2] = RED(color, 8); |
fbaddress[startbyte + 1] = GREEN(color, 8); |
fbaddress[startbyte + 0] = BLUE(color, 8); |
#endif |
} |
/** Return pixel color - 24-bit depth */ |
static int getpixel_3byte(unsigned int x, unsigned int y) |
{ |
unsigned int startbyte = POINTPOS(x, y); |
#if (defined(BIG_ENDIAN) || defined(FB_BIG_ENDIAN)) |
return fbaddress[startbyte] << 16 | fbaddress[startbyte + 1] << 8 | fbaddress[startbyte + 2]; |
#else |
return fbaddress[startbyte + 2] << 16 | fbaddress[startbyte + 1] << 8 | fbaddress[startbyte + 0]; |
#endif |
} |
/** Put pixel - 16-bit depth (5:6:6) */ |
static void putpixel_2byte(unsigned int x, unsigned int y, int color) |
{ |
/* 5-bit, 5-bits, 5-bits */ |
*((__u16 *)(fbaddress + POINTPOS(x, y))) = RED(color, 5) << 11 | GREEN(color, 6) << 5 | BLUE(color, 5); |
} |
/** Return pixel color - 16-bit depth (5:6:6) */ |
static int getpixel_2byte(unsigned int x, unsigned int y) |
{ |
int color = *((__u16 *)(fbaddress + POINTPOS(x, y))); |
return (((color >> 11) & 0x1f) << (16 + 3)) | (((color >> 5) & 0x3f) << (8 + 2)) | ((color & 0x1f) << 3); |
} |
/** Put pixel - 8-bit depth (3:2:3) */ |
static void putpixel_1byte(unsigned int x, unsigned int y, int color) |
{ |
fbaddress[POINTPOS(x, y)] = RED(color, 3) << 5 | GREEN(color, 2) << 3 | BLUE(color, 3); |
} |
/** Return pixel color - 8-bit depth (3:2:3) */ |
static int getpixel_1byte(unsigned int x, unsigned int y) |
{ |
int color = fbaddress[POINTPOS(x, y)]; |
return (((color >> 5) & 0x7) << (16 + 5)) | (((color >> 3) & 0x3) << (8 + 6)) | ((color & 0x7) << 5); |
} |
/** Fill line with color BGCOLOR */ |
static void clear_line(unsigned int y) |
{ |
unsigned int x; |
for (x = 0; x < xres; x++) |
(*putpixel)(x, y, BGCOLOR); |
} |
/** Fill screen with background color */ |
static void clear_screen(void) |
{ |
unsigned int y; |
for (y = 0; y < yres; y++) |
clear_line(y); |
} |
/** Scroll screen one row up */ |
static void scroll_screen(void) |
{ |
unsigned int i; |
__u8 *lastline = &fbaddress[(rows - 1) * ROW_BYTES]; |
memcpy((void *) fbaddress, (void *) &fbaddress[ROW_BYTES], scanline * yres - ROW_BYTES); |
/* Clear last row */ |
if (blankline) { |
memcpy((void *) lastline, (void *) blankline, ROW_BYTES); |
} else { |
for (i = 0; i < FONT_SCANLINES; i++) |
clear_line((rows - 1) * FONT_SCANLINES + i); |
if (config.mm_initialized) { |
/* Save a blank line aside. */ |
blankline = (__u8 *) malloc(ROW_BYTES, FRAME_ATOMIC); |
if (blankline) |
memcpy((void *) blankline, (void *) lastline, 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(__u8 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(__address addr, unsigned int x, unsigned int y, unsigned int bpp, unsigned int scan) |
{ |
switch (bpp) { |
case 8: |
putpixel = putpixel_1byte; |
getpixel = getpixel_1byte; |
pixelbytes = 1; |
break; |
case 16: |
putpixel = putpixel_2byte; |
getpixel = getpixel_2byte; |
pixelbytes = 2; |
break; |
case 24: |
putpixel = putpixel_3byte; |
getpixel = getpixel_3byte; |
pixelbytes = 3; |
break; |
case 32: |
putpixel = putpixel_4byte; |
getpixel = getpixel_4byte; |
pixelbytes = 4; |
break; |
default: |
panic("Unsupported bpp"); |
} |
unsigned int fbsize = scan * y; |
/* Map the framebuffer */ |
fbaddress = (__u8 *) hw_map((__address) addr, fbsize); |
xres = x; |
yres = y; |
bitspp = bpp; |
scanline = scan; |
rows = y / FONT_SCANLINES; |
columns = x / COL_WIDTH; |
clear_screen(); |
draw_logo(xres - helenos_width, 0); |
invert_cursor(); |
chardev_initialize("fb", &framebuffer, &fb_ops); |
stdout = &framebuffer; |
sysinfo_set_item_val("fb", NULL, true); |
sysinfo_set_item_val("fb.kind", NULL, 1); |
sysinfo_set_item_val("fb.width", NULL, x); |
sysinfo_set_item_val("fb.height", NULL, y); |
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); |
} |
/tags/0.2.0/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/kernel/genarch/src/fb/font-8x16.c |
---|
0,0 → 1,4641 |
/* |
* 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 <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/kernel/genarch/src/acpi/madt.c |
---|
0,0 → 1,241 |
/* |
* 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. |
*/ |
/** |
* @file madt.c |
* @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, __u32 index); |
static void madt_io_apic_entry(struct madt_io_apic *ioa, __u32 index); |
static void madt_intr_src_ovrd_entry(struct madt_intr_src_ovrd *override, __u32 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 __u8 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(); |
} |
__u8 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 *) (((__u8 *) acpi_madt) + acpi_madt->header.length); |
struct madt_apic_header *h; |
l_apic = (__u32 *) (__native) acpi_madt->l_apic_address; |
/* calculate madt entries */ |
for (h = &acpi_madt->apic_header[0]; h < end; h = (struct madt_apic_header *) (((__u8 *) 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."); |
__u32 index = 0; |
for (h = &acpi_madt->apic_header[0]; h < end; h = (struct madt_apic_header *) (((__u8 *) h) + h->length)) { |
madt_entries_index[index++] = h; |
} |
/* Quicksort MADT index structure */ |
qsort(madt_entries_index, madt_entries_index_cnt, sizeof(__address), &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, __u32 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, __u32 index) |
{ |
if (!madt_io_apic_entry_cnt++) { |
/* remember index of the first io apic entry */ |
madt_io_apic_entry_index = index; |
io_apic = (__u32 *) (__native) ioa->io_apic_address; |
} else { |
/* currently not supported */ |
return; |
} |
} |
void madt_intr_src_ovrd_entry(struct madt_intr_src_ovrd *override, __u32 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/kernel/genarch/src/acpi/acpi.c |
---|
0,0 → 1,180 |
/* |
* 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. |
*/ |
/** |
* @file acpi.c |
* @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[] = { |
{ (__u8 *)"APIC", (void *) &acpi_madt, "Multiple APIC Description Table" } |
}; |
static int rsdp_check(__u8 *rsdp) { |
struct acpi_rsdp *r = (struct acpi_rsdp *) rsdp; |
__u8 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(__u8 *sdt) |
{ |
struct acpi_sdt_header *h = (struct acpi_sdt_header *) sdt; |
__u8 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, (__address) sdt, (__address) sdt, PAGE_NOT_CACHEABLE); |
map_structure((__address) sdt, sdt->length); |
} |
static void configure_via_rsdt(void) |
{ |
int i, j, cnt = (acpi_rsdt->header.length - sizeof(struct acpi_sdt_header))/sizeof(__u32); |
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 *) (__native) acpi_rsdt->entry[i]; |
map_sdt(h); |
if (*((__u32 *) &h->signature[0])==*((__u32 *) &signature_map[j].signature[0])) { |
if (!acpi_sdt_check((__u8 *) 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(__u64); |
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 *) ((__address) acpi_rsdt->entry[i]); |
map_sdt(h); |
if (*((__u32 *) &h->signature[0])==*((__u32 *) &signature_map[j].signature[0])) { |
if (!acpi_sdt_check((__u8 *) 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) |
{ |
__u8 *addr[2] = { NULL, (__u8 *) PA2KA(0xe0000) }; |
int i, j, length[2] = { 1024, 128*1024 }; |
__u64 *sig = (__u64 *) RSDP_SIGNATURE; |
/* |
* Find Root System Description Pointer |
* 1. search first 1K of EBDA |
* 2. search 128K starting at 0xe0000 |
*/ |
addr[0] = (__u8 *) PA2KA(ebda); |
for (i = (ebda ? 0 : 1); i < 2; i++) { |
for (j = 0; j < length[i]; j += 16) { |
if (*((__u64 *) &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 *) (__native) acpi_rsdp->rsdt_address; |
if (acpi_rsdp->revision) acpi_xsdt = (struct acpi_xsdt *) ((__address) 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((__u8 *) acpi_rsdt)) { |
printf("RSDT: %s\n", "bad checksum"); |
return; |
} |
if (acpi_xsdt && !acpi_sdt_check((__u8 *) 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/kernel/genarch/src/softint/division.c |
---|
0,0 → 1,188 |
/* |
* 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. |
*/ |
#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/kernel/genarch/src/ofw/memory_init.c |
---|
0,0 → 1,88 |
/* |
* 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 <genarch/ofw/memory_init.h> |
#include <genarch/ofw/ofw.h> |
#include <panic.h> |
#include <mm/frame.h> |
#include <align.h> |
#include <arch/types.h> |
#include <typedefs.h> |
#define MEMMAP_MAX_RECORDS 32 |
typedef struct { |
__address start; |
size_t size; |
} memmap_t; |
static memmap_t memmap[MEMMAP_MAX_RECORDS]; |
size_t total_mem = 0; |
void ofw_init_memmap(void) |
{ |
int i; |
int ret; |
phandle handle = ofw_find_device("/memory"); |
if (handle == -1) |
panic("No RAM\n"); |
ret = ofw_get_property(handle, "reg", &memmap, sizeof(memmap)); |
if (ret == -1) |
panic("Device /memory has no reg property\n"); |
for (i = 0; i < MEMMAP_MAX_RECORDS; i++) { |
if (memmap[i].size == 0) |
break; |
total_mem += memmap[i].size; |
} |
} |
size_t ofw_get_memory_size(void) |
{ |
return total_mem; |
} |
void ofw_init_zones(void) |
{ |
int i; |
pfn_t confdata; |
for (i = 0; i < MEMMAP_MAX_RECORDS; i++) { |
if (memmap[i].size == 0) |
break; |
confdata = ADDR2PFN(memmap[i].start); |
if (confdata == 0) |
confdata = 2; |
zone_create(ADDR2PFN(memmap[i].start), |
SIZE2FRAMES(ALIGN_DOWN(memmap[i].size,PAGE_SIZE)), |
confdata, 0); |
} |
} |
/tags/0.2.0/kernel/genarch/src/ofw/ofw.c |
---|
0,0 → 1,123 |
/* |
* 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 <genarch/ofw/ofw.h> |
#include <arch/asm.h> |
#include <stdarg.h> |
#include <cpu.h> |
#include <arch/types.h> |
ofw_entry ofw; |
phandle ofw_chosen; |
ihandle ofw_stdin; |
ihandle ofw_stdout; |
void ofw_init(void) |
{ |
ofw_chosen = ofw_find_device("/chosen"); |
if (ofw_chosen == -1) |
ofw_done(); |
if (ofw_get_property(ofw_chosen, "stdin", &ofw_stdin, sizeof(ofw_stdin)) <= 0) |
ofw_stdin = 0; |
if (ofw_get_property(ofw_chosen, "stdout", &ofw_stdout, sizeof(ofw_stdout)) <= 0) |
ofw_stdout = 0; |
} |
void ofw_done(void) |
{ |
(void) ofw_call("exit", 0, 0); |
cpu_halt(); |
} |
__native ofw_call(const char *service, const int nargs, const int nret, ...) |
{ |
va_list list; |
ofw_args_t args; |
int i; |
args.service = service; |
args.nargs = nargs; |
args.nret = nret; |
va_start(list, nret); |
for (i = 0; i < nargs; i++) |
args.args[i] = va_arg(list, ofw_arg_t); |
va_end(list); |
for (i = 0; i < nret; i++) |
args.args[i + nargs] = 0; |
ofw(&args); |
return args.args[nargs]; |
} |
void ofw_putchar(const char ch) |
{ |
if (ofw_stdout == 0) |
return; |
(void) ofw_call("write", 3, 1, ofw_stdout, &ch, 1); |
} |
/** Read character from OFW's input. |
* |
* This call is non-blocking. |
* |
* @return 0 if no character was read, character read otherwise. |
*/ |
char ofw_getchar(void) |
{ |
char ch; |
if (ofw_stdin == 0) |
return 0; |
if (ofw_call("read", 3, 1, ofw_stdin, &ch, 1) == 1) |
return ch; |
else |
return 0; |
} |
phandle ofw_find_device(const char *name) |
{ |
return (phandle) ofw_call("finddevice", 1, 1, name); |
} |
int ofw_get_property(const phandle device, const char *name, void *buf, const int buflen) |
{ |
return (int) ofw_call("getprop", 4, 1, device, name, buf, buflen); |
} |
void *ofw_claim(const void *addr, const int size, const int align) |
{ |
return (void *) ofw_call("claim", 3, 1, addr, size, align); |
} |
/tags/0.2.0/kernel/genarch/include/i8042/i8042.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. |
*/ |
#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/kernel/genarch/include/mm/page_pt.h |
---|
0,0 → 1,111 |
/* |
* 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. |
*/ |
/* |
* 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, __address page, __address frame, int flags); |
extern pte_t *page_mapping_find_pt(as_t *as, __address page); |
#endif |
#endif |
/tags/0.2.0/kernel/genarch/include/mm/page_ht.h |
---|
0,0 → 1,82 |
/* |
* 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. |
*/ |
/* |
* 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. */ |
__address page; /**< Virtual memory page. */ |
__address 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/kernel/genarch/include/mm/as_ht.h |
---|
0,0 → 1,36 |
/* |
* 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. |
*/ |
#ifndef __AS_HT_H__ |
#define __AS_HT_H__ |
#include <mm/as.h> |
extern as_operations_t as_ht_operations; |
#endif |
/tags/0.2.0/kernel/genarch/include/mm/as_pt.h |
---|
0,0 → 1,36 |
/* |
* 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. |
*/ |
#ifndef __AS_PT_H__ |
#define __AS_PT_H__ |
#include <mm/as.h> |
extern as_operations_t as_pt_operations; |
#endif |
/tags/0.2.0/kernel/genarch/include/mm/asid_fifo.h |
---|
0,0 → 1,34 |
/* |
* 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. |
*/ |
#ifndef __ASID_FIFO_H__ |
#define __ASID_FIFO_H__ |
extern void asid_fifo_init(void); |
#endif |
/tags/0.2.0/kernel/genarch/include/fb/fb.h |
---|
0,0 → 1,38 |
/* |
* 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. |
*/ |
#ifndef _FB_H_ |
#define _FB_H_ |
#include <typedefs.h> |
#include <arch/types.h> |
extern spinlock_t fb_lock; |
void fb_init(__address addr, unsigned int x, unsigned int y, unsigned int bpp, unsigned int scan); |
#endif |
/tags/0.2.0/kernel/genarch/include/fb/font-8x16.h |
---|
0,0 → 1,37 |
/* |
* 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. |
*/ |
#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/kernel/genarch/include/softint/division.h |
---|
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. |
*/ |
#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/kernel/genarch/include/ofw/memory_init.h |
---|
0,0 → 1,38 |
/* |
* 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. |
*/ |
#ifndef __OFW_MEMORY_INIT_H__ |
#define __OFW_MEMORY_INIT_H__ |
#include <typedefs.h> |
extern void ofw_init_memmap(void); |
extern size_t ofw_get_memory_size(void); |
extern void ofw_init_zones(void); |
#endif |
/tags/0.2.0/kernel/genarch/include/ofw/ofw.h |
---|
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. |
*/ |
#ifndef __OFW_H__ |
#define __OFW_H__ |
#include <arch/types.h> |
#define MAX_OFW_ARGS 10 |
typedef __native ofw_arg_t; |
typedef int ihandle; |
typedef int phandle; |
/** OpenFirmware command structure |
* |
*/ |
typedef struct { |
const char *service; /**< Command name */ |
__native nargs; /**< Number of in arguments */ |
__native nret; /**< Number of out arguments */ |
ofw_arg_t args[MAX_OFW_ARGS]; /**< List of arguments */ |
} ofw_args_t; |
typedef void (*ofw_entry)(ofw_args_t *); |
extern ofw_entry ofw; |
extern void ofw_init(void); |
extern void ofw_done(void); |
extern __native ofw_call(const char *service, const int nargs, const int nret, ...); |
extern void ofw_putchar(const char ch); |
extern char ofw_getchar(void); |
extern phandle ofw_find_device(const char *name); |
extern int ofw_get_property(const phandle device, const char *name, void *buf, const int buflen); |
extern void *ofw_claim(const void *addr, const int size, const int align); |
#endif |
/tags/0.2.0/kernel/genarch/include/acpi/madt.h |
---|
0,0 → 1,140 |
/* |
* 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. |
*/ |
#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 { |
__u8 type; |
__u8 length; |
} __attribute__ ((packed)); |
/* Multiple APIC Description Table */ |
struct acpi_madt { |
struct acpi_sdt_header header; |
__u32 l_apic_address; |
__u32 flags; |
struct madt_apic_header apic_header[]; |
} __attribute__ ((packed)); |
struct madt_l_apic { |
struct madt_apic_header header; |
__u8 acpi_id; |
__u8 apic_id; |
__u32 flags; |
} __attribute__ ((packed)); |
struct madt_io_apic { |
struct madt_apic_header header; |
__u8 io_apic_id; |
__u8 reserved; |
__u32 io_apic_address; |
__u32 global_intr_base; |
} __attribute__ ((packed)); |
struct madt_intr_src_ovrd { |
struct madt_apic_header header; |
__u8 bus; |
__u8 source; |
__u32 global_int; |
__u16 flags; |
} __attribute__ ((packed)); |
struct madt_nmi_src { |
struct madt_apic_header header; |
__u16 flags; |
__u32 global_intr; |
} __attribute__ ((packed)); |
struct madt_l_apic_nmi { |
struct madt_apic_header header; |
__u8 acpi_id; |
__u16 flags; |
__u8 l_apic_lint; |
} __attribute__ ((packed)); |
struct madt_l_apic_addr_ovrd { |
struct madt_apic_header header; |
__u16 reserved; |
__u64 l_apic_address; |
} __attribute__ ((packed)); |
struct madt_io_sapic { |
struct madt_apic_header header; |
__u8 io_apic_id; |
__u8 reserved; |
__u32 global_intr_base; |
__u64 io_apic_address; |
} __attribute__ ((packed)); |
struct madt_l_sapic { |
struct madt_apic_header header; |
__u8 acpi_id; |
__u8 sapic_id; |
__u8 sapic_eid; |
__u8 reserved[3]; |
__u32 flags; |
__u32 acpi_processor_uid_value; |
__u8 acpi_processor_uid_str[1]; |
} __attribute__ ((packed)); |
struct madt_platform_intr_src { |
struct madt_apic_header header; |
__u16 flags; |
__u8 intr_type; |
__u8 processor_id; |
__u8 processor_eid; |
__u8 io_sapic_vector; |
__u32 global_intr; |
__u32 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/kernel/genarch/include/acpi/acpi.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. |
*/ |
#ifndef __ACPI_H__ |
#define __ACPI_H__ |
#include <arch/types.h> |
/* Root System Description Pointer */ |
struct acpi_rsdp { |
__u8 signature[8]; |
__u8 checksum; |
__u8 oemid[6]; |
__u8 revision; |
__u32 rsdt_address; |
__u32 length; |
__u64 xsdt_address; |
__u32 ext_checksum; |
__u8 reserved[3]; |
} __attribute__ ((packed)); |
/* System Description Table Header */ |
struct acpi_sdt_header { |
__u8 signature[4]; |
__u32 length; |
__u8 revision; |
__u8 checksum; |
__u8 oemid[6]; |
__u8 oem_table_id[8]; |
__u32 oem_revision; |
__u32 creator_id; |
__u32 creator_revision; |
} __attribute__ ((packed));; |
struct acpi_signature_map { |
__u8 *signature; |
struct acpi_sdt_header **sdt_ptr; |
char *description; |
}; |
/* Root System Description Table */ |
struct acpi_rsdt { |
struct acpi_sdt_header header; |
__u32 entry[]; |
} __attribute__ ((packed));; |
/* Extended System Description Table */ |
struct acpi_xsdt { |
struct acpi_sdt_header header; |
__u64 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(__u8 *sdt); |
#endif /* __ACPI_H__ */ |
/tags/0.2.0/kernel/genarch/Makefile.inc |
---|
0,0 → 1,76 |
# 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_OFW),y) |
GENARCH_SOURCES += \ |
genarch/src/ofw/ofw.c \ |
genarch/src/ofw/memory_init.c |
endif |
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/kernel/generic/src/main/kinit.c |
---|
0,0 → 1,192 |
/* |
* 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. |
*/ |
/** |
* @file kinit.c |
* @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/kernel/generic/src/main/main.c |
---|
0,0 → 1,321 |
/* |
* 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. |
*/ |
/** |
* @file main.c |
* @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 = { |
.mm_initialized = false |
}; |
/** 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. |
*/ |
__address hardcoded_load_address = 0; |
size_t hardcoded_ktext_size = 0; |
size_t hardcoded_kdata_size = 0; |
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) |
{ |
__address stackaddr; |
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); |
stackaddr = config.base + config.kernel_size; |
/* Avoid placing kernel on top of init */ |
count_t i; |
bool overlap = false; |
for (i = 0; i < init.cnt; i++) |
if (PA_overlaps(stackaddr, CONFIG_STACK_SIZE, init.tasks[i].addr, init.tasks[i].size)) { |
stackaddr = ALIGN_UP(init.tasks[i].addr + init.tasks[i].size, CONFIG_STACK_SIZE); |
init.tasks[i].size = ALIGN_UP(init.tasks[i].size, CONFIG_STACK_SIZE) + CONFIG_STACK_SIZE; |
overlap = true; |
} |
if (!overlap) |
config.kernel_size += CONFIG_STACK_SIZE; |
context_save(&ctx); |
context_set(&ctx, FADDR(main_bsp_separated_stack), stackaddr, 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(); |
config.mm_initialized = true; |
arch_post_mm_init(); |
version_print(); |
printf("%.*p: hardcoded_ktext_size=%zdK, hardcoded_kdata_size=%zdK\n", sizeof(__address) * 2, config.base, hardcoded_ktext_size >> 10, hardcoded_kdata_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(); |
for (i = 0; i < init.cnt; i++) |
printf("init[%zd].addr=%.*p, init[%zd].size=%zd\n", i, sizeof(__address) * 2, init.tasks[i].addr, i, init.tasks[i].size); |
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), (__address) 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/kernel/generic/src/main/uinit.c |
---|
0,0 → 1,62 |
/* |
* Copyright (C) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** |
* @file uinit.c |
* @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/kernel/generic/src/main/version.c |
---|
0,0 → 1,54 |
/* |
* 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 <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/kernel/generic/src/proc/task.c |
---|
0,0 → 1,491 |
/* |
* 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. |
*/ |
/** |
* @file task.c |
* @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->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. |
*/ |
__native 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 (__native) 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 this one. |
*/ |
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): address=%#zX, as=%#zX, ActiveCalls: %zd", |
t->name, t->taskid, 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 task used to kill a 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->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); |
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/kernel/generic/src/proc/thread.c |
---|
0,0 → 1,614 |
/* |
* 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. |
*/ |
/** |
* @file thread.c |
* @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); |
__u32 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; |
pfn_t pfn; |
int status; |
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 |
pfn = frame_alloc_rc(STACK_FRAMES, FRAME_KA | kmflags,&status); |
if (status) { |
#ifdef ARCH_HAS_FPU |
if (t->saved_fpu_context) |
slab_free(fpu_context_slab,t->saved_fpu_context); |
#endif |
return -1; |
} |
t->kstack = (__u8 *)PA2KA(PFN2ADDR(pfn)); |
return 0; |
} |
/** Destruction of thread_t object */ |
static int thr_destructor(void *obj) |
{ |
thread_t *t = (thread_t *)obj; |
frame_free(ADDR2PFN(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) ((__address ) 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((__address)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), (__address) 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->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. |
*/ |
spinlock_lock(&task->lock); |
if (!task->accept_new_threads) { |
spinlock_unlock(&task->lock); |
slab_free(thread_slab, t); |
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. |
*/ |
ipl = interrupts_disable(); |
spinlock_lock(&threads_lock); |
btree_insert(&threads_btree, (btree_key_t) ((__address) t), (void *) t, NULL); |
spinlock_unlock(&threads_lock); |
interrupts_restore(ipl); |
return t; |
} |
/** Make thread exiting |
* |
* 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(__u32 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, __u32 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); |
(void) waitq_sleep_prepare(&t->join_wq); |
spinlock_unlock(&t->lock); |
rc = waitq_sleep_timeout_unsafe(&t->join_wq, usec, flags); |
waitq_sleep_finish(&t->join_wq, rc, ipl); |
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(__u32 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, state=%s, task=%#zX, code=%#zX, stack=%#zX, cpu=", |
t->name, t, t->tid, 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) ((__address) t), &leaf) != NULL; |
} |
/** Process syscall to create new thread. |
* |
*/ |
__native sys_thread_create(uspace_arg_t *uspace_uarg, char *uspace_name) |
{ |
thread_t *t; |
char namebuf[THREAD_NAME_BUFLEN]; |
uspace_arg_t *kernel_uarg; |
__u32 tid; |
int rc; |
rc = copy_from_uspace(namebuf, uspace_name, THREAD_NAME_BUFLEN); |
if (rc != 0) |
return (__native) 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 (__native) rc; |
} |
if ((t = thread_create(uinit, kernel_uarg, TASK, 0, namebuf))) { |
tid = t->tid; |
thread_ready(t); |
return (__native) tid; |
} else { |
free(kernel_uarg); |
} |
return (__native) ENOMEM; |
} |
/** Process syscall to terminate thread. |
* |
*/ |
__native sys_thread_exit(int uspace_status) |
{ |
thread_exit(); |
/* Unreachable */ |
return 0; |
} |
/tags/0.2.0/kernel/generic/src/proc/scheduler.c |
---|
0,0 → 1,694 |
/* |
* 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. |
*/ |
/** |
* @file scheduler.c |
* @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), (__address) 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/kernel/generic/src/proc/the.c |
---|
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. |
*/ |
/** |
* @file the.c |
* @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; |
} |
/** 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/kernel/generic/src/console/klog.c |
---|
0,0 → 1,100 |
/* |
* 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 <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 = (void *)PFN2ADDR(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, (__native)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); |
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/kernel/generic/src/console/cmd.c |
---|
0,0 → 1,750 |
/* |
* 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. |
*/ |
/** |
* @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> |
/** 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) |
{ |
__address symaddr; |
char *symbol; |
__native (*f)(void); |
symaddr = get_symbol_addr(argv->buffer); |
if (!symaddr) |
printf("Symbol %s not found.\n", argv->buffer); |
else if (symaddr == (__address) -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(__address) * 2, symaddr, symbol); |
f = (__native (*)(void)) symaddr; |
printf("Result: %#zx\n", f()); |
} |
return 1; |
} |
/** Call function with one parameter */ |
int cmd_call1(cmd_arg_t *argv) |
{ |
__address symaddr; |
char *symbol; |
__native (*f)(__native,...); |
__native arg1 = argv[1].intval; |
symaddr = get_symbol_addr(argv->buffer); |
if (!symaddr) |
printf("Symbol %s not found.\n", argv->buffer); |
else if (symaddr == (__address) -1) { |
symtab_print_search(argv->buffer); |
printf("Duplicate symbol, be more specific.\n"); |
} else { |
symbol = get_symtab_entry(symaddr); |
printf("Calling f(0x%zX): %.*p: %s\n", arg1, sizeof(__address) * 2, symaddr, symbol); |
f = (__native (*)(__native,...)) symaddr; |
printf("Result: %#zx\n", f(arg1)); |
} |
return 1; |
} |
/** Call function with two parameters */ |
int cmd_call2(cmd_arg_t *argv) |
{ |
__address symaddr; |
char *symbol; |
__native (*f)(__native,__native,...); |
__native arg1 = argv[1].intval; |
__native arg2 = argv[2].intval; |
symaddr = get_symbol_addr(argv->buffer); |
if (!symaddr) |
printf("Symbol %s not found.\n", argv->buffer); |
else if (symaddr == (__address) -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(__address) * 2, symaddr, symbol); |
f = (__native (*)(__native,__native,...)) symaddr; |
printf("Result: %#zx\n", f(arg1, arg2)); |
} |
return 1; |
} |
/** Call function with three parameters */ |
int cmd_call3(cmd_arg_t *argv) |
{ |
__address symaddr; |
char *symbol; |
__native (*f)(__native,__native,__native,...); |
__native arg1 = argv[1].intval; |
__native arg2 = argv[2].intval; |
__native arg3 = argv[3].intval; |
symaddr = get_symbol_addr(argv->buffer); |
if (!symaddr) |
printf("Symbol %s not found.\n", argv->buffer); |
else if (symaddr == (__address) -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(__address) * 2, symaddr, symbol); |
f = (__native (*)(__native,__native,__native,...)) symaddr; |
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) |
{ |
__u32 *addr ; |
__u32 arg1 = argv[1].intval; |
bool pointer = false; |
if (((char *)argv->buffer)[0] == '*') { |
addr = (__u32 *) get_symbol_addr(argv->buffer+1); |
pointer = true; |
} else if (((char *)argv->buffer)[0] >= '0' && |
((char *)argv->buffer)[0] <= '9') |
addr = (__u32 *)atoi((char *)argv->buffer); |
else |
addr = (__u32 *)get_symbol_addr(argv->buffer); |
if (!addr) |
printf("Symbol %s not found.\n", argv->buffer); |
else if (addr == (__u32 *) -1) { |
symtab_print_search(argv->buffer); |
printf("Duplicate symbol, be more specific.\n"); |
} else { |
if (pointer) |
addr = (__u32 *)(*(__native *)addr); |
printf("Writing 0x%x -> %.*p\n", arg1, sizeof(__address) * 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) |
{ |
arch_release_console(); |
return 1; |
} |
/tags/0.2.0/kernel/generic/src/console/kconsole.c |
---|
0,0 → 1,623 |
/* |
* 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. |
*/ |
/** |
* @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 arg Not used. |
*/ |
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, __native *result) |
{ |
char symname[MAX_SYMBOL_NAME]; |
__address 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 == (__address) -1) { |
printf("Duplicate symbol %s.\n",symname); |
symtab_print_search(symname); |
return -1; |
} |
if (isaddr) |
*result = (__native)symaddr; |
else if (isptr) |
*result = **((__native **)symaddr); |
else |
*result = *((__native *)symaddr); |
} else { /* It's a number - convert it */ |
*result = atoi(text); |
if (isptr) |
*result = *((__native *)*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 = (__native) 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/kernel/generic/src/console/console.c |
---|
0,0 → 1,160 |
/* |
* 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. |
*/ |
#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. |
*/ |
__u8 _getc(chardev_t *chardev) |
{ |
__u8 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 len 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 */ |
__u8 getc(chardev_t *chardev) |
{ |
__u8 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/kernel/generic/src/console/chardev.c |
---|
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. |
*/ |
#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, __u8 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/kernel/generic/src/ipc/irq.c |
---|
0,0 → 1,321 |
/* |
* 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. |
*/ |
/** 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: IPC_M_INTERRUPT |
* - ARG1: interrupt number |
* - ARG2: payload modified by a 'top-half' handler |
* - ARG3: 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; |
if (!code) |
return; |
for (i=0; i < code->cmdcount;i++) { |
switch (code->cmds[i].cmd) { |
case CMD_MEM_READ_1: |
IPC_SET_ARG2(call->data, *((__u8 *)code->cmds[i].addr)); |
break; |
case CMD_MEM_READ_2: |
IPC_SET_ARG2(call->data, *((__u16 *)code->cmds[i].addr)); |
break; |
case CMD_MEM_READ_4: |
IPC_SET_ARG2(call->data, *((__u32 *)code->cmds[i].addr)); |
break; |
case CMD_MEM_READ_8: |
IPC_SET_ARG2(call->data, *((__u64 *)code->cmds[i].addr)); |
break; |
case CMD_MEM_WRITE_1: |
*((__u8 *)code->cmds[i].addr) = code->cmds[i].value; |
break; |
case CMD_MEM_WRITE_2: |
*((__u16 *)code->cmds[i].addr) = code->cmds[i].value; |
break; |
case CMD_MEM_WRITE_4: |
*((__u32 *)code->cmds[i].addr) = code->cmds[i].value; |
break; |
case CMD_MEM_WRITE_8: |
*((__u64 *)code->cmds[i].addr) = code->cmds[i].value; |
break; |
#if defined(ia32) || defined(amd64) |
case CMD_PORT_READ_1: |
IPC_SET_ARG2(call->data, 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: |
IPC_SET_ARG2(call->data, _getc(&ski_uconsole)); |
break; |
#endif |
#if defined(ppc32) |
case CMD_PPC32_GETCHAR: |
IPC_SET_ARG2(call->data, cuda_get_scancode()); |
break; |
#endif |
default: |
break; |
} |
} |
} |
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, __native a2, __native 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, IPC_M_INTERRUPT); |
IPC_SET_ARG1(call->data, irq); |
IPC_SET_ARG2(call->data, a2); |
IPC_SET_ARG3(call->data, a3); |
send_call(mq, call); |
} |
spinlock_unlock(&irq_conns[mq].lock); |
} |
/** Notify process that an irq had happend |
* |
* 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; |
IPC_SET_METHOD(call->data, IPC_M_INTERRUPT); |
IPC_SET_ARG1(call->data, irq); |
IPC_SET_ARG3(call->data, atomic_preinc(&irq_conns[mq].counter)); |
/* 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/kernel/generic/src/ipc/sysipc.c |
---|
0,0 → 1,581 |
/* |
* 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 <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(__native 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(__native 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, (__native)&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, (__native)&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 |
*/ |
__native sys_ipc_call_sync_fast(__native phoneid, __native method, |
__native 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 */ |
__native sys_ipc_call_sync(__native 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 (__native) 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 |
*/ |
__native sys_ipc_call_async_fast(__native phoneid, __native method, |
__native arg1, __native 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); |
if (!(res=request_preprocess(call))) |
ipc_call(phone, call); |
else |
ipc_backsend_err(phone, call, res); |
return (__native) call; |
} |
/** Synchronous IPC call allowing to send whole message |
* |
* @return The same as sys_ipc_call_async |
*/ |
__native sys_ipc_call_async(__native 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 (__native) rc; |
} |
if (!(res=request_preprocess(call))) |
ipc_call(phone, call); |
else |
ipc_backsend_err(phone, call, res); |
return (__native) 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 |
*/ |
__native sys_ipc_forward_fast(__native callid, __native phoneid, |
__native method, __native 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 */ |
__native sys_ipc_answer_fast(__native callid, __native retval, |
__native arg1, __native 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 */ |
__native sys_ipc_answer(__native 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 |
* |
*/ |
__native 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 |
*/ |
__native sys_ipc_wait_for_call(ipc_data_t *calldata, __u32 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)); |
STRUCT_TO_USPACE(&calldata->args, &call->data.args); |
ipc_call_free(call); |
return ((__native)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 ((__native)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 (__native)call; |
} |
/** Connect irq handler to task */ |
__native 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 (__native) ELIMIT; |
irq_ipc_bind_arch(irq); |
return ipc_irq_register(&TASK->answerbox, irq, ucode); |
} |
/* Disconnect irq handler from task */ |
__native 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 (__native) ELIMIT; |
ipc_irq_unregister(&TASK->answerbox, irq); |
return 0; |
} |
/tags/0.2.0/kernel/generic/src/ipc/ipc.c |
---|
0,0 → 1,525 |
/* |
* 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. |
*/ |
/* 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((__address)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, __native 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 request Request to be sent |
*/ |
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, __u32 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/kernel/generic/src/ipc/ipcrsc.c |
---|
0,0 → 1,208 |
/* |
* 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. |
*/ |
/* 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 process. 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(__native 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 ((__native)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/kernel/generic/src/lib/memstr.c |
---|
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. |
*/ |
/** |
* @file memstr.c |
* @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((__address) src, sizeof(__native)) != (__address) src || |
ALIGN_UP((__address) dst, sizeof(__native)) != (__address) dst) { |
for (i = 0; i < cnt; i++) |
((__u8 *) dst)[i] = ((__u8 *) src)[i]; |
} else { |
for (i = 0; i < cnt/sizeof(__native); i++) |
((__native *) dst)[i] = ((__native *) src)[i]; |
for (j = 0; j < cnt%sizeof(__native); j++) |
((__u8 *)(((__native *) dst) + i))[j] = ((__u8 *)(((__native *) 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(__address dst, size_t cnt, __u8 x) |
{ |
int i; |
__u8 *p = (__u8 *) 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(__address dst, size_t cnt, __u16 x) |
{ |
int i; |
__u16 *p = (__u16 *) dst; |
for(i=0; i<cnt; i++) |
p[i] = x; |
} |
/tags/0.2.0/kernel/generic/src/lib/elf.c |
---|
0,0 → 1,218 |
/* |
* 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. |
*/ |
/** |
* @file elf.c |
* @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 *)(((__u8 *) 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 *)(((__u8 *) 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/kernel/generic/src/lib/sort.c |
---|
0,0 → 1,196 |
/* |
* 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. |
*/ |
/** |
* @file sort.c |
* @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)) |
{ |
__u8 buf_tmp[EBUFSIZE]; |
__u8 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)) |
{ |
__u8 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 __u8_cmp(void * a, void * b) |
{ |
return (* (__u8 *) a > * (__u8 *)b) ? 1 : (*(__u8 *)a < * (__u8 *)b) ? -1 : 0; |
} |
int __u16_cmp(void * a, void * b) |
{ |
return (* (__u16 *) a > * (__u16 *)b) ? 1 : (*(__u16 *)a < * (__u16 *)b) ? -1 : 0; |
} |
int __u32_cmp(void * a, void * b) |
{ |
return (* (__u32 *) a > * (__u32 *)b) ? 1 : (*(__u32 *)a < * (__u32 *)b) ? -1 : 0; |
} |
/tags/0.2.0/kernel/generic/src/lib/func.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. |
*/ |
/** |
* @file func.c |
* @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 dst 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 __native |
* |
* 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 |
*/ |
__native atoi(const char *text) |
{ |
int base = 10; |
__native 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/kernel/generic/src/printf/vsnprintf.c |
---|
0,0 → 1,95 |
/* |
* 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. |
*/ |
#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/kernel/generic/src/printf/printf_core.c |
---|
0,0 → 1,718 |
/* |
* 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. |
*/ |
/** |
* @file print.c |
* @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 __native strlen(const char *str) |
{ |
__native 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 or 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 or 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 or 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, __u64 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 */ |
/* FIXME: painful slow */ |
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, __u64 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(__u64 num, int width, int precision, int base , __u64 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" __native (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 */ |
__u64 number; /**< argument value */ |
size_t size; /**< byte size of integer parameter */ |
int width, precision; |
__u64 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': /* __native */ |
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 = (__u64)va_arg(ap, unsigned int); |
break; |
case PrintfQualifierShort: |
size = sizeof(unsigned short); |
number = (__u64)va_arg(ap, unsigned int); |
break; |
case PrintfQualifierInt: |
size = sizeof(unsigned int); |
number = (__u64)va_arg(ap, unsigned int); |
break; |
case PrintfQualifierLong: |
size = sizeof(unsigned long); |
number = (__u64)va_arg(ap, unsigned long); |
break; |
case PrintfQualifierLongLong: |
size = sizeof(unsigned long long); |
number = (__u64)va_arg(ap, unsigned long long); |
break; |
case PrintfQualifierPointer: |
size = sizeof(void *); |
number = (__u64)(unsigned long)va_arg(ap, void *); |
break; |
case PrintfQualifierNative: |
size = sizeof(__native); |
number = (__u64)va_arg(ap, __native); |
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(__u64)) { |
number = -((__s64)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], (__native)(i - j), ps)) < 0) { /* error */ |
counter = -counter; |
goto out; |
} |
counter += retval; |
} |
out: |
spinlock_unlock(&printflock); |
interrupts_restore(irqpri); |
return counter; |
} |
/tags/0.2.0/kernel/generic/src/printf/printf.c |
---|
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. |
*/ |
#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/kernel/generic/src/printf/snprintf.c |
---|
0,0 → 1,43 |
/* |
* 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. |
*/ |
#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/kernel/generic/src/printf/sprintf.c |
---|
0,0 → 1,42 |
/* |
* 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. |
*/ |
#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/kernel/generic/src/printf/vprintf.c |
---|
0,0 → 1,50 |
/* |
* 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. |
*/ |
#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/kernel/generic/src/printf/vsprintf.c |
---|
0,0 → 1,35 |
/* |
* 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. |
*/ |
#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/kernel/generic/src/mm/frame.c |
---|
0,0 → 1,1144 |
/* |
* 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. |
*/ |
/** |
* @file frame.c |
* @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 */ |
__u8 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, __u8 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(__u8 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, |
__u8 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, __u8 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 __u8 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, __u8 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; |
__u8 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) |
{ |
__u8 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((__address)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; |
__u8 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; |
__u8 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)); |
order = fnzb(cframes) + 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; |
__u8 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) |
*/ |
__address 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; |
__address 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; |
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 Allocated frame. |
* |
*/ |
pfn_t frame_alloc_generic(__u8 order, int flags, int *status, 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) { |
if (flags & FRAME_PANIC) |
panic("Can't allocate frame.\n"); |
/* |
* TODO: Sleep until frames are available again. |
*/ |
interrupts_restore(ipl); |
if (flags & FRAME_ATOMIC) { |
ASSERT(status != NULL); |
if (status) |
*status = FRAME_NO_MEMORY; |
return NULL; |
} |
panic("Sleep not implemented.\n"); |
goto loop; |
} |
v = zone_frame_alloc(zone, order); |
v += zone->base; |
spinlock_unlock(&zone->lock); |
interrupts_restore(ipl); |
if (status) |
*status = FRAME_OK; |
return 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 Frame number to be freed. |
*/ |
void frame_free(pfn_t pfn) |
{ |
ipl_t ipl; |
zone_t *zone; |
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 frame Frame no 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) { |
pfn_t firstframe = ADDR2PFN(KA2PA(config.base)); |
pfn_t lastframe = ADDR2PFN(KA2PA(config.base+config.kernel_size)); |
frame_mark_unavailable(firstframe,lastframe-firstframe+1); |
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 on 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(__address) * 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 base 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(__address) * 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/kernel/generic/src/mm/as.c |
---|
0,0 → 1,1526 |
/* |
* 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. |
*/ |
/** |
* @file as.c |
* @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 space 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> |
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, __address va); |
static bool check_area_conflicts(as_t *as, __address 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, __address 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((__address) &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, __address 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; |
__address 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)) { |
__address 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, __address address) |
{ |
as_area_t *area; |
__address 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++) { |
__address 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, __address src_base, size_t acc_size, |
as_t *dst_as, __address 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(__address 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, (__address) &memcpy_from_uspace_failover_address); |
} else if (THREAD->in_copy_to_uspace) { |
THREAD->in_copy_to_uspace = false; |
istate_set_retaddr(istate, (__address) &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, __address 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, __address 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(__address 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, __address 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) { |
__address 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]) { |
__address 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) { |
__address 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]) { |
__address 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]) { |
__address 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, __address 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]) { |
__address 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]) { |
__address 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]) { |
__address 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(ADDR2PFN((__address) 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(). */ |
__native sys_as_area_create(__address 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 (__native) address; |
else |
return (__native) -1; |
} |
/** Wrapper for as_area_resize. */ |
__native sys_as_area_resize(__address address, size_t size, int flags) |
{ |
return (__native) as_area_resize(AS, address, size, 0); |
} |
/** Wrapper for as_area_destroy. */ |
__native sys_as_area_destroy(__address address) |
{ |
return (__native) as_area_destroy(AS, address); |
} |
/tags/0.2.0/kernel/generic/src/mm/slab.c |
---|
0,0 → 1,900 |
/* |
* 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. |
*/ |
/** |
* @file slab.c |
* @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:@n |
* 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. |
* |
* @li 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 status; |
pfn_t pfn; |
int zone=0; |
pfn = frame_alloc_rc_zone(cache->order, FRAME_KA | flags, &status, &zone); |
data = (void *) PA2KA(PFN2ADDR(pfn)); |
if (status != FRAME_OK) { |
return NULL; |
} |
if (! (cache->flags & SLAB_CACHE_SLINSIDE)) { |
slab = slab_alloc(slab_extern_cache, flags); |
if (!slab) { |
frame_free(ADDR2PFN(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(pfn+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(ADDR2PFN(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((__address)&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((__address)cache, sizeof(*cache), 0); |
cache->name = name; |
if (align < sizeof(__native)) |
align = sizeof(__native); |
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 = ((cache->size-1) >> PAGE_WIDTH) + 1; |
cache->order = fnzb(pages); |
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(__address), |
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(__address), |
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/kernel/generic/src/mm/backend_elf.c |
---|
0,0 → 1,302 |
/* |
* 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. |
*/ |
/** |
* @file backend_elf.c |
* @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, __address addr, pf_access_t access); |
static void elf_frame_free(as_area_t *area, __address page, __address 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, __address 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; |
__address 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 = (__address) (((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 = (__address) 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 = PFN2ADDR(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 = PFN2ADDR(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 = PFN2ADDR(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, __address page, __address frame) |
{ |
elf_header_t *elf = area->backend_data.elf; |
elf_segment_header_t *entry = area->backend_data.segment; |
__address base; |
index_t i; |
ASSERT((page >= entry->p_vaddr) && (page < entry->p_vaddr + entry->p_memsz)); |
i = (page - entry->p_vaddr) >> PAGE_WIDTH; |
base = (__address) (((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(ADDR2PFN(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(ADDR2PFN(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; |
__address 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++) { |
__address 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/kernel/generic/src/mm/backend_anon.c |
---|
0,0 → 1,202 |
/* |
* 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. |
*/ |
/** |
* @file backend_anon.c |
* @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, __address addr, pf_access_t access); |
static void anon_frame_free(as_area_t *area, __address page, __address 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, __address addr, pf_access_t access) |
{ |
__address 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 = (__address) 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 = PFN2ADDR(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 = PFN2ADDR(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, __address page, __address frame) |
{ |
frame_free(ADDR2PFN(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++) { |
__address 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/kernel/generic/src/mm/backend_phys.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. |
*/ |
/** |
* @file backend_elf.c |
* @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, __address 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, __address addr, pf_access_t access) |
{ |
__address 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/kernel/generic/src/mm/tlb.c |
---|
0,0 → 1,182 |
/* |
* 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. |
*/ |
/** |
* @file tlb.c |
* @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, __address 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; |
__address 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/kernel/generic/src/mm/buddy.c |
---|
0,0 → 1,318 |
/* |
* 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. |
*/ |
/** |
* @file buddy.c |
* @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, |
__u8 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, __u8 i) { |
__u8 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; |
__u8 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, __u8 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; |
__u8 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 es 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/kernel/generic/src/mm/page.c |
---|
0,0 → 1,136 |
/* |
* 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. |
*/ |
/** |
* @file page.c |
* @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(__address 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, __address page, __address 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, __address 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, __address page) |
{ |
ASSERT(page_mapping_operations); |
ASSERT(page_mapping_operations->mapping_find); |
return page_mapping_operations->mapping_find(as, page); |
} |
/tags/0.2.0/kernel/generic/src/interrupt/interrupt.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. |
*/ |
/** |
* @file interrupt.c |
* @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((__native)exc_table[i].f); |
if (!symbol) |
symbol = "not found"; |
printf("%d %s %.*p(%s)\n", i + IVT_FIRST, exc_table[i].name, |
sizeof(__address) * 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/kernel/generic/src/syscall/syscall.c |
---|
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. |
*/ |
/** |
* @file syscall.c |
* @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 __native 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 __native sys_debug_enable_console(void) |
{ |
arch_grab_console(); |
return 0; |
} |
/** Dispatch system call */ |
__native syscall_handler(__native a1, __native a2, __native a3, |
__native a4, __native id) |
{ |
__native 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/kernel/generic/src/syscall/copy.c |
---|
0,0 → 1,125 |
/* |
* 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. |
*/ |
/** |
* @file copy.c |
* @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((__address) 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 uspace_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((__address) 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/kernel/generic/src/synch/waitq.c |
---|
0,0 → 1,432 |
/* |
* 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. |
*/ |
/** |
* @file waitq.c |
* @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; |
spinlock_unlock(&wq->lock); |
t->sleep_queue = NULL; |
} |
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; |
spinlock_unlock(&wq->lock); |
t->sleep_queue = NULL; |
} |
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, __u32 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, __u32 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, (__u64) 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); |
list_remove(&t->wq_link); |
spinlock_lock(&t->lock); |
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/kernel/generic/src/synch/futex.c |
---|
0,0 → 1,332 |
/* |
* 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. |
*/ |
/** |
* @file futex.c |
* @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(__address paddr); |
static index_t futex_ht_hash(__native *key); |
static bool futex_ht_compare(__native *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. |
*/ |
__native sys_futex_sleep_timeout(__address uaddr, __u32 usec, int flags) |
{ |
futex_t *futex; |
__address 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 (__native) 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 (__native) 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. |
*/ |
__native sys_futex_wakeup(__address uaddr) |
{ |
futex_t *futex; |
__address 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 (__native) 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(__address 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(__native *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(__native *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; |
__address 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/kernel/generic/src/synch/rwlock.c |
---|
0,0 → 1,381 |
/* |
* 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. |
*/ |
/** |
* @file rwlock.c |
* @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 technique called direct hand-off is used, 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, __u32 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, __u32 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/kernel/generic/src/synch/mutex.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. |
*/ |
/** |
* @file mutex.c |
* @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, __u32 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/kernel/generic/src/synch/semaphore.c |
---|
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. |
*/ |
/** |
* @file semaphore.c |
* @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, __u32 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/kernel/generic/src/synch/condvar.c |
---|
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. |
*/ |
/** |
* @file condvar.c |
* @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, __u32 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/kernel/generic/src/synch/spinlock.c |
---|
0,0 → 1,154 |
/* |
* 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. |
*/ |
/** |
* @file spinlock.c |
* @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 |
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++ > 10000000) { |
printf("cpu%d: looping on spinlock %.*p:%s, caller=%.*p", |
CPU->id, sizeof(__address) * 2, sl, sl->name, sizeof(__address) * 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/kernel/generic/src/ddi/ddi.c |
---|
0,0 → 1,200 |
/* |
* 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. |
*/ |
/** |
* @file ddi.c |
* @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(__address pf, __address 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, __address 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 |
*/ |
__native sys_physmem_map(__native phys_base, __native virt_base, __native pages, |
__native flags) |
{ |
return (__native) ddi_physmem_map(ALIGN_DOWN((__address) phys_base, FRAME_SIZE), |
ALIGN_DOWN((__address) virt_base, PAGE_SIZE), (count_t) pages, |
(int) flags); |
} |
/** Wrapper for SYS_ENABLE_IOSPACE syscall. |
* |
* @param User space address of DDI argument structure. |
* |
* @return 0 on success, otherwise it returns error code found in errno.h |
*/ |
__native 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 (__native) rc; |
return (__native) ddi_iospace_enable((task_id_t) arg.task_id, (__address) 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. |
*/ |
__native 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/kernel/generic/src/security/cap.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. |
*/ |
/** |
* @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. |
*/ |
__native 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 (__native) EPERM; |
rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t)); |
if (rc != 0) |
return (__native) 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 (__native) 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. |
*/ |
__native 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 (__native) 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 (__native) 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 (__native) 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/kernel/generic/src/adt/bitmap.c |
---|
0,0 → 1,183 |
/* |
* 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. |
*/ |
/** |
* @file bitmap.c |
* @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, __u8 *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/kernel/generic/src/adt/btree.c |
---|
0,0 → 1,995 |
/* |
* 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. |
*/ |
/** |
* @file btree.c |
* @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 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 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 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 rnode 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/kernel/generic/src/adt/hash_table.c |
---|
0,0 → 1,170 |
/* |
* 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. |
*/ |
/** |
* @file hash_table.c |
* @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((__address) 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 hey 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, __native 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, __native 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, __native 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/kernel/generic/src/adt/list.c |
---|
0,0 → 1,87 |
/* |
* 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. |
*/ |
/** |
* @file list.c |
* @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/kernel/generic/src/time/clock.c |
---|
0,0 → 1,184 |
/* |
* 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. |
*/ |
/** |
* @file clock.c |
* @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 { |
__native seconds1; |
__native useconds; |
__native seconds2; |
}; |
struct ptime *public_time; |
/* Variable holding fragment of second, so that we would update |
* seconds correctly |
*/ |
static __native 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 = (void *)PFN2ADDR(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, (__native)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) { |
__u64 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/kernel/generic/src/time/delay.c |
---|
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. |
*/ |
/** |
* @file delay.c |
* @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(__u32 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/kernel/generic/src/time/timeout.c |
---|
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. |
*/ |
/** |
* @file timeout.c |
* @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, __u64 time, timeout_handler_t f, void *arg) |
{ |
timeout_t *hlp = NULL; |
link_t *l, *m; |
ipl_t ipl; |
__u64 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/kernel/generic/src/sysinfo/sysinfo.c |
---|
0,0 → 1,301 |
/* |
* 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. |
*/ |
#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, __native 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; |
__native 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; |
} |
__native sys_sysinfo_valid(__native ptr, __native 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; |
} |
__native sys_sysinfo_value(__native ptr, __native 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/kernel/generic/src/smp/ipi.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. |
*/ |
/** |
* @file ipi.c |
* @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/kernel/generic/src/debug/symtab.c |
---|
0,0 → 1,194 |
/* |
* 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. |
*/ |
/** |
* @file symtab.c |
* @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(__native addr) |
{ |
count_t i; |
for (i=1;symbol_table[i].address_le;++i) { |
if (addr < __u64_le2host(symbol_table[i].address_le)) |
break; |
} |
if (addr >= __u64_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 |
*/ |
__address get_symbol_addr(const char *name) |
{ |
count_t found = 0; |
__address addr = NULL; |
char *hint; |
int i; |
i = 0; |
while ((hint=symtab_search_one(name, &i))) { |
if (!strlen(hint)) { |
addr = __u64_le2host(symbol_table[i].address_le); |
found++; |
} |
i++; |
} |
if (found > 1) |
return ((__address) -1); |
return addr; |
} |
/** Find symbols that match parameter and prints them */ |
void symtab_print_search(const char *name) |
{ |
int i; |
__address addr; |
char *realname; |
i = 0; |
while (symtab_search_one(name, &i)) { |
addr = __u64_le2host(symbol_table[i].address_le); |
realname = symbol_table[i].symbol_name; |
printf("%.*p: %s\n", sizeof(__address) * 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/kernel/generic/src/cpu/cpu.c |
---|
0,0 → 1,106 |
/* |
* 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. |
*/ |
/** |
* @file cpu.c |
* @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((__address) cpus, sizeof(cpu_t) * config.cpu_count, 0); |
for (i=0; i < config.cpu_count; i++) { |
cpus[i].stack = (__u8 *) PA2KA(PFN2ADDR(frame_alloc(STACK_FRAMES, FRAME_KA | FRAME_PANIC))); |
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/kernel/generic/src/preempt/preemption.c |
---|
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. |
*/ |
/** |
* @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/kernel/generic/include/proc/thread.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. |
*/ |
#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. */ |
__u64 ticks; /**< Ticks before preemption. */ |
int priority; /**< Thread's priority. Implemented as index to CPU->rq */ |
__u32 tid; /**< Thread ID. */ |
thread_arch_t arch; /**< Architecture-specific data. */ |
__u8 *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(__u32 sec); |
extern void thread_usleep(__u32 usec); |
#define thread_join(t) thread_join_timeout((t), SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE) |
extern int thread_join_timeout(thread_t *t, __u32 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. */ |
__native sys_thread_create(uspace_arg_t *uspace_uarg, char *uspace_name); |
__native sys_thread_exit(int uspace_status); |
#endif |
/tags/0.2.0/kernel/generic/include/proc/task.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. |
*/ |
#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 */ |
/** 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 __native sys_task_get_id(task_id_t *uspace_task_id); |
#endif |
/tags/0.2.0/kernel/generic/include/proc/scheduler.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. |
*/ |
#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/kernel/generic/include/proc/uarg.h |
---|
0,0 → 1,43 |
/* |
* 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. |
*/ |
#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/kernel/generic/include/ipc/ipc.h |
---|
0,0 → 1,240 |
/* |
* 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. |
*/ |
#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 |
/** Interrupt notification */ |
#define IPC_M_INTERRUPT 4 |
/** 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 { |
__native 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; |
__native 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, __u32 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, __native err); |
extern void ipc_print_task(task_id_t taskid); |
extern answerbox_t *ipc_phone_0; |
#endif |
#endif |
/tags/0.2.0/kernel/generic/include/ipc/irq.h |
---|
0,0 → 1,81 |
/* |
* 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. |
*/ |
#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) |
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; |
} 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, __native a2, __native a3); |
extern void ipc_irq_unregister(answerbox_t *box, int irq); |
extern void irq_ipc_bind_arch(__native irq); |
extern void ipc_irq_cleanup(answerbox_t *box); |
#endif |
#endif |
/tags/0.2.0/kernel/generic/include/ipc/sysipc.h |
---|
0,0 → 1,53 |
/* |
* 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. |
*/ |
#ifndef __SYSIPC_H__ |
#define __SYSIPC_H__ |
#include <ipc/ipc.h> |
#include <ipc/irq.h> |
#include <arch/types.h> |
__native sys_ipc_call_sync_fast(__native phoneid, __native method, |
__native arg1, ipc_data_t *data); |
__native sys_ipc_call_sync(__native phoneid, ipc_data_t *question, |
ipc_data_t *reply); |
__native sys_ipc_call_async_fast(__native phoneid, __native method, |
__native arg1, __native arg2); |
__native sys_ipc_call_async(__native phoneid, ipc_data_t *data); |
__native sys_ipc_answer_fast(__native callid, __native retval, |
__native arg1, __native arg2); |
__native sys_ipc_answer(__native callid, ipc_data_t *data); |
__native sys_ipc_wait_for_call(ipc_data_t *calldata, __u32 usec, int nonblocking); |
__native sys_ipc_forward_fast(__native callid, __native phoneid, |
__native method, __native arg1); |
__native sys_ipc_hangup(int phoneid); |
__native sys_ipc_register_irq(int irq, irq_code_t *ucode); |
__native sys_ipc_unregister_irq(int irq); |
#endif |
/tags/0.2.0/kernel/generic/include/ipc/ipcrsc.h |
---|
0,0 → 1,37 |
/* |
* 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. |
*/ |
#ifndef __IPCRSC_H__ |
#define __IPCRSC_H__ |
call_t * get_call(__native callid); |
int phone_alloc(void); |
void phone_connect(int phoneid, answerbox_t *box); |
void phone_dealloc(int phoneid); |
#endif |
/tags/0.2.0/kernel/generic/include/stackarg.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. |
*/ |
/* |
* 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; |
__u8 *last; |
} va_list; |
#define va_start(ap, lst) \ |
(ap).pos = sizeof(lst); \ |
(ap).last = (__u8 *) &(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/kernel/generic/include/interrupt.h |
---|
0,0 → 1,64 |
/* |
* 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. |
*/ |
#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/kernel/generic/include/console/klog.h |
---|
0,0 → 1,35 |
/* |
* 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. |
*/ |
#ifndef _KLOG_H_ |
#define _KLOG_H_ |
void klog_init(void); |
void klog_printf(const char *fmt, ...); |
#endif |
/tags/0.2.0/kernel/generic/include/console/console.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. |
*/ |
#ifndef __CONSOLE_H__ |
#define __CONSOLE_H__ |
#include <arch/types.h> |
#include <typedefs.h> |
extern chardev_t *stdin; |
extern chardev_t *stdout; |
extern __u8 getc(chardev_t *chardev); |
__u8 _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/kernel/generic/include/console/kconsole.h |
---|
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. |
*/ |
#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. */ |
__native 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/kernel/generic/include/console/chardev.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. |
*/ |
#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. */ |
__u8 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, __u8 ch); |
#endif /* __CHARDEV_H__ */ |
/tags/0.2.0/kernel/generic/include/console/cmd.h |
---|
0,0 → 1,37 |
/* |
* 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. |
*/ |
#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/kernel/generic/include/stdarg.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. |
*/ |
/* |
* 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/kernel/generic/include/synch/futex.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. |
*/ |
#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 { |
__address 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 __native sys_futex_sleep_timeout(__address uaddr, __u32 usec, int flags); |
extern __native sys_futex_wakeup(__address uaddr); |
extern void futex_cleanup(void); |
#endif |
/tags/0.2.0/kernel/generic/include/synch/condvar.h |
---|
0,0 → 1,51 |
/* |
* 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. |
*/ |
#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, __u32 usec, int flags); |
#endif |
/tags/0.2.0/kernel/generic/include/synch/rwlock.h |
---|
0,0 → 1,70 |
/* |
* 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. |
*/ |
#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, __u32 usec, int flags); |
extern int _rwlock_write_lock_timeout(rwlock_t *rwl, __u32 usec, int flags); |
#endif |
/tags/0.2.0/kernel/generic/include/synch/mutex.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. |
*/ |
#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, __u32 usec, int flags); |
extern void mutex_unlock(mutex_t *mtx); |
#endif |
/tags/0.2.0/kernel/generic/include/synch/semaphore.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. |
*/ |
#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, __u32 usec, int flags); |
extern void semaphore_up(semaphore_t *s); |
#endif |
/tags/0.2.0/kernel/generic/include/synch/synch.h |
---|
0,0 → 1,47 |
/* |
* 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. |
*/ |
#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/kernel/generic/include/synch/waitq.h |
---|
0,0 → 1,66 |
/* |
* 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. |
*/ |
#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, __u32 usec, int flags); |
extern ipl_t waitq_sleep_prepare(waitq_t *wq); |
extern int waitq_sleep_timeout_unsafe(waitq_t *wq, __u32 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/kernel/generic/include/synch/spinlock.h |
---|
0,0 → 1,111 |
/* |
* 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. |
*/ |
#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/kernel/generic/include/mm/slab.h |
---|
0,0 → 1,130 |
/* |
* 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. |
*/ |
#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 */ |
__u8 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/kernel/generic/include/mm/page.h |
---|
0,0 → 1,92 |
/* |
* 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. |
*/ |
#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, __address page, __address frame, int flags); |
void (* mapping_remove)(as_t *as, __address page); |
pte_t *(* mapping_find)(as_t *as, __address 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, __address page, __address frame, int flags); |
extern void page_mapping_remove(as_t *as, __address page); |
extern pte_t *page_mapping_find(as_t *as, __address page); |
extern pte_t *page_table_create(int flags); |
extern void page_table_destroy(pte_t *page_table); |
extern void map_structure(__address s, size_t size); |
extern __address hw_map(__address physaddr, size_t size); |
#endif |
/tags/0.2.0/kernel/generic/include/mm/as.h |
---|
0,0 → 1,201 |
/* |
* 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. |
*/ |
#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, __address addr, pf_access_t access); |
void (* frame_free)(as_area_t *area, __address page, __address 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 */ |
__address 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. */ |
__address 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(__address page, pf_access_t access, istate_t *istate); |
extern as_area_t *as_area_create(as_t *as, int flags, size_t size, __address base, int attrs, |
mem_backend_t *backend, mem_backend_data_t *backend_data); |
extern int as_area_destroy(as_t *as, __address address); |
extern int as_area_resize(as_t *as, __address address, size_t size, int flags); |
int as_area_share(as_t *src_as, __address src_base, size_t acc_size, |
as_t *dst_as, __address 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(__address base); |
extern int used_space_insert(as_area_t *a, __address page, count_t count); |
extern int used_space_remove(as_area_t *a, __address 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 __native sys_as_area_create(__address address, size_t size, int flags); |
extern __native sys_as_area_resize(__address address, size_t size, int flags); |
extern __native sys_as_area_destroy(__address address); |
#endif /* KERNEL */ |
#endif |
/tags/0.2.0/kernel/generic/include/mm/frame.h |
---|
0,0 → 1,109 |
/* |
* 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. |
*/ |
#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_PANIC 0x2 /* panic on failure */ |
#define FRAME_ATOMIC 0x4 /* do not panic and do not sleep on failure */ |
#define FRAME_NO_RECLAIM 0x8 /* 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 __address PFN2ADDR(pfn_t frame) |
{ |
return (__address)(frame << FRAME_WIDTH); |
} |
static inline pfn_t ADDR2PFN(__address 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) ((~(((__native) -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, NULL) |
#define frame_alloc_rc(order, flags, status) frame_alloc_generic(order, flags, status, NULL) |
#define frame_alloc_rc_zone(order, flags, status, zone) frame_alloc_generic(order, flags, status, zone) |
extern void frame_init(void); |
extern pfn_t frame_alloc_generic(__u8 order, int flags, int * status, int *pzone); |
extern void frame_free(pfn_t pfn); |
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); |
__address 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/kernel/generic/include/mm/buddy.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. |
*/ |
#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 *, __u8); /**< Set order of block passed as argument. */ |
__u8 (*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 *, __u8); |
void (* print_id)(buddy_system_t *, link_t *); |
}; |
struct buddy_system { |
__u8 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, |
__u8 max_order, |
buddy_system_operations_t *op, void *data); |
extern link_t *buddy_system_alloc(buddy_system_t *b, __u8 i); |
extern bool buddy_system_can_alloc(buddy_system_t *b, __u8 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/kernel/generic/include/mm/tlb.h |
---|
0,0 → 1,81 |
/* |
* 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. |
*/ |
#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. */ |
__address 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, __address 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, __address page, count_t cnt); |
#endif |
/tags/0.2.0/kernel/generic/include/mm/asid.h |
---|
0,0 → 1,79 |
/* |
* 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. |
*/ |
/* |
* 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/kernel/generic/include/errno.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. |
*/ |
#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/kernel/generic/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. |
*/ |
#ifndef __DDI_H__ |
#define __DDI_H__ |
#include <ddi/ddi_arg.h> |
#include <arch/types.h> |
#include <typedefs.h> |
__native sys_physmem_map(__native phys_base, __native virt_base, __native pages, |
__native flags); |
extern __native sys_iospace_enable(ddi_ioarg_t *uspace_io_arg); |
extern __native sys_preempt_control(int enable); |
/* |
* Interface to be implemented by all architectures. |
*/ |
extern int ddi_iospace_enable_arch(task_t *task, __address ioaddr, size_t size); |
#endif |
/tags/0.2.0/kernel/generic/include/ddi/ddi_arg.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. |
*/ |
#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/kernel/generic/include/syscall/syscall.h |
---|
0,0 → 1,80 |
/* |
* 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. |
*/ |
#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 __native (*syshandler_t)(); |
extern syshandler_t syscall_table[SYSCALL_END]; |
extern __native syscall_handler(__native a1, __native a2, __native a3, |
__native a4, __native id); |
extern __native sys_tls_set(__native addr); |
#endif |
#endif |
/tags/0.2.0/kernel/generic/include/syscall/sysarg64.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. |
*/ |
/** |
* @file sysarg64.h |
* @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/kernel/generic/include/syscall/copy.h |
---|
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. |
*/ |
#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/kernel/generic/include/print.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. |
*/ |
#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/kernel/generic/include/time/clock.h |
---|
0,0 → 1,37 |
/* |
* 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. |
*/ |
#ifndef __CLOCK_H__ |
#define __CLOCK_H__ |
#define HZ 100 |
extern void clock(void); |
extern void clock_counter_init(void); |
#endif |
/tags/0.2.0/kernel/generic/include/time/timeout.h |
---|
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. |
*/ |
#ifndef __TIMEOUT_H__ |
#define __TIMEOUT_H__ |
#include <arch/types.h> |
#include <typedefs.h> |
#include <synch/spinlock.h> |
#include <adt/list.h> |
#define us2ticks(us) ((__u64)(((__u32) (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 */ |
__u64 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, __u64 usec, timeout_handler_t f, void *arg); |
extern bool timeout_unregister(timeout_t *t); |
#endif |
/tags/0.2.0/kernel/generic/include/time/delay.h |
---|
0,0 → 1,36 |
/* |
* 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. |
*/ |
#ifndef __DELAY_H__ |
#define __DELAY_H__ |
#include <arch/types.h> |
extern void delay(__u32 microseconds); |
#endif |
/tags/0.2.0/kernel/generic/include/cpu.h |
---|
0,0 → 1,99 |
/* |
* 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. |
*/ |
#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; |
__u16 frequency_mhz; |
__u32 delay_loop_const; |
cpu_arch_t arch; |
thread_t *fpu_owner; |
/** |
* Stack used by scheduler when there is no running thread. |
*/ |
__u8 *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/kernel/generic/include/elf.h |
---|
0,0 → 1,335 |
/* |
* 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. |
*/ |
#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 __u64 elf_xword; |
typedef __s64 elf_sxword; |
typedef __u32 elf_word; |
typedef __s32 elf_sword; |
typedef __u16 elf_half; |
/** |
* 32-bit ELF data types. |
* |
* These types are specific for 32-bit format. |
*/ |
typedef __u32 elf32_addr; |
typedef __u32 elf32_off; |
/** |
* 64-bit ELF data types. |
* |
* These types are specific for 64-bit format. |
*/ |
typedef __u64 elf64_addr; |
typedef __u64 elf64_off; |
/** ELF header */ |
struct elf32_header { |
__u8 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 { |
__u8 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; |
__u8 st_info; |
__u8 st_other; |
elf_half st_shndx; |
}; |
struct elf64_symbol { |
elf_word st_name; |
__u8 st_info; |
__u8 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/kernel/generic/include/typedefs.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. |
*/ |
#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 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/kernel/generic/include/sysinfo/sysinfo.h |
---|
0,0 → 1,85 |
/* |
* 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. |
*/ |
#include <arch/types.h> |
typedef union sysinfo_item_val |
{ |
__native val; |
void *fn; |
}sysinfo_item_val_t; |
typedef struct sysinfo_item |
{ |
char *name; |
union |
{ |
__native 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 __native (*sysinfo_val_fn_t)(sysinfo_item_t *root); |
typedef __native (*sysinfo_subinfo_fn_t)(const char *subname); |
typedef struct sysinfo_rettype |
{ |
__native val; |
__native valid; |
}sysinfo_rettype_t; |
void sysinfo_set_item_val(const char *name,sysinfo_item_t **root,__native 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); |
__native sys_sysinfo_valid(__native ptr,__native len); |
__native sys_sysinfo_value(__native ptr,__native len); |
/tags/0.2.0/kernel/generic/include/config.h |
---|
0,0 → 1,66 |
/* |
* 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. |
*/ |
#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 { |
__address 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; |
volatile count_t cpu_active; |
__address base; |
size_t memory_size; |
size_t kernel_size; /**< Size of memory in bytes taken by kernel and stack */ |
bool mm_initialized; |
} config_t; |
extern config_t config; |
extern init_t init; |
#endif |
/tags/0.2.0/kernel/generic/include/bitops.h |
---|
0,0 → 1,61 |
/* |
* 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. |
*/ |
#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(__u32 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(__u64 arg) |
{ |
int n = 0; |
if (arg >> 32) { arg >>= 32;n += 32;} |
return n + fnzb32((__u32) arg); |
} |
#define fnzb(x) fnzb32(x) |
#endif |
/tags/0.2.0/kernel/generic/include/security/cap.h |
---|
0,0 → 1,84 |
/* |
* 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. |
*/ |
/** |
* @file cap.h |
* @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 __u32 cap_t; |
extern void cap_set(task_t *t, cap_t caps); |
extern cap_t cap_get(task_t *t); |
extern __native sys_cap_grant(sysarg64_t *uspace_taskid_arg, cap_t caps); |
extern __native sys_cap_revoke(sysarg64_t *uspace_taskid_arg, cap_t caps); |
#endif |
/tags/0.2.0/kernel/generic/include/printf/printf_core.h |
---|
0,0 → 1,46 |
/* |
* 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. |
*/ |
#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/kernel/generic/include/adt/bitmap.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. |
*/ |
#ifndef __BITMAP_H__ |
#define __BITMAP_H__ |
#include <arch/types.h> |
#include <typedefs.h> |
#define BITS2BYTES(bits) (bits ? ((((bits)-1)>>3)+1) : 0) |
typedef struct { |
__u8 *map; |
count_t bits; |
} bitmap_t; |
extern void bitmap_initialize(bitmap_t *bitmap, __u8 *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/kernel/generic/include/adt/btree.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. |
*/ |
#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 __u64 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/kernel/generic/include/adt/fifo.h |
---|
0,0 → 1,113 |
/* |
* 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. |
*/ |
/* |
* 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/kernel/generic/include/adt/hash_table.h |
---|
0,0 → 1,76 |
/* |
* 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. |
*/ |
#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)(__native 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)(__native 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, __native key[], link_t *item); |
extern link_t *hash_table_find(hash_table_t *h, __native key[]); |
extern void hash_table_remove(hash_table_t *h, __native key[], count_t keys); |
#endif |
/tags/0.2.0/kernel/generic/include/adt/list.h |
---|
0,0 → 1,177 |
/* |
* 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. |
*/ |
#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 *)(((__u8*)(link))-((__u8*)&(((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/kernel/generic/include/debug.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. |
*/ |
#ifndef __DEBUG_H__ |
#define __DEBUG_H__ |
#include <panic.h> |
#include <arch/debug.h> |
#define CALLER ((__address)__builtin_return_address(0)) |
#ifndef HERE |
/** Current Instruction Pointer address */ |
# define HERE ((__address *)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(__address) * 2, CALLER); } |
#else |
# define ASSERT(expr) |
#endif |
#define STRING(arg) STRING_ARG(arg) |
#define STRING_ARG(arg) #arg |
#endif |
/tags/0.2.0/kernel/generic/include/arch.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. |
*/ |
#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. */ |
}; |
#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/kernel/generic/include/atomic.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. |
*/ |
#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/kernel/generic/include/func.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. |
*/ |
#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 __native atoi(const char *text); |
#endif |
/tags/0.2.0/kernel/generic/include/macros.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. |
*/ |
#ifndef __MACROS_H__ |
#define __MACROS_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(__address s1, size_t sz1, __address s2, size_t sz2) |
{ |
__address e1 = s1+sz1; |
__address 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) |
#endif |
/tags/0.2.0/kernel/generic/include/userspace.h |
---|
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. |
*/ |
#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/kernel/generic/include/fpu_context.h |
---|
0,0 → 1,48 |
/* |
* 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. |
*/ |
#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/kernel/generic/include/align.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. |
*/ |
#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/kernel/generic/include/context.h |
---|
0,0 → 1,85 |
/* |
* 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. |
*/ |
#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 = (__address) (_pc); \ |
(c)->sp = ((__address) (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/kernel/generic/include/main/uinit.h |
---|
0,0 → 1,36 |
/* |
* 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. |
*/ |
#ifndef __UINIT_H__ |
#define __UINIT_H__ |
#include <arch/types.h> |
extern void uinit(void *arg); |
#endif |
/tags/0.2.0/kernel/generic/include/main/version.h |
---|
0,0 → 1,34 |
/* |
* 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. |
*/ |
#ifndef __VERSION_H__ |
#define __VERSION_H__ |
extern void version_print(void); |
#endif |
/tags/0.2.0/kernel/generic/include/main/kinit.h |
---|
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. |
*/ |
#ifndef __KINIT_H__ |
#define __KINIT_H__ |
extern void kinit(void *arg); |
#endif |
/tags/0.2.0/kernel/generic/include/panic.h |
---|
0,0 → 1,40 |
/* |
* 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. |
*/ |
#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/kernel/generic/include/symtab.h |
---|
0,0 → 1,49 |
/* |
* 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. |
*/ |
#ifndef __SYMTAB_H__ |
#define __SYMTAB_H__ |
#include <arch/types.h> |
#define MAX_SYMBOL_NAME 64 |
struct symtab_entry { |
__u64 address_le; |
char symbol_name[MAX_SYMBOL_NAME]; |
}; |
extern char * get_symtab_entry(__native addr); |
extern __address 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/kernel/generic/include/sort.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. |
*/ |
#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 __u32_cmp(void * a, void * b); |
extern int __u16_cmp(void * a, void * b); |
extern int __u8_cmp(void * a, void * b); |
#endif |
/tags/0.2.0/kernel/generic/include/smp/smp.h |
---|
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. |
*/ |
#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/kernel/generic/include/smp/ipi.h |
---|
0,0 → 1,39 |
/* |
* 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. |
*/ |
#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/kernel/generic/include/memstr.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. |
*/ |
#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(__address dst, size_t cnt, __u8 x); |
extern void _memsetw(__address dst, size_t cnt, __u16 x); |
#endif |
/tags/0.2.0/kernel/generic/include/byteorder.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. |
*/ |
#ifndef __BYTEORDER_H__ |
#define __BYTEORDER_H__ |
static inline __u64 __u64_byteorder_swap(__u64 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 __u32 __u32_byteorder_swap(__u32 n) |
{ |
return ((n & 0xff) << 24) | |
((n & 0xff00) << 8) | |
((n & 0xff0000) >> 8) | |
((n & 0xff000000) >> 24); |
} |
#endif |
/tags/0.2.0/kernel/generic/include/preemption.h |
---|
0,0 → 1,35 |
/* |
* 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. |
*/ |
#ifndef __PREEMPTION_H__ |
#define __PREEMPTION_H__ |
extern void preemption_disable(void); |
extern void preemption_enable(void); |
#endif |
/tags/0.2.0/kernel/generic/include/putchar.h |
---|
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. |
*/ |
#ifndef __PUTCHAR_H__ |
#define __PUTCHAR_H__ |
extern void putchar(const char ch); |
#endif |
/tags/0.2.0/kernel/generic/include/test.h |
---|
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. |
*/ |
#ifndef __TEST_H__ |
#define __TEST_H__ |
extern void test(void); |
#endif |
/tags/0.2.0/kernel/Makefile |
---|
0,0 → 1,265 |
# |
# 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. |
# |
## Kernel release |
# |
VERSION = 0 |
PATCHLEVEL = 2 |
SUBLEVEL = 0 |
EXTRAVERSION = |
NAME = Daylight |
RELEASE = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) |
## Include configuration |
# |
-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 |
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 default $(NARCH) |
ifdef NARCH |
ifneq ($(ARCH), $(NARCH)) |
$(MAKE) -C . clean |
endif |
endif |
$(MAKE) -C . build |
build: kernel.bin disasm |
config: |
-rm Makefile.depend |
tools/config.py |
-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/kernel/arch/mips32/src/mips32.c |
---|
0,0 → 1,178 |
/* |
* 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.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 <debug.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) |
void arch_pre_main(void) |
{ |
/* Setup usermode */ |
init.cnt = 6; |
init.tasks[0].addr = INIT_ADDRESS; |
init.tasks[0].size = INIT_SIZE; |
init.tasks[1].addr = INIT_ADDRESS + 0x100000; |
init.tasks[1].size = INIT_SIZE; |
init.tasks[2].addr = INIT_ADDRESS + 0x200000; |
init.tasks[2].size = INIT_SIZE; |
init.tasks[3].addr = INIT_ADDRESS + 0x300000; |
init.tasks[3].size = INIT_SIZE; |
init.tasks[4].addr = INIT_ADDRESS + 0x400000; |
init.tasks[4].size = INIT_SIZE; |
init.tasks[5].addr = INIT_ADDRESS + 0x500000; |
init.tasks[5].size = INIT_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) |
{ |
} |
/* Stack pointer saved when entering user mode */ |
/* TODO: How do we do it on SMP system???? */ |
/* Why the linker moves the variable 64K away in assembler |
* when not in .text section ???????? |
*/ |
__address supervisor_sp __attribute__ ((section (".text"))); |
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((__address) kernel_uarg->uspace_entry); |
userspace_asm(((__address) kernel_uarg->uspace_stack+PAGE_SIZE), |
(__address) kernel_uarg->uspace_uarg, |
(__address) 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 = (__address) &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. |
*/ |
__native sys_tls_set(__native addr) |
{ |
return 0; |
} |
/tags/0.2.0/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/kernel/arch/mips32/src/exception.c |
---|
0,0 → 1,167 |
/* |
* 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/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 (*((__u32 *)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) |
{ |
__u32 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/kernel/arch/mips32/src/mm/tlb.c |
---|
0,0 → 1,604 |
/* |
* 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/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(__address 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, __address pfn); |
static void prepare_entry_hi(entry_hi_t *hi, asid_t asid, __address 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; |
__address 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; |
__address 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; |
__address 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(__address 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, __address 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, __address 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, __address 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/kernel/arch/mips32/src/mm/page.c |
---|
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. |
*/ |
#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 |
*/ |
__address hw_map(__address physaddr, size_t size) |
{ |
return physaddr + 0xa0000000; |
} |
/tags/0.2.0/kernel/arch/mips32/src/mm/frame.c |
---|
0,0 → 1,51 |
/* |
* 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/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 vektor |
*/ |
frame_mark_unavailable(0, 1); |
} |
} |
/tags/0.2.0/kernel/arch/mips32/src/mm/as.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. |
*/ |
#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/kernel/arch/mips32/src/console.c |
---|
0,0 → 1,59 |
/* |
* 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 <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/kernel/arch/mips32/src/drivers/msim.c |
---|
0,0 → 1,120 |
/* |
* 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 <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) |
{ |
int_register(MSIM_KBD_IRQ, "user_interrupt", oldvector); |
} |
/tags/0.2.0/kernel/arch/mips32/src/drivers/arc.c |
---|
0,0 → 1,403 |
/* |
* 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 <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 ", |
(__address)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 ", |
(__address)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) |
{ |
__u32 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; |
__u32 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; |
__u32 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; |
__address 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/kernel/arch/mips32/src/drivers/serial.c |
---|
0,0 → 1,138 |
/* |
* 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 <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/kernel/arch/mips32/src/interrupt.c |
---|
0,0 → 1,136 |
/* |
* 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 <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(__native 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/kernel/arch/mips32/src/start.S |
---|
0,0 → 1,315 |
# |
# 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) |
/* Not sure about this, but might be needed for PIC code???? */ |
lui $gp, 0x8000 |
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 /* tlb_refill(register_space) */ |
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 |
nop |
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/kernel/arch/mips32/src/ddi/ddi.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. |
*/ |
#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, __address ioaddr, size_t size) |
{ |
return 0; |
} |
/tags/0.2.0/kernel/arch/mips32/src/debugger.c |
---|
0,0 → 1,378 |
/* |
* 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 <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 { |
__u32 andmask; |
__u32 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(__native 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 == (__address)argv->intval) { |
printf("Duplicate breakpoint %d.\n", i); |
spinlock_unlock(&bkpoints_lock); |
return 0; |
} else if (breakpoints[i].address == (__address)argv->intval + sizeof(__native) || \ |
breakpoints[i].address == (__address)argv->intval - sizeof(__native)) { |
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 = (__address) argv->intval; |
printf("Adding breakpoint on address: %p\n", argv->intval); |
cur->instruction = ((__native *)cur->address)[0]; |
cur->nextinstruction = ((__native *)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 */ |
*((__native *)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; |
} |
((__u32 *)cur->address)[0] = cur->instruction; |
((__u32 *)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; |
__address 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(__native))) { |
cur = &breakpoints[i]; |
break; |
} |
} |
if (cur) { |
if (cur->flags & BKPOINT_REINST) { |
/* Set breakpoint on first instruction */ |
((__u32 *)cur->address)[0] = 0x0d; |
/* Return back the second */ |
((__u32 *)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 */ |
((__u32 *)cur->address)[0] = cur->instruction; |
if (! (cur->flags & BKPOINT_ONESHOT)) { |
/* Set Breakpoint on next instruction */ |
((__u32 *)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/kernel/arch/mips32/src/fpu_context.c |
---|
0,0 → 1,52 |
/* |
* 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 <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/kernel/arch/mips32/src/cpu/cpu.c |
---|
0,0 → 1,129 |
/* |
* 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/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/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/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/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/kernel/arch/mips32/src/cache.c |
---|
0,0 → 1,35 |
/* |
* 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/cache.h> |
#include <panic.h> |
void cache_error(void) |
{ |
panic("cache_error exception\n"); |
} |
/tags/0.2.0/kernel/arch/mips32/Makefile.inc |
---|
0,0 → 1,136 |
# |
# 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 |
## Make some default assumptions |
# |
ifndef MIPS_MACHINE |
MIPS_MACHINE = msim |
endif |
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=${MIPS_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 ($(MIPS_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 ($(MIPS_MACHINE),lgxemul) |
BFD_NAME=elf32-tradlittlemips |
BFD = ecoff-littlemips |
CFLAGS += -DFB_BIG_ENDIAN -DARCH_HAS_FPU -mips3 |
INIT_ADDRESS = 0x81800000 |
endif |
ifeq ($(MIPS_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 ($(MIPS_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 ($(MIPS_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/kernel/arch/mips32/include/exception.h |
---|
0,0 → 1,118 |
/* |
* 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. |
*/ |
#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 { |
__u32 at; |
__u32 v0; |
__u32 v1; |
__u32 a0; |
__u32 a1; |
__u32 a2; |
__u32 a3; |
__u32 t0; |
__u32 t1; |
__u32 t2; |
__u32 t3; |
__u32 t4; |
__u32 t5; |
__u32 t6; |
__u32 t7; |
__u32 s0; |
__u32 s1; |
__u32 s2; |
__u32 s3; |
__u32 s4; |
__u32 s5; |
__u32 s6; |
__u32 s7; |
__u32 t8; |
__u32 t9; |
__u32 gp; |
__u32 sp; |
__u32 s8; |
__u32 ra; |
__u32 lo; |
__u32 hi; |
__u32 status; /* cp0_status */ |
__u32 epc; /* cp0_epc */ |
__u32 k1; /* We use it as thread-local pointer */ |
}; |
static inline void istate_set_retaddr(istate_t *istate, __address 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 __native 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/kernel/arch/mips32/include/arg.h |
---|
0,0 → 1,51 |
/* |
* 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. |
*/ |
#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 __address 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) ? ((__address)((ap) + 2*4 - 1) & (~3)) : ((__address)((ap) + 2*8 -1) & (~7)) )))[-1]) |
#define va_copy(dst,src) ((dst)=(src)) |
#define va_end(ap) |
#endif |
/tags/0.2.0/kernel/arch/mips32/include/proc/task.h |
---|
0,0 → 1,38 |
/* |
* 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. |
*/ |
#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/kernel/arch/mips32/include/proc/thread.h |
---|
0,0 → 1,37 |
/* |
* 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. |
*/ |
#ifndef __mips32_THREAD_H__ |
#define __mips32_THREAD_H__ |
typedef struct { |
} thread_arch_t; |
#define thread_create_arch(t) |
#endif |
/tags/0.2.0/kernel/arch/mips32/include/mm/as.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. |
*/ |
#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/kernel/arch/mips32/include/mm/page.h |
---|
0,0 → 1,147 |
/* |
* 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. |
*/ |
#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) (((__address) (x)) - 0x80000000) |
# define PA2KA(x) (((__address) (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) (*((__u32 *) (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/kernel/arch/mips32/include/mm/frame.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. |
*/ |
#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/kernel/arch/mips32/include/mm/tlb.h |
---|
0,0 → 1,176 |
/* |
* 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. |
*/ |
#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)); |
__u32 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)); |
__u32 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)); |
__u32 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)); |
__u32 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/kernel/arch/mips32/include/mm/asid.h |
---|
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. |
*/ |
#ifndef __mips32_ASID_H__ |
#define __mips32_ASID_H__ |
#include <arch/types.h> |
#define ASID_MAX_ARCH 255 /* 2^8 - 1 */ |
typedef __u8 asid_t; |
#endif |
/tags/0.2.0/kernel/arch/mips32/include/mm/memory_init.h |
---|
0,0 → 1,39 |
/* |
* 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. |
*/ |
#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/kernel/arch/mips32/include/drivers/msim.h |
---|
0,0 → 1,43 |
/* |
* 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. |
*/ |
#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/kernel/arch/mips32/include/drivers/arc.h |
---|
0,0 → 1,258 |
/* |
* 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. |
*/ |
#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 { |
__u8 type; |
__u8 sharedisposition; |
__u16 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 { |
__u16 version; |
__u16 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; |
__u16 revision; |
__u16 version; |
__u32 key; |
__u32 affinitymask; |
__u32 configdatasize; |
__u32 identifier_len; |
char *identifier; |
} __attribute__ ((packed)) arc_component; |
typedef struct { |
__u16 year; |
__u16 month; |
__u16 day; |
__u16 hour; |
__u16 minutes; |
__u16 seconds; |
__u16 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; |
__u32 basepage; /* *4096 = baseaddr */ |
__u32 basecount; |
}arc_memdescriptor_t; |
typedef struct { |
char vendorid[8]; |
char prodid[8]; |
}arc_sysid_t; |
typedef struct { |
long (*load)(void); /* ... */ |
long (*invoke)(__u32 eaddr,__u32 saddr,__u32 argc,char **argv, |
char **envp); |
long (*execute)(char *path,__u32 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); |
__u32 (*getrelativetime)(void); |
long (*getdirectoryentry)(); |
long (*open)(void); /* ... */ |
long (*close)(__u32 fileid); |
long (*read)(__u32 fileid,void *buf,__u32 n,__u32 *cnt); |
long (*getreadstatus)(__u32 fileid); |
long (*write)(__u32 fileid, void *buf,__u32 n,__u32 *cnt); |
long (*seek)(void); /* ... */ |
/* 30 */ |
long (*mount)(void); /* ... */ |
char * (*getenvironmentvariable)(char *name); |
char * (*setenvironmentvariable)(char *name, char *value); |
long (*getfileinformation)(void); /* ... */ |
long (*setfileinformation)(__u32 fileid,__u32 attflags,__u32 attmask); |
void (*flushallcaches)(void); |
long (*testunicodecharacter)(void); /* ... */ |
long (*getdisplaystatus)(void); /* ... */ |
} arc_func_vector_t; |
typedef struct { |
__u32 signature; |
__u32 length; |
__u16 version; |
__u16 revision; |
void *restartblock; |
void *debugblock; |
void *gevector; |
void *utlbmissvector; |
__u32 firmwarevectorlen; |
arc_func_vector_t *firmwarevector; |
__u32 privvectorlen; |
void *privvector; |
__u32 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/kernel/arch/mips32/include/drivers/serial.h |
---|
0,0 → 1,62 |
/* |
* 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. |
*/ |
#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/kernel/arch/mips32/include/cp0.h |
---|
0,0 → 1,114 |
/* |
* 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. |
*/ |
#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 __u32 cp0_ ##nm##_read(void) \ |
{ \ |
__u32 retval; \ |
asm("mfc0 %0, $" #reg : "=r"(retval)); \ |
return retval; \ |
} |
#define GEN_WRITE_CP0(nm,reg) static inline void cp0_ ##nm##_write(__u32 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/kernel/arch/mips32/include/barrier.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. |
*/ |
#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/kernel/arch/mips32/include/interrupt.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. |
*/ |
#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/kernel/arch/mips32/include/arch.h |
---|
0,0 → 1,32 |
/* |
* 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. |
*/ |
#ifndef __mips32_ARCH_H__ |
#define __mips32_ARCH_H__ |
#endif |
/tags/0.2.0/kernel/arch/mips32/include/asm.h |
---|
0,0 → 1,63 |
/* |
* 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. |
*/ |
#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 __address get_stack_base(void) |
{ |
__address 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(__u32 t); |
extern void userspace_asm(__address ustack, __address uspace_uarg, |
__address entry); |
#endif |
/tags/0.2.0/kernel/arch/mips32/include/atomic.h |
---|
0,0 → 1,67 |
/* |
* 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. |
*/ |
#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 */ /* nop is inserted automatically by compiler */ |
: "=r" (tmp), "=m" (val->count), "=r" (v) |
: "i" (i), "i" (0) |
); |
return v; |
} |
#endif |
/tags/0.2.0/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/kernel/arch/mips32/include/stack.h |
---|
0,0 → 1,35 |
/* |
* 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. |
*/ |
#ifndef __mips32_STACK_H__ |
#define __mips32_STACK_H__ |
#define STACK_ITEM_SIZE 4 |
#define STACK_ALIGNMENT 8 |
#endif |
/tags/0.2.0/kernel/arch/mips32/include/context.h |
---|
0,0 → 1,71 |
/* |
* 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. |
*/ |
#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 { |
__address sp; |
__address pc; |
__u32 s0; |
__u32 s1; |
__u32 s2; |
__u32 s3; |
__u32 s4; |
__u32 s5; |
__u32 s6; |
__u32 s7; |
__u32 s8; |
__u32 gp; |
ipl_t ipl; |
}; |
#endif /* __ASM__ */ |
#endif |
/tags/0.2.0/kernel/arch/mips32/include/debugger.h |
---|
0,0 → 1,60 |
/* |
* 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. |
*/ |
#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 { |
__address address; /**< Breakpoint address */ |
__native instruction; /**< Original instruction */ |
__native 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/kernel/arch/mips32/include/types.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. |
*/ |
#ifndef __mips32_TYPES_H__ |
#define __mips32_TYPES_H__ |
#define NULL 0 |
typedef signed char __s8; |
typedef unsigned char __u8; |
typedef signed short __s16; |
typedef unsigned short __u16; |
typedef unsigned long __u32; |
typedef signed long __s32; |
typedef unsigned long long __u64; |
typedef signed long long __s64; |
typedef __u32 __address; |
typedef __u32 ipl_t; |
typedef __u32 __native; |
typedef __s32 __snative; |
typedef struct pte pte_t; |
typedef __u32 pfn_t; |
#endif |
/tags/0.2.0/kernel/arch/mips32/include/elf.h |
---|
0,0 → 1,42 |
/* |
* 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. |
*/ |
#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/kernel/arch/mips32/include/fpu_context.h |
---|
0,0 → 1,41 |
/* |
* 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. |
*/ |
#ifndef __mips32_FPU_CONTEXT_H__ |
#define __mips32_FPU_CONTEXT_H__ |
#include <arch/types.h> |
#define FPU_CONTEXT_ALIGN sizeof(__native) |
struct fpu_context { |
__native dregs[32]; |
__native cregs[32]; |
}; |
#endif |
/tags/0.2.0/kernel/arch/mips32/include/asm/regname.h |
---|
0,0 → 1,89 |
/* |
* 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. |
*/ |
#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/kernel/arch/mips32/include/asm/boot.h |
---|
0,0 → 1,36 |
/* |
* 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. |
*/ |
#ifndef __mips32_BOOT_H_ |
#define __mips32_BOOT_H_ |
/* Temporary stack size for boot process */ |
#define TEMP_STACK_SIZE 0x100 |
#endif |
/tags/0.2.0/kernel/arch/mips32/include/memstr.h |
---|
0,0 → 1,39 |
/* |
* 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. |
*/ |
#ifndef __mips32_MEMSTR_H__ |
#define __mips32_MEMSTR_H__ |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
extern void memsetw(__address dst, size_t cnt, __u16 x); |
extern void memsetb(__address dst, size_t cnt, __u8 x); |
extern int memcmp(__address src, __address dst, int cnt); |
#endif |
/tags/0.2.0/kernel/arch/mips32/include/debug.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. |
*/ |
#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/kernel/arch/mips32/include/console.h |
---|
0,0 → 1,35 |
/* |
* 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. |
*/ |
#ifndef __mips32_CONSOLE_H__ |
#define __mips32_CONSOLE_H__ |
void console_init(void); |
#endif |
/tags/0.2.0/kernel/arch/mips32/include/cpu.h |
---|
0,0 → 1,39 |
/* |
* 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. |
*/ |
#ifndef __mips32_CPU_H__ |
#define __mips32_CPU_H__ |
#include <arch/types.h> |
struct cpu_arch { |
__u32 imp_num; |
__u32 rev_num; |
}; |
#endif |
/tags/0.2.0/kernel/arch/mips32/include/byteorder.h |
---|
0,0 → 1,51 |
/* |
* 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. |
*/ |
#ifndef __mips32_BYTEORDER_H__ |
#define __mips32_BYTEORDER_H__ |
#include <arch/types.h> |
#include <byteorder.h> |
#ifdef BIG_ENDIAN |
static inline __u64 __u64_le2host(__u64 n) |
{ |
return __u64_byteorder_swap(n); |
} |
static inline __native __native_le2host(__native n) |
{ |
return __u32_byteorder_swap(n); |
} |
#else |
# define __native_le2host(n) (n) |
# define __u64_le2host(n) (n) |
#endif |
#endif |
/tags/0.2.0/kernel/arch/mips32/include/cache.h |
---|
0,0 → 1,34 |
/* |
* 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. |
*/ |
#ifndef __mips32_CACHE_H__ |
#define __mips32_CACHE_H__ |
extern void cache_error(void); |
#endif |
/tags/0.2.0/kernel/arch/mips32/include/faddr.h |
---|
0,0 → 1,36 |
/* |
* 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. |
*/ |
#ifndef __mips32_FADDR_H__ |
#define __mips32_FADDR_H__ |
#include <arch/types.h> |
#define FADDR(fptr) ((__address) (fptr)) |
#endif |
/tags/0.2.0/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/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/kernel/arch/amd64/src/mm/page.c |
---|
0,0 → 1,208 |
/* |
* 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 <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), (__address)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), (__address)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), (__address)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), (__address)KA2PA(tgt)); \ |
SET_FRAME_FLAGS_ARCH(ptl3, PTL3_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \ |
} |
void page_arch_init(void) |
{ |
__address 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 (i=0; i < init.cnt; i++) { |
for (cur=init.tasks[i].addr;cur < 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((__address) AS_KERNEL->page_table); |
} |
else { |
write_cr3((__address) 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) |
{ |
__address page; |
static __address 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) |
{ |
__address 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"); |
} |
} |
__address hw_map(__address 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) |
__address 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/kernel/arch/amd64/src/mm/memory_init.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 <arch/boot/memmap.h> |
#include <arch/mm/memory_init.h> |
#include <arch/mm/page.h> |
#include <print.h> |
__u8 e820counter = 0xff; |
struct e820memmap_ e820table[MEMMAP_E820_MAX_RECORDS]; |
__u32 e801memorysize; |
size_t get_memory_size(void) |
{ |
return e801memorysize*1024; |
} |
void memory_print_map(void) |
{ |
__u8 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/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/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/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/kernel/arch/amd64/src/interrupt.c |
---|
0,0 → 1,176 |
/* |
* 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 <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; |
/* __u64 *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)(__u16 irqmask) = NULL; |
void (* enable_irqs_function)(__u16 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(__u16 irqmask) |
{ |
if (enable_irqs_function) |
enable_irqs_function(irqmask); |
else |
panic("no enable_irqs_function\n"); |
} |
void trap_virtual_disable_irqs(__u16 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) |
{ |
trap_virtual_eoi(); |
ipc_irq_send_notif(n-IVT_IRQBASE); |
} |
/* Reregister irq to be IPC-ready */ |
void irq_ipc_bind_arch(__native irq) |
{ |
if (irq == IRQ_CLK) |
return; |
exc_register(IVT_IRQBASE+irq, "ipc_int", ipc_int); |
} |
/tags/0.2.0/kernel/arch/amd64/src/proc/task.c |
---|
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. |
*/ |
#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/kernel/arch/amd64/src/proc/scheduler.c |
---|
0,0 → 1,75 |
/* |
* 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 <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 = (__address) &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, (__u64)&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/kernel/arch/amd64/src/proc/thread.c |
---|
0,0 → 1,38 |
/* |
* 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 <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/kernel/arch/amd64/src/amd64.c |
---|
0,0 → 1,203 |
/* |
* 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 <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. |
*/ |
__native sys_tls_set(__native 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/kernel/arch/amd64/src/pm.c |
---|
0,0 → 1,235 |
/* |
* 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. |
*/ |
#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= (__u64) gdt }; |
ptr_16_64_t idtr = {.limit = sizeof(idt), .base= (__u64) idt }; |
static tss_t tss; |
tss_t *tss_p = NULL; |
void gdt_tss_setbase(descriptor_t *d, __address 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, __u32 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, __address 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((__address) 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, ((__address) 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((__address) 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], (__address) 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/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/kernel/arch/amd64/src/ddi/ddi.c |
---|
0,0 → 1,157 |
/* |
* 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 <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, __address 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; |
__u8 *newmap; |
/* |
* The I/O permission bitmap is too small and needs to be grown. |
*/ |
newmap = (__u8 *) 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/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/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/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/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/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/kernel/arch/amd64/src/debugger.c |
---|
0,0 → 1,377 |
/* |
* 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 <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 { |
__address 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) |
{ |
__native 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 |= ((__native) 0x3) << (18 + 4*curidx); |
else /* 8 */ |
dr7 |= ((__native) 0x2) << (18 + 4*curidx); |
if ((flags & BKPOINT_WRITE)) |
dr7 |= ((__native) 0x1) << (16 + 4*curidx); |
else if ((flags & BKPOINT_READ_WRITE)) |
dr7 |= ((__native) 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 = (__address) 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 (*((__native *) breakpoints[slot].address) != 0) |
return; |
printf("**** Found ZERO on address %p ****\n", |
slot, breakpoints[slot].address); |
} else { |
printf("Data watchpoint - new data: %p\n", |
*((__native *) 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) |
{ |
__native 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/kernel/arch/amd64/src/cpu/cpu.c |
---|
0,0 → 1,159 |
/* |
* 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 <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] - ((__u8 *) 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/kernel/arch/amd64/src/userspace.c |
---|
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. |
*/ |
#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/kernel/arch/amd64/src/syscall.c |
---|
0,0 → 1,62 |
/* |
* 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 <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, |
((__u64)(gdtselector(KDATA_DES) | PL_USER)<<48) \ |
| ((__u64)(gdtselector(KTEXT_DES) | PL_KERNEL)<<32)); |
write_msr(AMD_MSR_LSTAR, (__u64)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/kernel/arch/amd64/src/fpu_context.c |
---|
0,0 → 1,58 |
/* |
* 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 <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/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/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/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/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/kernel/arch/amd64/include/interrupt.h |
---|
0,0 → 1,123 |
/* |
* 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. |
*/ |
#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 { |
__u64 rax; |
__u64 rbx; |
__u64 rcx; |
__u64 rdx; |
__u64 rsi; |
__u64 rdi; |
__u64 r8; |
__u64 r9; |
__u64 r10; |
__u64 r11; |
__u64 r12; |
__u64 r13; |
__u64 r14; |
__u64 r15; |
__u64 rbp; |
__u64 error_word; |
__u64 rip; |
__u64 cs; |
__u64 rflags; |
__u64 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, __address retaddr) |
{ |
istate->rip = retaddr; |
} |
static inline __native istate_get_pc(istate_t *istate) |
{ |
return istate->rip; |
} |
extern void (* disable_irqs_function)(__u16 irqmask); |
extern void (* enable_irqs_function)(__u16 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(__u16 irqmask); |
extern void trap_virtual_disable_irqs(__u16 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/kernel/arch/amd64/include/mm/as.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. |
*/ |
#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/kernel/arch/amd64/include/mm/page.h |
---|
0,0 → 1,192 |
/* |
* 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. |
*/ |
/** 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 __address ka2pa(__address x) |
{ |
if (x > 0xffffffff80000000) |
return x - 0xffffffff80000000; |
else |
return x - 0xffff800000000000; |
} |
# define KA2PA(x) ka2pa((__address)x) |
# define PA2KA_CODE(x) (((__address) (x)) + 0xffffffff80000000) |
# define PA2KA(x) (((__address) (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 *) ((((__u64) ((pte_t *)(ptl0))[(i)].addr_12_31)<<12) | (((__u64) ((pte_t *)(ptl0))[(i)].addr_32_51)<<32 ))) |
#define GET_PTL2_ADDRESS_ARCH(ptl1, i) ((pte_t *) ((((__u64) ((pte_t *)(ptl1))[(i)].addr_12_31)<<12) | (((__u64) ((pte_t *)(ptl1))[(i)].addr_32_51)<<32 ))) |
#define GET_PTL3_ADDRESS_ARCH(ptl2, i) ((pte_t *) ((((__u64) ((pte_t *)(ptl2))[(i)].addr_12_31)<<12) | (((__u64) ((pte_t *)(ptl2))[(i)].addr_32_51)<<32 ))) |
#define GET_FRAME_ADDRESS_ARCH(ptl3, i) ((__address *) ((((__u64) ((pte_t *)(ptl3))[(i)].addr_12_31)<<12) | (((__u64) ((pte_t *)(ptl3))[(i)].addr_32_51)<<32 ))) |
#define SET_PTL0_ADDRESS_ARCH(ptl0) (write_cr3((__address) (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) (*((__u64 *) (p)) != 0) |
#define PTE_PRESENT_ARCH(p) ((p)->present != 0) |
#define PTE_GET_FRAME_ARCH(p) ((((__address)(p)->addr_12_31)<<12) | ((__address)(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, __address 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/kernel/arch/amd64/include/mm/frame.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. |
*/ |
#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 __address last_frame; |
extern void frame_arch_init(void); |
#endif /* __ASM__ */ |
#endif |
/tags/0.2.0/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/kernel/arch/amd64/include/mm/tlb.h |
---|
0,0 → 1,35 |
/* |
* 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. |
*/ |
#ifndef __amd64_TLB_H__ |
#define __amd64_TLB_H__ |
#define tlb_arch_init() |
#define tlb_print() |
#endif |
/tags/0.2.0/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/kernel/arch/amd64/include/mm/ptl.h |
---|
0,0 → 1,43 |
/* |
* 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. |
*/ |
#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/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/kernel/arch/amd64/include/drivers/vesa.h |
---|
0,0 → 1,37 |
/* |
* 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. |
*/ |
#ifndef __VESA_H__ |
#define __VESA_H__ |
int vesa_present(void); |
void vesa_init(void); |
#endif |
/tags/0.2.0/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/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/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/kernel/arch/amd64/include/pm.h |
---|
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. |
*/ |
#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 { |
__u16 limit; |
__u64 base; |
} __attribute__ ((packed)); |
typedef struct ptr_16_64 ptr_16_64_t; |
struct ptr_16_32 { |
__u16 limit; |
__u32 base; |
} __attribute__ ((packed)); |
typedef struct ptr_16_32 ptr_16_32_t; |
struct tss { |
__u32 reserve1; |
__u64 rsp0; |
__u64 rsp1; |
__u64 rsp2; |
__u64 reserve2; |
__u64 ist1; |
__u64 ist2; |
__u64 ist3; |
__u64 ist4; |
__u64 ist5; |
__u64 ist6; |
__u64 ist7; |
__u64 reserve3; |
__u16 reserve4; |
__u16 iomap_base; |
__u8 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, __address base); |
extern void gdt_tss_setlimit(descriptor_t *d, __u32 limit); |
extern void idt_init(void); |
extern void idt_setoffset(idescriptor_t *d, __address offset); |
extern void tss_initialize(tss_t *t); |
#endif /* __ASM__ */ |
#endif |
/tags/0.2.0/kernel/arch/amd64/include/ddi/ddi.h |
---|
0,0 → 1,39 |
/* |
* 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. |
*/ |
/** |
* @file ddi.h |
* @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/kernel/arch/amd64/include/proc/task.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. |
*/ |
#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/kernel/arch/amd64/include/proc/thread.h |
---|
0,0 → 1,38 |
/* |
* 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. |
*/ |
#ifndef __amd64_THREAD_H__ |
#define __amd64_THREAD_H__ |
#include <arch/types.h> |
typedef struct { |
__native tls; |
} thread_arch_t; |
#endif |
/tags/0.2.0/kernel/arch/amd64/include/cpu.h |
---|
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. |
*/ |
#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 __u64 read_efer_flag(void); |
void cpu_setup_fpu(void); |
#endif /* __ASM__ */ |
#endif |
/tags/0.2.0/kernel/arch/amd64/include/asm.h |
---|
0,0 → 1,275 |
/* |
* 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. |
*/ |
#ifndef __amd64_ASM_H__ |
#define __amd64_ASM_H__ |
#include <arch/pm.h> |
#include <arch/types.h> |
#include <config.h> |
extern void asm_delay_loop(__u32 t); |
extern void asm_fake_loop(__u32 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 __address get_stack_base(void) |
{ |
__address v; |
__asm__ volatile ("andq %%rsp, %0\n" : "=r" (v) : "0" (~((__u64)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 __u8 inb(__u16 port) { __u8 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(__u16 port, __u8 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(__u32 msr, __u64 value) |
{ |
__asm__ volatile ( |
"wrmsr;" : : "c" (msr), |
"a" ((__u32)(value)), |
"d" ((__u32)(value >> 32)) |
); |
} |
static inline __native read_msr(__u32 msr) |
{ |
__u32 ax, dx; |
__asm__ volatile ( |
"rdmsr;" : "=a"(ax), "=d"(dx) : "c" (msr) |
); |
return ((__u64)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 __address * get_ip() |
{ |
__address *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(__address addr) |
{ |
__asm__ volatile ("invlpg %0\n" :: "m" (*((__native *)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(__u16 sel) |
{ |
__asm__ volatile ("ltr %0" : : "r" (sel)); |
} |
#define GEN_READ_REG(reg) static inline __native read_ ##reg (void) \ |
{ \ |
__native res; \ |
__asm__ volatile ("movq %%" #reg ", %0" : "=r" (res) ); \ |
return res; \ |
} |
#define GEN_WRITE_REG(reg) static inline void write_ ##reg (__native 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/kernel/arch/amd64/include/atomic.h |
---|
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. |
*/ |
#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; |
__asm__ volatile ( |
"movq $1, %0\n" |
"lock xaddq %0, %1\n" |
: "=r" (r), "=m" (val->count) |
); |
return r; |
} |
static inline long atomic_postdec(atomic_t *val) |
{ |
long r; |
__asm__ volatile ( |
"movq $-1, %0\n" |
"lock xaddq %0, %1\n" |
: "=r" (r), "=m" (val->count) |
); |
return r; |
} |
#define atomic_preinc(val) (atomic_postinc(val)+1) |
#define atomic_predec(val) (atomic_postdec(val)-1) |
static inline __u64 test_and_set(atomic_t *val) { |
__u64 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) |
{ |
__u64 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/kernel/arch/amd64/include/syscall.h |
---|
0,0 → 1,36 |
/* |
* 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. |
*/ |
#ifndef __amd64_SYSCALL_H__ |
#define __amd64_SYSCALL_H__ |
#include <arch/types.h> |
extern void syscall_setup_cpu(void); |
#endif |
/tags/0.2.0/kernel/arch/amd64/include/debugger.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. |
*/ |
#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/kernel/arch/amd64/include/context_offset.h |
---|
0,0 → 1,10 |
/* 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/kernel/arch/amd64/include/context.h |
---|
0,0 → 1,61 |
/* |
* 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. |
*/ |
#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 { |
__address sp; |
__address pc; |
__u64 rbx; |
__u64 rbp; |
__u64 r12; |
__u64 r13; |
__u64 r14; |
__u64 r15; |
ipl_t ipl; |
} __attribute__ ((packed)); |
#endif |
/tags/0.2.0/kernel/arch/amd64/include/types.h |
---|
0,0 → 1,55 |
/* |
* 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. |
*/ |
#ifndef __amd64_TYPES_H__ |
#define __amd64_TYPES_H__ |
#define NULL 0 |
typedef signed char __s8; |
typedef signed short __s16; |
typedef signed int __s32; |
typedef signed long long __s64; |
typedef unsigned char __u8; |
typedef unsigned short __u16; |
typedef unsigned int __u32; |
typedef unsigned long long __u64; |
typedef __u64 __address; |
typedef __u64 pfn_t; |
/* Flags of processor (return value of interrupts_disable()) */ |
typedef __u64 ipl_t; |
typedef __u64 __native; |
typedef __s64 __snative; |
typedef struct page_specifier pte_t; |
#endif |
/tags/0.2.0/kernel/arch/amd64/include/elf.h |
---|
0,0 → 1,36 |
/* |
* 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. |
*/ |
#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/kernel/arch/amd64/include/cpuid.h |
---|
0,0 → 1,58 |
/* |
* 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. |
*/ |
#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 { |
__u32 cpuid_eax; |
__u32 cpuid_ebx; |
__u32 cpuid_ecx; |
__u32 cpuid_edx; |
} __attribute__ ((packed)); |
extern int has_cpuid(void); |
extern void cpuid(__u32 cmd, cpu_info_t *info); |
extern __u64 rdtsc(void); |
#endif /* __ASM__ */ |
#endif |
/tags/0.2.0/kernel/arch/amd64/include/boot/boot.h |
---|
0,0 → 1,41 |
/* |
* 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. |
*/ |
#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/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/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/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/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/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/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/kernel/arch/amd64/include/memstr.h |
---|
0,0 → 1,136 |
/* |
* 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. |
*/ |
#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) |
{ |
__native 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" ((__native)(cnt / 8)), "g" ((__native)cnt), "1" ((__native) dst), "2" ((__native) 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) |
{ |
__native d0, d1, d2; |
__native 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" ((__native)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(__address dst, size_t cnt, __u16 x) |
{ |
__native d0, d1; |
__asm__ __volatile__ ( |
"rep stosw\n\t" |
: "=&D" (d0), "=&c" (d1), "=a" (x) |
: "0" (dst), "1" ((__native)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(__address dst, size_t cnt, __u8 x) |
{ |
__native d0, d1; |
__asm__ __volatile__ ( |
"rep stosb\n\t" |
: "=&D" (d0), "=&c" (d1), "=a" (x) |
: "0" (dst), "1" ((__native)cnt), "2" (x) |
: "memory" |
); |
} |
#endif |
/tags/0.2.0/kernel/arch/amd64/include/byteorder.h |
---|
0,0 → 1,36 |
/* |
* 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. |
*/ |
#ifndef __amd64_BYTEORDER_H__ |
#define __amd64_BYTEORDER_H__ |
/* AMD64 is little-endian */ |
#define __native_le2host(n) (n) |
#define __u64_le2host(n) (n) |
#endif |
/tags/0.2.0/kernel/arch/amd64/include/arch.h |
---|
0,0 → 1,32 |
/* |
* 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. |
*/ |
#ifndef __amd64_ARCH_H__ |
#define __amd64_ARCH_H__ |
#endif |
/tags/0.2.0/kernel/arch/amd64/include/faddr.h |
---|
0,0 → 1,36 |
/* |
* 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. |
*/ |
#ifndef __amd64_FADDR_H__ |
#define __amd64_FADDR_H__ |
#include <arch/types.h> |
#define FADDR(fptr) ((__address) (fptr)) |
#endif |
/tags/0.2.0/kernel/arch/amd64/include/arg.h |
---|
0,0 → 1,34 |
/* |
* 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. |
*/ |
#ifndef __amd64_ARG_H__ |
#define __amd64_ARG_H__ |
#include <stdarg.h> |
#endif |
/tags/0.2.0/kernel/arch/amd64/Makefile.inc |
---|
0,0 → 1,121 |
# |
# 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 |
## Make some default assumptions |
# |
ifndef CPU |
CPU = opteron |
endif |
CFLAGS += -fno-unwind-tables -m64 -mcmodel=kernel -mno-red-zone |
DEFS += -D_CPU=${CPU} -D__64_BITS__ |
## Accepted CPUs |
# |
ifeq ($(CPU),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/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/kernel/arch/ia32/src/boot/boot.S |
---|
0,0 → 1,431 |
# |
# 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" |
KTEXT=8 |
KDATA=16 |
.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 $KDATA, %cx |
movw %cx, %es |
movw %cx, %fs |
movw %cx, %gs |
movw %cx, %ds # kernel data + stack |
movw %cx, %ss |
jmpl $KTEXT, $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 $KTEXT, $(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 $KDATA, %cx |
movw %cx, %es |
movw %cx, %fs |
movw %cx, %gs |
movw %cx, %ds # kernel data + stack |
movw %cx, %ss |
jmpl $KTEXT, $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/kernel/arch/ia32/src/mm/page.c |
---|
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. |
*/ |
#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) |
{ |
__address 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((__address) AS_KERNEL->page_table); |
} |
else { |
write_cr3((__address) AS_KERNEL->page_table); |
} |
paging_on(); |
} |
__address hw_map(__address 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) |
__address 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) |
{ |
__address 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/kernel/arch/ia32/src/mm/frame.c |
---|
0,0 → 1,137 |
/* |
* 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 <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; |
__address 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(__native) * 2, |
(__native) e820table[i].base_address, |
(__u64) 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 this addresses help */ |
frame_mark_unavailable(0xd000 >> FRAME_WIDTH,3); |
#endif |
#endif |
} |
} |
/tags/0.2.0/kernel/arch/ia32/src/mm/memory_init.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 <arch/boot/memmap.h> |
#include <arch/mm/memory_init.h> |
#include <arch/mm/page.h> |
#include <print.h> |
__u8 e820counter = 0xff; |
struct e820memmap_ e820table[MEMMAP_E820_MAX_RECORDS]; |
__u32 e801memorysize; |
size_t get_memory_size(void) |
{ |
return e801memorysize*1024; |
} |
void memory_print_map(void) |
{ |
__u8 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/kernel/arch/ia32/src/mm/as.c |
---|
0,0 → 1,36 |
/* |
* 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 <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/kernel/arch/ia32/src/mm/tlb.c |
---|
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. |
*/ |
#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, __address page, count_t cnt) |
{ |
int i; |
for (i = 0; i < cnt; i++) |
invlpg(page + i * PAGE_SIZE); |
} |
/tags/0.2.0/kernel/arch/ia32/src/interrupt.c |
---|
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. |
*/ |
#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)(__u16 irqmask) = NULL; |
void (* enable_irqs_function)(__u16 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) |
{ |
__u32 mxcsr; |
asm |
( |
"stmxcsr %0;\n" |
:"=m"(mxcsr) |
); |
fault_if_from_uspace(istate, "SIMD FP exception(19), MXCSR: %#zX", |
(__native)mxcsr); |
PRINT_INFO_ERRCODE(istate); |
printf("MXCSR: %#zX\n",(__native)(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(__u16 irqmask) |
{ |
if (enable_irqs_function) |
enable_irqs_function(irqmask); |
else |
panic("no enable_irqs_function\n"); |
} |
void trap_virtual_disable_irqs(__u16 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) |
{ |
trap_virtual_eoi(); |
ipc_irq_send_notif(n-IVT_IRQBASE); |
} |
/* Reregister irq to be IPC-ready */ |
void irq_ipc_bind_arch(__native irq) |
{ |
if (irq == IRQ_CLK) |
return; |
exc_register(IVT_IRQBASE+irq, "ipc_int", ipc_int); |
} |
/tags/0.2.0/kernel/arch/ia32/src/proc/task.c |
---|
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. |
*/ |
#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/kernel/arch/ia32/src/proc/scheduler.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. |
*/ |
#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 = (__address) &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/kernel/arch/ia32/src/proc/thread.c |
---|
0,0 → 1,38 |
/* |
* 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 <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/kernel/arch/ia32/src/smp/mps.c |
---|
0,0 → 1,425 |
/* |
* 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. |
*/ |
#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(__u8 *base); |
int mps_ct_check(void); |
int configure_via_ct(void); |
int configure_via_default(__u8 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 __u8 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; |
} |
__u8 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(__u8 *base) |
{ |
int i; |
__u8 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) |
{ |
__u8 *base = (__u8 *) ct; |
__u8 *ext = base + ct->base_table_length; |
__u8 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) |
{ |
__u8 *addr[2] = { NULL, (__u8 *) 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] = (__u8 *) PA2KA(ebda ? ebda : 639 * 1024); |
for (i = 0; i < 2; i++) { |
for (j = 0; j < length[i]; j += 16) { |
if (*((__u32 *) &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((__address)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) |
{ |
__u8 *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 = (__u32 *)(__address)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(__u8 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 = (__u32 *)(__address)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) |
{ |
__u8 *ext = (__u8 *) ct + ct->base_table_length; |
__u8 *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/kernel/arch/ia32/src/smp/smp.c |
---|
0,0 → 1,176 |
/* |
* 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 <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) |
{ |
int status; |
__address 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 = PA2KA(PFN2ADDR(frame_alloc_rc(ONE_FRAME, FRAME_ATOMIC | FRAME_KA, &status))); |
if (status != FRAME_OK) |
panic("cannot allocate address for l_apic\n"); |
io_apic_address = PA2KA(PFN2ADDR(frame_alloc_rc(ONE_FRAME, FRAME_ATOMIC | FRAME_KA, &status))); |
if (status != FRAME_OK) |
panic("cannot allocate address for io_apic\n"); |
if (config.cpu_count > 1) { |
page_mapping_insert(AS_KERNEL, l_apic_address, (__address) l_apic, |
PAGE_NOT_CACHEABLE); |
page_mapping_insert(AS_KERNEL, io_apic_address, (__address) io_apic, |
PAGE_NOT_CACHEABLE); |
l_apic = (__u32 *) l_apic_address; |
io_apic = (__u32 *) 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() |
*/ |
*((__u16 *) (PA2KA(0x467+0))) = ((__address) ap_boot) >> 4; /* segment */ |
*((__u16 *) (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((__address)(&gdt_new[TSS_DES]), sizeof(struct descriptor), 0); |
protected_ap_gdtr.limit = GDT_ITEMS * sizeof(struct descriptor); |
protected_ap_gdtr.base = KA2PA((__address) gdt_new); |
gdtr.base = (__address) 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/kernel/arch/ia32/src/smp/apic.c |
---|
0,0 → 1,563 |
/* |
* 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 <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 __u32 *l_apic = (__u32 *) 0xfee00000; |
volatile __u32 *io_apic = (__u32 *) 0xfec00000; |
__u32 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 stack Interrupted stack. |
*/ |
void apic_spurious(int n, istate_t *istate) |
{ |
printf("cpu%d: APIC spurious interrupt\n", CPU->id); |
} |
/** 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(__u8 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) |
printf("IPI is pending.\n"); |
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(__u8 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) |
printf("IPI is pending.\n"); |
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 = ((__address) 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; |
__u32 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 stack Interrupted stack. |
*/ |
void l_apic_timer_interrupt(int n, istate_t *istate) |
{ |
l_apic_eoi(); |
clock(); |
} |
/** Get Local APIC ID. |
* |
* @return Local APIC ID. |
*/ |
__u8 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. |
*/ |
__u32 io_apic_read(__u8 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 Content to be written to the addressed IO APIC register. |
*/ |
void io_apic_write(__u8 address, __u32 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, __u8 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(__u16 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(__u16 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/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((__address) &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/kernel/arch/ia32/src/smp/ipi.c |
---|
0,0 → 1,39 |
/* |
* 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. |
*/ |
#ifdef CONFIG_SMP |
#include <smp/ipi.h> |
#include <arch/smp/apic.h> |
void ipi_broadcast_arch(int ipi) |
{ |
(void) l_apic_broadcast_custom_ipi((__u8) ipi); |
} |
#endif /* CONFIG_SMP */ |
/tags/0.2.0/kernel/arch/ia32/src/ia32.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. |
*/ |
#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. |
*/ |
__native sys_tls_set(__native 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/kernel/arch/ia32/src/drivers/vesa.c |
---|
0,0 → 1,65 |
/* |
* 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. |
*/ |
#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> |
__u32 vesa_ph_addr; |
__u16 vesa_width; |
__u16 vesa_height; |
__u16 vesa_bpp; |
__u16 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/kernel/arch/ia32/src/drivers/i8259.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 <arch/drivers/i8259.h> |
#include <cpu.h> |
#include <arch/types.h> |
#include <arch/asm.h> |
#include <arch.h> |
#include <print.h> |
#include <interrupt.h> |
/* |
* This is the PIC driver. |
* Programmable Interrupt Controller for UP systems. |
*/ |
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(__u16 irqmask) |
{ |
__u8 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(__u16 irqmask) |
{ |
__u8 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) |
{ |
printf("cpu%d: PIC spurious interrupt\n", CPU->id); |
} |
/tags/0.2.0/kernel/arch/ia32/src/drivers/i8254.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 <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> |
/* |
* i8254 chip driver. |
* Low level time functions. |
*/ |
#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) |
{ |
__u64 clk1, clk2; |
__u32 t1, t2, o1, o2; |
__u8 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/kernel/arch/ia32/src/drivers/ega.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. |
*/ |
#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 __u32 ega_cursor; |
static __u8 *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) |
{ |
__u8 hi, lo; |
videoram = (__u8 *) 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((__address) (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/kernel/arch/ia32/src/pm.c |
---|
0,0 → 1,231 |
/* |
* 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 <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((__address) gdt) }; |
ptr_16_32_t gdtr = { .limit = sizeof(gdt), .base = (__address) gdt }; |
void gdt_setbase(descriptor_t *d, __address 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, __u32 limit) |
{ |
d->limit_0_15 = limit & 0xffff; |
d->limit_16_19 = (limit >> 16) & 0xf; |
} |
void idt_setoffset(idescriptor_t *d, __address 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((__address) 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, ((__address) 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 = (__address) 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], (__address) 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(__address 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/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/kernel/arch/ia32/src/ddi/ddi.c |
---|
0,0 → 1,156 |
/* |
* 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 <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, __address 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; |
__u8 *newmap; |
/* |
* The I/O permission bitmap is too small and needs to be grown. |
*/ |
newmap = (__u8 *) 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/kernel/arch/ia32/src/cpu/cpu.c |
---|
0,0 → 1,157 |
/* |
* 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 <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; |
__u32 help = 0; |
CPU->arch.tss = tss_p; |
CPU->arch.tss->iomap_base = &CPU->arch.tss->iomap[0] - ((__u8 *) 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/kernel/arch/ia32/src/userspace.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. |
*/ |
#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/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/kernel/arch/ia32/src/fpu_context.c |
---|
0,0 → 1,116 |
/* |
* 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 <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() |
{ |
__u32 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/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/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/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/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/kernel/arch/ia32/src/bios/bios.c |
---|
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. |
*/ |
#include <arch/bios/bios.h> |
#include <arch/types.h> |
__address ebda = 0; |
void bios_init(void) |
{ |
/* Copy the EBDA address out from BIOS Data Area */ |
ebda = *((__u16 *) BIOS_EBDA_PTR) * 0x10; |
} |
/tags/0.2.0/kernel/arch/ia32/include/interrupt.h |
---|
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. |
*/ |
#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 { |
__u32 eax; |
__u32 ecx; |
__u32 edx; |
__u32 esi; |
__u32 edi; |
__u32 ebp; |
__u32 ebx; |
__u32 gs; |
__u32 fs; |
__u32 es; |
__u32 ds; |
__u32 error_word; |
__u32 eip; |
__u32 cs; |
__u32 eflags; |
__u32 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, __address retaddr) |
{ |
istate->eip = retaddr; |
} |
static inline __native istate_get_pc(istate_t *istate) |
{ |
return istate->eip; |
} |
extern void (* disable_irqs_function)(__u16 irqmask); |
extern void (* enable_irqs_function)(__u16 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(__u16 irqmask); |
extern void trap_virtual_disable_irqs(__u16 irqmask); |
extern void trap_virtual_eoi(void); |
#endif |
/tags/0.2.0/kernel/arch/ia32/include/smp/mps.h |
---|
0,0 → 1,125 |
/* |
* 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. |
*/ |
#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 { |
__u32 signature; |
__u32 configuration_table; |
__u8 length; |
__u8 revision; |
__u8 checksum; |
__u8 config_type; |
__u8 mpfib2; |
__u8 mpfib3; |
__u8 mpfib4; |
__u8 mpfib5; |
} __attribute__ ((packed)); |
struct mps_ct { |
__u32 signature; |
__u16 base_table_length; |
__u8 revision; |
__u8 checksum; |
__u8 oem_id[8]; |
__u8 product_id[12]; |
__u32 oem_table; |
__u16 oem_table_size; |
__u16 entry_count; |
__u32 l_apic; |
__u16 ext_table_length; |
__u8 ext_table_checksum; |
__u8 xxx; |
__u8 base_table[0]; |
} __attribute__ ((packed)); |
struct __processor_entry { |
__u8 type; |
__u8 l_apic_id; |
__u8 l_apic_version; |
__u8 cpu_flags; |
__u8 cpu_signature[4]; |
__u32 feature_flags; |
__u32 xxx[2]; |
} __attribute__ ((packed)); |
struct __bus_entry { |
__u8 type; |
__u8 bus_id; |
__u8 bus_type[6]; |
} __attribute__ ((packed)); |
struct __io_apic_entry { |
__u8 type; |
__u8 io_apic_id; |
__u8 io_apic_version; |
__u8 io_apic_flags; |
__u32 io_apic; |
} __attribute__ ((packed)); |
struct __io_intr_entry { |
__u8 type; |
__u8 intr_type; |
__u8 poel; |
__u8 xxx; |
__u8 src_bus_id; |
__u8 src_bus_irq; |
__u8 dst_io_apic_id; |
__u8 dst_io_apic_pin; |
} __attribute__ ((packed)); |
struct __l_intr_entry { |
__u8 type; |
__u8 intr_type; |
__u8 poel; |
__u8 xxx; |
__u8 src_bus_id; |
__u8 src_bus_irq; |
__u8 dst_l_apic_id; |
__u8 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/kernel/arch/ia32/include/smp/apic.h |
---|
0,0 → 1,361 |
/* |
* 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. |
*/ |
#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(__u32)) |
#define ICRhi (0x310/sizeof(__u32)) |
struct icr { |
union { |
__u32 lo; |
struct { |
__u8 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 { |
__u32 hi; |
struct { |
unsigned : 24; /**< Reserved. */ |
__u8 dest; /**< Destination field. */ |
} __attribute__ ((packed)); |
}; |
} __attribute__ ((packed)); |
typedef struct icr icr_t; |
/* End Of Interrupt. */ |
#define EOI (0x0b0/sizeof(__u32)) |
/** Error Status Register. */ |
#define ESR (0x280/sizeof(__u32)) |
union esr { |
__u32 value; |
__u8 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(__u32)) |
union tpr { |
__u32 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(__u32)) |
union svr { |
__u32 value; |
struct { |
__u8 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(__u32)) |
union tdcr { |
__u32 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(__u32)) |
/* Current Count Register for Timer */ |
#define CCRT (0x390/sizeof(__u32)) |
/** LVT Timer register. */ |
#define LVT_Tm (0x320/sizeof(__u32)) |
union lvt_tm { |
__u32 value; |
struct { |
__u8 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(__u32)) |
#define LVT_LINT1 (0x360/sizeof(__u32)) |
union lvt_lint { |
__u32 value; |
struct { |
__u8 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(__u32)) |
union lvt_error { |
__u32 value; |
struct { |
__u8 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(__u32)) |
union l_apic_id { |
__u32 value; |
struct { |
unsigned : 24; /**< Reserved. */ |
__u8 apic_id; /**< Local APIC ID. */ |
} __attribute__ ((packed)); |
}; |
typedef union l_apic_id l_apic_id_t; |
/** Local APIC Version Register */ |
#define LAVR (0x030/sizeof(__u32)) |
#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(__u32)) |
union ldr { |
__u32 value; |
struct { |
unsigned : 24; /**< Reserved. */ |
__u8 id; /**< Logical APIC ID. */ |
} __attribute__ ((packed)); |
}; |
typedef union ldr ldr_t; |
/** Destination Format Register. */ |
#define DFR (0x0e0/sizeof(__u32)) |
union dfr { |
__u32 value; |
struct { |
unsigned : 28; /**< Reserved, all ones. */ |
unsigned model : 4; /**< Model. */ |
} __attribute__ ((packed)); |
}; |
typedef union dfr dfr_t; |
/* IO APIC */ |
#define IOREGSEL (0x00/sizeof(__u32)) |
#define IOWIN (0x10/sizeof(__u32)) |
#define IOAPICID 0x00 |
#define IOAPICVER 0x01 |
#define IOAPICARB 0x02 |
#define IOREDTBL 0x10 |
/** I/O Register Select Register. */ |
union io_regsel { |
__u32 value; |
struct { |
__u8 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 { |
__u32 lo; |
struct { |
__u8 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 { |
__u32 hi; |
struct { |
unsigned : 24; /**< Reserved. */ |
__u8 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 { |
__u32 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 __u32 *l_apic; |
extern volatile __u32 *io_apic; |
extern __u32 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(__u8 vector); |
extern int l_apic_send_init_ipi(__u8 apicid); |
extern void l_apic_debug(void); |
extern __u8 l_apic_id(void); |
extern __u32 io_apic_read(__u8 address); |
extern void io_apic_write(__u8 address , __u32 x); |
extern void io_apic_change_ioredtbl(int pin, int dest, __u8 v, int flags); |
extern void io_apic_disable_irqs(__u16 irqmask); |
extern void io_apic_enable_irqs(__u16 irqmask); |
#endif |
/tags/0.2.0/kernel/arch/ia32/include/smp/smp.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. |
*/ |
#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. */ |
__u8 (*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/kernel/arch/ia32/include/smp/ap.h |
---|
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. |
*/ |
#ifndef __AP_H__ |
#define __AP_H__ |
extern void ap_boot(void); |
#endif |
/tags/0.2.0/kernel/arch/ia32/include/mm/as.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. |
*/ |
#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/kernel/arch/ia32/include/mm/asid.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. |
*/ |
/* |
* 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/kernel/arch/ia32/include/mm/page.h |
---|
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. |
*/ |
#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) (((__address) (x)) - 0x80000000) |
# define PA2KA(x) (((__address) (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) ((__address)((((pte_t *)(ptl3))[(i)].frame_address)<<12)) |
#define SET_PTL0_ADDRESS_ARCH(ptl0) (write_cr3((__address) (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) (*((__u32 *) (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/kernel/arch/ia32/include/mm/frame.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. |
*/ |
#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 __address last_frame; |
extern void frame_arch_init(void); |
#endif /* __ASM__ */ |
#endif /* KERNEL */ |
#endif |
/tags/0.2.0/kernel/arch/ia32/include/mm/tlb.h |
---|
0,0 → 1,35 |
/* |
* 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. |
*/ |
#ifndef __ia32_TLB_H__ |
#define __ia32_TLB_H__ |
#define tlb_arch_init() |
#define tlb_print() |
#endif |
/tags/0.2.0/kernel/arch/ia32/include/mm/memory_init.h |
---|
0,0 → 1,38 |
/* |
* 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. |
*/ |
#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/kernel/arch/ia32/include/drivers/i8254.h |
---|
0,0 → 1,38 |
/* |
* 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. |
*/ |
#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/kernel/arch/ia32/include/drivers/vesa.h |
---|
0,0 → 1,35 |
/* |
* 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. |
*/ |
#ifndef __VESA_H__ |
#define __VESA_H__ |
extern int vesa_present(void); |
extern void vesa_init(void); |
#endif |
/tags/0.2.0/kernel/arch/ia32/include/drivers/i8259.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. |
*/ |
#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(__u16 irqmask); |
extern void pic_disable_irqs(__u16 irqmask); |
extern void pic_eoi(void); |
#endif |
/tags/0.2.0/kernel/arch/ia32/include/drivers/ega.h |
---|
0,0 → 1,39 |
/* |
* 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. |
*/ |
#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/kernel/arch/ia32/include/drivers/i8042.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. |
*/ |
/** |
* 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(__u8 data) |
{ |
outb(i8042_DATA, data); |
} |
static inline __u8 i8042_data_read(void) |
{ |
return inb(i8042_DATA); |
} |
static inline __u8 i8042_status_read(void) |
{ |
return inb(i8042_STATUS); |
} |
static inline void i8042_command_write(__u8 command) |
{ |
outb(i8042_STATUS, command); |
} |
#endif |
/tags/0.2.0/kernel/arch/ia32/include/barrier.h |
---|
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. |
*/ |
#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/kernel/arch/ia32/include/pm.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. |
*/ |
#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 { |
__u16 limit; |
__u32 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 { |
__u16 link; |
unsigned : 16; |
__u32 esp0; |
__u16 ss0; |
unsigned : 16; |
__u32 esp1; |
__u16 ss1; |
unsigned : 16; |
__u32 esp2; |
__u16 ss2; |
unsigned : 16; |
__u32 cr3; |
__u32 eip; |
__u32 eflags; |
__u32 eax; |
__u32 ecx; |
__u32 edx; |
__u32 ebx; |
__u32 esp; |
__u32 ebp; |
__u32 esi; |
__u32 edi; |
__u16 es; |
unsigned : 16; |
__u16 cs; |
unsigned : 16; |
__u16 ss; |
unsigned : 16; |
__u16 ds; |
unsigned : 16; |
__u16 fs; |
unsigned : 16; |
__u16 gs; |
unsigned : 16; |
__u16 ldtr; |
unsigned : 16; |
unsigned : 16; |
__u16 iomap_base; |
__u8 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, __address base); |
extern void gdt_setlimit(descriptor_t *d, __u32 limit); |
extern void idt_init(void); |
extern void idt_setoffset(idescriptor_t *d, __address offset); |
extern void tss_initialize(tss_t *t); |
extern void set_tls_desc(__address tls); |
#endif /* __ASM__ */ |
#endif |
/tags/0.2.0/kernel/arch/ia32/include/ddi/ddi.h |
---|
0,0 → 1,39 |
/* |
* 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. |
*/ |
/** |
* @file ddi.h |
* @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/kernel/arch/ia32/include/proc/task.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. |
*/ |
#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/kernel/arch/ia32/include/proc/thread.h |
---|
0,0 → 1,38 |
/* |
* 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. |
*/ |
#ifndef __ia32_THREAD_H__ |
#define __ia32_THREAD_H__ |
#include <arch/types.h> |
typedef struct { |
__native tls; |
} thread_arch_t; |
#endif |
/tags/0.2.0/kernel/arch/ia32/include/cpu.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. |
*/ |
#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/kernel/arch/ia32/include/asm.h |
---|
0,0 → 1,291 |
/* |
* 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. |
*/ |
#ifndef __ia32_ASM_H__ |
#define __ia32_ASM_H__ |
#include <arch/pm.h> |
#include <arch/types.h> |
#include <config.h> |
extern __u32 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(__u32 t); |
extern void asm_fake_loop(__u32 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 __native read_ ##reg (void) \ |
{ \ |
__native res; \ |
__asm__ volatile ("movl %%" #reg ", %0" : "=r" (res) ); \ |
return res; \ |
} |
#define GEN_WRITE_REG(reg) static inline void write_ ##reg (__native 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(__u16 port, __u8 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(__u16 port, __u16 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(__u16 port, __u32 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 __u8 inb(__u16 port) { __u8 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 __u16 inw(__u16 port) { __u16 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 __u32 inl(__u16 port) { __u32 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 __address get_stack_base(void) |
{ |
__address v; |
__asm__ volatile ("andl %%esp, %0\n" : "=r" (v) : "0" (~(STACK_SIZE-1))); |
return v; |
} |
static inline __u64 rdtsc(void) |
{ |
__u64 v; |
__asm__ volatile("rdtsc\n" : "=A" (v)); |
return v; |
} |
/** Return current IP address */ |
static inline __address * get_ip() |
{ |
__address *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(__address addr) |
{ |
__asm__ volatile ("invlpg %0\n" :: "m" (*(__native *)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(__u16 sel) |
{ |
__asm__ volatile ("ltr %0" : : "r" (sel)); |
} |
#endif |
/tags/0.2.0/kernel/arch/ia32/include/atomic.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. |
*/ |
#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; |
__asm__ volatile ( |
"movl $1, %0\n" |
"lock xaddl %0, %1\n" |
: "=r" (r), "=m" (val->count) |
); |
return r; |
} |
static inline long atomic_postdec(atomic_t *val) |
{ |
long r; |
__asm__ volatile ( |
"movl $-1, %0\n" |
"lock xaddl %0, %1\n" |
: "=r" (r), "=m" (val->count) |
); |
return r; |
} |
#define atomic_preinc(val) (atomic_postinc(val)+1) |
#define atomic_predec(val) (atomic_postdec(val)-1) |
static inline __u32 test_and_set(atomic_t *val) { |
__u32 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) |
{ |
__u32 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/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/kernel/arch/ia32/include/fpu_context.h |
---|
0,0 → 1,46 |
/* |
* 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. |
*/ |
#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 { |
__u8 fpu[512]; /* FXSAVE & FXRSTOR storage area */ |
}; |
#endif |
/tags/0.2.0/kernel/arch/ia32/include/cpuid.h |
---|
0,0 → 1,110 |
/* |
* 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. |
*/ |
#ifndef __ia32_CPUID_H__ |
#define __ia32_CPUID_H__ |
#include <arch/types.h> |
struct cpu_info { |
__u32 cpuid_eax; |
__u32 cpuid_ebx; |
__u32 cpuid_ecx; |
__u32 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; |
__u32 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; |
__u32 word ; |
}cpuid_feature_info; |
static inline __u32 has_cpuid(void) |
{ |
__u32 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(__u32 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/kernel/arch/ia32/include/types.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. |
*/ |
#ifndef __TYPES_H__ |
#define __TYPES_H__ |
#define NULL 0 |
typedef signed char __s8; |
typedef signed short __s16; |
typedef signed long __s32; |
typedef signed long long __s64; |
typedef unsigned char __u8; |
typedef unsigned short __u16; |
typedef unsigned long __u32; |
typedef unsigned long long __u64; |
typedef __u32 __address; |
typedef __u32 pfn_t; |
typedef __u32 ipl_t; |
typedef __u32 __native; |
typedef __s32 __snative; |
typedef struct page_specifier pte_t; |
#endif |
/tags/0.2.0/kernel/arch/ia32/include/boot/boot.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. |
*/ |
#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/kernel/arch/ia32/include/boot/memmap.h |
---|
0,0 → 1,68 |
/* |
* 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. |
*/ |
#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_ { |
__u64 base_address; |
__u64 size; |
__u32 type; |
} __attribute__ ((packed)); |
extern struct e820memmap_ e820table[MEMMAP_E820_MAX_RECORDS]; |
extern __u8 e820counter; |
extern __u32 e801memorysize; /**< Size of available memory in KB. */ |
#endif |
#endif |
/tags/0.2.0/kernel/arch/ia32/include/elf.h |
---|
0,0 → 1,36 |
/* |
* 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. |
*/ |
#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/kernel/arch/ia32/include/debug.h |
---|
0,0 → 1,36 |
/* |
* 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. |
*/ |
#ifndef __ia32_DEBUG_H__ |
#define __ia32_DEBUG_H__ |
#include <arch/asm.h> |
#define HERE get_ip() |
#endif |
/tags/0.2.0/kernel/arch/ia32/include/memstr.h |
---|
0,0 → 1,142 |
/* |
* 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. |
*/ |
#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) |
{ |
__native 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" ((__native) (cnt / 4)), "g" ((__native) cnt), "1" ((__native) dst), "2" ((__native) 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) |
{ |
__u32 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" ((__native) src), "2" ((__native) dst), "3" ((__native) 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(__address dst, size_t cnt, __u16 x) |
{ |
__u32 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(__address dst, size_t cnt, __u8 x) |
{ |
__u32 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/kernel/arch/ia32/include/context.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. |
*/ |
#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 { |
__address sp; |
__address pc; |
__u32 ebx; |
__u32 esi; |
__u32 edi; |
__u32 ebp; |
ipl_t ipl; |
} __attribute__ ((packed)); |
#endif |
/tags/0.2.0/kernel/arch/ia32/include/byteorder.h |
---|
0,0 → 1,36 |
/* |
* 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. |
*/ |
#ifndef __ia32_BYTEORDER_H__ |
#define __ia32_BYTEORDER_H__ |
/* IA-32 is little-endian */ |
#define __native_le2host(n) (n) |
#define __u64_le2host(n) (n) |
#endif |
/tags/0.2.0/kernel/arch/ia32/include/arch.h |
---|
0,0 → 1,32 |
/* |
* 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. |
*/ |
#ifndef __ia32_ARCH_H__ |
#define __ia32_ARCH_H__ |
#endif |
/tags/0.2.0/kernel/arch/ia32/include/faddr.h |
---|
0,0 → 1,36 |
/* |
* 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. |
*/ |
#ifndef __ia32_FADDR_H__ |
#define __ia32_FADDR_H__ |
#include <arch/types.h> |
#define FADDR(fptr) ((__address) (fptr)) |
#endif |
/tags/0.2.0/kernel/arch/ia32/include/arg.h |
---|
0,0 → 1,34 |
/* |
* 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. |
*/ |
#ifndef __ia32_ARG_H__ |
#define __ia32_ARG_H__ |
#include <stackarg.h> |
#endif |
/tags/0.2.0/kernel/arch/ia32/include/bios/bios.h |
---|
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. |
*/ |
#ifndef __BIOS_H__ |
#define __BIOS_H__ |
#include <arch/types.h> |
#define BIOS_EBDA_PTR 0x40e |
extern __address ebda; |
extern void bios_init(void); |
#endif /* __BIOS_H__ */ |
/tags/0.2.0/kernel/arch/ia32/Makefile.inc |
---|
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. |
# |
## Toolchain configuration |
# |
BFD_NAME = elf32-i386 |
BFD_ARCH = i386 |
BFD = binary |
TARGET = i686-pc-linux-gnu |
TOOLCHAIN_DIR = /usr/local/i686/bin |
## Make some default assumptions |
# |
ifndef IA32_CPU |
IA32_CPU = pentium4 |
endif |
DEFS += -D_CPU=${IA32_CPU} -D__32_BITS__ |
## Accepted CPUs |
# |
ifeq ($(IA32_CPU),athlon-xp) |
CFLAGS += -march=athlon-xp -mmmx -msse -m3dnow |
DEFS += -DCONFIG_FENCES_P3 |
CONFIG_SMP = n |
CONFIG_HT = n |
endif |
ifeq ($(IA32_CPU),athlon-mp) |
CFLAGS += -march=athlon-mp -mmmx -msse -m3dnow |
DEFS += -DCONFIG_FENCES_P3 |
CONFIG_HT = n |
endif |
ifeq ($(IA32_CPU),pentium3) |
CFLAGS += -march=pentium3 -mmmx -msse |
DEFS += -DCONFIG_FENCES_P3 |
CONFIG_HT = n |
endif |
ifeq ($(IA32_CPU),prescott) |
CFLAGS += -march=pentium4 -mfpmath=sse -mmmx -msse -msse2 -msse3 |
DEFS += -DCONFIG_FENCES_P4 |
endif |
ifeq ($(IA32_CPU),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/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/kernel/arch/ppc32/include/drivers/cuda.h |
---|
0,0 → 1,40 |
/* |
* 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 __CUDA_H__ |
#define __CUDA_H__ |
#include <arch/types.h> |
#include <typedefs.h> |
#define CUDA_IRQ 10 |
extern void cuda_init(__address base, size_t size); |
extern int cuda_get_scancode(void); |
#endif |
/tags/0.2.0/kernel/arch/ppc32/include/drivers/pic.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. |
*/ |
#ifndef __PIC_H_ |
#define __PIC_H_ |
/* PIC handler, read from pearpc source codes */ |
#define PIC_HW_ADDR 0x80800000 |
#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(void); |
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/kernel/arch/ppc32/include/arch.h |
---|
0,0 → 1,34 |
/* |
* 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. |
*/ |
#ifndef __ppc32_ARCH_H__ |
#define __ppc32_ARCH_H__ |
#include <arch/drivers/cuda.h> |
#endif |
/tags/0.2.0/kernel/arch/ppc32/include/boot/boot.h |
---|
0,0 → 1,89 |
/* |
* 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 __ppc32_BOOT_H__ |
#define __ppc32_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 { |
__address addr; |
__u32 size; |
} utask_t; |
typedef struct { |
__u32 count; |
utask_t tasks[TASKMAP_MAX_RECORDS]; |
} taskmap_t; |
typedef struct { |
__address start; |
__u32 size; |
} memzone_t; |
typedef struct { |
__u32 total; |
__u32 count; |
memzone_t zones[MEMMAP_MAX_RECORDS]; |
} memmap_t; |
typedef struct { |
__address addr; |
unsigned int width; |
unsigned int height; |
unsigned int bpp; |
unsigned int scanline; |
} screen_t; |
typedef struct { |
__address addr; |
unsigned int 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 |
/tags/0.2.0/kernel/arch/ppc32/include/interrupt.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. |
*/ |
#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/kernel/arch/ppc32/include/mm/page.h |
---|
0,0 → 1,153 |
/* |
* 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. |
*/ |
#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) (((__address) (x)) - 0x80000000) |
# define PA2KA(x) (((__address) (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) (*((__u32 *) (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); |
#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(int n, istate_t *istate); |
extern void pht_init(void); |
#endif /* __ASM__ */ |
#endif /* KERNEL */ |
#endif |
/tags/0.2.0/kernel/arch/ppc32/include/mm/as.h |
---|
0,0 → 1,45 |
/* |
* 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. |
*/ |
#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)) |
#define as_install_arch(as) |
extern void as_arch_init(void); |
#endif |
/tags/0.2.0/kernel/arch/ppc32/include/mm/asid.h |
---|
0,0 → 1,39 |
/* |
* 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. |
*/ |
#ifndef __ppc32_ASID_H__ |
#define __ppc32_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/kernel/arch/ppc32/include/mm/frame.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. |
*/ |
#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 __address last_frame; |
extern void frame_arch_init(void); |
#endif /* __ASM__ */ |
#endif /* KERNEL */ |
#endif |
/tags/0.2.0/kernel/arch/ppc32/include/mm/tlb.h |
---|
0,0 → 1,33 |
/* |
* 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 __ppc32_TLB_H__ |
#define __ppc32_TLB_H__ |
#endif |
/tags/0.2.0/kernel/arch/ppc32/include/mm/memory_init.h |
---|
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. |
*/ |
#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/kernel/arch/ppc32/include/exception.h |
---|
0,0 → 1,95 |
/* |
* 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 __ppc32_EXCEPTION_H__ |
#define __ppc32_EXCEPTION_H__ |
#ifndef __ppc32_TYPES_H__ |
# include <arch/types.h> |
#endif |
#include <typedefs.h> |
struct istate { |
__u32 r0; |
__u32 r2; |
__u32 r3; |
__u32 r4; |
__u32 r5; |
__u32 r6; |
__u32 r7; |
__u32 r8; |
__u32 r9; |
__u32 r10; |
__u32 r11; |
__u32 r13; |
__u32 r14; |
__u32 r15; |
__u32 r16; |
__u32 r17; |
__u32 r18; |
__u32 r19; |
__u32 r20; |
__u32 r21; |
__u32 r22; |
__u32 r23; |
__u32 r24; |
__u32 r25; |
__u32 r26; |
__u32 r27; |
__u32 r28; |
__u32 r29; |
__u32 r30; |
__u32 r31; |
__u32 cr; |
__u32 pc; |
__u32 srr1; |
__u32 lr; |
__u32 ctr; |
__u32 xer; |
__u32 r12; |
__u32 sp; |
}; |
static inline void istate_set_retaddr(istate_t *istate, __address 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 __native istate_get_pc(istate_t *istate) |
{ |
return istate->pc; |
} |
#endif |
/tags/0.2.0/kernel/arch/ppc32/include/proc/task.h |
---|
0,0 → 1,38 |
/* |
* 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. |
*/ |
#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/kernel/arch/ppc32/include/proc/thread.h |
---|
0,0 → 1,37 |
/* |
* 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. |
*/ |
#ifndef __ppc32_THREAD_H__ |
#define __ppc32_THREAD_H__ |
typedef struct { |
} thread_arch_t; |
#define thread_create_arch(t) |
#endif |
/tags/0.2.0/kernel/arch/ppc32/include/asm/regname.h |
---|
0,0 → 1,222 |
/* |
* 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. |
*/ |
#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/kernel/arch/ppc32/include/types.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. |
*/ |
#ifndef __ppc32_TYPES_H__ |
#define __ppc32_TYPES_H__ |
#define NULL 0 |
typedef signed char __s8; |
typedef signed short __s16; |
typedef signed int __s32; |
typedef signed long long __s64; |
typedef unsigned char __u8; |
typedef unsigned short __u16; |
typedef unsigned int __u32; |
typedef unsigned long long __u64; |
typedef __u32 __address; |
typedef __u32 pfn_t; |
typedef __u32 ipl_t; |
typedef __u32 __native; |
/** 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/kernel/arch/ppc32/include/asm.h |
---|
0,0 → 1,146 |
/* |
* 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. |
*/ |
#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 __address get_stack_base(void) |
{ |
__address 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(__u32 t); |
extern void userspace_asm(__address uspace_uarg, __address stack, __address entry); |
#endif |
/tags/0.2.0/kernel/arch/ppc32/include/byteorder.h |
---|
0,0 → 1,64 |
/* |
* Copyright (C) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#ifndef __ppc32_BYTEORDER_H__ |
#define __ppc32_BYTEORDER_H__ |
#include <arch/types.h> |
#include <byteorder.h> |
#define BIG_ENDIAN |
static inline __u64 __u64_le2host(__u64 n) |
{ |
return __u64_byteorder_swap(n); |
} |
/** Convert little-endian __native to host __native |
* |
* Convert little-endian __native parameter to host endianess. |
* |
* @param n Little-endian __native argument. |
* |
* @return Result in host endianess. |
* |
*/ |
static inline __native __native_le2host(__native n) |
{ |
__address v; |
asm volatile ( |
"lwbrx %0, %1, %2\n" |
: "=r" (v) |
: "i" (0), "r" (&n) |
); |
return v; |
} |
#endif |
/tags/0.2.0/kernel/arch/ppc32/include/cpuid.h |
---|
0,0 → 1,47 |
/* |
* 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 __ppc32_CPUID_H__ |
#define __ppc32_CPUID_H__ |
#include <arch/types.h> |
struct cpu_info { |
__u16 version; |
__u16 revision; |
} __attribute__ ((packed)); |
static inline void cpu_version(struct cpu_info *info) |
{ |
asm volatile ( |
"mfpvr %0\n" |
: "=r" (*info) |
); |
} |
#endif |
/tags/0.2.0/kernel/arch/ppc32/include/atomic.h |
---|
0,0 → 1,88 |
/* |
* 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. |
*/ |
#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/kernel/arch/ppc32/include/barrier.h |
---|
0,0 → 1,39 |
/* |
* 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. |
*/ |
#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/kernel/arch/ppc32/include/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. |
*/ |
#ifndef __ppc32_CONTEXT_H__ |
#define __ppc32_CONTEXT_H__ |
#ifndef __ppc32_TYPES_H__ |
# include <arch/types.h> |
#endif |
#define SP_DELTA 16 |
struct context { |
__address sp; |
__address pc; |
__u32 r2; |
__u32 r13; |
__u32 r14; |
__u32 r15; |
__u32 r16; |
__u32 r17; |
__u32 r18; |
__u32 r19; |
__u32 r20; |
__u32 r21; |
__u32 r22; |
__u32 r23; |
__u32 r24; |
__u32 r25; |
__u32 r26; |
__u32 r27; |
__u32 r28; |
__u32 r29; |
__u32 r30; |
__u32 r31; |
__u32 cr; |
ipl_t ipl; |
} __attribute__ ((packed)); |
#endif |
/tags/0.2.0/kernel/arch/ppc32/include/elf.h |
---|
0,0 → 1,36 |
/* |
* 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. |
*/ |
#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/kernel/arch/ppc32/include/context_offset.h |
---|
0,0 → 1,45 |
/* 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/kernel/arch/ppc32/include/fpu_context.h |
---|
0,0 → 1,58 |
/* |
* 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. |
*/ |
#ifndef __ppc32_FPU_CONTEXT_H__ |
#define __ppc32_FPU_CONTEXT_H__ |
#ifndef __ppc32_TYPES_H__ |
# include <arch/types.h> |
#endif |
struct fpu_context { |
__u64 fr14; |
__u64 fr15; |
__u64 fr16; |
__u64 fr17; |
__u64 fr18; |
__u64 fr19; |
__u64 fr20; |
__u64 fr21; |
__u64 fr22; |
__u64 fr23; |
__u64 fr24; |
__u64 fr25; |
__u64 fr26; |
__u64 fr27; |
__u64 fr28; |
__u64 fr29; |
__u64 fr30; |
__u64 fr31; |
__u32 fpscr; |
} __attribute__ ((packed)); |
#endif |
/tags/0.2.0/kernel/arch/ppc32/include/cpu.h |
---|
0,0 → 1,39 |
/* |
* 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. |
*/ |
#ifndef __ppc32_CPU_H__ |
#define __ppc32_CPU_H__ |
#include <typedefs.h> |
struct cpu_arch { |
int version; |
int revision; |
}; |
#endif |
/tags/0.2.0/kernel/arch/ppc32/include/memstr.h |
---|
0,0 → 1,39 |
/* |
* 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. |
*/ |
#ifndef __ppc32_MEMSTR_H__ |
#define __ppc32_MEMSTR_H__ |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
extern void memsetw(__address dst, size_t cnt, __u16 x); |
extern void memsetb(__address dst, size_t cnt, __u8 x); |
extern int memcmp(__address src, __address dst, int cnt); |
#endif |
/tags/0.2.0/kernel/arch/ppc32/include/debug.h |
---|
0,0 → 1,32 |
/* |
* 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. |
*/ |
#ifndef __ppc32_DEBUG_H__ |
#define __ppc32_DEBUG_H__ |
#endif |
/tags/0.2.0/kernel/arch/ppc32/include/arg.h |
---|
0,0 → 1,34 |
/* |
* 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. |
*/ |
#ifndef __ppc32_ARG_H__ |
#define __ppc32_ARG_H__ |
#include <stdarg.h> |
#endif |
/tags/0.2.0/kernel/arch/ppc32/include/faddr.h |
---|
0,0 → 1,36 |
/* |
* 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. |
*/ |
#ifndef __ppc32_FADDR_H__ |
#define __ppc32_FADDR_H__ |
#include <arch/types.h> |
#define FADDR(fptr) ((__address) (fptr)) |
#endif |
/tags/0.2.0/kernel/arch/ppc32/src/drivers/cuda.c |
---|
0,0 → 1,302 |
/* |
* 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/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 __u8 *cuda = NULL; |
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 __u8 kind, index_t count, ...); |
static void receive_packet(__u8 *kind, index_t count, __u8 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) |
{ |
__u8 kind; |
__u8 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) { |
__u8 scancode = (__u8) scan_code; |
if ((scancode & 0x80) != 0x80) |
chardev_push_character(&kbrd, lchars[scancode & 0x7f]); |
} |
} |
void cuda_init(__address base, size_t size) |
{ |
cuda = (__u8 *) 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 __u8 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/kernel/arch/ppc32/src/drivers/pic.c |
---|
0,0 → 1,85 |
/* |
* 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 <arch/asm.h> |
#include <arch/drivers/pic.h> |
#include <byteorder.h> |
#include <bitops.h> |
static volatile __u32 *pic; |
void pic_init(void) |
{ |
pic = (__u32 *)hw_map(PIC_HW_ADDR, PAGE_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/kernel/arch/ppc32/src/ppc32.c |
---|
0,0 → 1,112 |
/* |
* 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.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; |
__u32 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(); |
cuda_init(bootinfo.keyboard.addr, bootinfo.keyboard.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((__address) kernel_uarg->uspace_uarg, (__address) kernel_uarg->uspace_stack + THREAD_STACK_SIZE - SP_DELTA, (__address) 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/kernel/arch/ppc32/src/exception.S |
---|
0,0 → 1,300 |
# |
# 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: |
CONTEXT_STORE |
lis r12, exc_dispatch@ha |
addi r12, r12, exc_dispatch@l |
mtsrr0 r12 |
li r3, 0 |
b jump_to_kernel |
.org 0x200 |
.global exc_machine_check |
exc_machine_check: |
CONTEXT_STORE |
lis r12, exc_dispatch@ha |
addi r12, r12, exc_dispatch@l |
mtsrr0 r12 |
li r3, 1 |
b jump_to_kernel |
.org 0x300 |
.global exc_data_storage |
exc_data_storage: |
CONTEXT_STORE |
lis r12, exc_dispatch@ha |
addi r12, r12, exc_dispatch@l |
mtsrr0 r12 |
li r3, 2 |
b jump_to_kernel |
.org 0x400 |
.global exc_instruction_storage |
exc_instruction_storage: |
CONTEXT_STORE |
lis r12, exc_dispatch@ha |
addi r12, r12, exc_dispatch@l |
mtsrr0 r12 |
li r3, 3 |
b jump_to_kernel |
.org 0x500 |
.global exc_external |
exc_external: |
CONTEXT_STORE |
lis r12, exc_dispatch@ha |
addi r12, r12, exc_dispatch@l |
mtsrr0 r12 |
li r3, 4 |
b jump_to_kernel |
.org 0x600 |
.global exc_alignment |
exc_alignment: |
CONTEXT_STORE |
lis r12, exc_dispatch@ha |
addi r12, r12, exc_dispatch@l |
mtsrr0 r12 |
li r3, 5 |
b jump_to_kernel |
.org 0x700 |
.global exc_program |
exc_program: |
CONTEXT_STORE |
lis r12, exc_dispatch@ha |
addi r12, r12, exc_dispatch@l |
mtsrr0 r12 |
li r3, 6 |
b jump_to_kernel |
.org 0x800 |
.global exc_fp_unavailable |
exc_fp_unavailable: |
CONTEXT_STORE |
lis r12, exc_dispatch@ha |
addi r12, r12, exc_dispatch@l |
mtsrr0 r12 |
li r3, 7 |
b jump_to_kernel |
.org 0x900 |
.global exc_decrementer |
exc_decrementer: |
CONTEXT_STORE |
lis r12, exc_dispatch@ha |
addi r12, r12, exc_dispatch@l |
mtsrr0 r12 |
li r3, 8 |
b jump_to_kernel |
.org 0xa00 |
.global exc_reserved0 |
exc_reserved0: |
CONTEXT_STORE |
lis r12, exc_dispatch@ha |
addi r12, r12, exc_dispatch@l |
mtsrr0 r12 |
li r3, 9 |
b jump_to_kernel |
.org 0xb00 |
.global exc_reserved1 |
exc_reserved1: |
CONTEXT_STORE |
lis r12, exc_dispatch@ha |
addi r12, r12, exc_dispatch@l |
mtsrr0 r12 |
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 |
lis r12, exc_dispatch@ha |
addi r12, r12, exc_dispatch@l |
mtsrr0 r12 |
li r3, 12 |
b jump_to_kernel |
/tags/0.2.0/kernel/arch/ppc32/src/mm/page.c |
---|
0,0 → 1,299 |
/* |
* 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/mm/page.h> |
#include <genarch/mm/page_pt.h> |
#include <arch/mm/frame.h> |
#include <arch/asm.h> |
#include <arch/interrupt.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, __address badvaddr, int access, |
istate_t *istate, int *pfcr) |
{ |
/* |
* 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)); |
return pte; |
case AS_PF_DEFER: |
page_table_lock(as, lock); |
*pfcr = rc; |
return NULL; |
case AS_PF_FAULT: |
page_table_lock(as, lock); |
printf("Page fault.\n"); |
*pfcr = rc; |
return NULL; |
default: |
panic("unexpected rc (%d)\n", rc); |
} |
} |
} |
static void pht_refill_fail(__address 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 __address vaddr, const pfn_t pfn) |
{ |
__u32 page = (vaddr >> 12) & 0xffff; |
__u32 api = (vaddr >> 22) & 0x3f; |
__u32 vsid; |
asm volatile ( |
"mfsrin %0, %1\n" |
: "=r" (vsid) |
: "r" (vaddr) |
); |
/* Primary hash (xor) */ |
__u32 h = 0; |
__u32 hash = vsid ^ page; |
__u32 base = (hash & 0x3ff) << 3; |
__u32 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) */ |
__u32 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(int n, istate_t *istate) |
{ |
__address badvaddr; |
pte_t *pte; |
int pfcr; |
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, &pfcr); |
if (!pte) { |
switch (pfcr) { |
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", pfcr); |
} |
} |
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((__address) phte, 1 << PHT_BITS, 0); |
} |
void page_arch_init(void) |
{ |
if (config.cpu_active == 1) { |
page_mapping_operations = &pt_mapping_operations; |
__address 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 *) PFN2ADDR(frame_alloc(PHT_ORDER, FRAME_KA | FRAME_PANIC)); |
phte = (phte_t *) PA2KA((__address) physical_phte); |
ASSERT((__address) physical_phte % (1 << PHT_BITS) == 0); |
pht_init(); |
asm volatile ( |
"mtsdr1 %0\n" |
: |
: "r" ((__address) physical_phte) |
); |
} |
} |
__address hw_map(__address 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) |
__address 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/kernel/arch/ppc32/src/mm/tlb.c |
---|
0,0 → 1,77 |
/* |
* 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 <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, __address page, count_t cnt) |
{ |
tlb_invalidate_all(); |
} |
/** Print contents of Page Hash Table. */ |
void tlb_print(void) |
{ |
} |
/tags/0.2.0/kernel/arch/ppc32/src/mm/frame.c |
---|
0,0 → 1,62 |
/* |
* 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/boot/boot.h> |
#include <arch/mm/frame.h> |
#include <arch/mm/memory_init.h> |
#include <mm/frame.h> |
#include <align.h> |
#include <macros.h> |
__address 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/kernel/arch/ppc32/src/mm/memory_init.c |
---|
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. |
*/ |
#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/kernel/arch/ppc32/src/mm/as.c |
---|
0,0 → 1,36 |
/* |
* 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 <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/kernel/arch/ppc32/src/interrupt.c |
---|
0,0 → 1,87 |
/* |
* 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 <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> |
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(__native irq) |
{ |
int_register(irq, "ipc_int", ipc_int); |
} |
/tags/0.2.0/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/kernel/arch/ppc32/src/proc/scheduler.c |
---|
0,0 → 1,54 |
/* |
* Copyright (C) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include <arch/mm/page.h> |
#include <arch/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) |
{ |
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/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/kernel/arch/ppc32/src/ddi/ddi.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. |
*/ |
#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, __address ioaddr, size_t size) |
{ |
return 0; |
} |
/tags/0.2.0/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 |
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/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/kernel/arch/ppc32/src/cpu/cpu.c |
---|
0,0 → 1,54 |
/* |
* 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/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/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/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/kernel/arch/ppc32/Makefile.inc |
---|
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. |
# |
## Toolchain configuration |
# |
BFD_NAME = elf32-powerpc |
BFD_ARCH = powerpc:common |
BFD = binary |
TARGET = ppc-linux-gnu |
TOOLCHAIN_DIR = /usr/local/ppc/bin |
## Make some default assumptions |
# |
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 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/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/kernel/arch/ia64/include/interrupt.h |
---|
0,0 → 1,138 |
/* |
* 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. |
*/ |
#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; |
__address ar_bsp; |
__address ar_bspstore; |
__address ar_bspstore_new; |
__u64 ar_rnat; |
__u64 ar_ifs; |
__u64 ar_pfs; |
__u64 ar_rsc; |
__address cr_ifa; |
cr_isr_t cr_isr; |
__address cr_iipa; |
psr_t cr_ipsr; |
__address cr_iip; |
__u64 pr; |
__address sp; |
/* |
* The following variables are defined only for break_instruction handler. |
*/ |
__u64 in0; |
__u64 in1; |
__u64 in2; |
__u64 in3; |
__u64 in4; |
}; |
static inline void istate_set_retaddr(istate_t *istate, __address retaddr) |
{ |
istate->cr_iip = retaddr; |
istate->cr_ipsr.ri = 0; /* return to instruction slot #0 */ |
} |
static inline __native 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(__u64 vector, istate_t *istate); |
extern int break_instruction(__u64 vector, istate_t *istate); |
extern void universal_handler(__u64 vector, istate_t *istate); |
extern void nop_handler(__u64 vector, istate_t *istate); |
extern void external_interrupt(__u64 vector, istate_t *istate); |
extern void virtual_interrupt(__u64 irq, void *param); |
extern void disabled_fp_register(__u64 vector, istate_t *istate); |
#endif |
/tags/0.2.0/kernel/arch/ia64/include/proc/task.h |
---|
0,0 → 1,38 |
/* |
* 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. |
*/ |
#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/kernel/arch/ia64/include/proc/thread.h |
---|
0,0 → 1,37 |
/* |
* 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. |
*/ |
#ifndef __ia64_THREAD_H__ |
#define __ia64_THREAD_H__ |
typedef struct { |
} thread_arch_t; |
#define thread_create_arch(t) |
#endif |
/tags/0.2.0/kernel/arch/ia64/include/mm/as.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. |
*/ |
#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/kernel/arch/ia64/include/mm/vhpt.h |
---|
0,0 → 1,54 |
/* |
* 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. |
*/ |
#ifndef __ia64_VHPT_H__ |
#define __ia64_VHPT_H__ |
#include <arch/mm/tlb.h> |
#include <arch/mm/page.h> |
__address 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(__address 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/kernel/arch/ia64/include/mm/page.h |
---|
0,0 → 1,274 |
/* |
* 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. |
*/ |
#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) ((__address) (x-(VRN_KERNEL<<VRN_SHIFT))) |
#define PA2KA(x) ((__address) (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 */ |
__u64 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 */ |
__u64 ig3 : 64; |
} __attribute__ ((packed)); |
typedef union vhpt_entry { |
struct vhpt_entry_present present; |
struct vhpt_entry_not_present not_present; |
__u64 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; |
__u64 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 __u64 thash(__u64 va) |
{ |
__u64 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 __u64 ttag(__u64 va) |
{ |
__u64 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 __u64 rr_read(index_t i) |
{ |
__u64 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, __u64 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 __u64 pta_read(void) |
{ |
__u64 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(__u64 v) |
{ |
__asm__ volatile ("mov cr.pta = %0\n" : : "r" (v)); |
} |
extern void page_arch_init(void); |
extern vhpt_entry_t *vhpt_hash(__address page, asid_t asid); |
extern bool vhpt_compare(__address page, asid_t asid, vhpt_entry_t *v); |
extern void vhpt_set_record(vhpt_entry_t *v, __address page, asid_t asid, __address frame, int flags); |
#endif /* __ASM__ */ |
#endif /* KERNEL */ |
#endif |
/tags/0.2.0/kernel/arch/ia64/include/mm/tlb.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. |
*/ |
#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 { |
__u64 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(__address va, asid_t asid, tlb_entry_t entry, bool dtc); |
extern void dtc_mapping_insert(__address va, asid_t asid, tlb_entry_t entry); |
extern void itc_mapping_insert(__address va, asid_t asid, tlb_entry_t entry); |
extern void tr_mapping_insert(__address va, asid_t asid, tlb_entry_t entry, bool dtr, index_t tr); |
extern void dtr_mapping_insert(__address va, asid_t asid, tlb_entry_t entry, index_t tr); |
extern void itr_mapping_insert(__address va, asid_t asid, tlb_entry_t entry, index_t tr); |
extern void dtlb_kernel_mapping_insert(__address page, __address frame, bool dtr, index_t tr); |
extern void dtc_pte_copy(pte_t *t); |
extern void itc_pte_copy(pte_t *t); |
extern void alternate_instruction_tlb_fault(__u64 vector, istate_t *istate); |
extern void alternate_data_tlb_fault(__u64 vector, istate_t *istate); |
extern void data_nested_tlb_fault(__u64 vector, istate_t *istate); |
extern void data_dirty_bit_fault(__u64 vector, istate_t *istate); |
extern void instruction_access_bit_fault(__u64 vector, istate_t *istate); |
extern void data_access_bit_fault(__u64 vector, istate_t *istate); |
extern void page_not_present(__u64 vector, istate_t *istate); |
#endif |
/tags/0.2.0/kernel/arch/ia64/include/mm/frame.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. |
*/ |
#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/kernel/arch/ia64/include/mm/memory_init.h |
---|
0,0 → 1,36 |
/* |
* 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. |
*/ |
#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/kernel/arch/ia64/include/mm/asid.h |
---|
0,0 → 1,57 |
/* |
* 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. |
*/ |
#ifndef __ia64_ASID_H__ |
#define __ia64_ASID_H__ |
#ifndef __ASM__ |
#include <arch/types.h> |
typedef __u16 asid_t; |
typedef __u32 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/kernel/arch/ia64/include/ski/ski.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. |
*/ |
#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/kernel/arch/ia64/include/arch.h |
---|
0,0 → 1,36 |
/* |
* 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. |
*/ |
#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/kernel/arch/ia64/include/asm.h |
---|
0,0 → 1,276 |
/* |
* 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. |
*/ |
#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 __address get_stack_base(void) |
{ |
__u64 v; |
__asm__ volatile ("and %0 = %1, r12" : "=r" (v) : "r" (~(STACK_SIZE-1))); |
return v; |
} |
/** Return Processor State Register. |
* |
* @return PSR. |
*/ |
static inline __u64 psr_read(void) |
{ |
__u64 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 __u64 iva_read(void) |
{ |
__u64 v; |
__asm__ volatile ("mov %0 = cr.iva\n" : "=r" (v)); |
return v; |
} |
/** Write IVA (Interruption Vector Address) register. |
* |
* @param New location of interruption vector table. |
*/ |
static inline void iva_write(__u64 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 __u64 ivr_read(void) |
{ |
__u64 v; |
__asm__ volatile ("mov %0 = cr.ivr\n" : "=r" (v)); |
return v; |
} |
/** Write ITC (Interval Timer Counter) register. |
* |
* @param New counter value. |
*/ |
static inline void itc_write(__u64 v) |
{ |
__asm__ volatile ("mov ar.itc = %0\n" : : "r" (v)); |
} |
/** Read ITC (Interval Timer Counter) register. |
* |
* @return Current counter value. |
*/ |
static inline __u64 itc_read(void) |
{ |
__u64 v; |
__asm__ volatile ("mov %0 = ar.itc\n" : "=r" (v)); |
return v; |
} |
/** Write ITM (Interval Timer Match) register. |
* |
* @param New match value. |
*/ |
static inline void itm_write(__u64 v) |
{ |
__asm__ volatile ("mov cr.itm = %0\n" : : "r" (v)); |
} |
/** Read ITM (Interval Timer Match) register. |
* |
* @return Match value. |
*/ |
static inline __u64 itm_read(void) |
{ |
__u64 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 __u64 itv_read(void) |
{ |
__u64 v; |
__asm__ volatile ("mov %0 = cr.itv\n" : "=r" (v)); |
return v; |
} |
/** Write ITV (Interval Timer Vector) register. |
* |
* @param New vector and mask bit. |
*/ |
static inline void itv_write(__u64 v) |
{ |
__asm__ volatile ("mov cr.itv = %0\n" : : "r" (v)); |
} |
/** Write EOI (End Of Interrupt) register. |
* |
* @param This value is ignored. |
*/ |
static inline void eoi_write(__u64 v) |
{ |
__asm__ volatile ("mov cr.eoi = %0\n" : : "r" (v)); |
} |
/** Read TPR (Task Priority Register). |
* |
* @return Current value of TPR. |
*/ |
static inline __u64 tpr_read(void) |
{ |
__u64 v; |
__asm__ volatile ("mov %0 = cr.tpr\n" : "=r" (v)); |
return v; |
} |
/** Write TPR (Task Priority Register). |
* |
* @param New value of TPR. |
*/ |
static inline void tpr_write(__u64 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) |
{ |
__u64 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) |
{ |
__u64 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(__u32 t); |
extern void switch_to_userspace(__address entry, __address sp, __address bsp, __address uspace_uarg, __u64 ipsr, __u64 rsc); |
#endif |
/tags/0.2.0/kernel/arch/ia64/include/context.h |
---|
0,0 → 1,127 |
/* |
* 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. |
*/ |
#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 = (__address) _pc; \ |
(c)->bsp = ((__address) stack) + ALIGN_UP((size), REGISTER_STACK_ALIGNMENT); \ |
(c)->ar_pfs &= PFM_MASK; \ |
(c)->sp = ((__address) stack) + ALIGN_UP((size), STACK_ALIGNMENT) - SP_DELTA; \ |
} while (0); |
/* |
* Only save registers that must be preserved across |
* function calls. |
*/ |
struct context { |
/* |
* Application registers |
*/ |
__u64 ar_pfs; |
__u64 ar_unat_caller; |
__u64 ar_unat_callee; |
__u64 ar_rsc; |
__address bsp; /* ar_bsp */ |
__u64 ar_rnat; |
__u64 ar_lc; |
/* |
* General registers |
*/ |
__u64 r1; |
__u64 r4; |
__u64 r5; |
__u64 r6; |
__u64 r7; |
__address sp; /* r12 */ |
__u64 r13; |
/* |
* Branch registers |
*/ |
__address pc; /* b0 */ |
__u64 b1; |
__u64 b2; |
__u64 b3; |
__u64 b4; |
__u64 b5; |
/* |
* Predicate registers |
*/ |
__u64 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/kernel/arch/ia64/include/faddr.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. |
*/ |
#ifndef __ia64_FADDR_H__ |
#define __ia64_FADDR_H__ |
#include <arch/types.h> |
/** |
* |
* Calculate absolute address of function |
* referenced by fptr pointer. |
* |
* @param fptr Function pointer. |
* |
*/ |
#define FADDR(f) (*((__address *)(f))); |
#endif |
/tags/0.2.0/kernel/arch/ia64/include/atomic.h |
---|
0,0 → 1,57 |
/* |
* 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. |
*/ |
#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/kernel/arch/ia64/include/fpu_context.h |
---|
0,0 → 1,44 |
/* |
* 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. |
*/ |
#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/kernel/arch/ia64/include/register.h |
---|
0,0 → 1,269 |
/* |
* 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. |
*/ |
#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 { |
__u64 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 { |
__u64 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 { |
__u8 vector; |
__u64 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)); |
__u64 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)); |
__u64 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)); |
__u16 code; |
}; |
__u8 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)); |
__u64 value; |
}; |
typedef union cr_isr cr_isr_t; |
/** CPUID Register 3 */ |
union cpuid3 { |
struct { |
__u8 number; |
__u8 revision; |
__u8 model; |
__u8 family; |
__u8 archrev; |
} __attribute__ ((packed)); |
__u64 value; |
}; |
typedef union cpuid3 cpuid3_t; |
#endif /* !__ASM__ */ |
#endif |
/tags/0.2.0/kernel/arch/ia64/include/types.h |
---|
0,0 → 1,62 |
/* |
* Copyright (C) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#ifndef __TYPES_H__ |
#define __TYPES_H__ |
#define NULL 0 |
typedef signed char __s8; |
typedef signed short int __s16; |
typedef signed int __s32; |
typedef signed long __s64; |
typedef unsigned char __u8; |
typedef unsigned short __u16; |
typedef unsigned int __u32; |
typedef unsigned long __u64; |
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 __u64 __address; |
typedef __u64 pfn_t; |
typedef __u64 ipl_t; |
typedef __u64 __native; |
typedef __s64 __snative; |
typedef struct pte pte_t; |
#endif |
/tags/0.2.0/kernel/arch/ia64/include/elf.h |
---|
0,0 → 1,36 |
/* |
* 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. |
*/ |
#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/kernel/arch/ia64/include/pal/pal.h |
---|
0,0 → 1,101 |
/* |
* 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. |
*/ |
#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/kernel/arch/ia64/include/memstr.h |
---|
0,0 → 1,39 |
/* |
* 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. |
*/ |
#ifndef __ia64_MEMSTR_H__ |
#define __ia64_MEMSTR_H__ |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
extern void memsetw(__address dst, size_t cnt, __u16 x); |
extern void memsetb(__address dst, size_t cnt, __u8 x); |
extern int memcmp(__address src, __address dst, int cnt); |
#endif |
/tags/0.2.0/kernel/arch/ia64/include/debug.h |
---|
0,0 → 1,32 |
/* |
* 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. |
*/ |
#ifndef __ia64_DEBUG_H__ |
#define __ia64_DEBUG_H__ |
#endif |
/tags/0.2.0/kernel/arch/ia64/include/drivers/it.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. |
*/ |
#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/kernel/arch/ia64/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. |
*/ |
#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 { |
__u64 cpuid0; |
__u64 cpuid1; |
cpuid3_t cpuid3; |
}; |
/** Read CPUID register. |
* |
* @param n CPUID register number. |
* |
* @return Value of CPUID[n] register. |
*/ |
static inline __u64 cpuid_read(int n) |
{ |
__u64 v; |
__asm__ volatile ("mov %0 = cpuid[%1]\n" : "=r" (v) : "r" (n)); |
return v; |
} |
#endif |
/tags/0.2.0/kernel/arch/ia64/include/stack.h |
---|
0,0 → 1,37 |
/* |
* 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. |
*/ |
#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/kernel/arch/ia64/include/barrier.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. |
*/ |
#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/kernel/arch/ia64/include/byteorder.h |
---|
0,0 → 1,36 |
/* |
* 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. |
*/ |
#ifndef __ia64_BYTEORDER_H__ |
#define __ia64_BYTEORDER_H__ |
/* IA-64 is little-endian */ |
#define __native_le2host(n) (n) |
#define __u64_le2host(n) (n) |
#endif |
/tags/0.2.0/kernel/arch/ia64/include/arg.h |
---|
0,0 → 1,34 |
/* |
* 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. |
*/ |
#ifndef __ia64_ARG_H__ |
#define __ia64_ARG_H__ |
#include <stdarg.h> |
#endif |
/tags/0.2.0/kernel/arch/ia64/include/smp/atomic.h |
---|
--- arch/ia64/src/mm/tlb.c (nonexistent) |
+++ arch/ia64/src/mm/tlb.c (revision 4036) |
@@ -0,0 +1,669 @@ |
+/* |
+ * 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. |
+ */ |
+ |
+/* |
+ * 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; |
+ __address adr; |
+ __u32 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, __address page, count_t cnt) |
+{ |
+ region_register rr; |
+ bool restore_rr = false; |
+ int b = 0; |
+ int c = cnt; |
+ |
+ __address 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; |
+ __u64 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(__address 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(__address 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(__address 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(__address 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(__address 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 dtc If true, insert into data translation register, use instruction translation register otherwise. |
+ * @param tr Translation register. |
+ */ |
+void tr_mapping_insert(__address 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 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 data translation cache otherwise. |
+ * @param tr Translation register if dtr is true, ignored otherwise. |
+ */ |
+void dtlb_kernel_mapping_insert(__address page, __address 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); |
+} |
+ |
+/** 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(__u64 vector, istate_t *istate) |
+{ |
+ region_register rr; |
+ rid_t rid; |
+ __address 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(__u64 vector, istate_t *istate) |
+{ |
+ region_register rr; |
+ rid_t rid; |
+ __address 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(__u64 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(__u64 vector, istate_t *istate) |
+{ |
+ region_register rr; |
+ rid_t rid; |
+ __address 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(__u64 vector, istate_t *istate) |
+{ |
+ region_register rr; |
+ rid_t rid; |
+ __address 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(__u64 vector, istate_t *istate) |
+{ |
+ region_register rr; |
+ rid_t rid; |
+ __address 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(__u64 vector, istate_t *istate) |
+{ |
+ region_register rr; |
+ rid_t rid; |
+ __address 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/kernel/arch/ia64/src/mm/vhpt.c |
---|
0,0 → 1,88 |
/* |
* 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. |
*/ |
#include <arch/mm/vhpt.h> |
#include <mm/frame.h> |
#include <print.h> |
static vhpt_entry_t* vhpt_base; |
__address vhpt_set_up(void) |
{ |
vhpt_base=(vhpt_entry_t*) PA2KA(PFN2ADDR(frame_alloc(VHPT_WIDTH-FRAME_WIDTH,FRAME_KA))); |
if(!vhpt_base) panic("Kernel configured with VHPT but no memory for table."); |
vhpt_invalidate_all(); |
return (__address) vhpt_base; |
} |
void vhpt_mapping_insert(__address va, asid_t asid, tlb_entry_t entry) |
{ |
region_register rr_save, rr; |
index_t vrn; |
rid_t rid; |
__u64 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((__address)vhpt_base,1<<VHPT_WIDTH,0); |
} |
void vhpt_invalidate_asid(asid_t asid) |
{ |
vhpt_invalidate_all(); |
} |
/tags/0.2.0/kernel/arch/ia64/src/mm/page.c |
---|
0,0 → 1,258 |
/* |
* 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. |
*/ |
#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 |
__address 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(__address 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(__address 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 t 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, __address page, asid_t asid, __address frame, int flags) |
{ |
region_register rr_save, rr; |
index_t vrn; |
rid_t rid; |
__u64 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/kernel/arch/ia64/src/mm/as.c |
---|
0,0 → 1,80 |
/* |
* 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 <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/kernel/arch/ia64/src/mm/frame.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. |
*/ |
#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/kernel/arch/ia64/src/interrupt.c |
---|
0,0 → 1,274 |
/* |
* 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. |
* |
*/ |
#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(__u16 vector); |
static void dump_interrupted_context(istate_t *istate); |
char *vector_to_string(__u16 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(__u64 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(__u64 vector, istate_t *istate) |
{ |
#ifdef CONFIG_FPU_LAZY |
scheduler_fpu_lazy_request(); |
#else |
fault_if_from_uspace(istate, "Interruption: %#hx (%s)", (__u16) vector, vector_to_string(vector)); |
dump_interrupted_context(istate); |
panic("Interruption: %#hx (%s)\n", (__u16) vector, vector_to_string(vector)); |
#endif |
} |
void nop_handler(__u64 vector, istate_t *istate) |
{ |
} |
/** Handle syscall. */ |
int break_instruction(__u64 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(__u64 vector, istate_t *istate) |
{ |
fault_if_from_uspace(istate,"Interruption: %#hx (%s)\n",(__u16) vector, vector_to_string(vector)); |
dump_interrupted_context(istate); |
panic("Interruption: %#hx (%s)\n", (__u16) vector, vector_to_string(vector)); |
} |
void external_interrupt(__u64 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(__u64 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(__native irq) |
{ |
if(irq==IRQ_KBD) { |
kbd_uspace=1; |
return; |
} |
return; |
panic("not implemented\n"); |
/* TODO */ |
} |
/tags/0.2.0/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/kernel/arch/ia64/src/ia64.c |
---|
0,0 → 1,147 |
/* |
* 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.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((__address) &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((__address) kernel_uarg->uspace_entry, |
((__address) kernel_uarg->uspace_stack)+PAGE_SIZE-ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT), |
((__address) kernel_uarg->uspace_stack)+PAGE_SIZE, |
(__address) 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. |
*/ |
__native sys_tls_set(__native 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/kernel/arch/ia64/src/ski/ski.c |
---|
0,0 → 1,195 |
/* |
* 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/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 __s32 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. |
*/ |
__s32 ski_getchar(void) |
{ |
__u64 ch; |
__asm__ volatile ( |
"mov r15=%1\n" |
"break 0x80000;;\n" /* modifies r8 */ |
"mov %0=r8;;\n" |
: "=r" (ch) |
: "i" (SKI_GETCHAR) |
: "r15", "r8" |
); |
return (__s32) 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/kernel/arch/ia64/src/drivers/it.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. |
*/ |
/** 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) |
{ |
__s64 c; |
__s64 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/kernel/arch/ia64/src/ddi/ddi.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. |
*/ |
#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, __address ioaddr, size_t size) |
{ |
return 0; |
} |
/tags/0.2.0/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/kernel/arch/ia64/src/proc/scheduler.c |
---|
0,0 → 1,78 |
/* |
* 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 <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) |
{ |
__address base; |
base = ALIGN_DOWN(config.base, 1<<KERNEL_PAGE_WIDTH); |
if ((__address) THREAD->kstack < base || (__address) 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. |
*/ |
dtlb_kernel_mapping_insert((__address) THREAD->kstack, KA2PA(THREAD->kstack), true, DTR_KSTACK1); |
dtlb_kernel_mapping_insert((__address) 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/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/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/kernel/arch/ia64/src/fpu_context.c |
---|
0,0 → 1,475 |
/* |
* 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 <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) |
{ |
__u64 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) |
{ |
__u64 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) |
{ |
__u64 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/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/kernel/arch/ia64/src/putchar.c |
---|
0,0 → 1,35 |
/* |
* 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 <putchar.h> |
#include <arch/ski/ski.h> |
void putchar(const char ch) |
{ |
ski_write(ch); |
} |
/tags/0.2.0/kernel/arch/ia64/src/cpu/cpu.c |
---|
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. |
*/ |
#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(__u64)+1]; |
*((__u64 *) &vendor[0*sizeof(__u64)]) = CPU->arch.cpuid0; |
*((__u64 *) &vendor[1*sizeof(__u64)]) = 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/kernel/arch/ia64/Makefile.inc |
---|
0,0 → 1,86 |
# |
# 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 |
## Make some default assumptions |
# |
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/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/kernel/arch/sparc64/include/interrupt.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. |
*/ |
#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, __address retaddr) |
{ |
/* TODO */ |
} |
static inline int istate_from_uspace(istate_t *istate) |
{ |
/* TODO */ |
return 0; |
} |
static inline __native 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/kernel/arch/sparc64/include/proc/task.h |
---|
0,0 → 1,38 |
/* |
* 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. |
*/ |
#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/kernel/arch/sparc64/include/proc/thread.h |
---|
0,0 → 1,37 |
/* |
* 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. |
*/ |
#ifndef __sparc64_THREAD_H__ |
#define __sparc64_THREAD_H__ |
typedef struct { |
} thread_arch_t; |
#define thread_create_arch(t) |
#endif |
/tags/0.2.0/kernel/arch/sparc64/include/mm/as.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. |
*/ |
#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/kernel/arch/sparc64/include/mm/page.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. |
*/ |
#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) ((__address) (x)) |
#define PA2KA(x) ((__address) (x)) |
union page_address { |
__address address; |
struct { |
__u64 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/kernel/arch/sparc64/include/mm/frame.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. |
*/ |
#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 { |
__address address; |
struct { |
unsigned : 23; |
__u64 pfn : 28; /**< Physical Frame Number. */ |
unsigned offset : 13; /**< Offset. */ |
} __attribute__ ((packed)); |
}; |
typedef union frame_address frame_address_t; |
extern void frame_arch_init(void); |
#endif |
#endif |
#endif |
/tags/0.2.0/kernel/arch/sparc64/include/mm/tlb.h |
---|
0,0 → 1,413 |
/* |
* 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. |
*/ |
#ifndef __sparc64_TLB_H__ |
#define __sparc64_TLB_H__ |
#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> |
#define ITLB_ENTRY_COUNT 64 |
#define DTLB_ENTRY_COUNT 64 |
/** 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 */ |
union tlb_context_reg { |
__u64 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 { |
__u64 value; |
struct { |
__u64 : 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 { |
__u64 value; |
struct { |
__u64 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 types. */ |
#define TLB_DEMAP_PAGE 0 |
#define TLB_DEMAP_CONTEXT 1 |
/** TLB Demap Operation Context register encodings. */ |
#define TLB_DEMAP_PRIMARY 0 |
#define TLB_DEMAP_SECONDARY 1 |
#define TLB_DEMAP_NUCLEUS 2 |
/** TLB Demap Operation Address. */ |
union tlb_demap_addr { |
__u64 value; |
struct { |
__u64 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 { |
__u64 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 __u64 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(__u64 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 __u64 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(__u64 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 __u64 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, __u64 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 __u64 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, __u64 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); |
flush(); |
} |
/** Read IMMU TLB Tag Read Register. |
* |
* @param entry TLB Entry index. |
* |
* @return Current value of specified IMMU TLB Tag Read Register. |
*/ |
static inline __u64 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 __u64 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(__u64 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 __u64 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(__u64 v) |
{ |
asi_u64_write(ASI_DMMU, VA_DMMU_TAG_ACCESS, v); |
flush(); |
} |
/** Read DMMU TLB Tag Access Register. |
* |
* @return Current value of DMMU TLB Tag Access Register. |
*/ |
static inline __u64 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(__u64 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(__u64 v) |
{ |
asi_u64_write(ASI_DTLB_DATA_IN_REG, 0, v); |
flush(); |
} |
/** Read ITLB Synchronous Fault Status Register. |
* |
* @return Current content of I-SFSR register. |
*/ |
static inline __u64 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(__u64 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 __u64 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(__u64 v) |
{ |
asi_u64_write(ASI_DMMU, VA_DMMU_SFSR, v); |
flush(); |
} |
/** Read DTLB Synchronous Fault Address Register. |
* |
* @return Current content of D-SFAR register. |
*/ |
static inline __u64 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, __address 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); |
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, __address 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); |
flush(); |
} |
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(__address page, __address frame, int pagesize, bool locked, bool cacheable); |
#endif |
/tags/0.2.0/kernel/arch/sparc64/include/mm/memory_init.h |
---|
0,0 → 1,36 |
/* |
* 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. |
*/ |
#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/kernel/arch/sparc64/include/mm/mmu.h |
---|
0,0 → 1,127 |
/* |
* 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. |
*/ |
#ifndef __sparc64_MMU_H__ |
#define __sparc64_MMU_H__ |
#include <arch/asm.h> |
#include <arch/barrier.h> |
#include <arch/types.h> |
#include <typedefs.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. */ |
/** LSU Control Register. */ |
union lsu_cr_reg { |
__u64 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; |
#define immu_enable() immu_set(true) |
#define immu_disable() immu_set(false) |
#define dmmu_enable() dmmu_set(true) |
#define dmmu_disable() dmmu_set(false) |
/** Disable or Enable IMMU. */ |
static inline void immu_set(bool enable) |
{ |
lsu_cr_reg_t cr; |
cr.value = asi_u64_read(ASI_LSU_CONTROL_REG, 0); |
cr.im = enable; |
asi_u64_write(ASI_LSU_CONTROL_REG, 0, cr.value); |
membar(); |
} |
/** Disable or Enable DMMU. */ |
static inline void dmmu_set(bool enable) |
{ |
lsu_cr_reg_t cr; |
cr.value = asi_u64_read(ASI_LSU_CONTROL_REG, 0); |
cr.dm = enable; |
asi_u64_write(ASI_LSU_CONTROL_REG, 0, cr.value); |
membar(); |
} |
#endif |
/tags/0.2.0/kernel/arch/sparc64/include/mm/asid.h |
---|
0,0 → 1,41 |
/* |
* 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. |
*/ |
#ifndef __sparc64_ASID_H__ |
#define __sparc64_ASID_H__ |
#include <arch/types.h> |
/* |
* On SPARC, Context means the same thing as ASID trough out the kernel. |
*/ |
typedef __u16 asid_t; |
#define ASID_MAX_ARCH 8191 /* 2^13 - 1 */ |
#endif |
/tags/0.2.0/kernel/arch/sparc64/include/mm/tte.h |
---|
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. |
*/ |
#ifndef __sparc64_TTE_H__ |
#define __sparc64_TTE_H__ |
#include <arch/types.h> |
/** Translation Table Entry - Tag. */ |
union tte_tag { |
__u64 value; |
struct { |
unsigned g : 1; /**< Global. */ |
unsigned : 2; /**< Reserved. */ |
unsigned context : 13; /**< Context identifier. */ |
unsigned : 6; /**< Reserved. */ |
__u64 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 { |
__u64 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 |
/tags/0.2.0/kernel/arch/sparc64/include/drivers/i8042.h |
---|
0,0 → 1,66 |
/* |
* 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. |
*/ |
#ifndef __sparc64_I8042_H__ |
#define __sparc64_I8042_H__ |
#include <arch/types.h> |
#define KBD_PHYS_ADDRESS 0x1fff8904000ULL |
#define STATUS_REG 4 |
#define COMMAND_REG 4 |
#define DATA_REG 6 |
#define LAST_REG DATA_REG |
extern volatile __u8 *kbd_virt_address; |
static inline void i8042_data_write(__u8 data) |
{ |
kbd_virt_address[DATA_REG] = data; |
} |
static inline __u8 i8042_data_read(void) |
{ |
return kbd_virt_address[DATA_REG]; |
} |
static inline __u8 i8042_status_read(void) |
{ |
return kbd_virt_address[STATUS_REG]; |
} |
static inline void i8042_command_write(__u8 command) |
{ |
kbd_virt_address[COMMAND_REG] = command; |
} |
extern void kbd_init(void); |
#endif |
/tags/0.2.0/kernel/arch/sparc64/include/drivers/fb.h |
---|
0,0 → 1,39 |
/* |
* 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. |
*/ |
#ifndef __sparc64_FB_H__ |
#define __sparc64_FB_H__ |
#define FB_PHYS_ADDRESS 0x1c901000000ULL |
#define FB_X_RES 1152 |
#define FB_Y_RES 900 |
#define FB_COLOR_DEPTH 8 |
#endif |
/tags/0.2.0/kernel/arch/sparc64/include/drivers/tick.h |
---|
0,0 → 1,39 |
/* |
* 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. |
*/ |
#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/kernel/arch/sparc64/include/atomic.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. |
*/ |
#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) |
{ |
__u64 a, b; |
volatile __u64 x = (__u64) &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" (*((__u64 *)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/kernel/arch/sparc64/include/types.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. |
*/ |
#ifndef __sparc64_TYPES_H__ |
#define __sparc64_TYPES_H__ |
#define NULL 0 |
typedef signed char __s8; |
typedef signed short __s16; |
typedef signed int __s32; |
typedef signed long __s64; |
typedef unsigned char __u8; |
typedef unsigned short __u16; |
typedef unsigned int __u32; |
typedef unsigned long __u64; |
typedef __u64 __address; |
typedef __u64 pfn_t; |
typedef __u64 ipl_t; |
typedef __u64 __native; |
typedef __s64 __snative; |
typedef struct pte pte_t; |
typedef __u8 asi_t; |
#endif |
/tags/0.2.0/kernel/arch/sparc64/include/elf.h |
---|
0,0 → 1,36 |
/* |
* 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. |
*/ |
#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/kernel/arch/sparc64/include/trap/exception.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. |
*/ |
#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/kernel/arch/sparc64/include/trap/mmu.h |
---|
0,0 → 1,70 |
/* |
* 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. |
*/ |
/** |
* 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/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. |
*/ |
#ifndef __sparc64_TRAP_H__ |
#define __sparc64_TRAP_H__ |
#include <arch/trap/trap_table.h> |
#include <arch/asm.h> |
/** Switch to in-kernel trap table. */ |
static inline void trap_switch_trap_table(void) |
{ |
/* Point TBA to kernel copy of OFW's trap table. */ |
tba_write((__u64) trap_table); |
} |
extern void trap_init(void); |
#endif |
/tags/0.2.0/kernel/arch/sparc64/include/trap/interrupt.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. |
*/ |
/** |
* 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/kernel/arch/sparc64/include/trap/trap_table.h |
---|
0,0 → 1,92 |
/* |
* 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. |
*/ |
#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 { |
__u8 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/kernel/arch/sparc64/include/trap/regwin.h |
---|
0,0 → 1,133 |
/* |
* 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 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/kernel/arch/sparc64/include/console.h |
---|
0,0 → 1,37 |
/* |
* 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. |
*/ |
#ifndef __sparc64_CONSOLE_H__ |
#define __sparc64_CONSOLE_H__ |
extern void kofwinput(void *arg); |
extern void kkbdpoll(void *arg); |
extern void ofw_sparc64_console_init(void); |
extern void standalone_sparc64_console_init(void); |
#endif |
/tags/0.2.0/kernel/arch/sparc64/include/asm.h |
---|
0,0 → 1,307 |
/* |
* 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. |
*/ |
#ifndef __sparc64_ASM_H__ |
#define __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 __u64 pstate_read(void) |
{ |
__u64 v; |
__asm__ volatile ("rdpr %%pstate, %0\n" : "=r" (v)); |
return v; |
} |
/** Write Processor State register. |
* |
* @param New value of PSTATE register. |
*/ |
static inline void pstate_write(__u64 v) |
{ |
__asm__ volatile ("wrpr %0, %1, %%pstate\n" : : "r" (v), "i" (0)); |
} |
/** Read TICK_compare Register. |
* |
* @return Value of TICK_comapre register. |
*/ |
static inline __u64 tick_compare_read(void) |
{ |
__u64 v; |
__asm__ volatile ("rd %%tick_cmpr, %0\n" : "=r" (v)); |
return v; |
} |
/** Write TICK_compare Register. |
* |
* @param New value of TICK_comapre register. |
*/ |
static inline void tick_compare_write(__u64 v) |
{ |
__asm__ volatile ("wr %0, %1, %%tick_cmpr\n" : : "r" (v), "i" (0)); |
} |
/** Read TICK Register. |
* |
* @return Value of TICK register. |
*/ |
static inline __u64 tick_read(void) |
{ |
__u64 v; |
__asm__ volatile ("rdpr %%tick, %0\n" : "=r" (v)); |
return v; |
} |
/** Write TICK Register. |
* |
* @param New value of TICK register. |
*/ |
static inline void tick_write(__u64 v) |
{ |
__asm__ volatile ("wrpr %0, %1, %%tick\n" : : "r" (v), "i" (0)); |
} |
/** Read SOFTINT Register. |
* |
* @return Value of SOFTINT register. |
*/ |
static inline __u64 softint_read(void) |
{ |
__u64 v; |
__asm__ volatile ("rd %%softint, %0\n" : "=r" (v)); |
return v; |
} |
/** Write SOFTINT Register. |
* |
* @param New value of SOFTINT register. |
*/ |
static inline void softint_write(__u64 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 New value of CLEAR_SOFTINT register. |
*/ |
static inline void clear_softint_write(__u64 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; |
__u64 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; |
__u64 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 __address get_stack_base(void) |
{ |
__address 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 __u64 ver_read(void) |
{ |
__u64 v; |
__asm__ volatile ("rdpr %%ver, %0\n" : "=r" (v)); |
return v; |
} |
/** Read Trap Base Address register. |
* |
* @return Current value in TBA. |
*/ |
static inline __u64 tba_read(void) |
{ |
__u64 v; |
__asm__ volatile ("rdpr %%tba, %0\n" : "=r" (v)); |
return v; |
} |
/** Read Trap Program Counter register. |
* |
* @return Current value in TPC. |
*/ |
static inline __u64 tpc_read(void) |
{ |
__u64 v; |
__asm__ volatile ("rdpr %%tpc, %0\n" : "=r" (v)); |
return v; |
} |
/** Read Trap Level register. |
* |
* @return Current value in TL. |
*/ |
static inline __u64 tl_read(void) |
{ |
__u64 v; |
__asm__ volatile ("rdpr %%tl, %0\n" : "=r" (v)); |
return v; |
} |
/** Write Trap Base Address register. |
* |
* @param New value of TBA. |
*/ |
static inline void tba_write(__u64 v) |
{ |
__asm__ volatile ("wrpr %0, %1, %%tba\n" : : "r" (v), "i" (0)); |
} |
/** Load __u64 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 __u64 asi_u64_read(asi_t asi, __address va) |
{ |
__u64 v; |
__asm__ volatile ("ldxa [%1] %2, %0\n" : "=r" (v) : "r" (va), "i" (asi)); |
return v; |
} |
/** Store __u64 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, __address va, __u64 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(__u32 t); |
#endif |
/tags/0.2.0/kernel/arch/sparc64/include/barrier.h |
---|
0,0 → 1,64 |
/* |
* Copyright (C) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#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. |
*/ |
/* |
* %i7 should provide address that is always mapped in DTLB |
* as it is a pointer to kernel code. |
*/ |
__asm__ volatile ("flush %i7\n"); |
} |
/** Memory Barrier instruction. */ |
static inline void membar(void) |
{ |
__asm__ volatile ("membar #Sync\n"); |
} |
#endif |
/tags/0.2.0/kernel/arch/sparc64/include/context_offset.h |
---|
0,0 → 1,21 |
/* 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/kernel/arch/sparc64/include/boot/boot.h |
---|
0,0 → 1,35 |
/* |
* 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. |
*/ |
#ifndef __sparc64_BOOT_H__ |
#define __sparc64_BOOT_H__ |
#define VMA 0x400000 |
#define LMA 0x4000 |
#endif |
/tags/0.2.0/kernel/arch/sparc64/include/context.h |
---|
0,0 → 1,84 |
/* |
* 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. |
*/ |
#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 = ((__address) _pc) - 8; \ |
(c)->sp = ((__address) 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 { |
__address sp; /* %o6 */ |
__address pc; /* %o7 */ |
__u64 i0; |
__u64 i1; |
__u64 i2; |
__u64 i3; |
__u64 i4; |
__u64 i5; |
__address fp; /* %i6 */ |
__address i7; |
__u64 l0; |
__u64 l1; |
__u64 l2; |
__u64 l3; |
__u64 l4; |
__u64 l5; |
__u64 l6; |
__u64 l7; |
ipl_t ipl; |
__u64 cleanwin; |
}; |
#endif |
/tags/0.2.0/kernel/arch/sparc64/include/register.h |
---|
0,0 → 1,101 |
/* |
* 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. |
*/ |
#ifndef __sparc64_REGISTER_H__ |
#define __sparc64_REGISTER_H__ |
#include <arch/types.h> |
/** Version Register. */ |
union ver_reg { |
__u64 value; |
struct { |
__u16 manuf; /**< Manufacturer code. */ |
__u16 impl; /**< Implementation code. */ |
__u8 mask; /**< Mask set revision. */ |
unsigned : 8; |
__u8 maxtl; |
unsigned : 3; |
unsigned maxwin : 5; |
} __attribute__ ((packed)); |
}; |
typedef union ver_reg ver_reg_t; |
/** Processor State Register. */ |
union pstate_reg { |
__u64 value; |
struct { |
__u64 : 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 { |
__u64 value; |
struct { |
unsigned npt : 1; /**< Non-privileged Trap enable. */ |
__u64 counter : 63; /**< Elapsed CPU clck cycle counter. */ |
} __attribute__ ((packed)); |
}; |
typedef union tick_reg tick_reg_t; |
/** TICK_compare Register. */ |
union tick_compare_reg { |
__u64 value; |
struct { |
unsigned int_dis : 1; /**< TICK_INT interrupt disabled flag. */ |
__u64 tick_cmpr : 63; /**< Compare value for TICK interrupts. */ |
} __attribute__ ((packed)); |
}; |
typedef union tick_compare_reg tick_compare_reg_t; |
/** SOFTINT Register. */ |
union softint_reg { |
__u64 value; |
struct { |
__u64 : 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/kernel/arch/sparc64/include/cpu.h |
---|
0,0 → 1,51 |
/* |
* 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. |
*/ |
#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/kernel/arch/sparc64/include/memstr.h |
---|
0,0 → 1,39 |
/* |
* 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. |
*/ |
#ifndef __sparc64_MEMSTR_H__ |
#define __sparc64_MEMSTR_H__ |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
extern void memsetw(__address dst, size_t cnt, __u16 x); |
extern void memsetb(__address dst, size_t cnt, __u8 x); |
extern int memcmp(__address src, __address dst, int cnt); |
#endif |
/tags/0.2.0/kernel/arch/sparc64/include/debug.h |
---|
0,0 → 1,32 |
/* |
* 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. |
*/ |
#ifndef __sparc64_DEBUG_H__ |
#define __sparc64_DEBUG_H__ |
#endif |
/tags/0.2.0/kernel/arch/sparc64/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. |
*/ |
#ifndef __sparc64_STACK_H__ |
#define __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/kernel/arch/sparc64/include/arg.h |
---|
0,0 → 1,34 |
/* |
* 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. |
*/ |
#ifndef __sparc64_ARG_H__ |
#define __sparc64_ARG_H__ |
#include <stdarg.h> |
#endif |
/tags/0.2.0/kernel/arch/sparc64/include/fpu_context.h |
---|
0,0 → 1,37 |
/* |
* 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. |
*/ |
#ifndef __sparc64_FPU_CONTEXT_H__ |
#define __sparc64_FPU_CONTEXT_H__ |
#include <arch/types.h> |
struct fpu_context { |
}; |
#endif |
/tags/0.2.0/kernel/arch/sparc64/include/byteorder.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. |
*/ |
#ifndef __sparc64_BYTEORDER_H__ |
#define __sparc64_BYTEORDER_H__ |
#include <arch/types.h> |
#include <byteorder.h> |
static inline __u64 __u64_le2host(__u64 n) |
{ |
return __u64_byteorder_swap(n); |
} |
static inline __native __native_le2host(__native n) |
{ |
return __u64_byteorder_swap(n); |
} |
#endif |
/tags/0.2.0/kernel/arch/sparc64/include/arch.h |
---|
0,0 → 1,32 |
/* |
* 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. |
*/ |
#ifndef __sparc64_ARCH_H__ |
#define __sparc64_ARCH_H__ |
#endif |
/tags/0.2.0/kernel/arch/sparc64/include/faddr.h |
---|
0,0 → 1,36 |
/* |
* 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. |
*/ |
#ifndef __sparc64_FADDR_H__ |
#define __sparc64_FADDR_H__ |
#include <arch/types.h> |
#define FADDR(fptr) ((__address) (fptr)) |
#endif |
/tags/0.2.0/kernel/arch/sparc64/src/sparc64.c |
---|
0,0 → 1,90 |
/* |
* 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.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> |
void arch_pre_mm_init(void) |
{ |
interrupts_disable(); |
ofw_sparc64_console_init(); |
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 reads characters from OFW's input. |
*/ |
t = thread_create(kofwinput, NULL, TASK, 0, "kofwinput"); |
if (!t) |
panic("cannot create kofwinput\n"); |
thread_ready(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/kernel/arch/sparc64/src/console.c |
---|
0,0 → 1,178 |
/* |
* 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/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 <genarch/ofw/ofw.h> |
#include <console/chardev.h> |
#include <console/console.h> |
#include <arch/asm.h> |
#include <arch/register.h> |
#include <proc/thread.h> |
#include <synch/mutex.h> |
#include <arch/mm/tlb.h> |
#define KEYBOARD_POLL_PAUSE 50000 /* 50ms */ |
static void ofw_sparc64_putchar(chardev_t *d, const char ch); |
static char ofw_sparc64_getchar(chardev_t *d); |
static void ofw_sparc64_suspend(chardev_t *d); |
static void ofw_sparc64_resume(chardev_t *d); |
mutex_t canwork; |
static volatile int ofw_console_active; |
static chardev_t ofw_sparc64_console; |
static chardev_operations_t ofw_sparc64_console_ops = { |
.write = ofw_sparc64_putchar, |
.read = ofw_sparc64_getchar, |
.resume = ofw_sparc64_resume, |
.suspend = ofw_sparc64_suspend |
}; |
/** Initialize kernel console to use OpenFirmware services. */ |
void ofw_sparc64_console_init(void) |
{ |
chardev_initialize("ofw_sparc64_console", &ofw_sparc64_console, &ofw_sparc64_console_ops); |
stdin = &ofw_sparc64_console; |
stdout = &ofw_sparc64_console; |
mutex_initialize(&canwork); |
ofw_console_active = 1; |
} |
/** Initialize kernel console to use framebuffer and keyboard directly. */ |
void standalone_sparc64_console_init(void) |
{ |
ofw_console_active = 0; |
stdin = NULL; |
kbd_init(); |
fb_init(FB_PHYS_ADDRESS, FB_X_RES, FB_Y_RES, FB_COLOR_DEPTH, FB_X_RES * FB_COLOR_DEPTH / 8); |
} |
/** Write one character using OpenFirmware. |
* |
* @param d Character device (ignored). |
* @param ch Character to be written. |
*/ |
void ofw_sparc64_putchar(chardev_t *d, const char ch) |
{ |
pstate_reg_t pstate; |
/* |
* 32-bit OpenFirmware depends on PSTATE.AM bit set. |
*/ |
pstate.value = pstate_read(); |
pstate.am = true; |
pstate_write(pstate.value); |
if (ch == '\n') |
ofw_putchar('\r'); |
ofw_putchar(ch); |
pstate.am = false; |
pstate_write(pstate.value); |
} |
/** Read one character using OpenFirmware. |
* |
* The call is non-blocking. |
* |
* @param d Character device (ignored). |
* @return Character read or zero if no character was read. |
*/ |
char ofw_sparc64_getchar(chardev_t *d) |
{ |
char ch; |
pstate_reg_t pstate; |
/* |
* 32-bit OpenFirmware depends on PSTATE.AM bit set. |
*/ |
pstate.value = pstate_read(); |
pstate.am = true; |
pstate_write(pstate.value); |
ch = ofw_getchar(); |
pstate.am = false; |
pstate_write(pstate.value); |
return ch; |
} |
void ofw_sparc64_suspend(chardev_t *d) |
{ |
mutex_lock(&canwork); |
} |
void ofw_sparc64_resume(chardev_t *d) |
{ |
mutex_unlock(&canwork); |
} |
/** Kernel thread for pushing characters read from OFW to input buffer. |
* |
* @param arg Ignored. |
*/ |
void kofwinput(void *arg) |
{ |
while (ofw_console_active) { |
char ch = 0; |
mutex_lock(&canwork); |
mutex_unlock(&canwork); |
ch = ofw_sparc64_getchar(NULL); |
if (ch) { |
if (ch == '\r') |
ch = '\n'; |
chardev_push_character(&ofw_sparc64_console, ch); |
} |
thread_usleep(KEYBOARD_POLL_PAUSE); |
} |
} |
/** Kernel thread for polling keyboard. |
* |
* @param arg Ignored. |
*/ |
void kkbdpoll(void *arg) |
{ |
while (1) { |
i8042_poll(); |
thread_usleep(KEYBOARD_POLL_PAUSE); |
} |
} |
/tags/0.2.0/kernel/arch/sparc64/src/mm/page.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. |
*/ |
#include <arch/mm/page.h> |
#include <arch/mm/tlb.h> |
#include <genarch/mm/page_ht.h> |
#include <mm/frame.h> |
#include <bitops.h> |
#include <debug.h> |
void page_arch_init(void) |
{ |
page_mapping_operations = &ht_mapping_operations; |
} |
__address hw_map(__address 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; |
__address virtaddr = PA2KA(PFN2ADDR(frame_alloc(order, FRAME_KA))); |
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/kernel/arch/sparc64/src/mm/tlb.c |
---|
0,0 → 1,274 |
/* |
* 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/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" |
}; |
/** Initialize ITLB and DTLB. |
* |
* The goal of this function is to disable MMU |
* so that both TLBs can be purged and new |
* kernel 4M locked entry can be installed. |
* After TLB is initialized, MMU is enabled |
* again. |
* |
* Switching MMU off imposes the requirement for |
* the kernel to run in identity mapped environment. |
*/ |
void tlb_arch_init(void) |
{ |
tlb_tag_access_reg_t tag; |
tlb_data_t data; |
frame_address_t fr; |
page_address_t pg; |
fr.address = config.base; |
pg.address = config.base; |
immu_disable(); |
dmmu_disable(); |
/* |
* Demap everything, especially OpenFirmware. |
*/ |
itlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_NUCLEUS, 0); |
dtlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_NUCLEUS, 0); |
/* |
* We do identity mapping of 4M-page at 4M. |
*/ |
tag.value = ASID_KERNEL; |
tag.vpn = pg.vpn; |
itlb_tag_access_write(tag.value); |
dtlb_tag_access_write(tag.value); |
data.value = 0; |
data.v = true; |
data.size = PAGESIZE_4M; |
data.pfn = fr.pfn; |
data.l = true; |
data.cp = 1; |
data.cv = 1; |
data.p = true; |
data.w = true; |
data.g = true; |
itlb_data_in_write(data.value); |
dtlb_data_in_write(data.value); |
/* |
* Register window traps can occur before MMU is enabled again. |
* This ensures that any such traps will be handled from |
* kernel identity mapped trap handler. |
*/ |
trap_switch_trap_table(); |
tlb_invalidate_all(); |
dmmu_enable(); |
immu_enable(); |
} |
/** 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(__address page, __address 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; |
__address 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, __address 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/kernel/arch/sparc64/src/mm/memory_init.c |
---|
0,0 → 1,36 |
/* |
* 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 <arch/mm/memory_init.h> |
#include <genarch/ofw/memory_init.h> |
#include <typedefs.h> |
size_t get_memory_size(void) |
{ |
return ofw_get_memory_size(); |
} |
/tags/0.2.0/kernel/arch/sparc64/src/mm/frame.c |
---|
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. |
*/ |
#include <arch/mm/frame.h> |
#include <genarch/ofw/memory_init.h> |
#include <mm/frame.h> |
#include <config.h> |
#include <align.h> |
void frame_arch_init(void) |
{ |
ofw_init_zones(); |
/* |
* Workaround to prevent slab allocator from allocating frame 0. |
* Frame 0 is |
* a) not mapped by OFW |
* b) would be confused with NULL error return code |
*/ |
frame_mark_unavailable(0, 1); |
} |
/tags/0.2.0/kernel/arch/sparc64/src/mm/as.c |
---|
0,0 → 1,38 |
/* |
* 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 <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/kernel/arch/sparc64/src/drivers/i8042.c |
---|
0,0 → 1,40 |
/* |
* 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 <arch/drivers/i8042.h> |
#include <genarch/i8042/i8042.h> |
#include <arch/types.h> |
#include <arch/mm/page.h> |
volatile __u8 *kbd_virt_address = NULL; |
void kbd_init() |
{ |
kbd_virt_address = (__u8 *) hw_map(KBD_PHYS_ADDRESS, LAST_REG); |
i8042_init(); |
} |
/tags/0.2.0/kernel/arch/sparc64/src/drivers/tick.c |
---|
0,0 → 1,83 |
/* |
* 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/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/kernel/arch/sparc64/src/asm.S |
---|
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. |
# |
.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: |
b _memcpy |
nop |
memcpy_from_uspace_failover_address: |
memcpy_to_uspace_failover_address: |
b memcpy_from_uspace_failover_address |
nop |
memsetb: |
b _memsetb |
nop |
/tags/0.2.0/kernel/arch/sparc64/src/ddi/ddi.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. |
*/ |
#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, __address ioaddr, size_t size) |
{ |
return 0; |
} |
/tags/0.2.0/kernel/arch/sparc64/src/trap/interrupt.c |
---|
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. |
*/ |
#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(__native irq) |
{ |
panic("not implemented\n"); |
/* TODO */ |
} |
/tags/0.2.0/kernel/arch/sparc64/src/trap/exception.c |
---|
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. |
*/ |
#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/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/kernel/arch/sparc64/src/trap/trap.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. |
*/ |
#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/kernel/arch/sparc64/src/proc/scheduler.c |
---|
0,0 → 1,74 |
/* |
* 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 <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) |
{ |
__address base; |
base = ALIGN_DOWN(config.base, 1<<KERNEL_PAGE_WIDTH); |
if ((__address) THREAD->kstack < base || (__address) 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, (__address) THREAD->kstack); |
dtlb_insert_mapping((__address) THREAD->kstack, KA2PA(THREAD->kstack), PAGESIZE_8K, true, true); |
} |
} |
/** Unlock thread's stack from TLB, if necessary. */ |
void after_thread_ran_arch(void) |
{ |
__address base; |
base = ALIGN_DOWN(config.base, 1<<KERNEL_PAGE_WIDTH); |
if ((__address) THREAD->kstack < base || (__address) 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, (__address) THREAD->kstack); |
} |
} |
/tags/0.2.0/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/kernel/arch/sparc64/src/start.S |
---|
0,0 → 1,113 |
# |
# 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/boot/boot.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. |
* The code must be position independent until |
* the kernel relocates itself to its VMA. |
*/ |
.global kernel_image_start |
kernel_image_start: |
0: |
b 1f |
nop |
/* |
* This header forces SILO to load the kernel at 0x4000. |
* More precisely, SILO will think this is an old version of Linux. |
*/ |
.ascii "HdrS" |
.word 0 |
.half 0 |
.align 8 |
1: |
flushw ! flush all but the active register window |
/* |
* Prepare to copy the kernel image to 4M. |
*/ |
set LMA, %g1 ! source address |
set VMA, %g2 ! destination address |
set hardcoded_ktext_size, %g3 ! link address of hardcoded_ktext_size |
set hardcoded_kdata_size, %g4 ! link address of hardcoded_kdata_size |
sub %g3, %g2, %g3 ! offset of hardcoded_ktext_size from the beginning of the load address |
sub %g4, %g2, %g4 ! offset of hardcoded_kdata_size from the beginning of the load address |
ldx [%g3 + %g1], %g3 ! hardcoded_ktext_size -> %g3 |
ldx [%g4 + %g1], %g4 ! hardcoded_kdata_size -> %g4 |
add %g3, %g4, %g3 ! size of kernel text and data |
/* |
* Start copying the kernel from higher addresses towards lower addresses. |
*/ |
2: dec %g3 |
ldub [%g1 + %g3], %g4 |
stb %g4, [%g2 + %g3] |
cmp %g3, 0 |
bnz 2b |
nop |
set relocated, %g1 |
jmp %g1 |
nop |
relocated: |
set ofw, %l0 |
call ofw_init |
stx %o4, [%l0] |
call ofw_init_memmap |
nop |
wrpr %r0, 0, %pil |
call main_bsp |
nop |
/* Not reached. */ |
2: |
b 2b |
nop |
/tags/0.2.0/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/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/kernel/arch/sparc64/src/cpu/cpu.c |
---|
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. |
*/ |
#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/kernel/arch/sparc64/Makefile.inc |
---|
0,0 → 1,94 |
# |
# 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 = elf64-sparc |
TARGET = sparc64-linux-gnu |
TOOLCHAIN_DIR = /usr/local/sparc64/bin |
## Make some default assumptions |
# |
CFLAGS += -mcpu=ultrasparc -m64 |
LFLAGS += -no-check-sections -N |
DEFS += -D__64_BITS__ |
## Own configuration directives |
# |
CONFIG_OFW = y |
## 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/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 __ASM__ |
#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/kernel/arch/ppc64/include/exception.h |
---|
0,0 → 1,95 |
/* |
* 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 __ppc64_EXCEPTION_H__ |
#define __ppc64_EXCEPTION_H__ |
#ifndef __ppc64_TYPES_H__ |
# include <arch/types.h> |
#endif |
#include <typedefs.h> |
struct istate { |
__u64 r0; |
__u64 r2; |
__u64 r3; |
__u64 r4; |
__u64 r5; |
__u64 r6; |
__u64 r7; |
__u64 r8; |
__u64 r9; |
__u64 r10; |
__u64 r11; |
__u64 r13; |
__u64 r14; |
__u64 r15; |
__u64 r16; |
__u64 r17; |
__u64 r18; |
__u64 r19; |
__u64 r20; |
__u64 r21; |
__u64 r22; |
__u64 r23; |
__u64 r24; |
__u64 r25; |
__u64 r26; |
__u64 r27; |
__u64 r28; |
__u64 r29; |
__u64 r30; |
__u64 r31; |
__u64 cr; |
__u64 pc; |
__u64 srr1; |
__u64 lr; |
__u64 ctr; |
__u64 xer; |
__u64 r12; |
__u64 sp; |
}; |
static inline void istate_set_retaddr(istate_t *istate, __address 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 __native istate_get_pc(istate_t *istate) |
{ |
return istate->pc; |
} |
#endif |
/tags/0.2.0/kernel/arch/ppc64/include/proc/task.h |
---|
0,0 → 1,38 |
/* |
* 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. |
*/ |
#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/kernel/arch/ppc64/include/proc/thread.h |
---|
0,0 → 1,37 |
/* |
* 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. |
*/ |
#ifndef __ppc64_THREAD_H__ |
#define __ppc64_THREAD_H__ |
typedef struct { |
} thread_arch_t; |
#define thread_create_arch(t) |
#endif |
/tags/0.2.0/kernel/arch/ppc64/include/mm/as.h |
---|
0,0 → 1,45 |
/* |
* 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. |
*/ |
#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/kernel/arch/ppc64/include/mm/asid.h |
---|
0,0 → 1,39 |
/* |
* 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. |
*/ |
#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/kernel/arch/ppc64/include/mm/page.h |
---|
0,0 → 1,153 |
/* |
* 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. |
*/ |
#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) (((__address) (x)) - 0x80000000) |
# define PA2KA(x) (((__address) (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) (*((__u32 *) (pte)) != 0) |
#define PTE_PRESENT_ARCH(pte) ((pte)->p != 0) |
#define PTE_GET_FRAME_ARCH(pte) ((__address) ((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/kernel/arch/ppc64/include/mm/frame.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. |
*/ |
#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 __address last_frame; |
extern void frame_arch_init(void); |
#endif /* __ASM__ */ |
#endif /* KERNEL */ |
#endif |
/tags/0.2.0/kernel/arch/ppc64/include/mm/tlb.h |
---|
0,0 → 1,33 |
/* |
* 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. |
*/ |
#ifndef __ppc64_TLB_H__ |
#define __ppc64_TLB_H__ |
#endif |
/tags/0.2.0/kernel/arch/ppc64/include/mm/memory_init.h |
---|
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. |
*/ |
#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/kernel/arch/ppc64/include/types.h |
---|
0,0 → 1,60 |
/* |
* 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 __ppc64_TYPES_H__ |
#define __ppc64_TYPES_H__ |
#define NULL 0 |
typedef signed char __s8; |
typedef signed short __s16; |
typedef signed int __s32; |
typedef signed long __s64; |
typedef unsigned char __u8; |
typedef unsigned short __u16; |
typedef unsigned int __u32; |
typedef unsigned long __u64; |
typedef __u64 __address; |
typedef __u64 pfn_t; |
typedef __u64 ipl_t; |
typedef __u64 __native; |
/** 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/kernel/arch/ppc64/include/asm.h |
---|
0,0 → 1,152 |
/* |
* 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. |
*/ |
#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 __address get_stack_base(void) |
{ |
__address 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(__u32 t); |
extern void userspace_asm(__address uspace_uarg, __address stack, __address entry); |
#endif |
/tags/0.2.0/kernel/arch/ppc64/include/asm/regname.h |
---|
0,0 → 1,206 |
/* |
* 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. |
*/ |
#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/kernel/arch/ppc64/include/byteorder.h |
---|
0,0 → 1,64 |
/* |
* Copyright (C) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#ifndef __ppc64_BYTEORDER_H__ |
#define __ppc64_BYTEORDER_H__ |
#include <arch/types.h> |
#include <byteorder.h> |
#define BIG_ENDIAN |
static inline __u64 __u64_le2host(__u64 n) |
{ |
return __u64_byteorder_swap(n); |
} |
/** Convert little-endian __native to host __native |
* |
* Convert little-endian __native parameter to host endianess. |
* |
* @param n Little-endian __native argument. |
* |
* @return Result in host endianess. |
* |
*/ |
static inline __native __native_le2host(__native n) |
{ |
__address v; |
asm volatile ( |
"lwbrx %0, %1, %2\n" |
: "=r" (v) |
: "i" (0), "r" (&n) |
); |
return v; |
} |
#endif |
/tags/0.2.0/kernel/arch/ppc64/include/cpuid.h |
---|
0,0 → 1,47 |
/* |
* 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 __ppc64_CPUID_H__ |
#define __ppc64_CPUID_H__ |
#include <arch/types.h> |
struct cpu_info { |
__u16 version; |
__u16 revision; |
} __attribute__ ((packed)); |
static inline void cpu_version(struct cpu_info *info) |
{ |
asm volatile ( |
"mfpvr %0\n" |
: "=r" (*info) |
); |
} |
#endif |
/tags/0.2.0/kernel/arch/ppc64/include/elf.h |
---|
0,0 → 1,36 |
/* |
* 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. |
*/ |
#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/kernel/arch/ppc64/include/atomic.h |
---|
0,0 → 1,88 |
/* |
* 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. |
*/ |
#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/kernel/arch/ppc64/include/boot/boot.h |
---|
0,0 → 1,83 |
/* |
* Copyright (C) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#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 { |
__address addr; |
__u64 size; |
} utask_t; |
typedef struct { |
__u32 count; |
utask_t tasks[TASKMAP_MAX_RECORDS]; |
} taskmap_t; |
typedef struct { |
__address start; |
__u64 size; |
} memzone_t; |
typedef struct { |
__u64 total; |
__u32 count; |
memzone_t zones[MEMMAP_MAX_RECORDS]; |
} memmap_t; |
typedef struct { |
__address 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/kernel/arch/ppc64/include/barrier.h |
---|
0,0 → 1,39 |
/* |
* 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. |
*/ |
#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/kernel/arch/ppc64/include/interrupt.h |
---|
0,0 → 1,43 |
/* |
* 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 __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/kernel/arch/ppc64/include/context_offset.h |
---|
0,0 → 1,45 |
/* 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/kernel/arch/ppc64/include/fpu_context.h |
---|
0,0 → 1,58 |
/* |
* 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. |
*/ |
#ifndef __ppc64_FPU_CONTEXT_H__ |
#define __ppc64_FPU_CONTEXT_H__ |
#ifndef __ppc64_TYPES_H__ |
# include <arch/types.h> |
#endif |
struct fpu_context { |
__u64 fr14; |
__u64 fr15; |
__u64 fr16; |
__u64 fr17; |
__u64 fr18; |
__u64 fr19; |
__u64 fr20; |
__u64 fr21; |
__u64 fr22; |
__u64 fr23; |
__u64 fr24; |
__u64 fr25; |
__u64 fr26; |
__u64 fr27; |
__u64 fr28; |
__u64 fr29; |
__u64 fr30; |
__u64 fr31; |
__u32 fpscr; |
} __attribute__ ((packed)); |
#endif |
/tags/0.2.0/kernel/arch/ppc64/include/memstr.h |
---|
0,0 → 1,39 |
/* |
* 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. |
*/ |
#ifndef __ppc64_MEMSTR_H__ |
#define __ppc64_MEMSTR_H__ |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
extern void memsetw(__address dst, size_t cnt, __u16 x); |
extern void memsetb(__address dst, size_t cnt, __u8 x); |
extern int memcmp(__address src, __address dst, int cnt); |
#endif |
/tags/0.2.0/kernel/arch/ppc64/include/arg.h |
---|
0,0 → 1,34 |
/* |
* 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. |
*/ |
#ifndef __ppc64_ARG_H__ |
#define __ppc64_ARG_H__ |
#include <stdarg.h> |
#endif |
/tags/0.2.0/kernel/arch/ppc64/include/arch.h |
---|
0,0 → 1,32 |
/* |
* 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. |
*/ |
#ifndef __ppc64_ARCH_H__ |
#define __ppc64_ARCH_H__ |
#endif |
/tags/0.2.0/kernel/arch/ppc64/include/faddr.h |
---|
0,0 → 1,36 |
/* |
* 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. |
*/ |
#ifndef __ppc64_FADDR_H__ |
#define __ppc64_FADDR_H__ |
#include <arch/types.h> |
#define FADDR(fptr) ((__address) (fptr)) |
#endif |
/tags/0.2.0/kernel/arch/ppc64/include/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. |
*/ |
#ifndef __ppc64_CONTEXT_H__ |
#define __ppc64_CONTEXT_H__ |
#ifndef __ppc64_TYPES_H__ |
# include <arch/types.h> |
#endif |
#define SP_DELTA 16 |
struct context { |
__address sp; |
__address pc; |
__u64 r2; |
__u64 r13; |
__u64 r14; |
__u64 r15; |
__u64 r16; |
__u64 r17; |
__u64 r18; |
__u64 r19; |
__u64 r20; |
__u64 r21; |
__u64 r22; |
__u64 r23; |
__u64 r24; |
__u64 r25; |
__u64 r26; |
__u64 r27; |
__u64 r28; |
__u64 r29; |
__u64 r30; |
__u64 r31; |
__u64 cr; |
ipl_t ipl; |
} __attribute__ ((packed)); |
#endif |
/tags/0.2.0/kernel/arch/ppc64/include/debug.h |
---|
0,0 → 1,32 |
/* |
* 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. |
*/ |
#ifndef __ppc64_DEBUG_H__ |
#define __ppc64_DEBUG_H__ |
#endif |
/tags/0.2.0/kernel/arch/ppc64/include/cpu.h |
---|
0,0 → 1,39 |
/* |
* 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 __ppc64_CPU_H__ |
#define __ppc64_CPU_H__ |
#include <typedefs.h> |
struct cpu_arch { |
int version; |
int revision; |
}; |
#endif |
/tags/0.2.0/kernel/arch/ppc64/src/ppc64.c |
---|
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.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; |
__u32 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((__address) kernel_uarg->uspace_uarg, (__address) kernel_uarg->uspace_stack + THREAD_STACK_SIZE - SP_DELTA, (__address) 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/kernel/arch/ppc64/src/mm/page.c |
---|
0,0 → 1,298 |
/* |
* 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/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, __address badvaddr, int access, |
istate_t *istate, int *pfcr) |
{ |
/* |
* 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)); |
return pte; |
case AS_PF_DEFER: |
page_table_lock(as, lock); |
*pfcr = rc; |
return NULL; |
case AS_PF_FAULT: |
page_table_lock(as, lock); |
printf("Page fault.\n"); |
*pfcr = rc; |
return NULL; |
default: |
panic("unexpected rc (%d)\n", rc); |
} |
} |
} |
static void pht_refill_fail(__address 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 __address vaddr, const pfn_t pfn) |
{ |
__u32 page = (vaddr >> 12) & 0xffff; |
__u32 api = (vaddr >> 22) & 0x3f; |
__u32 vsid; |
asm volatile ( |
"mfsrin %0, %1\n" |
: "=r" (vsid) |
: "r" (vaddr) |
); |
/* Primary hash (xor) */ |
__u32 h = 0; |
__u32 hash = vsid ^ page; |
__u32 base = (hash & 0x3ff) << 3; |
__u32 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) */ |
__u32 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) |
{ |
__address badvaddr; |
pte_t *pte; |
int pfcr; |
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, &pfcr); |
if (!pte) { |
switch (pfcr) { |
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", pfcr); |
} |
} |
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((__address) phte, 1 << PHT_BITS, 0); |
} |
void page_arch_init(void) |
{ |
if (config.cpu_active == 1) { |
page_mapping_operations = &pt_mapping_operations; |
__address 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 *) PFN2ADDR(frame_alloc(PHT_ORDER, FRAME_KA | FRAME_PANIC)); |
phte = (phte_t *) PA2KA((__address) physical_phte); |
ASSERT((__address) physical_phte % (1 << PHT_BITS) == 0); |
pht_init(); |
asm volatile ( |
"mtsdr1 %0\n" |
: |
: "r" ((__address) physical_phte) |
); |
} |
} |
__address hw_map(__address 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) |
__address 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/kernel/arch/ppc64/src/mm/tlb.c |
---|
0,0 → 1,77 |
/* |
* 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 <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, __address page, count_t cnt) |
{ |
tlb_invalidate_all(); |
} |
/** Print contents of Page Hash Table. */ |
void tlb_print(void) |
{ |
} |
/tags/0.2.0/kernel/arch/ppc64/src/mm/memory_init.c |
---|
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. |
*/ |
#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/kernel/arch/ppc64/src/mm/frame.c |
---|
0,0 → 1,62 |
/* |
* 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/boot/boot.h> |
#include <arch/mm/frame.h> |
#include <arch/mm/memory_init.h> |
#include <mm/frame.h> |
#include <align.h> |
#include <macros.h> |
__address 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/kernel/arch/ppc64/src/mm/as.c |
---|
0,0 → 1,36 |
/* |
* 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 <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/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/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/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/kernel/arch/ppc64/src/proc/scheduler.c |
---|
0,0 → 1,54 |
/* |
* Copyright (C) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include <arch/mm/page.h> |
#include <arch/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/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/kernel/arch/ppc64/src/interrupt.c |
---|
0,0 → 1,66 |
/* |
* 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 <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(__native irq) |
{ |
panic("not implemented\n"); |
/* TODO */ |
} |
/tags/0.2.0/kernel/arch/ppc64/src/ddi/ddi.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. |
*/ |
#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, __address ioaddr, size_t size) |
{ |
return 0; |
} |
/tags/0.2.0/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/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/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/kernel/arch/ppc64/src/cpu/cpu.c |
---|
0,0 → 1,54 |
/* |
* 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/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/kernel/arch/ppc64/Makefile.inc |
---|
0,0 → 1,75 |
# |
# Copyright (C) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
## Toolchain configuration |
# |
BFD_NAME = elf64-powerpc |
BFD_ARCH = powerpc:common64 |
BFD = binary |
TARGET = ppc64-linux-gnu |
TOOLCHAIN_DIR = /usr/local/ppc64/bin |
## Make some default assumptions |
# |
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/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 = .; |
} |
} |