/trunk/kernel/arch/arm32/_link.ld.in |
---|
6,9 → 6,12 |
* |
*/ |
OUTPUT_ARCH(arm) |
ENTRY(kernel_image_start) |
SECTIONS { |
. = KERNEL_LOAD_ADDRESS; |
.text : { |
ktext_start = .; |
*(.text); |
22,23 → 25,20 |
hardcoded_kdata_size = .; |
LONG(kdata_end - kdata_start); |
hardcoded_load_address = .; |
LONG(0); /* TODO */ |
LONG(KERNEL_LOAD_ADDRESS); |
*(.bss); /* uninitialized static variables */ |
*(COMMON); /* global variables */ |
*(.rodata*); |
*(.sdata); |
*(.reginfo); |
symbol_table = .; |
*(symtab.*); |
} |
_gp = . + 0x8000; |
.lit8 : { *(.lit8) } |
.lit4 : { *(.lit4) } |
.sbss : { |
*(.sbss); |
*(.scommon); |
} |
.bss : { |
*(.bss); /* uninitialized static variables */ |
*(COMMON); /* global variables */ |
} |
kdata_end = .; |
48,4 → 48,5 |
*(.comment); |
*(.note); |
} |
} |
/trunk/kernel/arch/arm32/include/asm/boot.h |
---|
0,0 → 1,62 |
/* |
* Copyright (c) 2007 Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
* @brief Initial kernel start. |
*/ |
#ifndef KERN_arm32_ASM_BOOT_H_ |
#define KERN_arm32_ASM_BOOT_H_ |
/** Size of a temporary stack used for initial kernel start. */ |
#define TEMP_STACK_SIZE 0x100 |
#ifndef __ASM__ |
/** Kernel entry point. |
* |
* Implemented in assembly. Copies boot_bootinfo (declared as bootinfo in |
* boot/arch/arm32/loader/main.c) to #bootinfo struct. Then jumps to |
* #arch_pre_main and #main_bsp. |
* |
* @param entry Entry point address (not used). |
* @param boot_bootinfo Struct holding information about loaded tasks. |
* @param bootinfo_size Size of the bootinfo structure. |
*/ |
extern void kernel_image_start(void *entry, void *boot_bootinfo, |
unsigned int bootinfo_size); |
#endif |
#endif |
/** @} |
*/ |
/trunk/kernel/arch/arm32/include/interrupt.h |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* Copyright (c) 2007 Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
27,18 → 27,31 |
*/ |
/** @addtogroup arm32interrupt |
* @ingroup interrupt |
* @{ |
*/ |
/** @file |
* @brief Declarations of interrupt controlling routines. |
*/ |
#ifndef KERN_arm32_INTERRUPT_H_ |
#define KERN_arm32_INTERRUPT_H_ |
#define IVT_ITEMS 0 /* TODO */ |
#define IVT_FIRST 0 /* TODO */ |
#include <arch/types.h> |
/** Initial size of exception dispatch table. */ |
#define IVT_ITEMS 6 |
/** Index of the first item in exception dispatch table. */ |
#define IVT_FIRST 0 |
extern void interrupt_init(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 |
/** @} |
/trunk/kernel/arch/arm32/include/fpu_context.h |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2005 Jakub Vana |
* Copyright (c) 2007 Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
30,6 → 30,9 |
* @{ |
*/ |
/** @file |
* @brief FPU context (not implemented). |
* |
* GXemul doesn't support FPU on its ARM CPU. |
*/ |
#ifndef KERN_arm32_FPU_CONTEXT_H_ |
37,7 → 40,7 |
#include <arch/types.h> |
#define FPU_CONTEXT_ALIGN 0 /* TODO */ |
#define FPU_CONTEXT_ALIGN 0 |
typedef struct { |
} fpu_context_t; |
/trunk/kernel/arch/arm32/include/exception.h |
---|
1,5 → 1,6 |
/* |
* Copyright (c) 2003-2004 Jakub Jermar |
* Copyright (c) 2007 Michal Kebrt, Petr Stepan |
* |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
30,6 → 31,7 |
* @{ |
*/ |
/** @file |
* @brief Exception declarations. |
*/ |
#ifndef KERN_arm32_EXCEPTION_H_ |
36,28 → 38,106 |
#define KERN_arm32_EXCEPTION_H_ |
#include <arch/types.h> |
#include <arch/regutils.h> |
/** If defined, forces using of high exception vectors. */ |
#define HIGH_EXCEPTION_VECTORS |
#ifdef HIGH_EXCEPTION_VECTORS |
#define EXC_BASE_ADDRESS 0xffff0000 |
#else |
#define EXC_BASE_ADDRESS 0x0 |
#endif |
/* Exception Vectors */ |
#define EXC_RESET_VEC (EXC_BASE_ADDRESS + 0x0) |
#define EXC_UNDEF_INSTR_VEC (EXC_BASE_ADDRESS + 0x4) |
#define EXC_SWI_VEC (EXC_BASE_ADDRESS + 0x8) |
#define EXC_PREFETCH_ABORT_VEC (EXC_BASE_ADDRESS + 0xc) |
#define EXC_DATA_ABORT_VEC (EXC_BASE_ADDRESS + 0x10) |
#define EXC_IRQ_VEC (EXC_BASE_ADDRESS + 0x18) |
#define EXC_FIQ_VEC (EXC_BASE_ADDRESS + 0x1c) |
/* Exception numbers */ |
#define EXC_RESET 0 |
#define EXC_UNDEF_INSTR 1 |
#define EXC_SWI 2 |
#define EXC_PREFETCH_ABORT 3 |
#define EXC_DATA_ABORT 4 |
#define EXC_IRQ 5 |
#define EXC_FIQ 6 |
/** Kernel stack pointer. |
* |
* It is set when thread switches to user mode, |
* and then used for exception handling. |
*/ |
extern uintptr_t supervisor_sp; |
/** Temporary exception stack pointer. |
* |
* Temporary stack is used in exceptions handling routines |
* before switching to thread's kernel stack. |
*/ |
extern uintptr_t exc_stack; |
/** Struct representing CPU state saved when an exception occurs. */ |
typedef struct { |
/* TODO */ |
uint32_t spsr; |
uint32_t sp; |
uint32_t lr; |
uint32_t r0; |
uint32_t r1; |
uint32_t r2; |
uint32_t r3; |
uint32_t r4; |
uint32_t r5; |
uint32_t r6; |
uint32_t r7; |
uint32_t r8; |
uint32_t r9; |
uint32_t r10; |
uint32_t r11; |
uint32_t r12; |
uint32_t pc; |
} istate_t; |
/** Sets Program Counter member of given istate structure. |
* |
* @param istate istate structure |
* @param retaddr new value of istate's PC member |
*/ |
static inline void istate_set_retaddr(istate_t *istate, uintptr_t retaddr) |
{ |
/* TODO */ |
istate->pc = retaddr; |
} |
/** Return true if exception happened while in userspace */ |
/** Returns true if exception happened while in userspace. */ |
static inline int istate_from_uspace(istate_t *istate) |
{ |
/* TODO */ |
return 0; |
return (istate->spsr & STATUS_REG_MODE_MASK) == USER_MODE; |
} |
/** Returns Program Counter member of given istate structure. */ |
static inline unative_t istate_get_pc(istate_t *istate) |
{ |
/* TODO */ |
return 0; |
return istate->pc; |
} |
extern void install_exception_handlers(void); |
extern void exception_init(void); |
extern void print_istate(istate_t *istate); |
#endif |
/** @} |
/trunk/kernel/arch/arm32/include/regutils.h |
---|
0,0 → 1,86 |
/* |
* Copyright (c) 2007 Petr Stepan |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
* @{ |
*/ |
/** |
* @file |
* @brief Utilities for convenient manipulation with ARM registers. |
*/ |
#ifndef KERN_arm32_REGUTILS_H_ |
#define KERN_arm32_REGUTILS_H_ |
#define STATUS_REG_IRQ_DISABLED_BIT (1 << 7) |
#define STATUS_REG_MODE_MASK 0x1f |
#define CP15_R1_HIGH_VECTORS_BIT (1 << 13) |
/* ARM Processor Operation Modes */ |
#define USER_MODE 0x10 |
#define FIQ_MODE 0x11 |
#define IRQ_MODE 0x12 |
#define SUPERVISOR_MODE 0x13 |
#define ABORT_MODE 0x17 |
#define UNDEFINED_MODE 0x1b |
#define SYSTEM_MODE 0x1f |
/* [CS]PRS manipulation macros */ |
#define GEN_STATUS_READ(nm,reg) \ |
static inline uint32_t nm## _status_reg_read(void) \ |
{ \ |
uint32_t retval; \ |
asm volatile("mrs %0, " #reg : "=r" (retval)); \ |
return retval; \ |
} |
#define GEN_STATUS_WRITE(nm,reg,fieldname, field) \ |
static inline void nm## _status_reg_ ##fieldname## _write(uint32_t value) \ |
{ \ |
asm volatile("msr " #reg "_" #field ", %0" : : "r" (value)); \ |
} |
/** Returns the value of CPSR (Current Program Status Register). */ |
GEN_STATUS_READ(current, cpsr) |
/** Sets control bits of CPSR. */ |
GEN_STATUS_WRITE(current, cpsr, control, c); |
/** Returns the value of SPSR (Saved Program Status Register). */ |
GEN_STATUS_READ(saved, spsr) |
#endif |
/** @} |
*/ |
/trunk/kernel/arch/arm32/include/cycle.h |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2006 Martin Decky |
* Copyright (c) 2007 Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
30,14 → 30,20 |
* @{ |
*/ |
/** @file |
* @brief Count of CPU cycles. |
*/ |
#ifndef KERN_arm32_CYCLE_H_ |
#define KERN_arm32_CYCLE_H_ |
/** Returns count of CPU cycles. |
* |
* No such instruction on ARM to get count of cycles. |
* |
* @return Count of CPU cycles. |
*/ |
static inline uint64_t get_cycle(void) |
{ |
/* TODO */ |
return 0; |
} |
/trunk/kernel/arch/arm32/include/byteorder.h |
---|
30,6 → 30,7 |
* @{ |
*/ |
/** @file |
* @brief Endianness definitions. |
*/ |
#ifndef KERN_arm32_BYTEORDER_H_ |
/trunk/kernel/arch/arm32/include/debug/print.h |
---|
0,0 → 1,56 |
/* |
* Copyright (c) 2007 Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
* @brief Debug printing functions. |
*/ |
#ifndef KERN_arm32_DEBUG_PRINT_H_ |
#define KERN_arm32_DEBUG_PRINT_H_ |
#include <stdarg.h> |
#include <arch/types.h> |
extern void debug_puts(const char *str); |
extern void debug_printf(const char *fmt, ...); |
#ifdef CONFIG_DEBUG |
# define dprintf(arg1...) debug_printf(arg1) |
# define dputs(arg1) debug_puts(arg1) |
#else |
# define dprintf(arg1...) |
# define dputs(arg1) |
#endif |
#endif |
/** @} |
*/ |
/trunk/kernel/arch/arm32/include/console.h |
---|
0,0 → 1,49 |
/* |
* Copyright (c) 2007 Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
* @brief Console. |
*/ |
#ifndef KERN_arm32_CONSOLE_H_ |
#define KERN_arm32_CONSOLE_H_ |
/** Initializes console. |
* |
* @param devno Console device number. |
*/ |
extern void console_init(devno_t devno); |
#endif |
/** @} |
*/ |
/trunk/kernel/arch/arm32/include/boot.h |
---|
0,0 → 1,76 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
* @brief Bootinfo declarations. |
* |
* Reflects boot/arch/arm32/loader/main.h. |
*/ |
#ifndef KERN_arm32_BOOT_H_ |
#define KERN_arm32_BOOT_H_ |
#include <arch/types.h> |
/** Maximum number of tasks in the #bootinfo_t struct. */ |
#define TASKMAP_MAX_RECORDS 32 |
/** Struct holding information about single loaded uspace task. */ |
typedef struct { |
/** Address where the task was placed. */ |
uintptr_t addr; |
/** Size of the task's binary. */ |
uint32_t size; |
} utask_t; |
/** Struct holding information about loaded uspace tasks. */ |
typedef struct { |
/** Number of loaded tasks. */ |
uint32_t cnt; |
/** Array of loaded tasks. */ |
utask_t tasks[TASKMAP_MAX_RECORDS]; |
} bootinfo_t; |
/** Bootinfo that is filled in #kernel_image_start. */ |
extern bootinfo_t bootinfo; |
#endif |
/** @} |
*/ |
/trunk/kernel/arch/arm32/include/types.h |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2003-2007 Jakub Jermar |
* Copyright (c) 2007 Pavel Jancik, Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
30,11 → 30,18 |
* @{ |
*/ |
/** @file |
* @brief Type definitions. |
*/ |
#ifndef KERN_arm32_TYPES_H_ |
#define KERN_arm32_TYPES_H_ |
#ifndef DOXYGEN |
# define ATTRIBUTE_PACKED __attribute__ ((packed)) |
#else |
# define ATTRIBUTE_PACKED |
#endif |
#define NULL 0 |
#define false 0 |
#define true 1 |
69,9 → 76,14 |
typedef int32_t inr_t; |
typedef int32_t devno_t; |
/** Page Table Entry. */ |
/** Page table entry. |
* |
* We have different structs for level 0 and level 1 page table entries. |
* See page.h for definition of pte_level*_t. |
*/ |
typedef struct { |
/* placeholder */ |
unsigned dummy : 32; |
} pte_t; |
#endif |
/trunk/kernel/arch/arm32/include/machine.h |
---|
0,0 → 1,122 |
/* |
* Copyright (c) 2007 Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
* @brief Declarations of machine specific functions. |
* |
* These functions enable to differentiate more kinds of ARM emulators |
* or CPUs. It's the same concept as "arch" functions on the architecture |
* level. |
*/ |
#ifndef KERN_arm32_MACHINE_H_ |
#define KERN_arm32_MACHINE_H_ |
#include <console/console.h> |
#include <arch/types.h> |
#include <arch/exception.h> |
#include <arch/drivers/gxemul.h> |
/** Initializes console. |
* |
* @param devno Console device number. |
*/ |
extern void machine_console_init(devno_t devno); |
/** Acquire console back for kernel. */ |
extern void machine_grab_console(void); |
/** Return console to userspace. */ |
extern void machine_release_console(void); |
/** Maps HW devices to the kernel address space using #hw_map. */ |
extern void machine_hw_map_init(void); |
/** Starts timer. */ |
extern void machine_timer_irq_start(void); |
/** Halts CPU. */ |
extern void machine_cpu_halt(void); |
/** Returns size of available memory. |
* |
* @return Size of available memory. |
*/ |
extern size_t machine_get_memory_size(void); |
/** Prints a character. |
* |
* @param ch Character to be printed. |
*/ |
extern void machine_debug_putc(char ch); |
/** Interrupt exception handler. |
* |
* @param exc_no Interrupt exception number. |
* @param istate Saved processor state. |
*/ |
extern void machine_irq_exception(int exc_no, istate_t *istate); |
/** Returns address of framebuffer device. |
* |
* @return Address of framebuffer device. |
*/ |
extern uintptr_t machine_get_fb_address(void); |
#ifdef MACHINE_GXEMUL_TESTARM |
#define machine_console_init(devno) gxemul_console_init(devno) |
#define machine_grab_console gxemul_grab_console |
#define machine_release_console gxemul_release_console |
#define machine_hw_map_init gxemul_hw_map_init |
#define machine_timer_irq_start gxemul_timer_irq_start |
#define machine_cpu_halt gxemul_cpu_halt |
#define machine_get_memory_size gxemul_get_memory_size |
#define machine_debug_putc(ch) gxemul_debug_putc(ch) |
#define machine_irq_exception(exc_no, istate) \ |
gxemul_irq_exception(exc_no, istate) |
#define machine_get_fb_address gxemul_get_fb_address |
#endif |
#endif |
/** @} |
*/ |
/trunk/kernel/arch/arm32/include/stack.h |
---|
0,0 → 1,49 |
/* |
* Copyright (c) 2007 Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
* @brief Stack constants. |
*/ |
#ifndef KERN_arm32_STACK_H_ |
#define KERN_arm32_STACK_H_ |
#define STACK_ITEM_SIZE 4 |
/** See <a href="http://www.arm.com/support/faqdev/14269.html">ABI</a> for |
* details |
*/ |
#define STACK_ALIGNMENT 8 |
#endif |
/** @} |
*/ |
/trunk/kernel/arch/arm32/include/elf.h |
---|
30,6 → 30,7 |
* @{ |
*/ |
/** @file |
* @brief ARM ELF constants. |
*/ |
#ifndef KERN_arm32_ELF_H_ |
/trunk/kernel/arch/arm32/include/memstr.h |
---|
30,6 → 30,7 |
* @{ |
*/ |
/** @file |
* @brief Memory manipulating functions declarations. |
*/ |
#ifndef KERN_arm32_MEMSTR_H_ |
/trunk/kernel/arch/arm32/include/arg.h |
---|
30,6 → 30,7 |
* @{ |
*/ |
/** @file |
* @brief Empty. |
*/ |
#ifndef KERN_arm32_ARG_H_ |
/trunk/kernel/arch/arm32/include/atomic.h |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2005 Ondrej Palkovsky |
* Copyright (c) 2007 Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
30,33 → 30,98 |
* @{ |
*/ |
/** @file |
* @brief Atomic operations. |
*/ |
#ifndef KERN_arm32_ATOMIC_H_ |
#define KERN_arm32_ATOMIC_H_ |
#define atomic_inc(x) ((void) atomic_add(x, 1)) |
#define atomic_dec(x) ((void) atomic_add(x, -1)) |
/** Atomic addition. |
* |
* @param val Where to add. |
* @param i Value to be added. |
* |
* @return Value after addition. |
*/ |
static inline long atomic_add(atomic_t *val, int i) |
{ |
int ret; |
volatile long *mem = &(val->count); |
#define atomic_postinc(x) (atomic_add(x, 1) - 1) |
#define atomic_postdec(x) (atomic_add(x, -1) + 1) |
asm volatile ( |
"1:\n" |
"ldr r2, [%1] \n" |
"add r3, r2, %2 \n" |
"str r3, %0 \n" |
"swp r3, r3, [%1] \n" |
"cmp r3, r2 \n" |
"bne 1b \n" |
#define atomic_preinc(x) atomic_add(x, 1) |
#define atomic_predec(x) atomic_add(x, -1) |
: "=m" (ret) |
: "r" (mem), "r" (i) |
: "r3", "r2" |
); |
/* Atomic addition of immediate value. |
return ret; |
} |
/** Atomic increment. |
* |
* @param val Memory location to which will be the immediate value added. |
* @param i Signed immediate that will be added to *val. |
* @param val Variable to be incremented. |
*/ |
static inline void atomic_inc(atomic_t *val) |
{ |
atomic_add(val, 1); |
} |
/** Atomic decrement. |
* |
* @return Value after addition. |
* @param val Variable to be decremented. |
*/ |
static inline long atomic_add(atomic_t *val, int i) |
static inline void atomic_dec(atomic_t *val) { |
atomic_add(val, -1); |
} |
/** Atomic pre-increment. |
* |
* @param val Variable to be incremented. |
* @return Value after incrementation. |
*/ |
static inline long atomic_preinc(atomic_t *val) |
{ |
/* TODO */ |
return (val->count += i); |
return atomic_add(val, 1); |
} |
/** Atomic pre-decrement. |
* |
* @param val Variable to be decremented. |
* @return Value after decrementation. |
*/ |
static inline long atomic_predec(atomic_t *val) |
{ |
return atomic_add(val, -1); |
} |
/** Atomic post-increment. |
* |
* @param val Variable to be incremented. |
* @return Value before incrementation. |
*/ |
static inline long atomic_postinc(atomic_t *val) |
{ |
return atomic_add(val, 1) - 1; |
} |
/** Atomic post-decrement. |
* |
* @param val Variable to be decremented. |
* @return Value before decrementation. |
*/ |
static inline long atomic_postdec(atomic_t *val) |
{ |
return atomic_add(val, -1) + 1; |
} |
#endif |
/** @} |
/trunk/kernel/arch/arm32/include/arch.h |
---|
30,6 → 30,7 |
* @{ |
*/ |
/** @file |
* @brief Empty. |
*/ |
#ifndef KERN_arm32_ARCH_H_ |
/trunk/kernel/arch/arm32/include/proc/task.h |
---|
30,6 → 30,7 |
* @{ |
*/ |
/** @file |
* @brief Task related declarations. |
*/ |
#ifndef KERN_arm32_TASK_H_ |
/trunk/kernel/arch/arm32/include/proc/thread.h |
---|
30,6 → 30,7 |
* @{ |
*/ |
/** @file |
* @brief Thread related declarations. |
*/ |
#ifndef KERN_arm32_THREAD_H_ |
46,4 → 47,3 |
/** @} |
*/ |
/trunk/kernel/arch/arm32/include/faddr.h |
---|
30,6 → 30,7 |
* @{ |
*/ |
/** @file |
* @brief Function address conversion. |
*/ |
#ifndef KERN_arm32_FADDR_H_ |
37,6 → 38,10 |
#include <arch/types.h> |
/** Calculate absolute address of function referenced by fptr pointer. |
* |
* @param fptr Function pointer. |
*/ |
#define FADDR(fptr) ((uintptr_t) (fptr)) |
#endif |
/trunk/kernel/arch/arm32/include/asm.h |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2003-2004 Jakub Jermar |
* Copyright (c) 2007 Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
30,6 → 30,7 |
* @{ |
*/ |
/** @file |
* @brief Declarations of functions implemented in assembly. |
*/ |
#ifndef KERN_arm32_ASM_H_ |
36,13 → 37,16 |
#define KERN_arm32_ASM_H_ |
#include <arch/types.h> |
#include <arch/stack.h> |
#include <config.h> |
#include <arch/interrupt.h> |
/** No such instruction on ARM to sleep CPU. */ |
static inline void cpu_sleep(void) |
{ |
/* TODO */ |
} |
/** Return base address of current stack |
/** Return base address of current stack. |
* |
* Return the base address of the current stack. |
* The stack is assumed to be STACK_SIZE bytes long. |
50,8 → 54,13 |
*/ |
static inline uintptr_t get_stack_base(void) |
{ |
/* TODO */ |
return NULL; |
uintptr_t v; |
asm volatile ( |
"and %0, sp, %1\n" |
: "=r" (v) |
: "r" (~(STACK_SIZE - 1)) |
); |
return v; |
} |
extern void cpu_halt(void); |
59,11 → 68,6 |
extern void userspace_asm(uintptr_t ustack, uintptr_t uspace_uarg, |
uintptr_t entry); |
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 |
/** @} |
/trunk/kernel/arch/arm32/include/mainpage.h |
---|
0,0 → 1,49 |
/* |
* Copyright (c) 2005 Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @mainpage HelenOS ARM 32-bit port |
* |
* |
* @section sec_arm32 ARM 32-bit port |
* arm32 port is the ninth port of SPARTAN, originally written by Michal Kebrt, |
* Petr Stepan, Pavel Jancik. The goal is to support 32-bit ARM architecture. |
* So far, it runs only in emulator. |
* |
* @subsection sec_arm32_doc Documentation |
* <ul> |
* <li>See 'kernel/doc/arm32_HOWTO' for information about getting an emulator, |
* building sources and running HelenOS. |
* </li> |
* <li>See <a href="http://www.helenos.eu/doc/slides/2007-05-21-Stepan-ARM.pdf">slides</a> |
* for some information about ARM architecture and porting HelenOS to ARM |
* (only in Czech). |
* </li> |
* </ul> |
* |
* |
*/ |
/trunk/kernel/arch/arm32/include/mm/frame.h |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* Copyright (c) 2007 Pavel Jancik, Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
30,18 → 30,30 |
* @{ |
*/ |
/** @file |
* @brief Frame related declarations. |
*/ |
#ifndef KERN_arm32_FRAME_H_ |
#define KERN_arm32_FRAME_H_ |
#define FRAME_WIDTH 0 /* TODO */ |
#define FRAME_WIDTH 12 /* 4KB frames */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#ifdef KERNEL |
#ifndef __ASM__ |
#include <arch/types.h> |
#define BOOT_PAGE_TABLE_SIZE 0x4000 |
#define BOOT_PAGE_TABLE_ADDRESS 0x4000 |
#define BOOT_PAGE_TABLE_START_FRAME (BOOT_PAGE_TABLE_ADDRESS >> FRAME_WIDTH) |
#define BOOT_PAGE_TABLE_SIZE_IN_FRAMES (BOOT_PAGE_TABLE_SIZE >> FRAME_WIDTH) |
extern uintptr_t last_frame; |
extern void frame_arch_init(void); |
extern void boot_page_table_free(void); |
#endif /* __ASM__ */ |
#endif /* KERNEL */ |
/trunk/kernel/arch/arm32/include/mm/memory_init.h |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* Copyright (c) 2007 Pavel Jancik |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
30,6 → 30,7 |
* @{ |
*/ |
/** @file |
* @brief Memory information functions declarations. |
*/ |
#ifndef KERN_arm32_MEMORY_INIT_H_ |
37,7 → 38,7 |
#include <config.h> |
#define get_memory_size() CONFIG_MEMORY_SIZE /* TODO */ |
size_t get_memory_size(void); |
#endif |
/trunk/kernel/arch/arm32/include/mm/page.h |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2003-2007 Jakub Jermar |
* Copyright (c) 2007 Pavel Jancik, Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
30,6 → 30,7 |
* @{ |
*/ |
/** @file |
* @brief Paging related declarations. |
*/ |
#ifndef KERN_arm32_PAGE_H_ |
36,6 → 37,8 |
#define KERN_arm32_PAGE_H_ |
#include <arch/mm/frame.h> |
#include <mm/mm.h> |
#include <arch/exception.h> |
#define PAGE_WIDTH FRAME_WIDTH |
#define PAGE_SIZE FRAME_SIZE |
52,62 → 55,261 |
#ifdef KERNEL |
#define PTL0_ENTRIES_ARCH 0 /* TODO */ |
#define PTL1_ENTRIES_ARCH 0 /* TODO */ |
#define PTL2_ENTRIES_ARCH 0 /* TODO */ |
#define PTL3_ENTRIES_ARCH 0 /* TODO */ |
#define PTL0_ENTRIES_ARCH (2 << 12) /* 4096 */ |
#define PTL1_ENTRIES_ARCH 0 |
#define PTL2_ENTRIES_ARCH 0 |
#define PTL0_INDEX_ARCH(vaddr) 0 /* TODO */ |
#define PTL1_INDEX_ARCH(vaddr) 0 /* TODO */ |
#define PTL2_INDEX_ARCH(vaddr) 0 /* TODO */ |
#define PTL3_INDEX_ARCH(vaddr) 0 /* TODO */ |
/* coarse page tables used (256 * 4 = 1KB per page) */ |
#define PTL3_ENTRIES_ARCH (2 << 8) /* 256 */ |
#define SET_PTL0_ADDRESS_ARCH(ptl0) |
#define PTL0_SIZE_ARCH FOUR_FRAMES |
#define PTL1_SIZE_ARCH 0 |
#define PTL2_SIZE_ARCH 0 |
#define PTL3_SIZE_ARCH ONE_FRAME |
#define GET_PTL1_ADDRESS_ARCH(ptl0, i) 0 /* TODO */ |
#define GET_PTL2_ADDRESS_ARCH(ptl1, i) 0 /* TODO */ |
#define GET_PTL3_ADDRESS_ARCH(ptl2, i) 0 /* TODO */ |
#define GET_FRAME_ADDRESS_ARCH(ptl3, i) 0 /* TODO */ |
#define PTL0_INDEX_ARCH(vaddr) (((vaddr) >> 20) & 0xfff) |
#define PTL1_INDEX_ARCH(vaddr) 0 |
#define PTL2_INDEX_ARCH(vaddr) 0 |
#define PTL3_INDEX_ARCH(vaddr) (((vaddr) >> 12) & 0x0ff) |
#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) /* TODO */ |
#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a) /* TODO */ |
#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a) /* TODO */ |
#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) /* TODO */ |
#define GET_PTL1_ADDRESS_ARCH(ptl0, i) \ |
((pte_t *) ((((pte_level0_t *)(ptl0))[(i)]).coarse_table_addr << 10)) |
#define GET_PTL2_ADDRESS_ARCH(ptl1, i) \ |
(ptl1) |
#define GET_PTL3_ADDRESS_ARCH(ptl2, i) \ |
(ptl2) |
#define GET_FRAME_ADDRESS_ARCH(ptl3, i) \ |
((uintptr_t) ((((pte_level1_t *)(ptl3))[(i)]).frame_base_addr << 12)) |
#define GET_PTL1_FLAGS_ARCH(ptl0, i) 0 /* TODO */ |
#define GET_PTL2_FLAGS_ARCH(ptl1, i) 0 /* TODO */ |
#define GET_PTL3_FLAGS_ARCH(ptl2, i) 0 /* TODO */ |
#define GET_FRAME_FLAGS_ARCH(ptl3, i) 0 /* TODO */ |
#define SET_PTL0_ADDRESS_ARCH(ptl0) \ |
(set_ptl0_addr((pte_level0_t *) (ptl0))) |
#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) \ |
(((pte_level0_t *) (ptl0))[(i)].coarse_table_addr = (a) >> 10) |
#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_level1_t *) (ptl3))[(i)].frame_base_addr = (a) >> 12) |
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) /* TODO */ |
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x) /* TODO */ |
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x) /* TODO */ |
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) /* TODO */ |
#define GET_PTL1_FLAGS_ARCH(ptl0, i) \ |
get_pt_level0_flags((pte_level0_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_level1_flags((pte_level1_t *) (ptl3), (index_t) (i)) |
#define PTE_VALID_ARCH(pte) 0 /* TODO */ |
#define PTE_PRESENT_ARCH(pte) 0 /* TODO */ |
#define PTE_GET_FRAME_ARCH(pte) 0 /* TODO */ |
#define PTE_WRITABLE_ARCH(pte) 0 /* TODO */ |
#define PTE_EXECUTABLE_ARCH(pte) 0 /* TODO */ |
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \ |
set_pt_level0_flags((pte_level0_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_level1_flags((pte_level1_t *) (ptl3), (index_t) (i), (x)) |
#define PTE_VALID_ARCH(pte) \ |
(*((uint32_t *) (pte)) != 0) |
#define PTE_PRESENT_ARCH(pte) \ |
(((pte_level0_t *) (pte))->descriptor_type != 0) |
/* pte should point into ptl3 */ |
#define PTE_GET_FRAME_ARCH(pte) \ |
(((pte_level1_t *) (pte))->frame_base_addr << FRAME_WIDTH) |
/* pte should point into ptl3 */ |
#define PTE_WRITABLE_ARCH(pte) \ |
(((pte_level1_t *) (pte))->access_permission_0 == \ |
PTE_AP_USER_RW_KERNEL_RW) |
#define PTE_EXECUTABLE_ARCH(pte) \ |
1 |
#ifndef __ASM__ |
#include <mm/mm.h> |
#include <arch/exception.h> |
/** Level 0 page table entry. */ |
typedef struct { |
/* 0b01 for coarse tables, see below for details */ |
unsigned descriptor_type : 2; |
unsigned impl_specific : 3; |
unsigned domain : 4; |
unsigned should_be_zero : 1; |
static inline int get_pt_flags(pte_t *pt, index_t i) |
/* Pointer to the coarse 2nd level page table (holding entries for small |
* (4KB) or large (64KB) pages. ARM also supports fine 2nd level page |
* tables that may hold even tiny pages (1KB) but they are bigger (4KB |
* per table in comparison with 1KB per the coarse table) |
*/ |
unsigned coarse_table_addr : 22; |
} ATTRIBUTE_PACKED pte_level0_t; |
/** Level 1 page table entry (small (4KB) pages used). */ |
typedef struct { |
/* 0b10 for small pages */ |
unsigned descriptor_type : 2; |
unsigned bufferable : 1; |
unsigned cacheable : 1; |
/* access permissions for each of 4 subparts of a page |
* (for each 1KB when small pages used */ |
unsigned access_permission_0 : 2; |
unsigned access_permission_1 : 2; |
unsigned access_permission_2 : 2; |
unsigned access_permission_3 : 2; |
unsigned frame_base_addr : 20; |
} ATTRIBUTE_PACKED pte_level1_t; |
/* Level 1 page tables access permissions */ |
/** User mode: no access, privileged mode: no access. */ |
#define PTE_AP_USER_NO_KERNEL_NO 0 |
/** User mode: no access, privileged mode: read/write. */ |
#define PTE_AP_USER_NO_KERNEL_RW 1 |
/** User mode: read only, privileged mode: read/write. */ |
#define PTE_AP_USER_RO_KERNEL_RW 2 |
/** User mode: read/write, privileged mode: read/write. */ |
#define PTE_AP_USER_RW_KERNEL_RW 3 |
/* pte_level0_t and pte_level1_t descriptor_type flags */ |
/** pte_level0_t and pte_level1_t "not present" flag (used in descriptor_type). */ |
#define PTE_DESCRIPTOR_NOT_PRESENT 0 |
/** pte_level0_t coarse page table flag (used in descriptor_type). */ |
#define PTE_DESCRIPTOR_COARSE_TABLE 1 |
/** pte_level1_t small page table flag (used in descriptor type). */ |
#define PTE_DESCRIPTOR_SMALL_PAGE 2 |
/** Sets the address of level 0 page table. |
* |
* @param pt Pointer to the page table to set. |
*/ |
static inline void set_ptl0_addr( pte_level0_t *pt) |
{ |
return 0; /* TODO */ |
asm volatile ( |
"mcr p15, 0, %0, c2, c0, 0 \n" |
: |
: "r"(pt) |
); |
} |
static inline void set_pt_flags(pte_t *pt, index_t i, int flags) |
/** Returns level 0 page table entry flags. |
* |
* @param pt Level 0 page table. |
* @param i Index of the entry to return. |
*/ |
static inline int get_pt_level0_flags(pte_level0_t *pt, index_t i) |
{ |
/* TODO */ |
return; |
pte_level0_t *p = &pt[i]; |
int np = (p->descriptor_type == PTE_DESCRIPTOR_NOT_PRESENT); |
return (np << PAGE_PRESENT_SHIFT) | (1 << PAGE_USER_SHIFT) | |
(1 << PAGE_READ_SHIFT) | (1 << PAGE_WRITE_SHIFT) | |
(1 << PAGE_EXEC_SHIFT) | (1 << PAGE_CACHEABLE_SHIFT); |
} |
/** Returns level 1 page table entry flags. |
* |
* @param pt Level 1 page table. |
* @param i Index of the entry to return. |
*/ |
static inline int get_pt_level1_flags(pte_level1_t *pt, index_t i) |
{ |
pte_level1_t *p = &pt[i]; |
int dt = p->descriptor_type; |
int ap = p->access_permission_0; |
return ((dt == PTE_DESCRIPTOR_NOT_PRESENT) << PAGE_PRESENT_SHIFT) | |
((ap == PTE_AP_USER_RO_KERNEL_RW) << PAGE_READ_SHIFT) | |
((ap == PTE_AP_USER_RW_KERNEL_RW) << PAGE_READ_SHIFT) | |
((ap == PTE_AP_USER_RW_KERNEL_RW) << PAGE_WRITE_SHIFT) | |
((ap != PTE_AP_USER_NO_KERNEL_RW) << PAGE_USER_SHIFT) | |
((ap == PTE_AP_USER_NO_KERNEL_RW) << PAGE_READ_SHIFT) | |
((ap == PTE_AP_USER_NO_KERNEL_RW) << PAGE_WRITE_SHIFT) | |
(1 << PAGE_EXEC_SHIFT) | |
(p->bufferable << PAGE_CACHEABLE); |
} |
/** Sets flags of level 0 page table entry. |
* |
* @param pt level 0 page table |
* @param i index of the entry to be changed |
* @param flags new flags |
*/ |
static inline void set_pt_level0_flags(pte_level0_t *pt, index_t i, int flags) |
{ |
pte_level0_t *p = &pt[i]; |
if (flags & PAGE_NOT_PRESENT) { |
p->descriptor_type = PTE_DESCRIPTOR_NOT_PRESENT; |
/* |
* Ensures that the entry will be recognized as valid when |
* PTE_VALID_ARCH applied. |
*/ |
p->should_be_zero = 1; |
} else { |
p->descriptor_type = PTE_DESCRIPTOR_COARSE_TABLE; |
p->should_be_zero = 0; |
} |
} |
/** Sets flags of level 1 page table entry. |
* |
* We use same access rights for the whole page. When page is not preset we |
* store 1 in acess_rigts_3 so that at least one bit is 1 (to mark correct |
* page entry, see #PAGE_VALID_ARCH). |
* |
* @param pt Level 1 page table. |
* @param i Index of the entry to be changed. |
* @param flags New flags. |
*/ |
static inline void set_pt_level1_flags(pte_level1_t *pt, index_t i, int flags) |
{ |
pte_level1_t *p = &pt[i]; |
if (flags & PAGE_NOT_PRESENT) { |
p->descriptor_type = PTE_DESCRIPTOR_NOT_PRESENT; |
p->access_permission_3 = 1; |
} else { |
p->descriptor_type = PTE_DESCRIPTOR_SMALL_PAGE; |
p->access_permission_3 = p->access_permission_0; |
} |
p->cacheable = p->bufferable = (flags & PAGE_CACHEABLE) != 0; |
/* default access permission */ |
p->access_permission_0 = p->access_permission_1 = |
p->access_permission_2 = p->access_permission_3 = |
PTE_AP_USER_NO_KERNEL_RW; |
if (flags & PAGE_USER) { |
if (flags & PAGE_READ) { |
p->access_permission_0 = p->access_permission_1 = |
p->access_permission_2 = p->access_permission_3 = |
PTE_AP_USER_RO_KERNEL_RW; |
} |
if (flags & PAGE_WRITE) { |
p->access_permission_0 = p->access_permission_1 = |
p->access_permission_2 = p->access_permission_3 = |
PTE_AP_USER_RW_KERNEL_RW; |
} |
} |
} |
extern void page_arch_init(void); |
#endif /* __ASM__ */ |
#endif /* KERNEL */ |
/trunk/kernel/arch/arm32/include/mm/asid.h |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2005 Martin Decky |
* Copyright (c) 2007 Pavel Jancik, Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
30,6 → 30,9 |
* @{ |
*/ |
/** @file |
* @brief ASIDs related declarations. |
* |
* ARM CPUs doesn't support ASIDs. |
*/ |
#ifndef KERN_arm32_ASID_H_ |
37,10 → 40,18 |
#include <arch/types.h> |
#define ASID_MAX_ARCH 3 /* TODO */ |
#define ASID_MAX_ARCH 3 /* minimal required number */ |
typedef uint8_t asid_t; |
/* |
* This works due to fact that this file is never included alone but only |
* through "generic/include/mm/asid.h" where ASID_START is defined. |
*/ |
#define asid_get() (ASID_START + 1) |
#define asid_put(asid) |
#endif |
/** @} |
/trunk/kernel/arch/arm32/include/mm/tlb.h |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* Copyright (c) 2007 Pavel Jancik |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
30,6 → 30,7 |
* @{ |
*/ |
/** @file |
* @brief TLB related declarations. |
*/ |
#ifndef KERN_arm32_TLB_H_ |
/trunk/kernel/arch/arm32/include/mm/as.h |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* Copyright (c) 2007 Pavel Jancik, Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
30,6 → 30,7 |
* @{ |
*/ |
/** @file |
* @brief Address space manipulating functions declarations. |
*/ |
#ifndef KERN_arm32_AS_H_ |
52,6 → 53,7 |
#define as_constructor_arch(as, flags) (as != as) |
#define as_destructor_arch(as) (as != as) |
#define as_create_arch(as, flags) (as != as) |
#define as_install_arch(as) |
#define as_deinstall_arch(as) |
#define as_invalidate_translation_cache(as, page, cnt) |
/trunk/kernel/arch/arm32/include/mm/page_fault.h |
---|
0,0 → 1,89 |
/* |
* Copyright (c) 2007 Pavel Jancik, Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32mm |
* @{ |
*/ |
/** @file |
* @brief Page fault related declarations. |
*/ |
#ifndef KERN_arm32_PAGE_FAULT_H_ |
#define KERN_arm32_PAGE_FAULT_H_ |
#include <arch/types.h> |
/** Decribes CP15 "fault status register" (FSR). */ |
typedef struct { |
unsigned status : 3; |
unsigned domain : 4; |
unsigned zero : 1; |
unsigned should_be_zero : 24; |
} ATTRIBUTE_PACKED fault_status_t; |
/** Help union used for casting integer value into #fault_status_t. */ |
typedef union { |
fault_status_t fs; |
uint32_t dummy; |
} fault_status_union_t; |
/** Simplified description of instruction code. |
* |
* @note Used for recognizing memory access instructions. |
* @see ARM architecture reference (chapter 3.1) |
*/ |
typedef struct { |
unsigned dummy1 : 4; |
unsigned bit4 : 1; |
unsigned bits567 : 3; |
unsigned dummy : 12; |
unsigned access : 1; |
unsigned opcode : 4; |
unsigned type : 3; |
unsigned condition : 4; |
} ATTRIBUTE_PACKED instruction_t; |
/** Help union used for casting pc register (uint_32_t) value into |
* #instruction_t pointer. |
*/ |
typedef union { |
instruction_t *instr; |
uint32_t pc; |
} instruction_union_t; |
extern void prefetch_abort(int n, istate_t *istate); |
extern void data_abort(int n, istate_t *istate); |
#endif |
/** @} |
*/ |
/trunk/kernel/arch/arm32/include/context.h |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2003-2004 Jakub Jermar |
* Copyright (c) 2007 Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
30,30 → 30,43 |
* @{ |
*/ |
/** @file |
* @brief Thread context. |
*/ |
#ifndef KERN_arm32_CONTEXT_H_ |
#define KERN_arm32_CONTEXT_H_ |
/* |
* Put one item onto the stack to support get_stack_base() and align it up. |
*/ |
#define SP_DELTA 0 /* TODO */ |
#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__ |
#include <arch/types.h> |
/* |
* Only save registers that must be preserved across function calls. |
/** Thread context containing registers that must be preserved across function |
* calls. |
*/ |
typedef struct { |
uint32_t cpu_mode; |
uintptr_t sp; |
uintptr_t pc; |
uint32_t r4; |
uint32_t r5; |
uint32_t r6; |
uint32_t r7; |
uint32_t r8; |
uint32_t r9; |
uint32_t r10; |
uint32_t r11; |
ipl_t ipl; |
} context_t; |
#endif /* __ASM__ */ |
#endif |
/trunk/kernel/arch/arm32/include/barrier.h |
---|
30,6 → 30,7 |
* @{ |
*/ |
/** @file |
* @brief Memory barriers. |
*/ |
#ifndef KERN_arm32_BARRIER_H_ |
/trunk/kernel/arch/arm32/include/debug.h |
---|
30,6 → 30,7 |
* @{ |
*/ |
/** @file |
* @brief Empty. |
*/ |
#ifndef KERN_arm32_DEBUG_H_ |
/trunk/kernel/arch/arm32/include/cpu.h |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2003-2004 Jakub Jermar |
* Copyright (c) 2007 Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
30,6 → 30,7 |
* @{ |
*/ |
/** @file |
* @brief CPU identification. |
*/ |
#ifndef KERN_arm32_CPU_H_ |
38,7 → 39,23 |
#include <arch/types.h> |
#include <arch/asm.h> |
/** Struct representing ARM CPU identifiaction. */ |
typedef struct { |
/** Implementator (vendor) number. */ |
uint32_t imp_num; |
/** Variant number. */ |
uint32_t variant_num; |
/** Architecture number. */ |
uint32_t arch_num; |
/** Primary part number. */ |
uint32_t prim_part_num; |
/** Revision number. */ |
uint32_t rev_num; |
} cpu_arch_t; |
#endif |
/trunk/kernel/arch/arm32/include/drivers/gxemul.h |
---|
0,0 → 1,79 |
/* |
* Copyright (c) 2007 Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32gxemul GXemul |
* @brief GXemul machine specific parts. |
* @ingroup arm32 |
* @{ |
*/ |
/** @file |
* @brief GXemul peripheries drivers declarations. |
*/ |
#ifndef KERN_arm32_GXEMUL_H_ |
#define KERN_arm32_GXEMUL_H_ |
#include <console/chardev.h> |
/** Last interrupt number (beginning from 0) whose status is probed |
* from interrupt controller |
*/ |
#define GXEMUL_IRQC_MAX_IRQ 8 |
/** Timer frequency */ |
#define GXEMUL_TIMER_FREQ 100 |
/** Struct containing mappings of gxemul HW devices into kernel part |
* of virtual address space. |
*/ |
typedef struct { |
uintptr_t videoram; |
uintptr_t kbd; |
uintptr_t rtc; |
uintptr_t rtc_freq; |
uintptr_t rtc_ack; |
uintptr_t irqc; |
uintptr_t irqc_mask; |
uintptr_t irqc_unmask; |
} gxemul_hw_map_t; |
extern void gxemul_hw_map_init(void); |
extern void gxemul_console_init(devno_t devno); |
extern void gxemul_release_console(void); |
extern void gxemul_grab_console(void); |
extern void gxemul_timer_irq_start(void); |
extern void gxemul_debug_putc(char ch); |
extern void gxemul_cpu_halt(void); |
extern void gxemul_irq_exception(int exc_no, istate_t *istate); |
extern size_t gxemul_get_memory_size(void); |
extern uintptr_t gxemul_get_fb_address(void); |
#endif |
/** @} |
*/ |
/trunk/kernel/arch/arm32/Makefile.inc |
---|
1,6 → 1,5 |
# |
# Copyright (c) 2005 Martin Decky |
# Copyright (c) 2007 Jakub Jermar |
# Copyright (c) 2007 Jakub Jermar, Michal Kebrt |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
32,14 → 31,26 |
BFD_NAME = elf32-little |
BFD_ARCH = arm |
BFD = elf32-little |
BFD = binary |
TARGET = arm-linux-gnu |
TOOLCHAIN_DIR = /usr/local/arm |
GCC_CFLAGS += |
KERNEL_LOAD_ADDRESS = 0x80200000 |
DEFS += -D__32_BITS__ -DMACHINE=$(MACHINE) |
ifeq ($(MACHINE), gxemul_testarm) |
DMACHINE = MACHINE_GXEMUL_TESTARM |
endif |
GCC_CFLAGS += -fno-zero-initialized-in-bss |
DEFS += -D__32_BITS__ -DKERNEL_LOAD_ADDRESS=$(KERNEL_LOAD_ADDRESS) -D$(DMACHINE) |
# Compile with framebuffer support |
ifeq ($(CONFIG_FB), y) |
DEFS += -DCONFIG_FB -DFB_INVERT_ENDIAN |
endif |
## Compile with hierarchical page tables support. |
# |
48,10 → 59,10 |
## Compile with support for address space identifiers. |
# |
# no HW support for ASIDs |
#CONFIG_ASID = y |
#CONFIG_ASID_FIFO = y |
CONFIG_ASID = y |
CONFIG_ASID_FIFO = y |
## Compile with support with software division and multiplication. |
# |
58,13 → 69,27 |
CONFIG_SOFTINT = y |
ARCH_SOURCES = \ |
arch/$(ARCH)/src/start.S \ |
arch/$(ARCH)/src/asm.S \ |
arch/$(ARCH)/src/arm32.c \ |
arch/$(ARCH)/src/start.S \ |
arch/$(ARCH)/src/context.S \ |
arch/$(ARCH)/src/dummy.S \ |
arch/$(ARCH)/src/panic.S \ |
arch/$(ARCH)/src/cpu/cpu.c \ |
arch/$(ARCH)/src/ddi/ddi.c \ |
arch/$(ARCH)/src/interrupt.c \ |
arch/$(ARCH)/src/debug/print.c \ |
arch/$(ARCH)/src/console.c \ |
arch/$(ARCH)/src/exception.c \ |
arch/$(ARCH)/src/userspace.c \ |
arch/$(ARCH)/src/mm/as.c \ |
arch/$(ARCH)/src/mm/frame.c \ |
arch/$(ARCH)/src/mm/page.c |
arch/$(ARCH)/src/mm/page.c \ |
arch/$(ARCH)/src/mm/tlb.c \ |
arch/$(ARCH)/src/mm/memory_init.c \ |
arch/$(ARCH)/src/mm/page_fault.c |
ifeq ($(MACHINE), gxemul_testarm) |
ARCH_SOURCES += arch/$(ARCH)/src/drivers/gxemul.c |
endif |
/trunk/kernel/arch/arm32/src/exception.c |
---|
0,0 → 1,387 |
/* |
* Copyright (c) 2007 Petr Stepan |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
* @brief Exception handlers and exception initialization routines. |
*/ |
#include <arch/exception.h> |
#include <arch/debug/print.h> |
#include <arch/memstr.h> |
#include <arch/regutils.h> |
#include <interrupt.h> |
#include <arch/machine.h> |
#include <arch/mm/page_fault.h> |
#include <print.h> |
#include <syscall/syscall.h> |
/** Offset used in calculation of exception handler's relative address. |
* |
* @see install_handler() |
*/ |
#define PREFETCH_OFFSET 0x8 |
/** LDR instruction's code */ |
#define LDR_OPCODE 0xe59ff000 |
/** Number of exception vectors. */ |
#define EXC_VECTORS 8 |
/** Size of memory block occupied by exception vectors. */ |
#define EXC_VECTORS_SIZE (EXC_VECTORS * 4) |
/** Switches to kernel stack and saves all registers there. |
* |
* Temporary exception stack is used to save a few registers |
* before stack switch takes place. |
*/ |
inline static void setup_stack_and_save_regs() |
{ |
asm volatile( |
"ldr r13, =exc_stack \n" |
"stmfd r13!, {r0} \n" |
"mrs r0, spsr \n" |
"and r0, r0, #0x1f \n" |
"cmp r0, #0x10 \n" |
"bne 1f \n" |
/* prev mode was usermode */ |
"ldmfd r13!, {r0} \n" |
"ldr r13, =supervisor_sp \n" |
"ldr r13, [r13] \n" |
"stmfd r13!, {lr} \n" |
"stmfd r13!, {r0-r12} \n" |
"stmfd r13!, {r13, lr}^ \n" |
"mrs r0, spsr \n" |
"stmfd r13!, {r0} \n" |
"b 2f \n" |
/* mode was not usermode */ |
"1:\n" |
"stmfd r13!, {r1, r2, r3} \n" |
"mrs r1, cpsr \n" |
"mov r2, lr \n" |
"bic r1, r1, #0x1f \n" |
"orr r1, r1, r0 \n" |
"mrs r0, cpsr \n" |
"msr cpsr_c, r1 \n" |
"mov r3, r13 \n" |
"stmfd r13!, {r2} \n" |
"mov r2, lr \n" |
"stmfd r13!, {r4-r12} \n" |
"mov r1, r13 \n" |
/* the following two lines are for debugging */ |
"mov sp, #0 \n" |
"mov lr, #0 \n" |
"msr cpsr_c, r0 \n" |
"ldmfd r13!, {r4, r5, r6, r7} \n" |
"stmfd r1!, {r4, r5, r6} \n" |
"stmfd r1!, {r7} \n" |
"stmfd r1!, {r2} \n" |
"stmfd r1!, {r3} \n" |
"mrs r0, spsr \n" |
"stmfd r1!, {r0} \n" |
"mov r13, r1 \n" |
"2:\n" |
); |
} |
/** Returns from exception mode. |
* |
* Previously saved state of registers (including control register) |
* is restored from the stack. |
*/ |
inline static void load_regs() |
{ |
asm volatile( |
"ldmfd r13!, {r0} \n" |
"msr spsr, r0 \n" |
"and r0, r0, #0x1f \n" |
"cmp r0, #0x10 \n" |
"bne 1f \n" |
/* return to user mode */ |
"ldmfd r13!, {r13, lr}^ \n" |
"b 2f \n" |
/* return to non-user mode */ |
"1:\n" |
"ldmfd r13!, {r1, r2} \n" |
"mrs r3, cpsr \n" |
"bic r3, r3, #0x1f \n" |
"orr r3, r3, r0 \n" |
"mrs r0, cpsr \n" |
"msr cpsr_c, r3 \n" |
"mov r13, r1 \n" |
"mov lr, r2 \n" |
"msr cpsr_c, r0 \n" |
/* actual return */ |
"2:\n" |
"ldmfd r13, {r0-r12, pc}^\n" |
); |
} |
/** Switch CPU to mode in which interrupts are serviced (currently it |
* is Undefined mode). |
* |
* The default mode for interrupt servicing (Interrupt Mode) |
* can not be used because of nested interrupts (which can occur |
* because interrupts are enabled in higher levels of interrupt handler). |
*/ |
inline static void switch_to_irq_servicing_mode() |
{ |
/* switch to Undefined mode */ |
asm volatile( |
/* save regs used during switching */ |
"stmfd sp!, {r0-r3} \n" |
/* save stack pointer and link register to r1, r2 */ |
"mov r1, sp \n" |
"mov r2, lr \n" |
/* mode switch */ |
"mrs r0, cpsr \n" |
"bic r0, r0, #0x1f \n" |
"orr r0, r0, #0x1b \n" |
"msr cpsr_c, r0 \n" |
/* restore saved sp and lr */ |
"mov sp, r1 \n" |
"mov lr, r2 \n" |
/* restore original regs */ |
"ldmfd sp!, {r0-r3} \n" |
); |
} |
/** Calls exception dispatch routine. */ |
#define CALL_EXC_DISPATCH(exception) \ |
asm("mov r0, %0" : : "i" (exception)); \ |
asm("mov r1, r13"); \ |
asm("bl exc_dispatch"); |
/** General exception handler. |
* |
* Stores registers, dispatches the exception, |
* and finally restores registers and returns from exception processing. |
* |
* @param exception Exception number. |
*/ |
#define PROCESS_EXCEPTION(exception) \ |
setup_stack_and_save_regs(); \ |
CALL_EXC_DISPATCH(exception) \ |
load_regs(); |
/** Updates specified exception vector to jump to given handler. |
* |
* Addresses of handlers are stored in memory following exception vectors. |
*/ |
static void install_handler (unsigned handler_addr, unsigned* vector) |
{ |
/* relative address (related to exc. vector) of the word |
* where handler's address is stored |
*/ |
volatile uint32_t handler_address_ptr = EXC_VECTORS_SIZE - PREFETCH_OFFSET; |
/* make it LDR instruction and store at exception vector */ |
*vector = handler_address_ptr | LDR_OPCODE; |
/* store handler's address */ |
*(vector + EXC_VECTORS) = handler_addr; |
} |
/** Low-level Reset Exception handler. */ |
static void reset_exception_entry() |
{ |
PROCESS_EXCEPTION(EXC_RESET); |
} |
/** Low-level Software Interrupt Exception handler. */ |
static void swi_exception_entry() |
{ |
PROCESS_EXCEPTION(EXC_SWI); |
} |
/** Low-level Undefined Instruction Exception handler. */ |
static void undef_instr_exception_entry() |
{ |
PROCESS_EXCEPTION(EXC_UNDEF_INSTR); |
} |
/** Low-level Fast Interrupt Exception handler. */ |
static void fiq_exception_entry() |
{ |
PROCESS_EXCEPTION(EXC_FIQ); |
} |
/** Low-level Prefetch Abort Exception handler. */ |
static void prefetch_abort_exception_entry() |
{ |
asm("sub lr, lr, #4"); |
PROCESS_EXCEPTION(EXC_PREFETCH_ABORT); |
} |
/** Low-level Data Abort Exception handler. */ |
static void data_abort_exception_entry() |
{ |
asm("sub lr, lr, #8"); |
PROCESS_EXCEPTION(EXC_DATA_ABORT); |
} |
/** Low-level Interrupt Exception handler. |
* |
* CPU is switched to Undefined mode before further interrupt processing |
* because of possible occurence of nested interrupt exception, which |
* would overwrite (and thus spoil) stack pointer. |
*/ |
static void irq_exception_entry() |
{ |
asm("sub lr, lr, #4"); |
setup_stack_and_save_regs(); |
switch_to_irq_servicing_mode(); |
CALL_EXC_DISPATCH(EXC_IRQ) |
load_regs(); |
} |
/** Software Interrupt handler. |
* |
* Dispatches the syscall. |
*/ |
static void swi_exception(int exc_no, istate_t *istate) |
{ |
/* |
dprintf("SYSCALL: r0-r4: %x, %x, %x, %x, %x; pc: %x\n", istate->r0, |
istate->r1, istate->r2, istate->r3, istate->r4, istate->pc); |
*/ |
istate->r0 = syscall_handler(istate->r0, istate->r1, istate->r2, |
istate->r3, istate->r4); |
} |
/** Interrupt Exception handler. |
* |
* Determines the sources of interrupt and calls their handlers. |
*/ |
static void irq_exception(int exc_no, istate_t *istate) |
{ |
machine_irq_exception(exc_no, istate); |
} |
/** Fills exception vectors with appropriate exception handlers. */ |
void install_exception_handlers(void) |
{ |
install_handler((unsigned) reset_exception_entry, |
(unsigned *) EXC_RESET_VEC); |
install_handler((unsigned) undef_instr_exception_entry, |
(unsigned *) EXC_UNDEF_INSTR_VEC); |
install_handler((unsigned) swi_exception_entry, |
(unsigned *) EXC_SWI_VEC); |
install_handler((unsigned) prefetch_abort_exception_entry, |
(unsigned *) EXC_PREFETCH_ABORT_VEC); |
install_handler((unsigned) data_abort_exception_entry, |
(unsigned *) EXC_DATA_ABORT_VEC); |
install_handler((unsigned) irq_exception_entry, |
(unsigned *) EXC_IRQ_VEC); |
install_handler((unsigned)fiq_exception_entry, |
(unsigned *) EXC_FIQ_VEC); |
} |
#ifdef HIGH_EXCEPTION_VECTORS |
/** Activates use of high exception vectors addresses. */ |
static void high_vectors(void) |
{ |
uint32_t control_reg; |
asm volatile("mrc p15, 0, %0, c1, c1" : "=r" (control_reg)); |
/* switch on the high vectors bit */ |
control_reg |= CP15_R1_HIGH_VECTORS_BIT; |
asm volatile("mcr p15, 0, %0, c1, c1" : : "r" (control_reg)); |
} |
#endif |
/** Initializes exception handling. |
* |
* Installs low-level exception handlers and then registers |
* exceptions and their handlers to kernel exception dispatcher. |
*/ |
void exception_init(void) |
{ |
#ifdef HIGH_EXCEPTION_VECTORS |
high_vectors(); |
#endif |
install_exception_handlers(); |
exc_register(EXC_IRQ, "interrupt", (iroutine) irq_exception); |
exc_register(EXC_PREFETCH_ABORT, "prefetch abort", |
(iroutine) prefetch_abort); |
exc_register(EXC_DATA_ABORT, "data abort", (iroutine) data_abort); |
exc_register(EXC_SWI, "software interrupt", (iroutine) swi_exception); |
} |
/** Prints #istate_t structure content. |
* |
* @param istate Structure to be printed. |
*/ |
void print_istate(istate_t *istate) |
{ |
dprintf("istate dump:\n"); |
dprintf(" r0: %x r1: %x r2: %x r3: %x\n", |
istate->r0, istate->r1, istate->r2, istate->r3); |
dprintf(" r4: %x r5: %x r6: %x r7: %x\n", |
istate->r4, istate->r5, istate->r6, istate->r7); |
dprintf(" r8: %x r8: %x r10: %x r11: %x\n", |
istate->r8, istate->r9, istate->r10, istate->r11); |
dprintf(" r12: %x sp: %x lr: %x spsr: %x\n", |
istate->r12, istate->sp, istate->lr, istate->spsr); |
dprintf(" pc: %x\n", istate->pc); |
} |
/** @} |
*/ |
/trunk/kernel/arch/arm32/src/ddi/ddi.c |
---|
30,6 → 30,7 |
* @{ |
*/ |
/** @file |
* @brief DDI. |
*/ |
#include <ddi/ddi.h> |
/trunk/kernel/arch/arm32/src/asm.S |
---|
0,0 → 1,98 |
# |
# Copyright (c) 2007 Michal Kebrt |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (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 memsetb |
.global memcpy |
.global memcpy_from_uspace |
.global memcpy_to_uspace |
.global memcpy_from_uspace_failover_address |
.global memcpy_to_uspace_failover_address |
memsetb: |
b _memsetb |
memcpy: |
memcpy_from_uspace: |
memcpy_to_uspace: |
add r3, r1, #3 |
bic r3, r3, #3 |
cmp r1, r3 |
stmdb sp!, {r4, lr} |
beq 4f |
1: |
cmp r2, #0 |
movne ip, #0 |
beq 3f |
2: |
ldrb r3, [ip, r1] |
strb r3, [ip, r0] |
add ip, ip, #1 |
cmp ip, r2 |
bne 2b |
3: |
mov r0, r1 |
ldmia sp!, {r4, pc} |
4: |
add r3, r0, #3 |
bic r3, r3, #3 |
cmp r0, r3 |
bne 1b |
movs r4, r2, lsr #2 |
moveq lr, r4 |
beq 6f |
mov lr, #0 |
mov ip, lr |
5: |
ldr r3, [ip, r1] |
add lr, lr, #1 |
cmp lr, r4 |
str r3, [ip, r0] |
add ip, ip, #4 |
bne 5b |
6: |
ands r4, r2, #3 |
beq 3b |
mov r3, lr, lsl #2 |
add r0, r3, r0 |
add ip, r3, r1 |
mov r2, #0 |
7: |
ldrb r3, [r2, ip] |
strb r3, [r2, r0] |
add r2, r2, #1 |
cmp r2, r4 |
bne 7b |
b 3b |
memcpy_from_uspace_failover_address: |
memcpy_to_uspace_failover_address: |
mov r0, #0 |
ldmia sp!, {r4, pc} |
/trunk/kernel/arch/arm32/src/console.c |
---|
0,0 → 1,58 |
/* |
* Copyright (c) 2007 Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
* @brief Console. |
*/ |
#include <console/console.h> |
#include <arch/console.h> |
#include <arch/machine.h> |
void console_init(devno_t devno) |
{ |
machine_console_init(devno); |
} |
/** Acquire console back for kernel. */ |
void arch_grab_console(void) |
{ |
machine_grab_console(); |
} |
/** Return console to userspace. */ |
void arch_release_console(void) |
{ |
machine_release_console(); |
} |
/** @} |
*/ |
/trunk/kernel/arch/arm32/src/arm32.c |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2003-2004 Jakub Jermar |
* Copyright (c) 2007 Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
30,63 → 30,135 |
* @{ |
*/ |
/** @file |
* @brief ARM32 architecture specific functions. |
*/ |
#include <arch.h> |
#include <arch/boot.h> |
#include <config.h> |
#include <arch/console.h> |
#include <ddi/device.h> |
#include <genarch/fb/fb.h> |
#include <genarch/fb/visuals.h> |
#include <ddi/irq.h> |
#include <arch/debug/print.h> |
#include <print.h> |
#include <config.h> |
#include <interrupt.h> |
#include <arch/regutils.h> |
#include <arch/machine.h> |
#include <userspace.h> |
/** Information about loaded tasks. */ |
bootinfo_t bootinfo; |
/** Performs arm32 specific initialization before main_bsp() is called. */ |
void arch_pre_main(void) |
{ |
/* TODO */ |
int i; |
init.cnt = bootinfo.cnt; |
for (i = 0; i < bootinfo.cnt; ++i) { |
init.tasks[i].addr = bootinfo.tasks[i].addr; |
init.tasks[i].size = bootinfo.tasks[i].size; |
} |
} |
/** Performs arm32 specific initialization before mm is initialized. */ |
void arch_pre_mm_init(void) |
{ |
/* TODO */ |
/* It is not assumed by default */ |
interrupts_disable(); |
} |
/** Performs arm32 specific initialization afterr mm is initialized. */ |
void arch_post_mm_init(void) |
{ |
/* TODO */ |
machine_hw_map_init(); |
/* Initialize exception dispatch table */ |
exception_init(); |
interrupt_init(); |
console_init(device_assign_devno()); |
#ifdef CONFIG_FB |
fb_init(machine_get_fb_address(), 640, 480, 1920, VISUAL_RGB_8_8_8); |
#endif |
} |
/** Performs arm32 specific tasks needed after cpu is initialized. |
* |
* Currently the function is empty. |
*/ |
void arch_post_cpu_init(void) |
{ |
/* TODO */ |
} |
/** Performs arm32 specific tasks needed before the multiprocessing is |
* initialized. |
* |
* Currently the function is empty because SMP is not supported. |
*/ |
void arch_pre_smp_init(void) |
{ |
/* TODO */ |
} |
/** Performs arm32 specific tasks needed after the multiprocessing is |
* initialized. |
* |
* Currently the function is empty because SMP is not supported. |
*/ |
void arch_post_smp_init(void) |
{ |
/* TODO */ |
} |
/** Perform arm32 specific tasks needed before the new task is run. */ |
/** Performs arm32 specific tasks needed before the new task is run. */ |
void before_task_runs_arch(void) |
{ |
/* TODO */ |
tlb_invalidate_all(); |
} |
/** Perform arm32 specific tasks needed before the new thread is scheduled. */ |
/** Performs arm32 specific tasks needed before the new thread is scheduled. |
* |
* It sets supervisor_sp. |
*/ |
void before_thread_runs_arch(void) |
{ |
/* TODO */ |
uint8_t *stck; |
stck = &THREAD->kstack[THREAD_STACK_SIZE - SP_DELTA]; |
supervisor_sp = (uintptr_t) stck; |
} |
/** Performs arm32 specific tasks before a thread stops running. |
* |
* Currently the function is empty. |
*/ |
void after_thread_ran_arch(void) |
{ |
/* TODO */ |
} |
void arch_reboot(void) |
/** Halts CPU. */ |
void cpu_halt(void) |
{ |
// TODO |
while (1); |
machine_cpu_halt(); |
} |
/** Reboot. */ |
void arch_reboot() |
{ |
/* not implemented */ |
for (;;) |
; |
} |
/** @} |
*/ |
/trunk/kernel/arch/arm32/src/context.S |
---|
1,5 → 1,5 |
# |
# Copyright (c) 2003-2004 Jakub Jermar |
# Copyright (c) 2007 Petr Stepan |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
32,7 → 32,28 |
.global context_restore_arch |
context_save_arch: |
/* TODO */ |
stmfd sp!, {r1} |
mrs r1, cpsr |
and r1, r1, #0x1f |
stmia r0!, {r1} |
ldmfd sp!, {r1} |
stmia r0!, {sp, lr} |
stmia r0!, {r4-r11} |
mov r0, #1 |
mov pc, lr |
context_restore_arch: |
/* TODO */ |
ldmia r0!, {r4} |
mrs r5, cpsr |
bic r5, r5, #0x1f |
orr r5, r5, r4 |
msr cpsr_c, r5 |
ldmia r0!, {sp, lr} |
ldmia r0!, {r4-r11} |
mov r0, #0 |
mov pc, lr |
/trunk/kernel/arch/arm32/src/debug/print.c |
---|
0,0 → 1,97 |
/* |
* Copyright (c) 2007 Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
* @brief Debug print functions. |
*/ |
#include <printf/printf_core.h> |
#include <arch/debug/print.h> |
#include <arch/machine.h> |
/** Prints a character to the console. |
* |
* @param ch Character to be printed. |
*/ |
static void putc(char ch) |
{ |
machine_debug_putc(ch); |
} |
/** Prints a string to the console. |
* |
* @param str String to be printed. |
* @param count Number of characters to be printed. |
* @param unused Unused parameter. |
* |
* @return Number of printed characters. |
*/ |
static int debug_write(const char *str, size_t count, void *unused) |
{ |
int i; |
for (i = 0; i < count; ++i) { |
putc(str[i]); |
} |
return i; |
} |
/** Prints a formated string. |
* |
* @param fmt "Printf-like" format. |
*/ |
void debug_printf(const char *fmt, ...) |
{ |
va_list args; |
va_start (args, fmt); |
struct printf_spec ps = { |
(int (*)(void *, size_t, void *)) debug_write, |
NULL |
}; |
printf_core(fmt, &ps, args); |
va_end(args); |
} |
/** Prints a string. |
* |
* @param str String to print. |
*/ |
void debug_puts(const char *str) |
{ |
while (*str) { |
putc(*str); |
str++; |
} |
} |
/** @} |
*/ |
/trunk/kernel/arch/arm32/src/cpu/cpu.c |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2003-2004 Jakub Jermar |
* Copyright (c) 2007 Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
30,24 → 30,102 |
* @{ |
*/ |
/** @file |
* @brief CPU identification. |
*/ |
#include <arch/cpu.h> |
#include <cpu.h> |
#include <arch.h> |
#include <print.h> |
/** Number of indexes left out in the #imp_data array */ |
#define IMP_DATA_START_OFFSET 0x40 |
/** Implementators (vendor) names */ |
static char *imp_data[] = { |
"?", /* IMP_DATA_START_OFFSET */ |
"ARM Ltd", /* 0x41 */ |
"", /* 0x42 */ |
"", /* 0x43 */ |
"Digital Equipment Corporation", /* 0x44 */ |
"", "", "", "", "", "", "", "", "", "", /* 0x45 - 0x4e */ |
"", "", "", "", "", "", "", "", "", "", /* 0x4f - 0x58 */ |
"", "", "", "", "", "", "", "", "", "", /* 0x59 - 0x62 */ |
"", "", "", "", "", "", /* 0x63 - 0x68 */ |
"Intel Corporation" /* 0x69 */ |
}; |
/** Length of the #imp_data array */ |
static int imp_data_length = sizeof(imp_data) / sizeof(char *); |
/** Architecture names */ |
static char *arch_data[] = { |
"?", /* 0x0 */ |
"4", /* 0x1 */ |
"4T", /* 0x2 */ |
"5", /* 0x3 */ |
"5T", /* 0x4 */ |
"5TE", /* 0x5 */ |
"5TEJ", /* 0x6 */ |
"6" /* 0x7 */ |
}; |
/** Length of the #arch_data array */ |
static int arch_data_length = sizeof(arch_data) / sizeof(char *); |
/** Retrieves processor identification from CP15 register 0. |
* |
* @param cpu Structure for storing CPU identification. |
*/ |
static void arch_cpu_identify(cpu_arch_t *cpu) |
{ |
uint32_t ident; |
asm volatile ( |
"mrc p15, 0, %0, c0, c0, 0\n" |
: "=r" (ident) |
); |
cpu->imp_num = ident >> 24; |
cpu->variant_num = (ident << 8) >> 28; |
cpu->arch_num = (ident << 12) >> 28; |
cpu->prim_part_num = (ident << 16) >> 20; |
cpu->rev_num = (ident << 28) >> 28; |
} |
/** Does nothing on ARM. */ |
void cpu_arch_init(void) |
{ |
} |
/** Retrieves processor identification and stores it to #CPU.arch */ |
void cpu_identify(void) |
{ |
/* TODO */ |
arch_cpu_identify(&CPU->arch); |
} |
/** Prints CPU identification. */ |
void cpu_print_report(cpu_t *m) |
{ |
/* TODO */ |
char * vendor = imp_data[0]; |
char * architecture = arch_data[0]; |
cpu_arch_t * cpu_arch = &m->arch; |
if ((cpu_arch->imp_num) > 0 && |
(cpu_arch->imp_num < (imp_data_length + IMP_DATA_START_OFFSET))) { |
vendor = imp_data[cpu_arch->imp_num - IMP_DATA_START_OFFSET]; |
} |
if ((cpu_arch->arch_num) > 0 && |
(cpu_arch->arch_num < arch_data_length)) { |
architecture = arch_data[cpu_arch->arch_num]; |
} |
printf("cpu%d: vendor=%s, architecture=ARM%s, part number=%x, " |
"variant=%x, revision=%x\n", |
m->id, vendor, architecture, cpu_arch->prim_part_num, |
cpu_arch->variant_num, cpu_arch->rev_num); |
} |
/** @} |
*/ |
/trunk/kernel/arch/arm32/src/mm/tlb.c |
---|
0,0 → 1,93 |
/* |
* Copyright (c) 2007 Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32mm |
* @{ |
*/ |
/** @file |
* @brief TLB related functions. |
*/ |
#include <mm/tlb.h> |
#include <arch/mm/asid.h> |
#include <arch/asm.h> |
#include <arch/types.h> |
#include <arch/mm/page.h> |
/** Invalidate all entries in TLB. |
* |
* @note See ARM Architecture reference section 3.7.7 for details. |
*/ |
void tlb_invalidate_all(void) |
{ |
asm volatile ( |
"eor r1, r1\n" |
"mcr p15, 0, r1, c8, c7, 0\n" |
: : : "r1" |
); |
} |
/** Invalidate all entries in TLB that belong to specified address space. |
* |
* @param asid Ignored as the ARM architecture doesn't support ASIDs. |
*/ |
void tlb_invalidate_asid(asid_t asid) |
{ |
tlb_invalidate_all(); |
} |
/** Invalidate single entry in TLB |
* |
* @param page Virtual adress of the page |
*/ |
static inline void invalidate_page(uintptr_t page) |
{ |
asm volatile ( |
"mcr p15, 0, %0, c8, c7, 1" |
: |
: "r" (page) |
); |
} |
/** Invalidate TLB entries for specified page range belonging to specified |
* address space. |
* |
* @param asid Ignored as the ARM architecture doesn't support it. |
* @param page Address of the first page whose entry is to be invalidated. |
* @param cnt Number of entries to invalidate. |
*/ |
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt) |
{ |
unsigned int i; |
for (i = 0; i < cnt; i++) |
invalidate_page(page + i * PAGE_SIZE); |
} |
/** @} |
*/ |
/trunk/kernel/arch/arm32/src/mm/as.c |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* Copyright (c) 2007 Pavel Jancik, Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
30,6 → 30,7 |
* @{ |
*/ |
/** @file |
* @brief Address space functions. |
*/ |
#include <arch/mm/as.h> |
38,23 → 39,14 |
#include <mm/as.h> |
#include <arch.h> |
/** Architecture dependent address space init. */ |
/** Architecture dependent address space init. |
* |
* Since ARM supports page tables, #as_pt_operations are used. |
*/ |
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) |
{ |
/* TODO */ |
} |
/** @} |
*/ |
/trunk/kernel/arch/arm32/src/mm/page_fault.c |
---|
0,0 → 1,212 |
/* |
* Copyright (c) 2007 Pavel Jancik, Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32mm |
* @{ |
*/ |
/** @file |
* @brief Page fault related functions. |
*/ |
#include <panic.h> |
#include <arch/exception.h> |
#include <arch/debug/print.h> |
#include <arch/mm/page_fault.h> |
#include <mm/as.h> |
#include <genarch/mm/page_pt.h> |
#include <arch.h> |
#include <interrupt.h> |
/** Returns value stored in fault status register. |
* |
* @return Value stored in CP15 fault status register (FSR). |
*/ |
static inline fault_status_t read_fault_status_register(void) |
{ |
fault_status_union_t fsu; |
/* fault status is stored in CP15 register 5 */ |
asm volatile ( |
"mrc p15, 0, %0, c5, c0, 0" |
: "=r"(fsu.dummy) |
); |
return fsu.fs; |
} |
/** Returns FAR (fault address register) content. |
* |
* @return FAR (fault address register) content (address that caused a page |
* fault) |
*/ |
static inline uintptr_t read_fault_address_register(void) |
{ |
uintptr_t ret; |
/* fault adress is stored in CP15 register 6 */ |
asm volatile ( |
"mrc p15, 0, %0, c6, c0, 0" |
: "=r"(ret) |
); |
return ret; |
} |
/** Decides whether the instruction is load/store or not. |
* |
* @param instr Instruction |
* |
* @return true when instruction is load/store, false otherwise |
*/ |
static inline bool is_load_store_instruction(instruction_t instr) |
{ |
/* load store immediate offset */ |
if (instr.type == 0x2) { |
return true; |
} |
/* load store register offset */ |
if (instr.type == 0x3 && instr.bit4 == 0) { |
return true; |
} |
/* load store multiple */ |
if (instr.type == 0x4) { |
return true; |
} |
/* oprocessor load/store */ |
if (instr.type == 0x6) { |
return true; |
} |
return false; |
} |
/** Decides whether the instruction is swap or not. |
* |
* @param instr Instruction |
* |
* @return true when instruction is swap, false otherwise |
*/ |
static inline bool is_swap_instruction(instruction_t instr) |
{ |
/* swap, swapb instruction */ |
if (instr.type == 0x0 && |
(instr.opcode == 0x8 || instr.opcode == 0xa) && |
instr.access == 0x0 && instr.bits567 == 0x4 && instr.bit4 == 1) { |
return true; |
} |
return false; |
} |
/** Decides whether read or write into memory is requested. |
* |
* @param instr_addr Address of instruction which tries to access memory. |
* @param badvaddr Virtual address the instruction tries to access. |
* |
* @return Type of access into memory, PF_ACCESS_EXEC if no memory access is |
* requested. |
*/ |
static pf_access_t get_memory_access_type(uint32_t instr_addr, |
uintptr_t badvaddr) |
{ |
instruction_union_t instr_union; |
instr_union.pc = instr_addr; |
instruction_t instr = *(instr_union.instr); |
/* undefined instructions */ |
if (instr.condition == 0xf) { |
panic("page_fault - instruction doesn't access memory " |
"(instr_code: %x, badvaddr:%x)", instr, badvaddr); |
return PF_ACCESS_EXEC; |
} |
/* load store instructions */ |
if (is_load_store_instruction(instr)) { |
if (instr.access == 1) { |
return PF_ACCESS_READ; |
} else { |
return PF_ACCESS_WRITE; |
} |
} |
/* swap, swpb instruction */ |
if (is_swap_instruction(instr)) { |
return PF_ACCESS_WRITE; |
} |
panic("page_fault - instruction doesn't access memory " |
"(instr_code: %x, badvaddr:%x)", instr, badvaddr); |
return PF_ACCESS_EXEC; |
} |
/** Handles "data abort" exception (load or store at invalid address). |
* |
* @param exc_no Exception number. |
* @param istate CPU state when exception occured. |
*/ |
void data_abort(int exc_no, istate_t *istate) |
{ |
fault_status_t fsr = read_fault_status_register(); |
uintptr_t badvaddr = read_fault_address_register(); |
pf_access_t access = get_memory_access_type(istate->pc, badvaddr); |
int ret = as_page_fault(badvaddr, access, istate); |
if (ret == AS_PF_FAULT) { |
print_istate(istate); |
dprintf("page fault - pc: %x, va: %x, status: %x(%x), " |
"access:%d\n", istate->pc, badvaddr, fsr.status, fsr, |
access); |
fault_if_from_uspace(istate, "Page fault: %#x", badvaddr); |
panic("page fault\n"); |
} |
} |
/** Handles "prefetch abort" exception (instruction couldn't be executed). |
* |
* @param exc_no Exception number. |
* @param istate CPU state when exception occured. |
*/ |
void prefetch_abort(int exc_no, istate_t *istate) |
{ |
int ret = as_page_fault(istate->pc, PF_ACCESS_EXEC, istate); |
if (ret == AS_PF_FAULT) { |
dprintf("prefetch_abort\n"); |
print_istate(istate); |
panic("page fault - prefetch_abort at address: %x\n", |
istate->pc); |
} |
} |
/** @} |
*/ |
/trunk/kernel/arch/arm32/src/mm/frame.c |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* Copyright (c) 2007 Pavel Jancik, Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
30,15 → 30,38 |
* @{ |
*/ |
/** @file |
* @brief Frame related functions. |
*/ |
#include <mm/frame.h> |
#include <arch/mm/frame.h> |
#include <config.h> |
#include <arch/debug/print.h> |
/** Create memory zones. */ |
/** Address of the last frame in the memory. */ |
uintptr_t last_frame = 0; |
/** Creates memory zones. */ |
void frame_arch_init(void) |
{ |
/* TODO */ |
/* all memory as one zone */ |
zone_create(0, ADDR2PFN(config.memory_size), |
BOOT_PAGE_TABLE_START_FRAME + BOOT_PAGE_TABLE_SIZE_IN_FRAMES, 0); |
last_frame = config.memory_size; |
/* blacklist boot page table */ |
frame_mark_unavailable(BOOT_PAGE_TABLE_START_FRAME, |
BOOT_PAGE_TABLE_SIZE_IN_FRAMES); |
} |
/** Frees the boot page table. */ |
void boot_page_table_free(void) |
{ |
int i; |
for (i = 0; i < BOOT_PAGE_TABLE_SIZE_IN_FRAMES; i++) { |
frame_free(i * FRAME_SIZE + BOOT_PAGE_TABLE_ADDRESS); |
} |
} |
/** @} |
*/ |
/trunk/kernel/arch/arm32/src/mm/memory_init.c |
---|
0,0 → 1,50 |
/* |
* Copyright (c) 2007 Pavel Jancik |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32mm |
* @{ |
*/ |
/** @file |
* @brief Memory information functions. |
*/ |
#include <arch/mm/memory_init.h> |
#include <arch/mm/page.h> |
#include <arch/machine.h> |
/** Returns memory size. |
* |
* @return Memory size in bytes |
*/ |
size_t get_memory_size(void) |
{ |
return machine_get_memory_size(); |
} |
/** @} |
*/ |
/trunk/kernel/arch/arm32/src/mm/page.c |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2003-2004 Jakub Jermar |
* Copyright (c) 2007 Pavel Jancik, Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
30,23 → 30,81 |
* @{ |
*/ |
/** @file |
* @brief Paging related functions. |
*/ |
#include <arch/mm/page.h> |
#include <genarch/mm/page_pt.h> |
#include <mm/page.h> |
#include <align.h> |
#include <config.h> |
#include <arch/exception.h> |
#include <typedefs.h> |
#include <arch/types.h> |
#include <interrupt.h> |
#include <arch/mm/frame.h> |
/** Initializes page tables. |
* |
* 1:1 virtual-physical mapping is created in kernel address space. Mapping |
* for table with exception vectors is also created. |
*/ |
void page_arch_init(void) |
{ |
uintptr_t cur; |
int flags; |
page_mapping_operations = &pt_mapping_operations; |
flags = PAGE_CACHEABLE; |
/* PA2KA(identity) mapping for all frames until last_frame */ |
for (cur = 0; cur < last_frame; cur += FRAME_SIZE) { |
page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags); |
} |
/** Map device into kernel space. */ |
/* create mapping for exception table at high offset */ |
#ifdef HIGH_EXCEPTION_VECTORS |
void *virtaddr = frame_alloc(ONE_FRAME, FRAME_KA); |
page_mapping_insert(AS_KERNEL, EXC_BASE_ADDRESS, KA2PA(virtaddr), flags); |
#else |
#error "Only high exception vector supported now" |
#endif |
as_switch(NULL, AS_KERNEL); |
boot_page_table_free(); |
} |
/** Maps device into the kernel space. |
* |
* Maps physical address of device into kernel virtual address space (so it can |
* be accessed only by kernel through virtual address). |
* |
* @param physaddr Physical address where device is connected. |
* @param size Length of area where device is present. |
* |
* @return Virtual address where device will be accessible. |
*/ |
uintptr_t hw_map(uintptr_t physaddr, size_t size) |
{ |
/* TODO */ |
return NULL; |
if (last_frame + ALIGN_UP(size, PAGE_SIZE) > |
KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) { |
panic("Unable to map physical memory %p (%d bytes)", |
physaddr, size) |
} |
uintptr_t virtaddr = PA2KA(last_frame); |
pfn_t i; |
for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++) { |
page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), |
physaddr + PFN2ADDR(i), |
PAGE_NOT_CACHEABLE | PAGE_READ | PAGE_WRITE | PAGE_KERNEL); |
} |
last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE); |
return virtaddr; |
} |
/** @} |
*/ |
/trunk/kernel/arch/arm32/src/panic.S |
---|
0,0 → 1,35 |
# |
# Copyright (c) 2007 Michal Kebrt |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (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: |
bl debug_printf |
bl cpu_halt |
/trunk/kernel/arch/arm32/src/userspace.c |
---|
0,0 → 1,105 |
/* |
* Copyright (c) 2007 Petr Stepan, Pavel Jancik |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
* @brief Userspace switch. |
*/ |
#include <userspace.h> |
/** Struct for holding all general purpose registers. |
* |
* Used to set registers when going to userspace. |
*/ |
typedef struct { |
uint32_t r0; |
uint32_t r1; |
uint32_t r2; |
uint32_t r3; |
uint32_t r4; |
uint32_t r5; |
uint32_t r6; |
uint32_t r7; |
uint32_t r8; |
uint32_t r9; |
uint32_t r10; |
uint32_t r11; |
uint32_t r12; |
uint32_t sp; |
uint32_t lr; |
uint32_t pc; |
} ustate_t; |
/** Changes processor mode and jumps to the address specified in the first |
* parameter. |
* |
* @param kernel_uarg Userspace settings (entry point, stack, ...). |
*/ |
void userspace(uspace_arg_t *kernel_uarg) |
{ |
volatile ustate_t ustate; |
/* set first parameter */ |
ustate.r0 = (uintptr_t) kernel_uarg->uspace_uarg; |
/* clear other registers */ |
ustate.r1 = ustate.r2 = ustate.r3 = ustate.r4 = ustate.r5 = |
ustate.r6 = ustate.r7 = ustate.r8 = ustate.r9 = ustate.r10 = |
ustate.r11 = ustate.r12 = ustate.lr = 0; |
/* set user stack */ |
ustate.sp = ((uint32_t)kernel_uarg->uspace_stack) + PAGE_SIZE; |
/* set where uspace execution starts */ |
ustate.pc = (uintptr_t) kernel_uarg->uspace_entry; |
/* status register in user mode */ |
ipl_t user_mode = current_status_reg_read() & |
(~STATUS_REG_MODE_MASK | USER_MODE); |
/* set user mode, set registers, jump */ |
asm volatile ( |
"mov r0, %0 \n" |
"msr spsr_c, %1 \n" |
"ldmfd r0!, {r0-r12, sp, lr}^ \n" |
"ldmfd r0!, {pc}^\n" |
: |
: "r" (&ustate), "r" (user_mode) |
: "r0", "r1" |
); |
/* unreachable */ |
while(1) |
; |
} |
/** @} |
*/ |
/trunk/kernel/arch/arm32/src/dummy.S |
---|
1,5 → 1,5 |
# |
# Copyright (c) 2003-2004 Jakub Jermar |
# Copyright (c) 2007 Michal Kebry, Pavel Jancik, Petr Stepan |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
30,55 → 30,35 |
.global calibrate_delay_loop |
.global asm_delay_loop |
.global dummy |
.global arch_grab_console |
.global arch_release_console |
.global cpu_halt |
.global fpu_context_restore |
.global fpu_context_save |
.global fpu_enable |
.global fpu_init |
.global interrupts_disable |
.global interrupts_enable |
.global interrupts_read |
.global interrupts_restore |
.global memcpy |
.global memcpy_from_uspace |
.global memcpy_to_uspace |
.global memsetb |
.global panic_printf |
.global symbol_table |
.global sys_tls_set |
.global tlb_invalidate_asid |
.global tlb_invalidate_pages |
.global userspace |
.global dummy |
calibrate_delay_loop: |
mov pc, lr |
asm_delay_loop: |
mov pc, lr |
arch_grab_console: |
arch_release_console: |
cpu_halt: |
fpu_context_restore: |
mov pc, lr |
fpu_context_save: |
mov pc, lr |
fpu_enable: |
mov pc, lr |
fpu_init: |
interrupts_disable: |
interrupts_enable: |
interrupts_read: |
interrupts_restore: |
memcpy: |
memcpy_from_uspace: |
memcpy_to_uspace: |
memsetb: |
panic_printf: |
symbol_table: |
mov pc, lr |
# not used on ARM |
sys_tls_set: |
tlb_invalidate_asid: |
tlb_invalidate_pages: |
userspace: |
dummy: |
0: |
b 0b |
mov pc, lr |
/trunk/kernel/arch/arm32/src/interrupt.c |
---|
0,0 → 1,101 |
/* |
* Copyright (c) 2007 Petr Stepan |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
* @brief Interrupts controlling routines. |
*/ |
#include <arch/asm.h> |
#include <arch/regutils.h> |
#include <ddi/irq.h> |
#include <arch/machine.h> |
#include <interrupt.h> |
/** Initial size of a table holding interrupt handlers. */ |
#define IRQ_COUNT 8 |
/** Disable interrupts. |
* |
* @return Old interrupt priority level. |
*/ |
ipl_t interrupts_disable(void) |
{ |
ipl_t ipl = current_status_reg_read(); |
current_status_reg_control_write(STATUS_REG_IRQ_DISABLED_BIT | ipl); |
return ipl; |
} |
/** Enable interrupts. |
* |
* @return Old interrupt priority level. |
*/ |
ipl_t interrupts_enable(void) |
{ |
ipl_t ipl = current_status_reg_read(); |
current_status_reg_control_write(ipl & ~STATUS_REG_IRQ_DISABLED_BIT); |
return ipl; |
} |
/** Restore interrupt priority level. |
* |
* @param ipl Saved interrupt priority level. |
*/ |
void interrupts_restore(ipl_t ipl) |
{ |
current_status_reg_control_write( |
(current_status_reg_read() & ~STATUS_REG_IRQ_DISABLED_BIT) | |
(ipl & STATUS_REG_IRQ_DISABLED_BIT)); |
} |
/** Read interrupt priority level. |
* |
* @return Current interrupt priority level. |
*/ |
ipl_t interrupts_read(void) |
{ |
return current_status_reg_read(); |
} |
/** Initialize basic tables for exception dispatching |
* and starts the timer. |
*/ |
void interrupt_init(void) |
{ |
irq_init(IRQ_COUNT, IRQ_COUNT); |
machine_timer_irq_start(); |
} |
/** @} |
*/ |
/trunk/kernel/arch/arm32/src/start.S |
---|
1,5 → 1,5 |
# |
# Copyright (c) 2003-2007 Jakub Jermar |
# Copyright (c) 2007 Michal Kebrt |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
26,10 → 26,52 |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
#include <arch/asm/boot.h> |
.text |
.global kernel_image_start |
.global exc_stack |
.global supervisor_sp |
kernel_image_start: |
/* TODO */ |
# switch to supervisor mode |
mrs r3, cpsr |
bic r3, r3, #0x1f |
orr r3, r3, #0x13 |
msr cpsr_c, r3 |
0: |
b 0b |
ldr sp, =temp_stack |
cmp r2, #0 |
beq bootinfo_end |
ldr r3, =bootinfo |
bootinfo_loop: |
ldr r4, [r1] |
str r4, [r3] |
add r1, r1, #4 |
add r3, r3, #4 |
add r2, r2, #-4 |
cmp r2, #0 |
bne bootinfo_loop |
bootinfo_end: |
bl arch_pre_main |
bl main_bsp |
.space TEMP_STACK_SIZE |
temp_stack: |
.space 1024 |
exc_stack: |
supervisor_sp: |
.space 4 |
/trunk/kernel/arch/arm32/src/drivers/gxemul.c |
---|
0,0 → 1,393 |
/* |
* Copyright (c) 2007 Michal Kebrt, Petr Stepan |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32gxemul |
* @{ |
*/ |
/** @file |
* @brief GXemul drivers. |
*/ |
#include <interrupt.h> |
#include <ipc/irq.h> |
#include <console/chardev.h> |
#include <arch/drivers/gxemul.h> |
#include <console/console.h> |
#include <sysinfo/sysinfo.h> |
#include <print.h> |
#include <ddi/device.h> |
#include <mm/page.h> |
#include <arch/machine.h> |
#include <arch/debug/print.h> |
/* Addresses of devices. */ |
#define GXEMUL_VIDEORAM 0x10000000 |
#define GXEMUL_KBD 0x10000000 |
#define GXEMUL_HALT_OFFSET 0x10 |
#define GXEMUL_RTC 0x15000000 |
#define GXEMUL_RTC_FREQ_OFFSET 0x100 |
#define GXEMUL_RTC_ACK_OFFSET 0x110 |
#define GXEMUL_IRQC 0x16000000 |
#define GXEMUL_IRQC_MASK_OFFSET 0x4 |
#define GXEMUL_IRQC_UNMASK_OFFSET 0x8 |
#define GXEMUL_MP 0x11000000 |
#define GXEMUL_MP_MEMSIZE_OFFSET 0x0090 |
#define GXEMUL_FB 0x12000000 |
/* IRQs */ |
#define GXEMUL_KBD_IRQ 2 |
#define GXEMUL_TIMER_IRQ 4 |
static gxemul_hw_map_t gxemul_hw_map; |
static chardev_t console; |
static irq_t gxemul_console_irq; |
static irq_t gxemul_timer_irq; |
static bool hw_map_init_called = false; |
static void gxemul_kbd_enable(chardev_t *dev); |
static void gxemul_kbd_disable(chardev_t *dev); |
static void gxemul_write(chardev_t *dev, const char ch); |
static char gxemul_do_read(chardev_t *dev); |
static chardev_operations_t gxemul_ops = { |
.resume = gxemul_kbd_enable, |
.suspend = gxemul_kbd_disable, |
.write = gxemul_write, |
.read = gxemul_do_read, |
}; |
/** Returns the mask of active interrupts. */ |
static inline uint32_t gxemul_irqc_get_sources(void) |
{ |
return *((uint32_t *) gxemul_hw_map.irqc); |
} |
/** Masks interrupt. |
* |
* @param irq interrupt number |
*/ |
static inline void gxemul_irqc_mask(uint32_t irq) |
{ |
*((uint32_t *) gxemul_hw_map.irqc_mask) = irq; |
} |
/** Unmasks interrupt. |
* |
* @param irq interrupt number |
*/ |
static inline void gxemul_irqc_unmask(uint32_t irq) |
{ |
*((uint32_t *) gxemul_hw_map.irqc_unmask) = irq; |
} |
/** Initializes #gxemul_hw_map. */ |
void gxemul_hw_map_init(void) |
{ |
gxemul_hw_map.videoram = hw_map(GXEMUL_VIDEORAM, PAGE_SIZE); |
gxemul_hw_map.kbd = hw_map(GXEMUL_KBD, PAGE_SIZE); |
gxemul_hw_map.rtc = hw_map(GXEMUL_RTC, PAGE_SIZE); |
gxemul_hw_map.irqc = hw_map(GXEMUL_IRQC, PAGE_SIZE); |
gxemul_hw_map.rtc_freq = gxemul_hw_map.rtc + GXEMUL_RTC_FREQ_OFFSET; |
gxemul_hw_map.rtc_ack = gxemul_hw_map.rtc + GXEMUL_RTC_ACK_OFFSET; |
gxemul_hw_map.irqc_mask = gxemul_hw_map.irqc + GXEMUL_IRQC_MASK_OFFSET; |
gxemul_hw_map.irqc_unmask = gxemul_hw_map.irqc + |
GXEMUL_IRQC_UNMASK_OFFSET; |
hw_map_init_called = true; |
} |
/** Putchar that works with gxemul. |
* |
* @param dev Not used. |
* @param ch Characted to be printed. |
*/ |
static void gxemul_write(chardev_t *dev, const char ch) |
{ |
*((char *) gxemul_hw_map.videoram) = ch; |
} |
/** Enables gxemul keyboard (interrupt unmasked). |
* |
* @param dev Not used. |
* |
* Called from getc(). |
*/ |
static void gxemul_kbd_enable(chardev_t *dev) |
{ |
gxemul_irqc_unmask(GXEMUL_KBD_IRQ); |
} |
/** Disables gxemul keyboard (interrupt masked). |
* |
* @param dev not used |
* |
* Called from getc(). |
*/ |
static void gxemul_kbd_disable(chardev_t *dev) |
{ |
gxemul_irqc_mask(GXEMUL_KBD_IRQ); |
} |
/** Read character using polling, assume interrupts disabled. |
* |
* @param dev Not used. |
*/ |
static char gxemul_do_read(chardev_t *dev) |
{ |
char ch; |
while (1) { |
ch = *((volatile char *) gxemul_hw_map.kbd); |
if (ch) { |
if (ch == '\r') |
return '\n'; |
if (ch == 0x7f) |
return '\b'; |
return ch; |
} |
} |
} |
/** Process keyboard interrupt. |
* |
* @param irq IRQ information. |
* @param arg Not used. |
*/ |
static void gxemul_irq_handler(irq_t *irq, void *arg, ...) |
{ |
if ((irq->notif_cfg.notify) && (irq->notif_cfg.answerbox)) { |
ipc_irq_send_notif(irq); |
} else { |
char ch = 0; |
ch = *((char *) gxemul_hw_map.kbd); |
if (ch == '\r') { |
ch = '\n'; |
} |
if (ch == 0x7f) { |
ch = '\b'; |
} |
chardev_push_character(&console, ch); |
} |
} |
static irq_ownership_t gxemul_claim(void) |
{ |
return IRQ_ACCEPT; |
} |
/** Acquire console back for kernel. */ |
void gxemul_grab_console(void) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&gxemul_console_irq.lock); |
gxemul_console_irq.notif_cfg.notify = false; |
spinlock_unlock(&gxemul_console_irq.lock); |
interrupts_restore(ipl); |
} |
/** Return console to userspace. */ |
void gxemul_release_console(void) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&gxemul_console_irq.lock); |
if (gxemul_console_irq.notif_cfg.answerbox) { |
gxemul_console_irq.notif_cfg.notify = true; |
} |
spinlock_unlock(&gxemul_console_irq.lock); |
interrupts_restore(ipl); |
} |
/** Initializes console object representing gxemul console. |
* |
* @param devno device number. |
*/ |
void gxemul_console_init(devno_t devno) |
{ |
chardev_initialize("gxemul_console", &console, &gxemul_ops); |
stdin = &console; |
stdout = &console; |
irq_initialize(&gxemul_console_irq); |
gxemul_console_irq.devno = devno; |
gxemul_console_irq.inr = GXEMUL_KBD_IRQ; |
gxemul_console_irq.claim = gxemul_claim; |
gxemul_console_irq.handler = gxemul_irq_handler; |
irq_register(&gxemul_console_irq); |
gxemul_irqc_unmask(GXEMUL_KBD_IRQ); |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.devno", NULL, devno); |
sysinfo_set_item_val("kbd.inr", NULL, GXEMUL_KBD_IRQ); |
sysinfo_set_item_val("kbd.address.virtual", NULL, gxemul_hw_map.kbd); |
} |
/** Starts gxemul Real Time Clock device, which asserts regular interrupts. |
* |
* @param frequency Interrupts frequency (0 disables RTC). |
*/ |
static void gxemul_timer_start(uint32_t frequency) |
{ |
*((uint32_t*) gxemul_hw_map.rtc_freq) = frequency; |
} |
static irq_ownership_t gxemul_timer_claim(void) |
{ |
return IRQ_ACCEPT; |
} |
/** Timer interrupt handler. |
* |
* @param irq Interrupt information. |
* @param arg Not used. |
*/ |
static void gxemul_timer_irq_handler(irq_t *irq, void *arg, ...) |
{ |
/* |
* We are holding a lock which prevents preemption. |
* Release the lock, call clock() and reacquire the lock again. |
*/ |
spinlock_unlock(&irq->lock); |
clock(); |
spinlock_lock(&irq->lock); |
/* acknowledge tick */ |
*((uint32_t*) gxemul_hw_map.rtc_ack) = 0; |
} |
/** Initializes and registers timer interrupt handler. */ |
static void gxemul_timer_irq_init(void) |
{ |
irq_initialize(&gxemul_timer_irq); |
gxemul_timer_irq.devno = device_assign_devno(); |
gxemul_timer_irq.inr = GXEMUL_TIMER_IRQ; |
gxemul_timer_irq.claim = gxemul_timer_claim; |
gxemul_timer_irq.handler = gxemul_timer_irq_handler; |
irq_register(&gxemul_timer_irq); |
} |
/** Starts timer. |
* |
* Initiates regular timer interrupts after initializing |
* corresponding interrupt handler. |
*/ |
void gxemul_timer_irq_start(void) |
{ |
gxemul_timer_irq_init(); |
gxemul_timer_start(GXEMUL_TIMER_FREQ); |
} |
/** Returns the size of emulated memory. |
* |
* @return Size in bytes. |
*/ |
size_t gxemul_get_memory_size(void) |
{ |
return *((int *) (GXEMUL_MP + GXEMUL_MP_MEMSIZE_OFFSET)); |
} |
/** Prints a character. |
* |
* @param ch Character to be printed. |
*/ |
void gxemul_debug_putc(char ch) |
{ |
char *addr = 0; |
if (!hw_map_init_called) { |
addr = (char *) GXEMUL_KBD; |
} else { |
addr = (char *) gxemul_hw_map.videoram; |
} |
*(addr) = ch; |
} |
/** Stops gxemul. */ |
void gxemul_cpu_halt(void) |
{ |
char * addr = 0; |
if (!hw_map_init_called) { |
addr = (char *) GXEMUL_KBD; |
} else { |
addr = (char *) gxemul_hw_map.videoram; |
} |
*(addr + GXEMUL_HALT_OFFSET) = '\0'; |
} |
/** Gxemul specific interrupt exception handler. |
* |
* Determines sources of the interrupt from interrupt controller and |
* calls high-level handlers for them. |
* |
* @param exc_no Interrupt exception number. |
* @param istate Saved processor state. |
*/ |
void gxemul_irq_exception(int exc_no, istate_t *istate) |
{ |
uint32_t sources = gxemul_irqc_get_sources(); |
int i; |
for (i = 0; i < GXEMUL_IRQC_MAX_IRQ; i++) { |
if (sources & (1 << i)) { |
irq_t *irq = irq_dispatch_and_lock(i); |
if (irq) { |
/* The IRQ handler was found. */ |
irq->handler(irq, irq->arg); |
spinlock_unlock(&irq->lock); |
} else { |
/* Spurious interrupt.*/ |
dprintf("cpu%d: spurious interrupt (inum=%d)\n", |
CPU->id, i); |
} |
} |
} |
} |
/** Returns address of framebuffer device. |
* |
* @return Address of framebuffer device. |
*/ |
uintptr_t gxemul_get_fb_address(void) |
{ |
return (uintptr_t) GXEMUL_FB; |
} |
/** @} |
*/ |
/trunk/kernel/arch/ppc32/include/mm/page.h |
---|
70,6 → 70,11 |
#define PTL2_ENTRIES_ARCH 0 |
#define PTL3_ENTRIES_ARCH 1024 |
#define PTL0_SIZE_ARCH ONE_FRAME |
#define PTL1_SIZE_ARCH 0 |
#define PTL2_SIZE_ARCH 0 |
#define PTL3_SIZE_ARCH ONE_FRAME |
#define PTL0_INDEX_ARCH(vaddr) (((vaddr) >> 22) & 0x3ff) |
#define PTL1_INDEX_ARCH(vaddr) 0 |
#define PTL2_INDEX_ARCH(vaddr) 0 |
/trunk/kernel/arch/ia32xen/include/mm/page.h |
---|
61,6 → 61,11 |
#define PTL2_ENTRIES_ARCH 0 |
#define PTL3_ENTRIES_ARCH 1024 |
#define PTL0_SIZE_ARCH ONE_FRAME |
#define PTL1_SIZE_ARCH 0 |
#define PTL2_SIZE_ARCH 0 |
#define PTL3_SIZE_ARCH ONE_FRAME |
#define PTL0_INDEX_ARCH(vaddr) (((vaddr) >> 22) & 0x3ff) |
#define PTL1_INDEX_ARCH(vaddr) 0 |
#define PTL2_INDEX_ARCH(vaddr) 0 |
/trunk/kernel/arch/amd64/include/mm/page.h |
---|
82,6 → 82,11 |
#define PTL2_ENTRIES_ARCH 512 |
#define PTL3_ENTRIES_ARCH 512 |
#define PTL0_SIZE_ARCH ONE_FRAME |
#define PTL1_SIZE_ARCH ONE_FRAME |
#define PTL2_SIZE_ARCH ONE_FRAME |
#define PTL3_SIZE_ARCH ONE_FRAME |
#define PTL0_INDEX_ARCH(vaddr) (((vaddr)>>39)&0x1ff) |
#define PTL1_INDEX_ARCH(vaddr) (((vaddr)>>30)&0x1ff) |
#define PTL2_INDEX_ARCH(vaddr) (((vaddr)>>21)&0x1ff) |
/trunk/kernel/arch/ppc64/include/mm/page.h |
---|
70,6 → 70,11 |
#define PTL2_ENTRIES_ARCH 0 |
#define PTL3_ENTRIES_ARCH 1024 |
#define PTL0_SIZE_ARCH ONE_FRAME |
#define PTL1_SIZE_ARCH 0 |
#define PTL2_SIZE_ARCH 0 |
#define PTL3_SIZE_ARCH ONE_FRAME |
#define PTL0_INDEX_ARCH(vaddr) (((vaddr) >> 22) & 0x3ff) |
#define PTL1_INDEX_ARCH(vaddr) 0 |
#define PTL2_INDEX_ARCH(vaddr) 0 |
/trunk/kernel/arch/mips32/include/mm/page.h |
---|
74,6 → 74,11 |
#define PTL2_ENTRIES_ARCH 0 |
#define PTL3_ENTRIES_ARCH 4096 |
#define PTL0_SIZE_ARCH ONE_FRAME |
#define PTL1_SIZE_ARCH 0 |
#define PTL2_SIZE_ARCH 0 |
#define PTL3_SIZE_ARCH ONE_FRAME |
#define PTL0_INDEX_ARCH(vaddr) ((vaddr)>>26) |
#define PTL1_INDEX_ARCH(vaddr) 0 |
#define PTL2_INDEX_ARCH(vaddr) 0 |
/trunk/kernel/arch/ia32/include/mm/page.h |
---|
61,6 → 61,11 |
#define PTL2_ENTRIES_ARCH 0 |
#define PTL3_ENTRIES_ARCH 1024 |
#define PTL0_SIZE_ARCH ONE_FRAME |
#define PTL1_SIZE_ARCH 0 |
#define PTL2_SIZE_ARCH 0 |
#define PTL3_SIZE_ARCH ONE_FRAME |
#define PTL0_INDEX_ARCH(vaddr) (((vaddr) >> 22) & 0x3ff) |
#define PTL1_INDEX_ARCH(vaddr) 0 |
#define PTL2_INDEX_ARCH(vaddr) 0 |