/branches/arm/kernel/arch/arm32/include/machine_func.h |
---|
File deleted |
/branches/arm/kernel/arch/arm32/include/mach/testarm/testarm.h |
---|
File deleted |
/branches/arm/kernel/arch/arm32/include/mach/integratorcp/integratorcp.h |
---|
File deleted |
/branches/arm/kernel/arch/arm32/include/machine.h |
---|
0,0 → 1,147 |
/* |
* 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> |
#ifdef MACHINE_GXEMUL_TESTARM |
#include <arch/drivers/gxemul.h> |
#endif |
#ifdef MACHINE_QEMU_ICP |
#include <arch/drivers/qemu.h> |
#endif |
/** 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); |
/** Initializes the Frame Buffer |
* |
*/ |
extern void machine_fb_init(void); |
/** 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 |
#define machine_fb_init gxemul_fb_init |
#endif |
#ifdef MACHINE_QEMU_ICP |
#define machine_console_init(devno) qemu_icp_console_init(devno) |
#define machine_grab_console qemu_icp_grab_console |
#define machine_release_console qemu_icp_release_console |
#define machine_hw_map_init qemu_icp_hw_map_init |
#define machine_timer_irq_start qemu_icp_timer_irq_start |
#define machine_cpu_halt qemu_icp_cpu_halt |
#define machine_get_memory_size qemu_icp_get_memory_size |
#define machine_debug_putc(ch) qemu_icp_debug_putc(ch) |
#define machine_irq_exception(exc_no, istate) \ |
qemu_icp_irq_exception(exc_no, istate) |
#define machine_get_fb_address qemu_icp_get_fb_address |
#define machine_fb_init qemu_icp_fb_init |
#endif |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/arm32/include/drivers/gxemul.h |
---|
0,0 → 1,80 |
/* |
* 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); |
extern void gxemul_fb_init(void); |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/arm32/include/drivers/qemu.h |
---|
0,0 → 1,81 |
/* |
* 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 arm32qemu_icp GXemul |
* @brief GXemul machine specific parts. |
* @ingroup arm32 |
* @{ |
*/ |
/** @file |
* @brief GXemul peripheries drivers declarations. |
*/ |
#ifndef KERN_arm32_QEMU_ICP_H_ |
#define KERN_arm32_QEMU_ICP_H_ |
#include <console/chardev.h> |
/** Last interrupt number (beginning from 0) whose status is probed |
* from interrupt controller |
*/ |
#define QEMU_ICP_IRQC_MAX_IRQ 8 |
/** Timer frequency */ |
#define QEMU_ICP_TIMER_FREQ 100 |
/** Struct containing mappings of qemu_icp 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; |
uintptr_t vga; |
uintptr_t cmcr; |
} qemu_icp_hw_map_t; |
extern void qemu_icp_hw_map_init(void); |
extern void qemu_icp_console_init(devno_t devno); |
extern void qemu_icp_release_console(void); |
extern void qemu_icp_grab_console(void); |
extern void qemu_icp_timer_irq_start(void); |
extern void qemu_icp_debug_putc(char ch); |
extern void qemu_icp_cpu_halt(void); |
extern void qemu_icp_irq_exception(int exc_no, istate_t *istate); |
extern size_t qemu_icp_get_memory_size(void); |
extern uintptr_t qemu_icp_get_fb_address(void); |
extern void qemu_icp_fb_init(void); |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/arm32/include/mm/page.h |
---|
94,21 → 94,21 |
/* Get PTE flags accessors for each level. */ |
#define GET_PTL1_FLAGS_ARCH(ptl0, i) \ |
get_pt_level0_flags((pte_level0_t *) (ptl0), (size_t) (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), (size_t) (i)) |
get_pt_level1_flags((pte_level1_t *) (ptl3), (index_t) (i)) |
/* Set PTE flags accessors for each level. */ |
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \ |
set_pt_level0_flags((pte_level0_t *) (ptl0), (size_t) (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), (size_t) (i), (x)) |
set_pt_level1_flags((pte_level1_t *) (ptl3), (index_t) (i), (x)) |
/* Macros for querying the last-level PTE entries. */ |
#define PTE_VALID_ARCH(pte) \ |
193,8 → 193,9 |
static inline void set_ptl0_addr(pte_level0_t *pt) |
{ |
asm volatile ( |
"mcr p15, 0, %[pt], c2, c0, 0\n" |
:: [pt] "r" (pt) |
"mcr p15, 0, %0, c2, c0, 0 \n" |
: |
: "r"(pt) |
); |
} |
204,7 → 205,7 |
* @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, size_t i) |
static inline int get_pt_level0_flags(pte_level0_t *pt, index_t i) |
{ |
pte_level0_t *p = &pt[i]; |
int np = (p->descriptor_type == PTE_DESCRIPTOR_NOT_PRESENT); |
219,7 → 220,7 |
* @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, size_t i) |
static inline int get_pt_level1_flags(pte_level1_t *pt, index_t i) |
{ |
pte_level1_t *p = &pt[i]; |
244,7 → 245,7 |
* @param i index of the entry to be changed |
* @param flags new flags |
*/ |
static inline void set_pt_level0_flags(pte_level0_t *pt, size_t i, int flags) |
static inline void set_pt_level0_flags(pte_level0_t *pt, index_t i, int flags) |
{ |
pte_level0_t *p = &pt[i]; |
272,7 → 273,7 |
* @param i Index of the entry to be changed. |
* @param flags New flags. |
*/ |
static inline void set_pt_level1_flags(pte_level1_t *pt, size_t i, int flags) |
static inline void set_pt_level1_flags(pte_level1_t *pt, index_t i, int flags) |
{ |
pte_level1_t *p = &pt[i]; |
/branches/arm/kernel/arch/arm32/include/mm/frame.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32mm |
/** @addtogroup arm32mm |
* @{ |
*/ |
/** @file |
36,8 → 36,8 |
#ifndef KERN_arm32_FRAME_H_ |
#define KERN_arm32_FRAME_H_ |
#define FRAME_WIDTH 12 /* 4KB frames */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#define FRAME_WIDTH 12 /* 4KB frames */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#ifdef KERNEL |
#ifndef __ASM__ |
44,8 → 44,8 |
#include <arch/types.h> |
#define BOOT_PAGE_TABLE_SIZE 0x4000 |
#define BOOT_PAGE_TABLE_ADDRESS 0x4000 |
#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) |
/branches/arm/kernel/arch/arm32/include/mm/tlb.h |
---|
36,6 → 36,9 |
#ifndef KERN_arm32_TLB_H_ |
#define KERN_arm32_TLB_H_ |
#define tlb_arch_init() |
#define tlb_print() |
#endif |
/** @} |
/branches/arm/kernel/arch/arm32/include/barrier.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
39,12 → 39,12 |
/* |
* TODO: implement true ARM memory barriers for macros below. |
*/ |
#define CS_ENTER_BARRIER() asm volatile ("" ::: "memory") |
#define CS_LEAVE_BARRIER() asm volatile ("" ::: "memory") |
#define CS_ENTER_BARRIER() asm volatile ("" ::: "memory") |
#define CS_LEAVE_BARRIER() asm volatile ("" ::: "memory") |
#define memory_barrier() asm volatile ("" ::: "memory") |
#define read_barrier() asm volatile ("" ::: "memory") |
#define write_barrier() asm volatile ("" ::: "memory") |
#define memory_barrier() asm volatile ("" ::: "memory") |
#define read_barrier() asm volatile ("" ::: "memory") |
#define write_barrier() asm volatile ("" ::: "memory") |
#define smc_coherence(a) |
#define smc_coherence_block(a, l) |
/branches/arm/kernel/arch/arm32/include/types.h |
---|
53,6 → 53,8 |
typedef unsigned long long uint64_t; |
typedef uint32_t size_t; |
typedef uint32_t count_t; |
typedef uint32_t index_t; |
typedef uint32_t uintptr_t; |
typedef uint32_t pfn_t; |
62,11 → 64,10 |
typedef uint32_t unative_t; |
typedef int32_t native_t; |
typedef struct { |
} fncptr_t; |
#define PRIp "x" /**< Format for uintptr_t. */ |
#define PRIs "u" /**< Format for size_t. */ |
#define PRIc "u" /**< Format for count_t. */ |
#define PRIi "u" /**< Format for index_t. */ |
#define PRId8 "d" /**< Format for int8_t. */ |
#define PRId16 "d" /**< Format for int16_t. */ |
/branches/arm/kernel/arch/arm32/include/byteorder.h |
---|
0,0 → 1,48 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
* @brief Endianness definitions. |
*/ |
#ifndef KERN_arm32_BYTEORDER_H_ |
#define KERN_arm32_BYTEORDER_H_ |
#ifdef BIG_ENDIAN |
#define ARCH_IS_BIG_ENDIAN |
#else |
#define ARCH_IS_LITTLE_ENDIAN |
#endif |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/arm32/include/asm/boot.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
37,9 → 37,26 |
#define KERN_arm32_ASM_BOOT_H_ |
/** Size of a temporary stack used for initial kernel start. */ |
#define TEMP_STACK_SIZE 0x100 |
#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 |
/** @} |
*/ |
/branches/arm/kernel/arch/arm32/include/exception.h |
---|
136,13 → 136,6 |
extern void install_exception_handlers(void); |
extern void exception_init(void); |
extern void print_istate(istate_t *istate); |
extern void reset_exception_entry(void); |
extern void irq_exception_entry(void); |
extern void fiq_exception_entry(void); |
extern void undef_instr_exception_entry(void); |
extern void prefetch_abort_exception_entry(void); |
extern void data_abort_exception_entry(void); |
extern void swi_exception_entry(void); |
#endif |
/branches/arm/kernel/arch/arm32/include/regutils.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
/** @addtogroup arm32 |
* @{ |
*/ |
/** |
57,10 → 57,7 |
static inline uint32_t nm## _status_reg_read(void) \ |
{ \ |
uint32_t retval; \ |
asm volatile( \ |
"mrs %[retval], " #reg \ |
: [retval] "=r" (retval) \ |
); \ |
asm volatile("mrs %0, " #reg : "=r" (retval)); \ |
return retval; \ |
} |
67,10 → 64,7 |
#define GEN_STATUS_WRITE(nm,reg,fieldname, field) \ |
static inline void nm## _status_reg_ ##fieldname## _write(uint32_t value) \ |
{ \ |
asm volatile( \ |
"msr " #reg "_" #field ", %[value]" \ |
:: [value] "r" (value) \ |
); \ |
asm volatile("msr " #reg "_" #field ", %0" : : "r" (value)); \ |
} |
/branches/arm/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 |
/** @} |
*/ |
/branches/arm/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 |
/** @} |
*/ |
/branches/arm/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 |
/** @} |
*/ |
/branches/arm/kernel/arch/arm32/include/atomic.h |
---|
26,10 → 26,10 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
/** @file |
* @brief Atomic operations. |
*/ |
42,26 → 42,26 |
* @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); |
asm volatile ( |
"1:\n" |
"ldr r2, [%[mem]]\n" |
"add r3, r2, %[i]\n" |
"str r3, %[ret]\n" |
"swp r3, r3, [%[mem]]\n" |
"cmp r3, r2\n" |
"bne 1b\n" |
: [ret] "=m" (ret) |
: [mem] "r" (mem), [i] "r" (i) |
"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" |
: "=m" (ret) |
: "r" (mem), "r" (i) |
: "r3", "r2" |
); |
return ret; |
} |
/branches/arm/kernel/arch/arm32/include/arch.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
36,26 → 36,6 |
#ifndef KERN_arm32_ARCH_H_ |
#define KERN_arm32_ARCH_H_ |
#define TASKMAP_MAX_RECORDS 32 |
#define CPUMAP_MAX_RECORDS 32 |
#define BOOTINFO_TASK_NAME_BUFLEN 32 |
#include <typedefs.h> |
typedef struct { |
uintptr_t addr; |
uint32_t size; |
char name[BOOTINFO_TASK_NAME_BUFLEN]; |
} utask_t; |
typedef struct { |
uint32_t cnt; |
utask_t tasks[TASKMAP_MAX_RECORDS]; |
} bootinfo_t; |
extern void arch_pre_main(void *entry, bootinfo_t *bootinfo); |
#endif |
/** @} |
/branches/arm/kernel/arch/arm32/include/asm.h |
---|
26,10 → 26,10 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
/** @file |
* @brief Declarations of functions implemented in assembly. |
*/ |
36,7 → 36,6 |
#ifndef KERN_arm32_ASM_H_ |
#define KERN_arm32_ASM_H_ |
#include <typedefs.h> |
#include <arch/types.h> |
#include <arch/stack.h> |
#include <config.h> |
47,50 → 46,19 |
{ |
} |
static inline void pio_write_8(ioport8_t *port, uint8_t v) |
{ |
*port = v; |
} |
static inline void pio_write_16(ioport16_t *port, uint16_t v) |
{ |
*port = v; |
} |
static inline void pio_write_32(ioport32_t *port, uint32_t v) |
{ |
*port = v; |
} |
static inline uint8_t pio_read_8(ioport8_t *port) |
{ |
return *port; |
} |
static inline uint16_t pio_read_16(ioport16_t *port) |
{ |
return *port; |
} |
static inline uint32_t pio_read_32(ioport32_t *port) |
{ |
return *port; |
} |
/** Return base address of current stack. |
* |
* |
* Return the base address of the current stack. |
* The stack is assumed to be STACK_SIZE bytes long. |
* The stack must start on page boundary. |
* |
*/ |
static inline uintptr_t get_stack_base(void) |
{ |
uintptr_t v; |
asm volatile ( |
"and %[v], sp, %[size]\n" |
: [v] "=r" (v) |
: [size] "r" (~(STACK_SIZE - 1)) |
"and %0, sp, %1\n" |
: "=r" (v) |
: "r" (~(STACK_SIZE - 1)) |
); |
return v; |
} |
/branches/arm/kernel/arch/arm32/src/machine_func.c |
---|
File deleted |
/branches/arm/kernel/arch/arm32/src/exc_handler.S |
---|
File deleted |
/branches/arm/kernel/arch/arm32/src/mach/testarm/testarm.c |
---|
File deleted |
Property changes: |
Deleted: svn:mergeinfo |
/branches/arm/kernel/arch/arm32/src/mach/integratorcp/integratorcp.c |
---|
File deleted |
/branches/arm/kernel/arch/arm32/src/arm32.c |
---|
34,37 → 34,36 |
*/ |
#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 <genarch/drivers/dsrln/dsrlnin.h> |
#include <genarch/drivers/dsrln/dsrlnout.h> |
#include <genarch/srln/srln.h> |
#include <sysinfo/sysinfo.h> |
#include <console/console.h> |
#include <ddi/irq.h> |
#include <arch/machine.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> |
#include <macros.h> |
#include <string.h> |
/** Performs arm32-specific initialization before main_bsp() is called. */ |
void arch_pre_main(void *entry __attribute__((unused)), bootinfo_t *bootinfo) |
/** Information about loaded tasks. */ |
bootinfo_t bootinfo; |
/** Performs arm32 specific initialization before main_bsp() is called. */ |
void arch_pre_main(void) |
{ |
unsigned 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; |
} |
init.cnt = bootinfo->cnt; |
for (i = 0; i < min3(bootinfo->cnt, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS); ++i) { |
init.tasks[i].addr = bootinfo->tasks[i].addr; |
init.tasks[i].size = bootinfo->tasks[i].size; |
str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN, |
bootinfo->tasks[i].name); |
} |
} |
/** Performs arm32 specific initialization before mm is initialized. */ |
77,19 → 76,18 |
/** Performs arm32 specific initialization afterr mm is initialized. */ |
void arch_post_mm_init(void) |
{ |
machine_init(); |
machine_hw_map_init(); |
/* Initialize exception dispatch table */ |
exception_init(); |
interrupt_init(); |
console_init(device_assign_devno()); |
#ifdef CONFIG_FB |
machine_fb_init(); |
#else |
#ifdef CONFIG_ARM_PRN |
machine_srlnout_init(); |
#endif /* CONFIG_ARM_PRN */ |
#endif /* CONFIG_FB */ |
#endif |
} |
/** Performs arm32 specific tasks needed after cpu is initialized. |
118,7 → 116,6 |
*/ |
void arch_post_smp_init(void) |
{ |
machine_input_init(); |
} |
125,6 → 122,7 |
/** Performs arm32 specific tasks needed before the new task is run. */ |
void before_task_runs_arch(void) |
{ |
tlb_invalidate_all(); |
} |
136,7 → 134,6 |
{ |
uint8_t *stck; |
tlb_invalidate_all(); |
stck = &THREAD->kstack[THREAD_STACK_SIZE - SP_DELTA]; |
supervisor_sp = (uintptr_t) stck; |
} |
159,37 → 156,9 |
void arch_reboot() |
{ |
/* not implemented */ |
while (1); |
for (;;) |
; |
} |
/** Construct function pointer |
* |
* @param fptr function pointer structure |
* @param addr function address |
* @param caller calling function address |
* |
* @return address of the function pointer |
* |
*/ |
void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller) |
{ |
return addr; |
} |
/** Acquire console back for kernel. */ |
void arch_grab_console(void) |
{ |
machine_grab_console(); |
#ifdef CONFIG_FB |
fb_redraw(); |
#endif |
} |
/** Return console to userspace. */ |
void arch_release_console(void) |
{ |
machine_release_console(); |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/arm32/src/drivers/gxemul.c |
---|
0,0 → 1,400 |
/* |
* 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> |
#include <genarch/fb/fb.h> |
#include <genarch/fb/visuals.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 the gxemul testarm frame buffer */ |
void gxemul_fb_init(void) |
{ |
fb_init(gxemul_get_fb_address(), 640, 480, 1920, VISUAL_RGB_8_8_8); |
} |
/** 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; |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/arm32/src/drivers/qemu.c |
---|
0,0 → 1,432 |
/* |
* 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 arm32qemu_icp |
* @{ |
*/ |
/** @file |
* @brief QEMU icp drivers. |
*/ |
#include <interrupt.h> |
#include <ipc/irq.h> |
#include <console/chardev.h> |
#include <arch/drivers/qemu.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> |
#include <genarch/fb/fb.h> |
#include <genarch/fb/visuals.h> |
/* Addresses of devices. */ |
#define QEMU_ICP_VIDEORAM 0x16000000 |
#define QEMU_ICP_KBD 0x18000000 |
#define QEMU_ICP_HALT_OFFSET 0x10 |
#define QEMU_ICP_RTC 0x13000000 |
#define QEMU_ICP_RTC_FREQ_OFFSET 0x100 |
#define QEMU_ICP_RTC_ACK_OFFSET 0x110 |
#define QEMU_ICP_IRQC 0x14000000 |
#define QEMU_ICP_IRQC_MASK_OFFSET 0x8 |
#define QEMU_ICP_IRQC_UNMASK_OFFSET 0xC |
#define QEMU_ICP_MP 0x11000000 |
#define QEMU_ICP_MP_MEMSIZE_OFFSET 0x0090 |
#define QEMU_ICP_FB 0x94000 |
#define ICP_VGA 0xC0000000 |
#define ICP_CMCR 0x10000000 |
/* IRQs */ |
#define QEMU_ICP_KBD_IRQ 3 |
#define QEMU_ICP_TIMER_IRQ 5 |
static qemu_icp_hw_map_t qemu_icp_hw_map; |
static chardev_t console; |
static irq_t qemu_icp_console_irq; |
static irq_t qemu_icp_timer_irq; |
static bool hw_map_init_called = false; |
static bool vga_init = false; |
static void qemu_icp_kbd_enable(chardev_t *dev); |
static void qemu_icp_kbd_disable(chardev_t *dev); |
static void qemu_icp_write(chardev_t *dev, const char ch); |
static char qemu_icp_do_read(chardev_t *dev); |
void icp_vga_init(void); |
static chardev_operations_t qemu_icp_ops = { |
.resume = qemu_icp_kbd_enable, |
.suspend = qemu_icp_kbd_disable, |
.write = qemu_icp_write, |
.read = qemu_icp_do_read, |
}; |
/** Initializes the vga |
* |
*/ |
void icp_vga_init(void) |
{ |
*(uint32_t*)((char *)(qemu_icp_hw_map.cmcr)+0x14) = 0xA05F0000; |
*(uint32_t*)((char *)(qemu_icp_hw_map.cmcr)+0x1C) = 0x12C11000; |
*(uint32_t*)qemu_icp_hw_map.vga = 0x3F1F3F9C; |
*(uint32_t*)((char *)(qemu_icp_hw_map.vga) + 0x4) = 0x080B61DF; |
*(uint32_t*)((char *)(qemu_icp_hw_map.vga) + 0x8) = 0x067F3800; |
*(uint32_t*)((char *)(qemu_icp_hw_map.vga) + 0x10) = QEMU_ICP_FB; |
*(uint32_t *)((char *)(qemu_icp_hw_map.vga) + 0x1C) = 0x182B; |
*(uint32_t*)((char *)(qemu_icp_hw_map.cmcr)+0xC) = 0x33805000; |
} |
/** Returns the mask of active interrupts. */ |
static inline uint32_t qemu_icp_irqc_get_sources(void) |
{ |
return *((uint32_t *) qemu_icp_hw_map.irqc); |
} |
/** Masks interrupt. |
* |
* @param irq interrupt number |
*/ |
static inline void qemu_icp_irqc_mask(uint32_t irq) |
{ |
*((uint32_t *) qemu_icp_hw_map.irqc_mask) = irq; |
} |
/** Unmasks interrupt. |
* |
* @param irq interrupt number |
*/ |
static inline void qemu_icp_irqc_unmask(uint32_t irq) |
{ |
*((uint32_t *) qemu_icp_hw_map.irqc_unmask) = irq; |
} |
/** Initializes the icp frame buffer */ |
void qemu_icp_fb_init(void) |
{ |
fb_init(qemu_icp_get_fb_address(), 640, 480, 2560, VISUAL_BGR_8_8_8_0); |
} |
/** Initializes #qemu_icp_hw_map. */ |
void qemu_icp_hw_map_init(void) |
{ |
qemu_icp_hw_map.videoram = hw_map(QEMU_ICP_VIDEORAM, PAGE_SIZE); |
qemu_icp_hw_map.kbd = hw_map(QEMU_ICP_KBD, PAGE_SIZE); |
qemu_icp_hw_map.rtc = hw_map(QEMU_ICP_RTC, PAGE_SIZE); |
qemu_icp_hw_map.irqc = hw_map(QEMU_ICP_IRQC, PAGE_SIZE); |
qemu_icp_hw_map.rtc_freq = qemu_icp_hw_map.rtc + QEMU_ICP_RTC_FREQ_OFFSET; |
qemu_icp_hw_map.rtc_ack = qemu_icp_hw_map.rtc + QEMU_ICP_RTC_ACK_OFFSET; |
qemu_icp_hw_map.irqc_mask = qemu_icp_hw_map.irqc + QEMU_ICP_IRQC_MASK_OFFSET; |
qemu_icp_hw_map.irqc_unmask = qemu_icp_hw_map.irqc + |
QEMU_ICP_IRQC_UNMASK_OFFSET; |
qemu_icp_hw_map.cmcr = hw_map(ICP_CMCR, PAGE_SIZE); |
qemu_icp_hw_map.vga = hw_map(ICP_VGA, PAGE_SIZE); |
//icp_vga_init(); |
hw_map_init_called = true; |
} |
/** Putchar that works with qemu_icp. |
* |
* @param dev Not used. |
* @param ch Characted to be printed. |
*/ |
static void qemu_icp_write(chardev_t *dev, const char ch) |
{ |
*((char *) qemu_icp_hw_map.videoram) = ch; |
} |
/** Enables qemu_icp keyboard (interrupt unmasked). |
* |
* @param dev Not used. |
* |
* Called from getc(). |
*/ |
static void qemu_icp_kbd_enable(chardev_t *dev) |
{ |
qemu_icp_irqc_unmask(QEMU_ICP_KBD_IRQ); |
} |
/** Disables qemu_icp keyboard (interrupt masked). |
* |
* @param dev not used |
* |
* Called from getc(). |
*/ |
static void qemu_icp_kbd_disable(chardev_t *dev) |
{ |
qemu_icp_irqc_mask(QEMU_ICP_KBD_IRQ); |
} |
/** Read character using polling, assume interrupts disabled. |
* |
* @param dev Not used. |
*/ |
static char qemu_icp_do_read(chardev_t *dev) |
{ |
char ch; |
while (1) { |
ch = *((volatile char *) qemu_icp_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 qemu_icp_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 *) qemu_icp_hw_map.kbd); |
if (ch == '\r') { |
ch = '\n'; |
} |
if (ch == 0x7f) { |
ch = '\b'; |
} |
chardev_push_character(&console, ch); |
} |
} |
static irq_ownership_t qemu_icp_claim(void) |
{ |
return IRQ_ACCEPT; |
} |
/** Acquire console back for kernel. */ |
void qemu_icp_grab_console(void) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&qemu_icp_console_irq.lock); |
qemu_icp_console_irq.notif_cfg.notify = false; |
spinlock_unlock(&qemu_icp_console_irq.lock); |
interrupts_restore(ipl); |
} |
/** Return console to userspace. */ |
void qemu_icp_release_console(void) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&qemu_icp_console_irq.lock); |
if (qemu_icp_console_irq.notif_cfg.answerbox) { |
qemu_icp_console_irq.notif_cfg.notify = true; |
} |
spinlock_unlock(&qemu_icp_console_irq.lock); |
interrupts_restore(ipl); |
} |
/** Initializes console object representing qemu_icp console. |
* |
* @param devno device number. |
*/ |
void qemu_icp_console_init(devno_t devno) |
{ |
chardev_initialize("qemu_icp_console", &console, &qemu_icp_ops); |
stdin = &console; |
stdout = &console; |
irq_initialize(&qemu_icp_console_irq); |
qemu_icp_console_irq.devno = devno; |
qemu_icp_console_irq.inr = QEMU_ICP_KBD_IRQ; |
qemu_icp_console_irq.claim = qemu_icp_claim; |
qemu_icp_console_irq.handler = qemu_icp_irq_handler; |
irq_register(&qemu_icp_console_irq); |
qemu_icp_irqc_unmask(QEMU_ICP_KBD_IRQ); |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.devno", NULL, devno); |
sysinfo_set_item_val("kbd.inr", NULL, QEMU_ICP_KBD_IRQ); |
sysinfo_set_item_val("kbd.address.virtual", NULL, qemu_icp_hw_map.kbd); |
} |
/** Starts qemu_icp Real Time Clock device, which asserts regular interrupts. |
* |
* @param frequency Interrupts frequency (0 disables RTC). |
*/ |
static void qemu_icp_timer_start(uint32_t frequency) |
{ |
*((uint32_t*) qemu_icp_hw_map.rtc_freq) = frequency; |
} |
static irq_ownership_t qemu_icp_timer_claim(void) |
{ |
return IRQ_ACCEPT; |
} |
/** Timer interrupt handler. |
* |
* @param irq Interrupt information. |
* @param arg Not used. |
*/ |
static void qemu_icp_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*) qemu_icp_hw_map.rtc_ack) = 0; |
} |
/** Initializes and registers timer interrupt handler. */ |
static void qemu_icp_timer_irq_init(void) |
{ |
irq_initialize(&qemu_icp_timer_irq); |
qemu_icp_timer_irq.devno = device_assign_devno(); |
qemu_icp_timer_irq.inr = QEMU_ICP_TIMER_IRQ; |
qemu_icp_timer_irq.claim = qemu_icp_timer_claim; |
qemu_icp_timer_irq.handler = qemu_icp_timer_irq_handler; |
irq_register(&qemu_icp_timer_irq); |
} |
/** Starts timer. |
* |
* Initiates regular timer interrupts after initializing |
* corresponding interrupt handler. |
*/ |
void qemu_icp_timer_irq_start(void) |
{ |
qemu_icp_timer_irq_init(); |
qemu_icp_timer_start(QEMU_ICP_TIMER_FREQ); |
} |
/** Returns the size of emulated memory. |
* |
* @return Size in bytes. |
*/ |
size_t qemu_icp_get_memory_size(void) |
{ |
//return *((int *) (QEMU_ICP_MP + QEMU_ICP_MP_MEMSIZE_OFFSET)); |
return 0x2000000; |
} |
/** Prints a character. |
* |
* @param ch Character to be printed. |
*/ |
void qemu_icp_debug_putc(char ch) |
{ |
char *addr = 0; |
if (!hw_map_init_called) { |
addr = (char *) QEMU_ICP_KBD; |
} else { |
addr = (char *) qemu_icp_hw_map.videoram; |
} |
if (ch == '\n') |
*(addr) = '\r'; |
*(addr) = ch; |
} |
/** Stops qemu_icp. */ |
void qemu_icp_cpu_halt(void) |
{ |
char * addr = 0; |
if (!hw_map_init_called) { |
addr = (char *) QEMU_ICP_KBD; |
} else { |
addr = (char *) qemu_icp_hw_map.videoram; |
} |
*(addr + QEMU_ICP_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 qemu_icp_irq_exception(int exc_no, istate_t *istate) |
{ |
uint32_t sources = qemu_icp_irqc_get_sources(); |
int i; |
for (i = 0; i < QEMU_ICP_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 qemu_icp_get_fb_address(void) |
{ |
if (!vga_init) { |
icp_vga_init(); |
vga_init = true; |
} |
return (uintptr_t) QEMU_ICP_FB; |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/arm32/src/asm.S |
---|
30,7 → 30,6 |
.text |
.global memsetb |
.global memsetw |
.global memcpy |
.global memcpy_from_uspace |
.global memcpy_to_uspace |
40,9 → 39,6 |
memsetb: |
b _memsetb |
memsetw: |
b _memsetw |
memcpy: |
memcpy_from_uspace: |
memcpy_to_uspace: |
/branches/arm/kernel/arch/arm32/src/userspace.c |
---|
90,11 → 90,12 |
/* set user mode, set registers, jump */ |
asm volatile ( |
"mov sp, %[ustate]\n" |
"msr spsr_c, %[user_mode]\n" |
"ldmfd sp!, {r0-r12, sp, lr}^\n" |
"mov sp, %0 \n" |
"msr spsr_c, %1 \n" |
"ldmfd sp!, {r0-r12, sp, lr}^ \n" |
"ldmfd sp!, {pc}^\n" |
:: [ustate] "r" (&ustate), [user_mode] "r" (user_mode) |
: |
: "r" (&ustate), "r" (user_mode) |
); |
/* unreachable */ |
/branches/arm/kernel/arch/arm32/src/exception.c |
---|
34,12 → 34,13 |
*/ |
#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 <arch/barrier.h> |
#include <arch/machine.h> |
#include <print.h> |
#include <syscall/syscall.h> |
58,6 → 59,153 |
/** 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. |
79,6 → 227,62 |
} |
/** Low-level Reset Exception handler. */ |
static void reset_exception_entry(void) |
{ |
PROCESS_EXCEPTION(EXC_RESET); |
} |
/** Low-level Software Interrupt Exception handler. */ |
static void swi_exception_entry(void) |
{ |
PROCESS_EXCEPTION(EXC_SWI); |
} |
/** Low-level Undefined Instruction Exception handler. */ |
static void undef_instr_exception_entry(void) |
{ |
PROCESS_EXCEPTION(EXC_UNDEF_INSTR); |
} |
/** Low-level Fast Interrupt Exception handler. */ |
static void fiq_exception_entry(void) |
{ |
PROCESS_EXCEPTION(EXC_FIQ); |
} |
/** Low-level Prefetch Abort Exception handler. */ |
static void prefetch_abort_exception_entry(void) |
{ |
asm("sub lr, lr, #4"); |
PROCESS_EXCEPTION(EXC_PREFETCH_ABORT); |
} |
/** Low-level Data Abort Exception handler. */ |
static void data_abort_exception_entry(void) |
{ |
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(void) |
{ |
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. |
89,6 → 293,15 |
istate->r3, istate->r4, istate->r5, istate->r6); |
} |
/** 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) |
{ |
110,7 → 323,7 |
install_handler((unsigned) irq_exception_entry, |
(unsigned *) EXC_IRQ_VEC); |
install_handler((unsigned) fiq_exception_entry, |
install_handler((unsigned)fiq_exception_entry, |
(unsigned *) EXC_FIQ_VEC); |
} |
120,32 → 333,17 |
{ |
uint32_t control_reg; |
asm volatile ( |
"mrc p15, 0, %[control_reg], c1, c1" |
: [control_reg] "=r" (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, %[control_reg], c1, c1" |
:: [control_reg] "r" (control_reg) |
); |
asm volatile("mcr p15, 0, %0, c1, c1" : : "r" (control_reg)); |
} |
#endif |
/** 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); |
} |
/** Initializes exception handling. |
* |
* |
* Installs low-level exception handlers and then registers |
* exceptions and their handlers to kernel exception dispatcher. |
*/ |
169,18 → 367,18 |
*/ |
void print_istate(istate_t *istate) |
{ |
printf("istate dump:\n"); |
printf(" r0: %x r1: %x r2: %x r3: %x\n", |
dprintf("istate dump:\n"); |
dprintf(" r0: %x r1: %x r2: %x r3: %x\n", |
istate->r0, istate->r1, istate->r2, istate->r3); |
printf(" r4: %x r5: %x r6: %x r7: %x\n", |
dprintf(" r4: %x r5: %x r6: %x r7: %x\n", |
istate->r4, istate->r5, istate->r6, istate->r7); |
printf(" r8: %x r8: %x r10: %x r11: %x\n", |
dprintf(" r8: %x r8: %x r10: %x r11: %x\n", |
istate->r8, istate->r9, istate->r10, istate->r11); |
printf(" r12: %x sp: %x lr: %x spsr: %x\n", |
dprintf(" r12: %x sp: %x lr: %x spsr: %x\n", |
istate->r12, istate->sp, istate->lr, istate->spsr); |
printf(" pc: %x\n", istate->pc); |
dprintf(" pc: %x\n", istate->pc); |
} |
/** @} |
/branches/arm/kernel/arch/arm32/src/mm/page_fault.c |
---|
34,6 → 34,7 |
*/ |
#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> |
48,13 → 49,12 |
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, %[dummy], c5, c0, 0" |
: [dummy] "=r" (fsu.dummy) |
"mrc p15, 0, %0, c5, c0, 0" |
: "=r"(fsu.dummy) |
); |
return fsu.fs; |
} |
61,18 → 61,17 |
/** Returns FAR (fault address register) content. |
* |
* @return FAR (fault address register) content (address that caused a page |
* fault) |
* 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, %[ret], c6, c0, 0" |
: [ret] "=r" (ret) |
"mrc p15, 0, %0, c6, c0, 0" |
: "=r"(ret) |
); |
return ret; |
} |
81,26 → 80,29 |
* @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) |
if (instr.type == 0x2) { |
return true; |
} |
/* load store register offset */ |
if ((instr.type == 0x3) && (instr.bit4 == 0)) |
if (instr.type == 0x3 && instr.bit4 == 0) { |
return true; |
} |
/* load store multiple */ |
if (instr.type == 0x4) |
if (instr.type == 0x4) { |
return true; |
} |
/* oprocessor load/store */ |
if (instr.type == 0x6) |
if (instr.type == 0x6) { |
return true; |
} |
return false; |
} |
113,11 → 115,12 |
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)) |
if (instr.type == 0x0 && |
(instr.opcode == 0x8 || instr.opcode == 0xa) && |
instr.access == 0x0 && instr.bits567 == 0x4 && instr.bit4 == 1) { |
return true; |
} |
return false; |
} |
139,8 → 142,8 |
/* undefined instructions */ |
if (instr.condition == 0xf) { |
panic("page_fault - instruction does not access memory " |
"(instr_code: %x, badvaddr:%x).", instr, badvaddr); |
panic("page_fault - instruction doesn't access memory " |
"(instr_code: %x, badvaddr:%x)", instr, badvaddr); |
return PF_ACCESS_EXEC; |
} |
159,7 → 162,7 |
} |
panic("page_fault - instruction doesn't access memory " |
"(instr_code: %x, badvaddr:%x).", instr, badvaddr); |
"(instr_code: %x, badvaddr:%x)", instr, badvaddr); |
return PF_ACCESS_EXEC; |
} |
181,12 → 184,12 |
if (ret == AS_PF_FAULT) { |
print_istate(istate); |
printf("page fault - pc: %x, va: %x, status: %x(%x), " |
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."); |
fault_if_from_uspace(istate, "Page fault: %#x", badvaddr); |
panic("page fault\n"); |
} |
} |
200,9 → 203,9 |
int ret = as_page_fault(istate->pc, PF_ACCESS_EXEC, istate); |
if (ret == AS_PF_FAULT) { |
printf("prefetch_abort\n"); |
dprintf("prefetch_abort\n"); |
print_istate(istate); |
panic("page fault - prefetch_abort at address: %x.", |
panic("page fault - prefetch_abort at address: %x\n", |
istate->pc); |
} |
} |
/branches/arm/kernel/arch/arm32/src/mm/frame.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32mm |
/** @addtogroup arm32mm |
* @{ |
*/ |
/** @file |
37,6 → 37,7 |
#include <arch/mm/frame.h> |
#include <arch/machine.h> |
#include <config.h> |
#include <arch/debug/print.h> |
/** Address of the last frame in the memory. */ |
uintptr_t last_frame = 0; |
44,25 → 45,23 |
/** Creates memory zones. */ |
void frame_arch_init(void) |
{ |
/* all memory as one zone */ |
zone_create(0, ADDR2PFN(machine_get_memory_size()), |
BOOT_PAGE_TABLE_START_FRAME + BOOT_PAGE_TABLE_SIZE_IN_FRAMES, 0); |
last_frame = machine_get_memory_size(); |
/* All memory as one zone */ |
zone_create(0, ADDR2PFN(last_frame), |
BOOT_PAGE_TABLE_START_FRAME + BOOT_PAGE_TABLE_SIZE_IN_FRAMES, 0); |
/* blacklist boot page table */ |
frame_mark_unavailable(BOOT_PAGE_TABLE_START_FRAME, |
BOOT_PAGE_TABLE_SIZE_IN_FRAMES); |
machine_frame_init(); |
} |
/** Frees the boot page table. */ |
void boot_page_table_free(void) |
{ |
unsigned int i; |
for (i = 0; i < BOOT_PAGE_TABLE_SIZE_IN_FRAMES; i++) |
int i; |
for (i = 0; i < BOOT_PAGE_TABLE_SIZE_IN_FRAMES; i++) { |
frame_free(i * FRAME_SIZE + BOOT_PAGE_TABLE_ADDRESS); |
} |
} |
/** @} |
/branches/arm/kernel/arch/arm32/src/mm/tlb.c |
---|
48,7 → 48,7 |
asm volatile ( |
"eor r1, r1\n" |
"mcr p15, 0, r1, c8, c7, 0\n" |
::: "r1" |
: : : "r1" |
); |
} |
68,8 → 68,9 |
static inline void invalidate_page(uintptr_t page) |
{ |
asm volatile ( |
"mcr p15, 0, %[page], c8, c7, 1\n" |
:: [page] "r" (page) |
"mcr p15, 0, %0, c8, c7, 1" |
: |
: "r" (page) |
); |
} |
80,7 → 81,7 |
* @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 __attribute__((unused)), uintptr_t page, size_t cnt) |
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt) |
{ |
unsigned int i; |
88,13 → 89,5 |
invalidate_page(page + i * PAGE_SIZE); |
} |
void tlb_arch_init(void) |
{ |
} |
void tlb_print(void) |
{ |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/arm32/src/mm/page.c |
---|
51,15 → 51,19 |
*/ |
void page_arch_init(void) |
{ |
int flags = PAGE_CACHEABLE; |
uintptr_t cur; |
int flags; |
page_mapping_operations = &pt_mapping_operations; |
uintptr_t cur; |
/* Kernel identity mapping */ |
for (cur = 0; cur < last_frame; cur += FRAME_SIZE) |
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); |
} |
/* Create mapping for exception table at high offset */ |
/* 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); |
66,9 → 70,9 |
#else |
#error "Only high exception vector supported now" |
#endif |
as_switch(NULL, AS_KERNEL); |
boot_page_table_free(); |
} |
86,10 → 90,10 |
{ |
if (last_frame + ALIGN_UP(size, PAGE_SIZE) > |
KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) { |
panic("Unable to map physical memory %p (%d bytes).", |
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++) { |
97,7 → 101,7 |
physaddr + PFN2ADDR(i), |
PAGE_NOT_CACHEABLE | PAGE_READ | PAGE_WRITE | PAGE_KERNEL); |
} |
last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE); |
return virtaddr; |
} |
/branches/arm/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) |
{ |
unsigned 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++; |
} |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/arm32/src/cpu/cpu.c |
---|
36,7 → 36,7 |
#include <arch/cpu.h> |
#include <cpu.h> |
#include <arch.h> |
#include <print.h> |
#include <print.h> |
/** Number of indexes left out in the #imp_data array */ |
#define IMP_DATA_START_OFFSET 0x40 |
82,10 → 82,10 |
{ |
uint32_t ident; |
asm volatile ( |
"mrc p15, 0, %[ident], c0, c0, 0\n" |
: [ident] "=r" (ident) |
"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; |
/branches/arm/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(); |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/arm32/src/panic.S |
---|
31,5 → 31,5 |
.global panic_printf |
panic_printf: |
bl printf |
bl debug_printf |
bl cpu_halt |
/branches/arm/kernel/arch/arm32/src/interrupt.c |
---|
35,9 → 35,8 |
#include <arch/asm.h> |
#include <arch/regutils.h> |
#include <ddi/irq.h> |
#include <arch/machine.h> |
#include <ddi/irq.h> |
#include <ddi/device.h> |
#include <interrupt.h> |
/** Initial size of a table holding interrupt handlers. */ |
65,7 → 64,7 |
ipl_t ipl = current_status_reg_read(); |
current_status_reg_control_write(ipl & ~STATUS_REG_IRQ_DISABLED_BIT); |
return ipl; |
} |
96,7 → 95,6 |
{ |
irq_init(IRQ_COUNT, IRQ_COUNT); |
machine_timer_irq_start(); |
} |
/** @} |
/branches/arm/kernel/arch/arm32/src/start.S |
---|
35,39 → 35,35 |
.global supervisor_sp |
kernel_image_start: |
# switch to supervisor mode |
mrs r3, cpsr |
bic r3, r3, #0x1f |
orr r3, r3, #0x13 |
msr cpsr_c, r3 |
ldr sp, =temp_stack |
# initialize Stack pointer for exception modes |
mrs r4, cpsr |
bic r4, r4, #0x1f |
cmp r2, #0 |
beq bootinfo_end |
#FIQ Mode |
orr r3, r4, #0x11 |
msr cpsr_c, r3 |
ldr sp, =exc_stack |
ldr r3, =bootinfo |
#IRQ Mode |
orr r3, r4, #0x12 |
msr cpsr_c, r3 |
ldr sp, =exc_stack |
bootinfo_loop: |
ldr r4, [r1] |
str r4, [r3] |
#ABORT Mode |
orr r3, r4, #0x17 |
msr cpsr_c, r3 |
ldr sp, =exc_stack |
add r1, r1, #4 |
add r3, r3, #4 |
add r2, r2, #-4 |
#UNDEFINED Mode |
orr r3, r4, #0x1b |
msr cpsr_c, r3 |
ldr sp, =exc_stack |
cmp r2, #0 |
bne bootinfo_loop |
bootinfo_end: |
# switch to supervisor mode |
orr r3, r4, #0x13 |
msr cpsr_c, r3 |
ldr sp, =temp_stack |
bl arch_pre_main |
bl main_bsp |
.space TEMP_STACK_SIZE |
78,3 → 74,4 |
supervisor_sp: |
.space 4 |
/branches/arm/kernel/arch/arm32/Makefile.inc |
---|
29,6 → 29,10 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf32-littlearm |
BFD_ARCH = arm |
BFD = binary |
35,37 → 39,66 |
TARGET = arm-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/arm |
KERNEL_LOAD_ADDRESS = 0x80200000 |
ifeq ($(MACHINE), gxemul_testarm) |
DMACHINE = MACHINE_GXEMUL_TESTARM |
else ifeq ($(MACHINE), qemu_icp) |
DMACHINE = MACHINE_QEMU_ICP |
endif |
ATSIGN = % |
GCC_CFLAGS += -fno-zero-initialized-in-bss |
BITS = 32 |
ENDIANESS = LE |
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. |
# |
CONFIG_PAGE_PT = y |
DEFS += -DCONFIG_PAGE_PT |
## Compile with support for address space identifiers. |
# |
# no HW support for ASIDs |
#CONFIG_ASID = y |
#CONFIG_ASID_FIFO = y |
## Compile with support with software division and multiplication. |
# |
CONFIG_SOFTINT = y |
ARCH_SOURCES = \ |
arch/$(KARCH)/src/start.S \ |
arch/$(KARCH)/src/asm.S \ |
arch/$(KARCH)/src/exc_handler.S \ |
arch/$(KARCH)/src/arm32.c \ |
arch/$(KARCH)/src/machine_func.c \ |
arch/$(KARCH)/src/context.S \ |
arch/$(KARCH)/src/dummy.S \ |
arch/$(KARCH)/src/panic.S \ |
arch/$(KARCH)/src/cpu/cpu.c \ |
arch/$(KARCH)/src/ddi/ddi.c \ |
arch/$(KARCH)/src/interrupt.c \ |
arch/$(KARCH)/src/exception.c \ |
arch/$(KARCH)/src/userspace.c \ |
arch/$(KARCH)/src/mm/as.c \ |
arch/$(KARCH)/src/mm/frame.c \ |
arch/$(KARCH)/src/mm/page.c \ |
arch/$(KARCH)/src/mm/tlb.c \ |
arch/$(KARCH)/src/mm/page_fault.c |
ifeq ($(MACHINE), testarm) |
ARCH_SOURCES += arch/$(KARCH)/src/mach/testarm/testarm.c |
else ifeq ($(MACHINE), integratorcp) |
ARCH_SOURCES += arch/$(KARCH)/src/mach/integratorcp/integratorcp.c |
arch/$(ARCH)/src/start.S \ |
arch/$(ARCH)/src/asm.S \ |
arch/$(ARCH)/src/arm32.c \ |
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/tlb.c \ |
arch/$(ARCH)/src/mm/page_fault.c |
ifeq ($(MACHINE), gxemul_testarm) |
ARCH_SOURCES += arch/$(ARCH)/src/drivers/gxemul.c |
else ifeq ($(MACHINE), qemu_icp) |
ARCH_SOURCES += arch/$(ARCH)/src/drivers/qemu.c |
endif |
ifeq ($(CONFIG_PL050), y) |
ARCH_SOURCES += genarch/src/drivers/pl050/pl050.c |
endif |
/branches/arm/kernel/arch/arm32/_link.ld.in |
---|
1,16 → 1,15 |
/* |
* ARM linker script |
* |
* ARM linker script |
* |
* kernel text |
* kernel data |
* |
* |
*/ |
#define KERNEL_LOAD_ADDRESS 0x80200000 |
OUTPUT_ARCH(arm) |
ENTRY(kernel_image_start) |
ENTRY(kernel_image_start) |
SECTIONS { |
. = KERNEL_LOAD_ADDRESS; |
.text : { |
20,29 → 19,29 |
} |
.data : { |
kdata_start = .; |
*(.data); /* initialized data */ |
*(.data); /* initialized data */ |
hardcoded_ktext_size = .; |
LONG(ktext_end - ktext_start); |
LONG(ktext_end - ktext_start); |
hardcoded_kdata_size = .; |
LONG(kdata_end - kdata_start); |
hardcoded_load_address = .; |
LONG(KERNEL_LOAD_ADDRESS); |
*(.bss); /* uninitialized static variables */ |
*(COMMON); /* global variables */ |
*(.bss); /* uninitialized static variables */ |
*(COMMON); /* global variables */ |
*(.rodata*); |
*(.sdata); |
*(.reginfo); |
symbol_table = .; |
*(symtab.*); |
*(symtab.*); |
} |
.sbss : { |
*(.sbss); |
*(.scommon); |
} |
kdata_end = .; |
/DISCARD/ : { |
*(.mdebug*); |
*(.pdr); |
49,4 → 48,5 |
*(.comment); |
*(.note); |
} |
} |
/branches/arm/kernel/arch/sparc64/include/cpu_node.h |
---|
File deleted |
/branches/arm/kernel/arch/sparc64/include/cpu_family.h |
---|
File deleted |
/branches/arm/kernel/arch/sparc64/include/trap/trap_table.h |
---|
100,7 → 100,7 |
.macro PREEMPTIBLE_HANDLER f |
sethi %hi(\f), %g1 |
ba %xcc, preemptible_handler |
b preemptible_handler |
or %g1, %lo(\f), %g1 |
.endm |
/branches/arm/kernel/arch/sparc64/include/trap/mmu.h |
---|
103,20 → 103,17 |
* Note that branch-delay slots are used in order to save space. |
*/ |
0: |
sethi %hi(fast_data_access_mmu_miss_data_hi), %g7 |
wr %g0, ASI_DMMU, %asi |
ldxa [VA_DMMU_TAG_ACCESS] %asi, %g1 ! read the faulting Context and VPN |
mov VA_DMMU_TAG_ACCESS, %g1 |
ldxa [%g1] ASI_DMMU, %g1 ! read the faulting Context and VPN |
set TLB_TAG_ACCESS_CONTEXT_MASK, %g2 |
andcc %g1, %g2, %g3 ! get Context |
bnz %xcc, 0f ! Context is non-zero |
bnz 0f ! Context is non-zero |
andncc %g1, %g2, %g3 ! get page address into %g3 |
bz %xcc, 0f ! page address is zero |
ldx [%g7 + %lo(end_of_identity)], %g4 |
cmp %g3, %g4 |
bgeu %xcc, 0f |
bz 0f ! page address is zero |
ldx [%g7 + %lo(kernel_8k_tlb_data_template)], %g2 |
add %g3, %g2, %g2 |
sethi %hi(kernel_8k_tlb_data_template), %g2 |
ldx [%g2 + %lo(kernel_8k_tlb_data_template)], %g2 |
or %g3, %g2, %g2 |
stxa %g2, [%g0] ASI_DTLB_DATA_IN_REG ! identity map the kernel page |
retry |
141,7 → 138,8 |
* Read the Tag Access register for the higher-level handler. |
* This is necessary to survive nested DTLB misses. |
*/ |
ldxa [VA_DMMU_TAG_ACCESS] %asi, %g2 |
mov VA_DMMU_TAG_ACCESS, %g2 |
ldxa [%g2] ASI_DMMU, %g2 |
/* |
* g2 will be passed as an argument to fast_data_access_mmu_miss(). |
/branches/arm/kernel/arch/sparc64/include/trap/interrupt.h |
---|
49,43 → 49,21 |
/* Interrupt ASI registers. */ |
#define ASI_INTR_W 0x77 |
#define ASI_UDB_INTR_W 0x77 |
#define ASI_INTR_DISPATCH_STATUS 0x48 |
#define ASI_INTR_R 0x7f |
#define ASI_UDB_INTR_R 0x7f |
#define ASI_INTR_RECEIVE 0x49 |
/* VA's used with ASI_INTR_W register. */ |
#if defined (US) |
/* VA's used with ASI_UDB_INTR_W register. */ |
#define ASI_UDB_INTR_W_DATA_0 0x40 |
#define ASI_UDB_INTR_W_DATA_1 0x50 |
#define ASI_UDB_INTR_W_DATA_2 0x60 |
#elif defined (US3) |
#define VA_INTR_W_DATA_0 0x40 |
#define VA_INTR_W_DATA_1 0x48 |
#define VA_INTR_W_DATA_2 0x50 |
#define VA_INTR_W_DATA_3 0x58 |
#define VA_INTR_W_DATA_4 0x60 |
#define VA_INTR_W_DATA_5 0x68 |
#define VA_INTR_W_DATA_6 0x80 |
#define VA_INTR_W_DATA_7 0x88 |
#endif |
#define VA_INTR_W_DISPATCH 0x70 |
#define ASI_UDB_INTR_W_DISPATCH 0x70 |
/* VA's used with ASI_INTR_R register. */ |
#if defined(US) |
/* VA's used with ASI_UDB_INTR_R register. */ |
#define ASI_UDB_INTR_R_DATA_0 0x40 |
#define ASI_UDB_INTR_R_DATA_1 0x50 |
#define ASI_UDB_INTR_R_DATA_2 0x60 |
#elif defined (US3) |
#define VA_INTR_R_DATA_0 0x40 |
#define VA_INTR_R_DATA_1 0x48 |
#define VA_INTR_R_DATA_2 0x50 |
#define VA_INTR_R_DATA_3 0x58 |
#define VA_INTR_R_DATA_4 0x60 |
#define VA_INTR_R_DATA_5 0x68 |
#define VA_INTR_R_DATA_6 0x80 |
#define VA_INTR_R_DATA_7 0x88 |
#endif |
/* Shifts in the Interrupt Vector Dispatch virtual address. */ |
#define INTR_VEC_DISPATCH_MID_SHIFT 14 |
/branches/arm/kernel/arch/sparc64/include/trap/regwin.h |
---|
39,7 → 39,6 |
#include <arch/stack.h> |
#include <arch/arch.h> |
#include <align.h> |
#define TT_CLEAN_WINDOW 0x24 |
#define TT_SPILL_0_NORMAL 0x80 /* kernel spills */ |
73,11 → 72,6 |
#define I6_OFFSET 112 |
#define I7_OFFSET 120 |
/* Uspace Window Buffer constants. */ |
#define UWB_SIZE ((NWINDOWS - 1) * STACK_WINDOW_SAVE_AREA_SIZE) |
#define UWB_ALIGNMENT 1024 |
#define UWB_ASIZE ALIGN_UP(UWB_SIZE, UWB_ALIGNMENT) |
#ifdef __ASM__ |
/* |
/branches/arm/kernel/arch/sparc64/include/atomic.h |
---|
123,7 → 123,7 |
"ldx %0, %2\n" |
"brz %2, 0b\n" |
"nop\n" |
"ba %xcc, 1b\n" |
"ba 1b\n" |
"nop\n" |
"2:\n" |
: "+m" (*((uint64_t *) x)), "+r" (tmp1), "+r" (tmp2) : "r" (0) |
/branches/arm/kernel/arch/sparc64/include/mm/tlb.h |
---|
35,17 → 35,9 |
#ifndef KERN_sparc64_TLB_H_ |
#define KERN_sparc64_TLB_H_ |
#if defined (US) |
#define ITLB_ENTRY_COUNT 64 |
#define DTLB_ENTRY_COUNT 64 |
#define DTLB_MAX_LOCKED_ENTRIES DTLB_ENTRY_COUNT |
#endif |
/** TLB_DSMALL is the only of the three DMMUs that can hold locked entries. */ |
#if defined (US3) |
#define DTLB_MAX_LOCKED_ENTRIES 16 |
#endif |
#define MEM_CONTEXT_KERNEL 0 |
#define MEM_CONTEXT_TEMP 1 |
61,9 → 53,6 |
/* TLB Demap Operation types. */ |
#define TLB_DEMAP_PAGE 0 |
#define TLB_DEMAP_CONTEXT 1 |
#if defined (US3) |
#define TLB_DEMAP_ALL 2 |
#endif |
#define TLB_DEMAP_TYPE_SHIFT 6 |
72,18 → 61,6 |
#define TLB_DEMAP_SECONDARY 1 |
#define TLB_DEMAP_NUCLEUS 2 |
/* There are more TLBs in one MMU in US3, their codes are defined here. */ |
#if defined (US3) |
/* D-MMU: one small (16-entry) TLB and two big (512-entry) TLBs */ |
#define TLB_DSMALL 0 |
#define TLB_DBIG_0 2 |
#define TLB_DBIG_1 3 |
/* I-MMU: one small (16-entry) TLB and one big TLB */ |
#define TLB_ISMALL 0 |
#define TLB_IBIG 2 |
#endif |
#define TLB_DEMAP_CONTEXT_SHIFT 4 |
/* TLB Tag Access shifts */ |
99,8 → 76,6 |
#include <arch/asm.h> |
#include <arch/barrier.h> |
#include <arch/types.h> |
#include <arch/register.h> |
#include <arch/cpu.h> |
union tlb_context_reg { |
uint64_t v; |
115,9 → 90,6 |
typedef tte_data_t tlb_data_t; |
/** I-/D-TLB Data Access Address in Alternate Space. */ |
#if defined (US) |
union tlb_data_access_addr { |
uint64_t value; |
struct { |
126,54 → 98,9 |
unsigned : 3; |
} __attribute__ ((packed)); |
}; |
typedef union tlb_data_access_addr dtlb_data_access_addr_t; |
typedef union tlb_data_access_addr dtlb_tag_read_addr_t; |
typedef union tlb_data_access_addr itlb_data_access_addr_t; |
typedef union tlb_data_access_addr itlb_tag_read_addr_t; |
typedef union tlb_data_access_addr tlb_data_access_addr_t; |
typedef union tlb_data_access_addr tlb_tag_read_addr_t; |
#elif defined (US3) |
/* |
* In US3, I-MMU and D-MMU have different formats of the data |
* access register virtual address. In the corresponding |
* structures the member variable for the entry number is |
* called "local_tlb_entry" - it contrasts with the "tlb_entry" |
* for the US data access register VA structure. The rationale |
* behind this is to prevent careless mistakes in the code |
* caused by setting only the entry number and not the TLB |
* number in the US3 code (when taking the code from US). |
*/ |
union dtlb_data_access_addr { |
uint64_t value; |
struct { |
uint64_t : 45; |
unsigned : 1; |
unsigned tlb_number : 2; |
unsigned : 4; |
unsigned local_tlb_entry : 9; |
unsigned : 3; |
} __attribute__ ((packed)); |
}; |
typedef union dtlb_data_access_addr dtlb_data_access_addr_t; |
typedef union dtlb_data_access_addr dtlb_tag_read_addr_t; |
union itlb_data_access_addr { |
uint64_t value; |
struct { |
uint64_t : 45; |
unsigned : 1; |
unsigned tlb_number : 2; |
unsigned : 6; |
unsigned local_tlb_entry : 7; |
unsigned : 3; |
} __attribute__ ((packed)); |
}; |
typedef union itlb_data_access_addr itlb_data_access_addr_t; |
typedef union itlb_data_access_addr itlb_tag_read_addr_t; |
#endif |
/** I-/D-TLB Tag Read Register. */ |
union tlb_tag_read_reg { |
uint64_t value; |
191,13 → 118,8 |
uint64_t value; |
struct { |
uint64_t vpn: 51; /**< Virtual Address bits 63:13. */ |
#if defined (US) |
unsigned : 6; /**< Ignored. */ |
unsigned type : 1; /**< The type of demap operation. */ |
#elif defined (US3) |
unsigned : 5; /**< Ignored. */ |
unsigned type: 2; /**< The type of demap operation. */ |
#endif |
unsigned context : 2; /**< Context register selection. */ |
unsigned : 4; /**< Zero. */ |
} __attribute__ ((packed)); |
208,19 → 130,10 |
union tlb_sfsr_reg { |
uint64_t value; |
struct { |
#if defined (US) |
unsigned long : 40; /**< Implementation dependent. */ |
unsigned asi : 8; /**< ASI. */ |
unsigned : 2; |
unsigned ft : 7; /**< Fault type. */ |
#elif defined (US3) |
unsigned long : 39; /**< Implementation dependent. */ |
unsigned nf : 1; /**< Non-faulting load. */ |
unsigned asi : 8; /**< ASI. */ |
unsigned tm : 1; /**< I-TLB miss. */ |
unsigned : 3; /**< Reserved. */ |
unsigned ft : 5; /**< Fault type. */ |
#endif |
unsigned e : 1; /**< Side-effect bit. */ |
unsigned ct : 2; /**< Context Register selection. */ |
unsigned pr : 1; /**< Privilege bit. */ |
231,53 → 144,9 |
}; |
typedef union tlb_sfsr_reg tlb_sfsr_reg_t; |
#if defined (US3) |
/* |
* Functions for determining the number of entries in TLBs. They either return |
* a constant value or a value based on the CPU autodetection. |
*/ |
/** |
* Determine the number of entries in the DMMU's small TLB. |
*/ |
static inline uint16_t tlb_dsmall_size(void) |
{ |
return 16; |
} |
/** |
* Determine the number of entries in each DMMU's big TLB. |
*/ |
static inline uint16_t tlb_dbig_size(void) |
{ |
return 512; |
} |
/** |
* Determine the number of entries in the IMMU's small TLB. |
*/ |
static inline uint16_t tlb_ismall_size(void) |
{ |
return 16; |
} |
/** |
* Determine the number of entries in the IMMU's big TLB. |
*/ |
static inline uint16_t tlb_ibig_size(void) |
{ |
if (((ver_reg_t) ver_read()).impl == IMPL_ULTRASPARCIV_PLUS) |
return 512; |
else |
return 128; |
} |
#endif |
/** Read MMU Primary Context Register. |
* |
* @return Current value of Primary Context Register. |
* @return Current value of Primary Context Register. |
*/ |
static inline uint64_t mmu_primary_context_read(void) |
{ |
286,7 → 155,7 |
/** Write MMU Primary Context Register. |
* |
* @param v New value of Primary Context Register. |
* @param v New value of Primary Context Register. |
*/ |
static inline void mmu_primary_context_write(uint64_t v) |
{ |
296,7 → 165,7 |
/** Read MMU Secondary Context Register. |
* |
* @return Current value of Secondary Context Register. |
* @return Current value of Secondary Context Register. |
*/ |
static inline uint64_t mmu_secondary_context_read(void) |
{ |
305,7 → 174,7 |
/** Write MMU Primary Context Register. |
* |
* @param v New value of Primary Context Register. |
* @param v New value of Primary Context Register. |
*/ |
static inline void mmu_secondary_context_write(uint64_t v) |
{ |
313,18 → 182,15 |
flush_pipeline(); |
} |
#if defined (US) |
/** Read IMMU TLB Data Access Register. |
* |
* @param entry TLB Entry index. |
* @param entry TLB Entry index. |
* |
* @return Current value of specified IMMU TLB Data Access |
* Register. |
* @return Current value of specified IMMU TLB Data Access Register. |
*/ |
static inline uint64_t itlb_data_access_read(size_t entry) |
static inline uint64_t itlb_data_access_read(index_t entry) |
{ |
itlb_data_access_addr_t reg; |
tlb_data_access_addr_t reg; |
reg.value = 0; |
reg.tlb_entry = entry; |
333,12 → 199,12 |
/** Write IMMU TLB Data Access Register. |
* |
* @param entry TLB Entry index. |
* @param value Value to be written. |
* @param entry TLB Entry index. |
* @param value Value to be written. |
*/ |
static inline void itlb_data_access_write(size_t entry, uint64_t value) |
static inline void itlb_data_access_write(index_t entry, uint64_t value) |
{ |
itlb_data_access_addr_t reg; |
tlb_data_access_addr_t reg; |
reg.value = 0; |
reg.tlb_entry = entry; |
348,14 → 214,13 |
/** Read DMMU TLB Data Access Register. |
* |
* @param entry TLB Entry index. |
* @param entry TLB Entry index. |
* |
* @return Current value of specified DMMU TLB Data Access |
* Register. |
* @return Current value of specified DMMU TLB Data Access Register. |
*/ |
static inline uint64_t dtlb_data_access_read(size_t entry) |
static inline uint64_t dtlb_data_access_read(index_t entry) |
{ |
dtlb_data_access_addr_t reg; |
tlb_data_access_addr_t reg; |
reg.value = 0; |
reg.tlb_entry = entry; |
364,12 → 229,12 |
/** Write DMMU TLB Data Access Register. |
* |
* @param entry TLB Entry index. |
* @param value Value to be written. |
* @param entry TLB Entry index. |
* @param value Value to be written. |
*/ |
static inline void dtlb_data_access_write(size_t entry, uint64_t value) |
static inline void dtlb_data_access_write(index_t entry, uint64_t value) |
{ |
dtlb_data_access_addr_t reg; |
tlb_data_access_addr_t reg; |
reg.value = 0; |
reg.tlb_entry = entry; |
379,13 → 244,13 |
/** Read IMMU TLB Tag Read Register. |
* |
* @param entry TLB Entry index. |
* @param entry TLB Entry index. |
* |
* @return Current value of specified IMMU TLB Tag Read Register. |
* @return Current value of specified IMMU TLB Tag Read Register. |
*/ |
static inline uint64_t itlb_tag_read_read(size_t entry) |
static inline uint64_t itlb_tag_read_read(index_t entry) |
{ |
itlb_tag_read_addr_t tag; |
tlb_tag_read_addr_t tag; |
tag.value = 0; |
tag.tlb_entry = entry; |
394,13 → 259,13 |
/** Read DMMU TLB Tag Read Register. |
* |
* @param entry TLB Entry index. |
* @param entry TLB Entry index. |
* |
* @return Current value of specified DMMU TLB Tag Read Register. |
* @return Current value of specified DMMU TLB Tag Read Register. |
*/ |
static inline uint64_t dtlb_tag_read_read(size_t entry) |
static inline uint64_t dtlb_tag_read_read(index_t entry) |
{ |
dtlb_tag_read_addr_t tag; |
tlb_tag_read_addr_t tag; |
tag.value = 0; |
tag.tlb_entry = entry; |
407,120 → 272,9 |
return asi_u64_read(ASI_DTLB_TAG_READ_REG, tag.value); |
} |
#elif defined (US3) |
/** Read IMMU TLB Data Access Register. |
* |
* @param tlb TLB number (one of TLB_ISMALL or TLB_IBIG) |
* @param entry TLB Entry index. |
* |
* @return Current value of specified IMMU TLB Data Access |
* Register. |
*/ |
static inline uint64_t itlb_data_access_read(int tlb, size_t entry) |
{ |
itlb_data_access_addr_t reg; |
reg.value = 0; |
reg.tlb_number = tlb; |
reg.local_tlb_entry = entry; |
return asi_u64_read(ASI_ITLB_DATA_ACCESS_REG, reg.value); |
} |
/** Write IMMU TLB Data Access Register. |
* @param tlb TLB number (one of TLB_ISMALL or TLB_IBIG) |
* @param entry TLB Entry index. |
* @param value Value to be written. |
*/ |
static inline void itlb_data_access_write(int tlb, size_t entry, |
uint64_t value) |
{ |
itlb_data_access_addr_t reg; |
reg.value = 0; |
reg.tlb_number = tlb; |
reg.local_tlb_entry = entry; |
asi_u64_write(ASI_ITLB_DATA_ACCESS_REG, reg.value, value); |
flush_pipeline(); |
} |
/** Read DMMU TLB Data Access Register. |
* |
* @param tlb TLB number (one of TLB_DSMALL, TLB_DBIG, TLB_DBIG) |
* @param entry TLB Entry index. |
* |
* @return Current value of specified DMMU TLB Data Access |
* Register. |
*/ |
static inline uint64_t dtlb_data_access_read(int tlb, size_t entry) |
{ |
dtlb_data_access_addr_t reg; |
reg.value = 0; |
reg.tlb_number = tlb; |
reg.local_tlb_entry = entry; |
return asi_u64_read(ASI_DTLB_DATA_ACCESS_REG, reg.value); |
} |
/** Write DMMU TLB Data Access Register. |
* |
* @param tlb TLB number (one of TLB_DSMALL, TLB_DBIG_0, TLB_DBIG_1) |
* @param entry TLB Entry index. |
* @param value Value to be written. |
*/ |
static inline void dtlb_data_access_write(int tlb, size_t entry, |
uint64_t value) |
{ |
dtlb_data_access_addr_t reg; |
reg.value = 0; |
reg.tlb_number = tlb; |
reg.local_tlb_entry = entry; |
asi_u64_write(ASI_DTLB_DATA_ACCESS_REG, reg.value, value); |
membar(); |
} |
/** Read IMMU TLB Tag Read Register. |
* |
* @param tlb TLB number (one of TLB_ISMALL or TLB_IBIG) |
* @param entry TLB Entry index. |
* |
* @return Current value of specified IMMU TLB Tag Read Register. |
*/ |
static inline uint64_t itlb_tag_read_read(int tlb, size_t entry) |
{ |
itlb_tag_read_addr_t tag; |
tag.value = 0; |
tag.tlb_number = tlb; |
tag.local_tlb_entry = entry; |
return asi_u64_read(ASI_ITLB_TAG_READ_REG, tag.value); |
} |
/** Read DMMU TLB Tag Read Register. |
* |
* @param tlb TLB number (one of TLB_DSMALL, TLB_DBIG_0, TLB_DBIG_1) |
* @param entry TLB Entry index. |
* |
* @return Current value of specified DMMU TLB Tag Read Register. |
*/ |
static inline uint64_t dtlb_tag_read_read(int tlb, size_t entry) |
{ |
dtlb_tag_read_addr_t tag; |
tag.value = 0; |
tag.tlb_number = tlb; |
tag.local_tlb_entry = entry; |
return asi_u64_read(ASI_DTLB_TAG_READ_REG, tag.value); |
} |
#endif |
/** Write IMMU TLB Tag Access Register. |
* |
* @param v Value to be written. |
* @param v Value to be written. |
*/ |
static inline void itlb_tag_access_write(uint64_t v) |
{ |
530,7 → 284,7 |
/** Read IMMU TLB Tag Access Register. |
* |
* @return Current value of IMMU TLB Tag Access Register. |
* @return Current value of IMMU TLB Tag Access Register. |
*/ |
static inline uint64_t itlb_tag_access_read(void) |
{ |
539,7 → 293,7 |
/** Write DMMU TLB Tag Access Register. |
* |
* @param v Value to be written. |
* @param v Value to be written. |
*/ |
static inline void dtlb_tag_access_write(uint64_t v) |
{ |
549,7 → 303,7 |
/** Read DMMU TLB Tag Access Register. |
* |
* @return Current value of DMMU TLB Tag Access Register. |
* @return Current value of DMMU TLB Tag Access Register. |
*/ |
static inline uint64_t dtlb_tag_access_read(void) |
{ |
559,7 → 313,7 |
/** Write IMMU TLB Data in Register. |
* |
* @param v Value to be written. |
* @param v Value to be written. |
*/ |
static inline void itlb_data_in_write(uint64_t v) |
{ |
569,7 → 323,7 |
/** Write DMMU TLB Data in Register. |
* |
* @param v Value to be written. |
* @param v Value to be written. |
*/ |
static inline void dtlb_data_in_write(uint64_t v) |
{ |
579,7 → 333,7 |
/** Read ITLB Synchronous Fault Status Register. |
* |
* @return Current content of I-SFSR register. |
* @return Current content of I-SFSR register. |
*/ |
static inline uint64_t itlb_sfsr_read(void) |
{ |
588,7 → 342,7 |
/** Write ITLB Synchronous Fault Status Register. |
* |
* @param v New value of I-SFSR register. |
* @param v New value of I-SFSR register. |
*/ |
static inline void itlb_sfsr_write(uint64_t v) |
{ |
598,7 → 352,7 |
/** Read DTLB Synchronous Fault Status Register. |
* |
* @return Current content of D-SFSR register. |
* @return Current content of D-SFSR register. |
*/ |
static inline uint64_t dtlb_sfsr_read(void) |
{ |
607,7 → 361,7 |
/** Write DTLB Synchronous Fault Status Register. |
* |
* @param v New value of D-SFSR register. |
* @param v New value of D-SFSR register. |
*/ |
static inline void dtlb_sfsr_write(uint64_t v) |
{ |
617,7 → 371,7 |
/** Read DTLB Synchronous Fault Address Register. |
* |
* @return Current content of D-SFAR register. |
* @return Current content of D-SFAR register. |
*/ |
static inline uint64_t dtlb_sfar_read(void) |
{ |
626,11 → 380,10 |
/** Perform IMMU TLB Demap Operation. |
* |
* @param type Selects between context and page demap (and entire MMU |
* demap on US3). |
* @param type Selects between context and page demap. |
* @param context_encoding Specifies which Context register has Context ID for |
* demap. |
* @param page Address which is on the page to be demapped. |
* demap. |
* @param page Address which is on the page to be demapped. |
*/ |
static inline void itlb_demap(int type, int context_encoding, uintptr_t page) |
{ |
644,19 → 397,18 |
da.context = context_encoding; |
da.vpn = pg.vpn; |
/* da.value is the address within the ASI */ |
asi_u64_write(ASI_IMMU_DEMAP, da.value, 0); |
asi_u64_write(ASI_IMMU_DEMAP, da.value, 0); /* da.value is the |
* address within the |
* ASI */ |
flush_pipeline(); |
} |
/** Perform DMMU TLB Demap Operation. |
* |
* @param type Selects between context and page demap (and entire MMU |
* demap on US3). |
* @param type Selects between context and page demap. |
* @param context_encoding Specifies which Context register has Context ID for |
* demap. |
* @param page Address which is on the page to be demapped. |
* demap. |
* @param page Address which is on the page to be demapped. |
*/ |
static inline void dtlb_demap(int type, int context_encoding, uintptr_t page) |
{ |
670,17 → 422,17 |
da.context = context_encoding; |
da.vpn = pg.vpn; |
/* da.value is the address within the ASI */ |
asi_u64_write(ASI_DMMU_DEMAP, da.value, 0); |
asi_u64_write(ASI_DMMU_DEMAP, da.value, 0); /* da.value is the |
* address within the |
* ASI */ |
membar(); |
} |
extern void fast_instruction_access_mmu_miss(unative_t, istate_t *); |
extern void fast_data_access_mmu_miss(tlb_tag_access_reg_t, istate_t *); |
extern void fast_data_access_protection(tlb_tag_access_reg_t , istate_t *); |
extern void fast_instruction_access_mmu_miss(unative_t unused, istate_t *istate); |
extern void fast_data_access_mmu_miss(tlb_tag_access_reg_t tag, istate_t *istate); |
extern void fast_data_access_protection(tlb_tag_access_reg_t tag , istate_t *istate); |
extern void dtlb_insert_mapping(uintptr_t, uintptr_t, int, bool, bool); |
extern void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize, bool locked, bool cacheable); |
extern void dump_sfsr_and_sfar(void); |
/branches/arm/kernel/arch/sparc64/include/mm/cache_spec.h |
---|
38,20 → 38,19 |
/* |
* The following macros are valid for the following processors: |
* |
* UltraSPARC, UltraSPARC II, UltraSPARC IIi, UltraSPARC III, |
* UltraSPARC III+, UltraSPARC IV, UltraSPARC IV+ |
* UltraSPARC, UltraSPARC II, UltraSPARC IIi |
* |
* Should we support other UltraSPARC processors, we need to make sure that |
* the macros are defined correctly for them. |
*/ |
#if defined (US) |
#define DCACHE_SIZE (16 * 1024) |
#elif defined (US3) |
#define DCACHE_SIZE (64 * 1024) |
#endif |
#define DCACHE_LINE_SIZE 32 |
#define ICACHE_SIZE (16 * 1024) |
#define ICACHE_WAYS 2 |
#define ICACHE_LINE_SIZE 32 |
#endif |
/** @} |
/branches/arm/kernel/arch/sparc64/include/mm/frame.h |
---|
59,13 → 59,8 |
union frame_address { |
uintptr_t address; |
struct { |
#if defined (US) |
unsigned : 23; |
uint64_t pfn : 28; /**< Physical Frame Number. */ |
#elif defined (US3) |
unsigned : 21; |
uint64_t pfn : 30; /**< Physical Frame Number. */ |
#endif |
unsigned offset : 13; /**< Offset. */ |
} __attribute__ ((packed)); |
}; |
73,8 → 68,6 |
typedef union frame_address frame_address_t; |
extern uintptr_t last_frame; |
extern uintptr_t end_of_identity; |
extern void frame_arch_init(void); |
#define physmem_print() |
/branches/arm/kernel/arch/sparc64/include/mm/cache.h |
---|
38,6 → 38,15 |
#include <mm/page.h> |
#include <mm/frame.h> |
#define dcache_flush_page(p) \ |
dcache_flush_color(PAGE_COLOR((p))) |
#define dcache_flush_frame(p, f) \ |
dcache_flush_tag(PAGE_COLOR((p)), ADDR2PFN((f))); |
extern void dcache_flush(void); |
extern void dcache_flush_color(int c); |
extern void dcache_flush_tag(int c, pfn_t tag); |
#endif |
/** @} |
/branches/arm/kernel/arch/sparc64/include/mm/tsb.h |
---|
107,62 → 107,13 |
asi_u64_write(ASI_DMMU, VA_DMMU_TSB_BASE, v); |
} |
#if defined (US3) |
/** Write DTSB Primary Extension register. |
* |
* @param v New content of the DTSB Primary Extension register. |
*/ |
static inline void dtsb_primary_extension_write(uint64_t v) |
{ |
asi_u64_write(ASI_DMMU, VA_DMMU_PRIMARY_EXTENSION, v); |
} |
/** Write DTSB Secondary Extension register. |
* |
* @param v New content of the DTSB Secondary Extension register. |
*/ |
static inline void dtsb_secondary_extension_write(uint64_t v) |
{ |
asi_u64_write(ASI_DMMU, VA_DMMU_SECONDARY_EXTENSION, v); |
} |
/** Write DTSB Nucleus Extension register. |
* |
* @param v New content of the DTSB Nucleus Extension register. |
*/ |
static inline void dtsb_nucleus_extension_write(uint64_t v) |
{ |
asi_u64_write(ASI_DMMU, VA_DMMU_NUCLEUS_EXTENSION, v); |
} |
/** Write ITSB Primary Extension register. |
* |
* @param v New content of the ITSB Primary Extension register. |
*/ |
static inline void itsb_primary_extension_write(uint64_t v) |
{ |
asi_u64_write(ASI_IMMU, VA_IMMU_PRIMARY_EXTENSION, v); |
} |
/** Write ITSB Nucleus Extension register. |
* |
* @param v New content of the ITSB Nucleus Extension register. |
*/ |
static inline void itsb_nucleus_extension_write(uint64_t v) |
{ |
asi_u64_write(ASI_IMMU, VA_IMMU_NUCLEUS_EXTENSION, v); |
} |
#endif |
/* Forward declarations. */ |
struct as; |
struct pte; |
extern void tsb_invalidate(struct as *as, uintptr_t page, size_t pages); |
extern void itsb_pte_copy(struct pte *t, size_t index); |
extern void dtsb_pte_copy(struct pte *t, size_t index, bool ro); |
extern void tsb_invalidate(struct as *as, uintptr_t page, count_t pages); |
extern void itsb_pte_copy(struct pte *t, index_t index); |
extern void dtsb_pte_copy(struct pte *t, index_t index, bool ro); |
#endif /* !def __ASM__ */ |
/branches/arm/kernel/arch/sparc64/include/mm/mmu.h |
---|
35,10 → 35,8 |
#ifndef KERN_sparc64_MMU_H_ |
#define KERN_sparc64_MMU_H_ |
#if defined(US) |
/* LSU Control Register ASI. */ |
#define ASI_LSU_CONTROL_REG 0x45 /**< Load/Store Unit Control Register. */ |
#endif |
/* I-MMU ASIs. */ |
#define ASI_IMMU 0x50 |
54,12 → 52,7 |
#define VA_IMMU_SFSR 0x18 /**< IMMU sync fault status register. */ |
#define VA_IMMU_TSB_BASE 0x28 /**< IMMU TSB base register. */ |
#define VA_IMMU_TAG_ACCESS 0x30 /**< IMMU TLB tag access register. */ |
#if defined (US3) |
#define VA_IMMU_PRIMARY_EXTENSION 0x48 /**< IMMU TSB primary extension register */ |
#define VA_IMMU_NUCLEUS_EXTENSION 0x58 /**< IMMU TSB nucleus extension register */ |
#endif |
/* D-MMU ASIs. */ |
#define ASI_DMMU 0x58 |
#define ASI_DMMU_TSB_8KB_PTR_REG 0x59 |
80,11 → 73,6 |
#define VA_DMMU_TAG_ACCESS 0x30 /**< DMMU TLB tag access register. */ |
#define VA_DMMU_VA_WATCHPOINT_REG 0x38 /**< DMMU VA data watchpoint register. */ |
#define VA_DMMU_PA_WATCHPOINT_REG 0x40 /**< DMMU PA data watchpoint register. */ |
#if defined (US3) |
#define VA_DMMU_PRIMARY_EXTENSION 0x48 /**< DMMU TSB primary extension register */ |
#define VA_DMMU_SECONDARY_EXTENSION 0x50 /**< DMMU TSB secondary extension register */ |
#define VA_DMMU_NUCLEUS_EXTENSION 0x58 /**< DMMU TSB nucleus extension register */ |
#endif |
#ifndef __ASM__ |
92,7 → 80,6 |
#include <arch/barrier.h> |
#include <arch/types.h> |
#if defined(US) |
/** LSU Control Register. */ |
typedef union { |
uint64_t value; |
113,7 → 100,6 |
} __attribute__ ((packed)); |
} lsu_cr_reg_t; |
#endif /* US */ |
#endif /* !def __ASM__ */ |
/branches/arm/kernel/arch/sparc64/include/mm/tte.h |
---|
50,7 → 50,6 |
#include <arch/types.h> |
/* TTE tag's VA_tag field contains bits <63:VA_TAG_PAGE_SHIFT> of the VA */ |
#define VA_TAG_PAGE_SHIFT 22 |
/** Translation Table Entry - Tag. */ |
76,13 → 75,8 |
unsigned nfo : 1; /**< No-Fault-Only. */ |
unsigned ie : 1; /**< Invert Endianness. */ |
unsigned soft2 : 9; /**< Software defined field. */ |
#if defined (US) |
unsigned diag : 9; /**< Diagnostic data. */ |
unsigned pfn : 28; /**< Physical Address bits, bits 40:13. */ |
#elif defined (US3) |
unsigned : 7; /**< Reserved. */ |
unsigned pfn : 30; /**< Physical Address bits, bits 42:13 */ |
#endif |
unsigned soft : 6; /**< Software defined field. */ |
unsigned l : 1; /**< Lock. */ |
unsigned cp : 1; /**< Cacheable in physically indexed cache. */ |
/branches/arm/kernel/arch/sparc64/include/barrier.h |
---|
82,8 → 82,6 |
asm volatile ("membar #Sync\n"); |
} |
#if defined (US) |
#define smc_coherence(a) \ |
{ \ |
write_barrier(); \ |
99,22 → 97,6 |
flush((void *)(a) + i); \ |
} |
#elif defined (US3) |
#define smc_coherence(a) \ |
{ \ |
write_barrier(); \ |
flush_pipeline(); \ |
} |
#define smc_coherence_block(a, l) \ |
{ \ |
write_barrier(); \ |
flush_pipeline(); \ |
} |
#endif /* defined(US3) */ |
#endif |
/** @} |
/branches/arm/kernel/arch/sparc64/include/memstr.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup sparc64 |
/** @addtogroup sparc64 |
* @{ |
*/ |
/** @file |
/branches/arm/kernel/arch/sparc64/include/asm.h |
---|
42,56 → 42,7 |
#include <arch/register.h> |
#include <config.h> |
#include <arch/stack.h> |
#include <arch/barrier.h> |
static inline void pio_write_8(ioport8_t *port, uint8_t v) |
{ |
*port = v; |
memory_barrier(); |
} |
static inline void pio_write_16(ioport16_t *port, uint16_t v) |
{ |
*port = v; |
memory_barrier(); |
} |
static inline void pio_write_32(ioport32_t *port, uint32_t v) |
{ |
*port = v; |
memory_barrier(); |
} |
static inline uint8_t pio_read_8(ioport8_t *port) |
{ |
uint8_t rv; |
rv = *port; |
memory_barrier(); |
return rv; |
} |
static inline uint16_t pio_read_16(ioport16_t *port) |
{ |
uint16_t rv; |
rv = *port; |
memory_barrier(); |
return rv; |
} |
static inline uint32_t pio_read_32(ioport32_t *port) |
{ |
uint32_t rv; |
rv = *port; |
memory_barrier(); |
return rv; |
} |
/** Read Processor State register. |
* |
* @return Value of PSTATE register. |
136,28 → 87,6 |
asm volatile ("wr %0, %1, %%tick_cmpr\n" : : "r" (v), "i" (0)); |
} |
/** Read STICK_compare Register. |
* |
* @return Value of STICK_compare register. |
*/ |
static inline uint64_t stick_compare_read(void) |
{ |
uint64_t v; |
asm volatile ("rd %%asr25, %0\n" : "=r" (v)); |
return v; |
} |
/** Write STICK_compare Register. |
* |
* @param v New value of STICK_comapre register. |
*/ |
static inline void stick_compare_write(uint64_t v) |
{ |
asm volatile ("wr %0, %1, %%asr25\n" : : "r" (v), "i" (0)); |
} |
/** Read TICK Register. |
* |
* @return Value of TICK register. |
429,6 → 358,15 |
asm volatile ("wrpr %g0, %g0, %tl\n"); |
} |
/** Read UPA_CONFIG register. |
* |
* @return Value of the UPA_CONFIG register. |
*/ |
static inline uint64_t upa_config_read(void) |
{ |
return asi_u64_read(ASI_UPA_CONFIG, 0); |
} |
extern void cpu_halt(void); |
extern void cpu_sleep(void); |
extern void asm_delay_loop(const uint32_t usec); |
/branches/arm/kernel/arch/sparc64/include/cpu.h |
---|
35,6 → 35,15 |
#ifndef KERN_sparc64_CPU_H_ |
#define KERN_sparc64_CPU_H_ |
#include <arch/types.h> |
#include <typedefs.h> |
#include <arch/register.h> |
#include <arch/asm.h> |
#ifdef CONFIG_SMP |
#include <arch/mm/cache.h> |
#endif |
#define MANUF_FUJITSU 0x04 |
#define MANUF_ULTRASPARC 0x17 /**< UltraSPARC I, UltraSPARC II */ |
#define MANUF_SUN 0x3e |
43,29 → 52,14 |
#define IMPL_ULTRASPARCII 0x11 |
#define IMPL_ULTRASPARCII_I 0x12 |
#define IMPL_ULTRASPARCII_E 0x13 |
#define IMPL_ULTRASPARCIII 0x14 |
#define IMPL_ULTRASPARCIII_PLUS 0x15 |
#define IMPL_ULTRASPARCIII_I 0x16 |
#define IMPL_ULTRASPARCIV 0x18 |
#define IMPL_ULTRASPARCIII 0x15 |
#define IMPL_ULTRASPARCIV_PLUS 0x19 |
#define IMPL_SPARC64V 0x5 |
#ifndef __ASM__ |
#include <arch/types.h> |
#include <typedefs.h> |
#include <arch/register.h> |
#include <arch/regdef.h> |
#include <arch/asm.h> |
#ifdef CONFIG_SMP |
#include <arch/mm/cache.h> |
#endif |
typedef struct { |
uint32_t mid; /**< Processor ID as read from |
UPA_CONFIG/FIREPLANE_CONFIG. */ |
UPA_CONFIG. */ |
ver_reg_t ver; |
uint32_t clock_frequency; /**< Processor frequency in Hz. */ |
uint64_t next_tick_cmpr; /**< Next clock interrupt should be |
72,28 → 66,8 |
generated when the TICK register |
matches this value. */ |
} cpu_arch_t; |
/** |
* Reads the module ID (agent ID/CPUID) of the current CPU. |
*/ |
static inline uint32_t read_mid(void) |
{ |
uint64_t icbus_config = asi_u64_read(ASI_ICBUS_CONFIG, 0); |
icbus_config = icbus_config >> ICBUS_CONFIG_MID_SHIFT; |
#if defined (US) |
return icbus_config & 0x1f; |
#elif defined (US3) |
if (((ver_reg_t) ver_read()).impl == IMPL_ULTRASPARCIII_I) |
return icbus_config & 0x1f; |
else |
return icbus_config & 0x3ff; |
#endif |
} |
#endif |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/sparc64/include/types.h |
---|
46,6 → 46,8 |
typedef unsigned long uint64_t; |
typedef uint64_t size_t; |
typedef uint64_t count_t; |
typedef uint64_t index_t; |
typedef uint64_t uintptr_t; |
typedef uint64_t pfn_t; |
55,12 → 57,11 |
typedef uint64_t unative_t; |
typedef int64_t native_t; |
typedef struct { |
} fncptr_t; |
/**< Formats for uintptr_t, size_t */ |
/**< Formats for uintptr_t, size_t, count_t and index_t */ |
#define PRIp "llx" |
#define PRIs "llu" |
#define PRIc "llu" |
#define PRIi "llu" |
/**< Formats for (u)int8_t, (u)int16_t, (u)int32_t, (u)int64_t and (u)native_t */ |
#define PRId8 "d" |
/branches/arm/kernel/arch/sparc64/include/byteorder.h |
---|
0,0 → 1,43 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup sparc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_sparc64_BYTEORDER_H_ |
#define KERN_sparc64_BYTEORDER_H_ |
#define ARCH_IS_BIG_ENDIAN |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/sparc64/include/drivers/sgcn.h |
---|
File deleted |
/branches/arm/kernel/arch/sparc64/include/drivers/scr.h |
---|
42,14 → 42,12 |
SCR_UNKNOWN, |
SCR_ATYFB, |
SCR_FFB, |
SCR_CGSIX, |
SCR_XVR |
SCR_CGSIX |
} scr_type_t; |
extern scr_type_t scr_type; |
extern void scr_init(ofw_tree_node_t *node); |
extern void scr_redraw(void); |
#endif |
/branches/arm/kernel/arch/sparc64/include/drivers/z8530.h |
---|
0,0 → 1,140 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup sparc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_sparc64_Z8530_H_ |
#define KERN_sparc64_Z8530_H_ |
#include <arch/types.h> |
#include <arch/drivers/kbd.h> |
#define Z8530_CHAN_A 4 |
#define Z8530_CHAN_B 0 |
#define WR0 0 |
#define WR1 1 |
#define WR2 2 |
#define WR3 3 |
#define WR4 4 |
#define WR5 5 |
#define WR6 6 |
#define WR7 7 |
#define WR8 8 |
#define WR9 9 |
#define WR10 10 |
#define WR11 11 |
#define WR12 12 |
#define WR13 13 |
#define WR14 14 |
#define WR15 15 |
#define RR0 0 |
#define RR1 1 |
#define RR2 2 |
#define RR3 3 |
#define RR8 8 |
#define RR10 10 |
#define RR12 12 |
#define RR13 13 |
#define RR14 14 |
#define RR15 15 |
/* Write Register 0 */ |
#define WR0_TX_IP_RST (0x5<<3) /** Reset pending TX interrupt. */ |
#define WR0_ERR_RST (0x6<<3) |
/* Write Register 1 */ |
#define WR1_RID (0x0<<3) /** Receive Interrupts Disabled. */ |
#define WR1_RIFCSC (0x1<<3) /** Receive Interrupt on First Character or Special Condition. */ |
#define WR1_IARCSC (0x2<<3) /** Interrupt on All Receive Characters or Special Conditions. */ |
#define WR1_RISC (0x3<<3) /** Receive Interrupt on Special Condition. */ |
#define WR1_PISC (0x1<<2) /** Parity Is Special Condition. */ |
/* Write Register 3 */ |
#define WR3_RX_ENABLE (0x1<<0) /** Rx Enable. */ |
#define WR3_RX8BITSCH (0x3<<6) /** 8-bits per character. */ |
/* Write Register 9 */ |
#define WR9_MIE (0x1<<3) /** Master Interrupt Enable. */ |
/* Read Register 0 */ |
#define RR0_RCA (0x1<<0) /** Receive Character Available. */ |
/** Structure representing the z8530 device. */ |
typedef struct { |
devno_t devno; |
volatile uint8_t *reg; /** Memory mapped registers of the z8530. */ |
} z8530_t; |
static inline void z8530_write(z8530_t *dev, index_t chan, uint8_t reg, uint8_t val) |
{ |
/* |
* Registers 8-15 will automatically issue the Point High |
* command as their bit 3 is 1. |
*/ |
dev->reg[WR0+chan] = reg; /* select register */ |
dev->reg[WR0+chan] = val; /* write value */ |
} |
static inline void z8530_write_a(z8530_t *dev, uint8_t reg, uint8_t val) |
{ |
z8530_write(dev, Z8530_CHAN_A, reg, val); |
} |
static inline void z8530_write_b(z8530_t *dev, uint8_t reg, uint8_t val) |
{ |
z8530_write(dev, Z8530_CHAN_B, reg, val); |
} |
static inline uint8_t z8530_read(z8530_t *dev, index_t chan, uint8_t reg) |
{ |
/* |
* Registers 8-15 will automatically issue the Point High |
* command as their bit 3 is 1. |
*/ |
dev->reg[WR0+chan] = reg; /* select register */ |
return dev->reg[WR0+chan]; |
} |
static inline uint8_t z8530_read_a(z8530_t *dev, uint8_t reg) |
{ |
return z8530_read(dev, Z8530_CHAN_A, reg); |
} |
static inline uint8_t z8530_read_b(z8530_t *dev, uint8_t reg) |
{ |
return z8530_read(dev, Z8530_CHAN_B, reg); |
} |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/sparc64/include/drivers/pci.h |
---|
51,8 → 51,8 |
}; |
struct pci_operations { |
void (* enable_interrupt)(pci_t *, int); |
void (* clear_interrupt)(pci_t *, int); |
void (* enable_interrupt)(pci_t *pci, int inr); |
void (* clear_interrupt)(pci_t *pci, int inr); |
}; |
struct pci { |
61,9 → 61,9 |
volatile uint64_t *reg; /**< Registers including interrupt registers. */ |
}; |
extern pci_t *pci_init(ofw_tree_node_t *); |
extern void pci_enable_interrupt(pci_t *, int); |
extern void pci_clear_interrupt(void *, int); |
extern pci_t *pci_init(ofw_tree_node_t *node); |
extern void pci_enable_interrupt(pci_t *pci, int inr); |
extern void pci_clear_interrupt(pci_t *pci, int inr); |
#endif |
/branches/arm/kernel/arch/sparc64/include/drivers/fhc.h |
---|
44,9 → 44,9 |
extern fhc_t *central_fhc; |
extern fhc_t *fhc_init(ofw_tree_node_t *); |
extern void fhc_enable_interrupt(fhc_t *, int); |
extern void fhc_clear_interrupt(void *, int); |
extern fhc_t *fhc_init(ofw_tree_node_t *node); |
extern void fhc_enable_interrupt(fhc_t *fhc, int inr); |
extern void fhc_clear_interrupt(fhc_t *fhc, int inr); |
#endif |
/branches/arm/kernel/arch/sparc64/include/drivers/kbd.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup sparc64 |
/** @addtogroup sparc64 |
* @{ |
*/ |
/** @file |
38,6 → 38,14 |
#include <arch/types.h> |
#include <genarch/ofw/ofw_tree.h> |
typedef enum { |
KBD_UNKNOWN, |
KBD_Z8530, |
KBD_NS16550 |
} kbd_type_t; |
extern kbd_type_t kbd_type; |
extern void kbd_init(ofw_tree_node_t *node); |
#endif |
/branches/arm/kernel/arch/sparc64/include/drivers/ns16550.h |
---|
0,0 → 1,102 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup sparc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_sparc64_NS16550_H_ |
#define KERN_sparc64_NS16550_H_ |
#include <arch/types.h> |
#include <arch/drivers/kbd.h> |
/* NS16550 registers */ |
#define RBR_REG 0 /** Receiver Buffer Register. */ |
#define IER_REG 1 /** Interrupt Enable Register. */ |
#define IIR_REG 2 /** Interrupt Ident Register (read). */ |
#define FCR_REG 2 /** FIFO control register (write). */ |
#define LCR_REG 3 /** Line Control register. */ |
#define LSR_REG 5 /** Line Status Register. */ |
#define IER_ERBFI 0x01 /** Enable Receive Buffer Full Interrupt. */ |
#define LCR_DLAB 0x80 /** Divisor Latch Access bit. */ |
/** Structure representing the ns16550 device. */ |
typedef struct { |
devno_t devno; |
volatile uint8_t *reg; /** Memory mapped registers of the ns16550. */ |
} ns16550_t; |
static inline uint8_t ns16550_rbr_read(ns16550_t *dev) |
{ |
return dev->reg[RBR_REG]; |
} |
static inline uint8_t ns16550_ier_read(ns16550_t *dev) |
{ |
return dev->reg[IER_REG]; |
} |
static inline void ns16550_ier_write(ns16550_t *dev, uint8_t v) |
{ |
dev->reg[IER_REG] = v; |
} |
static inline uint8_t ns16550_iir_read(ns16550_t *dev) |
{ |
return dev->reg[IIR_REG]; |
} |
static inline void ns16550_fcr_write(ns16550_t *dev, uint8_t v) |
{ |
dev->reg[FCR_REG] = v; |
} |
static inline uint8_t ns16550_lcr_read(ns16550_t *dev) |
{ |
return dev->reg[LCR_REG]; |
} |
static inline void ns16550_lcr_write(ns16550_t *dev, uint8_t v) |
{ |
dev->reg[LCR_REG] = v; |
} |
static inline uint8_t ns16550_lsr_read(ns16550_t *dev) |
{ |
return dev->reg[LSR_REG]; |
} |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/sparc64/include/boot/boot.h |
---|
48,12 → 48,9 |
#define TASKMAP_MAX_RECORDS 32 |
#define MEMMAP_MAX_RECORDS 32 |
#define BOOTINFO_TASK_NAME_BUFLEN 32 |
typedef struct { |
void * addr; |
uint32_t size; |
char name[BOOTINFO_TASK_NAME_BUFLEN]; |
} utask_t; |
typedef struct { |
/branches/arm/kernel/arch/sparc64/include/fpu_context.h |
---|
37,6 → 37,7 |
#include <arch/types.h> |
#define ARCH_HAS_FPU |
#define FPU_CONTEXT_ALIGN 8 |
typedef struct { |
/branches/arm/kernel/arch/sparc64/include/context.h |
---|
39,7 → 39,7 |
#include <arch/types.h> |
#include <align.h> |
#define SP_DELTA (STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE) |
#define SP_DELTA STACK_WINDOW_SAVE_AREA_SIZE |
#ifdef context_set |
#undef context_set |
/branches/arm/kernel/arch/sparc64/include/regdef.h |
---|
55,11 → 55,8 |
#define WSTATE_NORMAL(n) (n) |
#define WSTATE_OTHER(n) ((n) << 3) |
/* |
* The following definitions concern the UPA_CONFIG register on US and the |
* FIREPLANE_CONFIG register on US3. |
*/ |
#define ICBUS_CONFIG_MID_SHIFT 17 |
#define UPA_CONFIG_MID_SHIFT 17 |
#define UPA_CONFIG_MID_MASK 0x1f |
#endif |
/branches/arm/kernel/arch/sparc64/include/arch.h |
---|
41,16 → 41,10 |
#define ASI_AIUS 0x11 /** Access to secondary context with user privileges. */ |
#define ASI_NUCLEUS_QUAD_LDD 0x24 /** ASI for 16-byte atomic loads. */ |
#define ASI_DCACHE_TAG 0x47 /** ASI D-Cache Tag. */ |
#define ASI_ICBUS_CONFIG 0x4a /** ASI of the UPA_CONFIG/FIREPLANE_CONFIG register. */ |
#define ASI_UPA_CONFIG 0x4a /** ASI of the UPA_CONFIG register. */ |
#define NWINDOWS 8 /** Number of register window sets. */ |
#ifndef __ASM__ |
extern void arch_pre_main(void); |
#endif /* __ASM__ */ |
#endif |
/** @} |
/branches/arm/kernel/arch/sparc64/include/register.h |
---|
117,6 → 117,23 |
}; |
typedef union fprs_reg fprs_reg_t; |
/** UPA_CONFIG register. |
* |
* Note that format of this register differs significantly from |
* processor version to version. The format defined here |
* is the common subset for all supported processor versions. |
*/ |
union upa_config { |
uint64_t value; |
struct { |
uint64_t : 34; |
unsigned pcon : 8; /**< Processor configuration. */ |
unsigned mid : 5; /**< Module (processor) ID register. */ |
unsigned pcap : 17; /**< Processor capabilities. */ |
} __attribute__ ((packed)); |
}; |
typedef union upa_config upa_config_t; |
#endif |
/** @} |
/branches/arm/kernel/arch/sparc64/src/trap/trap_table.S |
---|
341,7 → 341,7 |
.org trap_table + (TT_TRAP_INSTRUCTION_0+\cur)*ENTRY_SIZE |
.global trap_instruction_\cur\()_tl0 |
trap_instruction_\cur\()_tl0: |
ba %xcc, trap_instruction_handler |
ba trap_instruction_handler |
mov \cur, %g2 |
.endr |
478,9 → 478,9 |
*/ |
rdpr %tl, %g3 |
cmp %g3, 1 |
be %xcc, 1f |
be 1f |
nop |
0: ba %xcc, 0b ! this is for debugging, if we ever get here |
0: ba 0b ! this is for debugging, if we ever get here |
nop ! it will be easy to find |
1: |
499,7 → 499,7 |
wrpr %g4, 0, %cwp ! resynchronize CWP |
andcc %g3, TSTATE_PRIV_BIT, %g0 ! if this trap came from the privileged mode... |
bnz %xcc, 0f ! ...skip setting of kernel stack and primary context |
bnz 0f ! ...skip setting of kernel stack and primary context |
nop |
.endif |
545,7 → 545,7 |
flush %l0 |
.if NOT(\is_syscall) |
ba %xcc, 1f |
ba 1f |
nop |
0: |
save %sp, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp |
606,10 → 606,10 |
add %sp, PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC, %o1 |
.else |
/* |
* Call the higher-level syscall handler and enable interrupts. |
* Call the higher-level syscall handler. |
*/ |
call syscall_handler |
wrpr %g0, PSTATE_PRIV_BIT | PSTATE_PEF_BIT | PSTATE_IE_BIT, %pstate |
nop |
mov %o0, %i0 ! copy the value returned by the syscall |
.endif |
672,7 → 672,7 |
and %l0, NWINDOWS - 1, %l0 ! %l0 mod NWINDOWS |
rdpr %cwp, %l1 |
cmp %l0, %l1 |
bz %xcc, 0f ! CWP is ok |
bz 0f ! CWP is ok |
nop |
/* |
712,7 → 712,7 |
.if NOT(\is_syscall) |
rdpr %tstate, %g1 |
andcc %g1, TSTATE_PRIV_BIT, %g0 ! if we are not returning to userspace..., |
bnz %xcc, 1f ! ...skip restoring userspace windows |
bnz 1f ! ...skip restoring userspace windows |
nop |
.endif |
748,8 → 748,9 |
* Fill all windows stored in the buffer. |
*/ |
clr %g4 |
0: andcc %g7, UWB_ALIGNMENT - 1, %g0 ! alignment check |
bz %xcc, 0f ! %g7 is UWB_ALIGNMENT-aligned, no more windows to refill |
set PAGE_SIZE - 1, %g5 |
0: andcc %g7, %g5, %g0 ! PAGE_SIZE alignment check |
bz 0f ! %g7 is page-aligned, no more windows to refill |
nop |
add %g7, -STACK_WINDOW_SAVE_AREA_SIZE, %g7 |
774,7 → 775,7 |
and %g3, NWINDOWS - 1, %g3 |
wrpr %g3, 0, %cwp ! switch to the preceeding window |
ba %xcc, 0b |
ba 0b |
inc %g4 |
0: |
785,7 → 786,7 |
wrpr %g1, 0, %cwp |
add %g4, %g2, %g2 |
cmp %g2, NWINDOWS - 2 |
bg %xcc, 2f ! fix the CANRESTORE=NWINDOWS-1 anomaly |
bg 2f ! fix the CANRESTORE=NWINDOWS-1 anomaly |
mov NWINDOWS - 2, %g1 ! use dealy slot for both cases |
sub %g1, %g2, %g1 |
/branches/arm/kernel/arch/sparc64/src/trap/exception.c |
---|
40,67 → 40,62 |
#include <arch/asm.h> |
#include <arch/register.h> |
#include <debug.h> |
#include <symtab.h> |
#include <print.h> |
#include <symtab.h> |
void dump_istate(istate_t *istate) |
{ |
char *tpcs, *tnpcs; |
tpcs = symtab_fmt_name_lookup(istate->tpc); |
tnpcs = symtab_fmt_name_lookup(istate->tnpc); |
printf("TSTATE=%#" PRIx64 "\n", istate->tstate); |
printf("TPC=%#" PRIx64 " (%s)\n", istate->tpc, tpcs); |
printf("TNPC=%#" PRIx64 " (%s)\n", istate->tnpc, tnpcs); |
printf("TPC=%#" PRIx64 " (%s)\n", istate->tpc, get_symtab_entry(istate->tpc)); |
printf("TNPC=%#" PRIx64 " (%s)\n", istate->tnpc, get_symtab_entry(istate->tnpc)); |
} |
/** Handle instruction_access_exception. (0x8) */ |
void instruction_access_exception(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle instruction_access_error. (0xa) */ |
void instruction_access_error(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle illegal_instruction. (0x10) */ |
void illegal_instruction(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle privileged_opcode. (0x11) */ |
void privileged_opcode(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle unimplemented_LDD. (0x12) */ |
void unimplemented_LDD(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle unimplemented_STD. (0x13) */ |
void unimplemented_STD(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle fp_disabled. (0x20) */ |
118,9 → 113,9 |
#ifdef CONFIG_FPU_LAZY |
scheduler_fpu_lazy_request(); |
#else |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
#endif |
} |
127,98 → 122,98 |
/** Handle fp_exception_ieee_754. (0x21) */ |
void fp_exception_ieee_754(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle fp_exception_other. (0x22) */ |
void fp_exception_other(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle tag_overflow. (0x23) */ |
void tag_overflow(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle division_by_zero. (0x28) */ |
void division_by_zero(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle data_access_exception. (0x30) */ |
void data_access_exception(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
dump_sfsr_and_sfar(); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle data_access_error. (0x32) */ |
void data_access_error(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle mem_address_not_aligned. (0x34) */ |
void mem_address_not_aligned(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle LDDF_mem_address_not_aligned. (0x35) */ |
void LDDF_mem_address_not_aligned(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle STDF_mem_address_not_aligned. (0x36) */ |
void STDF_mem_address_not_aligned(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle privileged_action. (0x37) */ |
void privileged_action(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle LDQF_mem_address_not_aligned. (0x38) */ |
void LDQF_mem_address_not_aligned(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle STQF_mem_address_not_aligned. (0x39) */ |
void STQF_mem_address_not_aligned(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** @} |
/branches/arm/kernel/arch/sparc64/src/trap/interrupt.c |
---|
67,19 → 67,11 |
*/ |
void interrupt(int n, istate_t *istate) |
{ |
uint64_t status; |
uint64_t intrcv; |
uint64_t data0; |
status = asi_u64_read(ASI_INTR_DISPATCH_STATUS, 0); |
if (status & (!INTR_DISPATCH_STATUS_BUSY)) |
panic("Interrupt Dispatch Status busy bit not set."); |
intrcv = asi_u64_read(ASI_INTR_RECEIVE, 0); |
#if defined (US) |
data0 = asi_u64_read(ASI_INTR_R, ASI_UDB_INTR_R_DATA_0); |
#elif defined (US3) |
data0 = asi_u64_read(ASI_INTR_R, VA_INTR_R_DATA_0); |
#endif |
data0 = asi_u64_read(ASI_UDB_INTR_R, ASI_UDB_INTR_R_DATA_0); |
irq_t *irq = irq_dispatch_and_lock(data0); |
if (irq) { |
86,13 → 78,7 |
/* |
* The IRQ handler was found. |
*/ |
irq->handler(irq); |
/* |
* See if there is a clear-interrupt-routine and call it. |
*/ |
if (irq->cir) { |
irq->cir(irq->cir_arg, irq->inr); |
} |
irq->handler(irq, irq->arg); |
spinlock_unlock(&irq->lock); |
} else if (data0 > config.base) { |
/* |
112,7 → 98,7 |
*/ |
#ifdef CONFIG_DEBUG |
printf("cpu%u: spurious interrupt (intrcv=%#" PRIx64 |
", data0=%#" PRIx64 ")\n", CPU->id, intrcv, data0); |
", data0=%#" PRIx64 ")\n", CPU->id, intrcv, data0); |
#endif |
} |
/branches/arm/kernel/arch/sparc64/src/asm.S |
---|
225,15 → 225,10 |
.global memsetb |
memsetb: |
ba %xcc, _memsetb |
b _memsetb |
nop |
.global memsetw |
memsetw: |
ba %xcc, _memsetw |
nop |
.macro WRITE_ALTERNATE_REGISTER reg, bit |
rdpr %pstate, %g1 ! save PSTATE.PEF |
wrpr %g0, (\bit | PSTATE_PRIV_BIT), %pstate |
277,7 → 272,7 |
*/ |
.global switch_to_userspace |
switch_to_userspace: |
save %o1, -(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE), %sp |
save %o1, -STACK_WINDOW_SAVE_AREA_SIZE, %sp |
flushw |
wrpr %g0, 0, %cleanwin ! avoid information leak |
/branches/arm/kernel/arch/sparc64/src/mm/cache.S |
---|
47,3 → 47,45 |
retl |
! beware SF Erratum #51, do not put the MEMBAR here |
nop |
/** Flush only D-cache lines of one virtual color. |
* |
* @param o0 Virtual color to be flushed. |
*/ |
.global dcache_flush_color |
dcache_flush_color: |
mov (DCACHE_SIZE / DCACHE_LINE_SIZE) / 2, %g1 |
set DCACHE_SIZE / 2, %g2 |
sllx %g2, %o0, %g2 |
sub %g2, DCACHE_LINE_SIZE, %g2 |
0: stxa %g0, [%g2] ASI_DCACHE_TAG |
membar #Sync |
subcc %g1, 1, %g1 |
bnz,pt %xcc, 0b |
sub %g2, DCACHE_LINE_SIZE, %g2 |
retl |
nop |
/** Flush only D-cache lines of one virtual color and one tag. |
* |
* @param o0 Virtual color to lookup the tag. |
* @param o1 Tag of the cachelines to be flushed. |
*/ |
.global dcache_flush_tag |
dcache_flush_tag: |
mov (DCACHE_SIZE / DCACHE_LINE_SIZE) / 2, %g1 |
set DCACHE_SIZE / 2, %g2 |
sllx %g2, %o0, %g2 |
sub %g2, DCACHE_LINE_SIZE, %g2 |
0: ldxa [%g2] ASI_DCACHE_TAG, %g3 |
srlx %g3, DCACHE_TAG_SHIFT, %g3 |
cmp %g3, %o1 |
bnz 1f |
nop |
stxa %g0, [%g2] ASI_DCACHE_TAG |
membar #Sync |
1: subcc %g1, 1, %g1 |
bnz,pt %xcc, 0b |
sub %g2, DCACHE_LINE_SIZE, %g2 |
retl |
nop |
/branches/arm/kernel/arch/sparc64/src/mm/as.c |
---|
89,7 → 89,7 |
* The count must be calculated with respect to the emualted 16K page |
* size. |
*/ |
size_t cnt = ((ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) * |
count_t cnt = ((ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) * |
sizeof(tsb_entry_t)) >> FRAME_WIDTH; |
frame_free(KA2PA((uintptr_t) as->arch.itsb)); |
return cnt; |
101,7 → 101,7 |
int as_create_arch(as_t *as, int flags) |
{ |
#ifdef CONFIG_TSB |
tsb_invalidate(as, 0, (size_t) -1); |
tsb_invalidate(as, 0, (count_t) -1); |
#endif |
return 0; |
} |
164,25 → 164,7 |
itsb_base_write(tsb_base.value); |
tsb_base.base = ((uintptr_t) as->arch.dtsb) >> MMU_PAGE_WIDTH; |
dtsb_base_write(tsb_base.value); |
#if defined (US3) |
/* |
* Clear the extension registers. |
* In HelenOS, primary and secondary context registers contain |
* equal values and kernel misses (context 0, ie. the nucleus context) |
* are excluded from the TSB miss handler, so it makes no sense |
* to have separate TSBs for primary, secondary and nucleus contexts. |
* Clearing the extension registers will ensure that the value of the |
* TSB Base register will be used as an address of TSB, making the code |
* compatible with the US port. |
*/ |
itsb_primary_extension_write(0); |
itsb_nucleus_extension_write(0); |
dtsb_primary_extension_write(0); |
dtsb_secondary_extension_write(0); |
dtsb_nucleus_extension_write(0); |
#endif |
#endif |
} |
/** Perform sparc64-specific tasks when an address space is removed from the |
/branches/arm/kernel/arch/sparc64/src/mm/tlb.c |
---|
54,13 → 54,14 |
#include <arch/mm/tsb.h> |
#endif |
static void dtlb_pte_copy(pte_t *, size_t, bool); |
static void itlb_pte_copy(pte_t *, size_t); |
static void do_fast_instruction_access_mmu_miss_fault(istate_t *, const char *); |
static void do_fast_data_access_mmu_miss_fault(istate_t *, tlb_tag_access_reg_t, |
const char *); |
static void do_fast_data_access_protection_fault(istate_t *, |
tlb_tag_access_reg_t, const char *); |
static void dtlb_pte_copy(pte_t *t, index_t index, bool ro); |
static void itlb_pte_copy(pte_t *t, index_t index); |
static void do_fast_instruction_access_mmu_miss_fault(istate_t *istate, |
const char *str); |
static void do_fast_data_access_mmu_miss_fault(istate_t *istate, |
tlb_tag_access_reg_t tag, const char *str); |
static void do_fast_data_access_protection_fault(istate_t *istate, |
tlb_tag_access_reg_t tag, const char *str); |
char *context_encoding[] = { |
"Primary", |
85,11 → 86,11 |
/** Insert privileged mapping into DMMU TLB. |
* |
* @param page Virtual page address. |
* @param frame Physical frame address. |
* @param pagesize Page size. |
* @param locked True for permanent mappings, false otherwise. |
* @param cacheable True if the mapping is cacheable, false otherwise. |
* @param page Virtual page address. |
* @param frame Physical frame address. |
* @param pagesize Page size. |
* @param locked True for permanent mappings, false otherwise. |
* @param cacheable True if the mapping is cacheable, false otherwise. |
*/ |
void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize, |
bool locked, bool cacheable) |
102,7 → 103,7 |
pg.address = page; |
fr.address = frame; |
tag.context = ASID_KERNEL; |
tag.value = ASID_KERNEL; |
tag.vpn = pg.vpn; |
dtlb_tag_access_write(tag.value); |
125,12 → 126,12 |
/** Copy PTE to TLB. |
* |
* @param t Page Table Entry to be copied. |
* @param index Zero if lower 8K-subpage, one if higher 8K-subpage. |
* @param ro If true, the entry will be created read-only, regardless |
* of its w field. |
* @param t Page Table Entry to be copied. |
* @param index Zero if lower 8K-subpage, one if higher 8K-subpage. |
* @param ro If true, the entry will be created read-only, regardless of its |
* w field. |
*/ |
void dtlb_pte_copy(pte_t *t, size_t index, bool ro) |
void dtlb_pte_copy(pte_t *t, index_t index, bool ro) |
{ |
tlb_tag_access_reg_t tag; |
tlb_data_t data; |
164,10 → 165,10 |
/** Copy PTE to ITLB. |
* |
* @param t Page Table Entry to be copied. |
* @param index Zero if lower 8K-subpage, one if higher 8K-subpage. |
* @param t Page Table Entry to be copied. |
* @param index Zero if lower 8K-subpage, one if higher 8K-subpage. |
*/ |
void itlb_pte_copy(pte_t *t, size_t index) |
void itlb_pte_copy(pte_t *t, index_t index) |
{ |
tlb_tag_access_reg_t tag; |
tlb_data_t data; |
199,12 → 200,12 |
/** ITLB miss handler. */ |
void fast_instruction_access_mmu_miss(unative_t unused, istate_t *istate) |
{ |
uintptr_t page_16k = ALIGN_DOWN(istate->tpc, PAGE_SIZE); |
size_t index = (istate->tpc >> MMU_PAGE_WIDTH) % MMU_PAGES_PER_PAGE; |
uintptr_t va = ALIGN_DOWN(istate->tpc, PAGE_SIZE); |
index_t index = (istate->tpc >> MMU_PAGE_WIDTH) % MMU_PAGES_PER_PAGE; |
pte_t *t; |
page_table_lock(AS, true); |
t = page_mapping_find(AS, page_16k); |
t = page_mapping_find(AS, va); |
if (t && PTE_EXECUTABLE(t)) { |
/* |
* The mapping was found in the software page hash table. |
222,8 → 223,7 |
* handler. |
*/ |
page_table_unlock(AS, true); |
if (as_page_fault(page_16k, PF_ACCESS_EXEC, istate) == |
AS_PF_FAULT) { |
if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) { |
do_fast_instruction_access_mmu_miss_fault(istate, |
__func__); |
} |
235,21 → 235,18 |
* Note that some faults (e.g. kernel faults) were already resolved by the |
* low-level, assembly language part of the fast_data_access_mmu_miss handler. |
* |
* @param tag Content of the TLB Tag Access register as it existed |
* when the trap happened. This is to prevent confusion |
* created by clobbered Tag Access register during a nested |
* DTLB miss. |
* @param istate Interrupted state saved on the stack. |
* @param tag Content of the TLB Tag Access register as it existed when the |
* trap happened. This is to prevent confusion created by clobbered |
* Tag Access register during a nested DTLB miss. |
* @param istate Interrupted state saved on the stack. |
*/ |
void fast_data_access_mmu_miss(tlb_tag_access_reg_t tag, istate_t *istate) |
{ |
uintptr_t page_8k; |
uintptr_t page_16k; |
size_t index; |
uintptr_t va; |
index_t index; |
pte_t *t; |
page_8k = (uint64_t) tag.vpn << MMU_PAGE_WIDTH; |
page_16k = ALIGN_DOWN(page_8k, PAGE_SIZE); |
va = ALIGN_DOWN((uint64_t) tag.vpn << MMU_PAGE_WIDTH, PAGE_SIZE); |
index = tag.vpn % MMU_PAGES_PER_PAGE; |
if (tag.context == ASID_KERNEL) { |
257,15 → 254,6 |
/* NULL access in kernel */ |
do_fast_data_access_mmu_miss_fault(istate, tag, |
__func__); |
} else if (page_8k >= end_of_identity) { |
/* |
* The kernel is accessing the I/O space. |
* We still do identity mapping for I/O, |
* but without caching. |
*/ |
dtlb_insert_mapping(page_8k, KA2PA(page_8k), |
PAGESIZE_8K, false, false); |
return; |
} |
do_fast_data_access_mmu_miss_fault(istate, tag, "Unexpected " |
"kernel page fault."); |
272,7 → 260,7 |
} |
page_table_lock(AS, true); |
t = page_mapping_find(AS, page_16k); |
t = page_mapping_find(AS, va); |
if (t) { |
/* |
* The mapping was found in the software page hash table. |
290,8 → 278,7 |
* handler. |
*/ |
page_table_unlock(AS, true); |
if (as_page_fault(page_16k, PF_ACCESS_READ, istate) == |
AS_PF_FAULT) { |
if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) { |
do_fast_data_access_mmu_miss_fault(istate, tag, |
__func__); |
} |
300,23 → 287,22 |
/** DTLB protection fault handler. |
* |
* @param tag Content of the TLB Tag Access register as it existed |
* when the trap happened. This is to prevent confusion |
* created by clobbered Tag Access register during a nested |
* DTLB miss. |
* @param istate Interrupted state saved on the stack. |
* @param tag Content of the TLB Tag Access register as it existed when the |
* trap happened. This is to prevent confusion created by clobbered |
* Tag Access register during a nested DTLB miss. |
* @param istate Interrupted state saved on the stack. |
*/ |
void fast_data_access_protection(tlb_tag_access_reg_t tag, istate_t *istate) |
{ |
uintptr_t page_16k; |
size_t index; |
uintptr_t va; |
index_t index; |
pte_t *t; |
page_16k = ALIGN_DOWN((uint64_t) tag.vpn << MMU_PAGE_WIDTH, PAGE_SIZE); |
va = ALIGN_DOWN((uint64_t) tag.vpn << MMU_PAGE_WIDTH, PAGE_SIZE); |
index = tag.vpn % MMU_PAGES_PER_PAGE; /* 16K-page emulation */ |
page_table_lock(AS, true); |
t = page_mapping_find(AS, page_16k); |
t = page_mapping_find(AS, va); |
if (t && PTE_WRITABLE(t)) { |
/* |
* The mapping was found in the software page hash table and is |
326,7 → 312,7 |
t->a = true; |
t->d = true; |
dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_SECONDARY, |
page_16k + index * MMU_PAGE_SIZE); |
va + index * MMU_PAGE_SIZE); |
dtlb_pte_copy(t, index, false); |
#ifdef CONFIG_TSB |
dtsb_pte_copy(t, index, false); |
338,8 → 324,7 |
* handler. |
*/ |
page_table_unlock(AS, true); |
if (as_page_fault(page_16k, PF_ACCESS_WRITE, istate) == |
AS_PF_FAULT) { |
if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) { |
do_fast_data_access_protection_fault(istate, tag, |
__func__); |
} |
346,26 → 331,6 |
} |
} |
/** Print TLB entry (for debugging purposes). |
* |
* The diag field has been left out in order to make this function more generic |
* (there is no diag field in US3 architeture). |
* |
* @param i TLB entry number |
* @param t TLB entry tag |
* @param d TLB entry data |
*/ |
static void print_tlb_entry(int i, tlb_tag_read_reg_t t, tlb_data_t d) |
{ |
printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, " |
"ie=%d, soft2=%#x, pfn=%#x, soft=%#x, l=%d, " |
"cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn, |
t.context, d.v, d.size, d.nfo, d.ie, d.soft2, |
d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g); |
} |
#if defined (US) |
/** Print contents of both TLBs. */ |
void tlb_print(void) |
{ |
377,7 → 342,12 |
for (i = 0; i < ITLB_ENTRY_COUNT; i++) { |
d.value = itlb_data_access_read(i); |
t.value = itlb_tag_read_read(i); |
print_tlb_entry(i, t, d); |
printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, " |
"ie=%d, soft2=%#x, diag=%#x, pfn=%#x, soft=%#x, l=%d, " |
"cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn, |
t.context, d.v, d.size, d.nfo, d.ie, d.soft2, d.diag, |
d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g); |
} |
printf("D-TLB contents:\n"); |
384,63 → 354,22 |
for (i = 0; i < DTLB_ENTRY_COUNT; i++) { |
d.value = dtlb_data_access_read(i); |
t.value = dtlb_tag_read_read(i); |
print_tlb_entry(i, t, d); |
printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, " |
"ie=%d, soft2=%#x, diag=%#x, pfn=%#x, soft=%#x, l=%d, " |
"cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn, |
t.context, d.v, d.size, d.nfo, d.ie, d.soft2, d.diag, |
d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g); |
} |
} |
#elif defined (US3) |
/** Print contents of all TLBs. */ |
void tlb_print(void) |
{ |
int i; |
tlb_data_t d; |
tlb_tag_read_reg_t t; |
printf("TLB_ISMALL contents:\n"); |
for (i = 0; i < tlb_ismall_size(); i++) { |
d.value = dtlb_data_access_read(TLB_ISMALL, i); |
t.value = dtlb_tag_read_read(TLB_ISMALL, i); |
print_tlb_entry(i, t, d); |
} |
printf("TLB_IBIG contents:\n"); |
for (i = 0; i < tlb_ibig_size(); i++) { |
d.value = dtlb_data_access_read(TLB_IBIG, i); |
t.value = dtlb_tag_read_read(TLB_IBIG, i); |
print_tlb_entry(i, t, d); |
} |
printf("TLB_DSMALL contents:\n"); |
for (i = 0; i < tlb_dsmall_size(); i++) { |
d.value = dtlb_data_access_read(TLB_DSMALL, i); |
t.value = dtlb_tag_read_read(TLB_DSMALL, i); |
print_tlb_entry(i, t, d); |
} |
printf("TLB_DBIG_1 contents:\n"); |
for (i = 0; i < tlb_dbig_size(); i++) { |
d.value = dtlb_data_access_read(TLB_DBIG_0, i); |
t.value = dtlb_tag_read_read(TLB_DBIG_0, i); |
print_tlb_entry(i, t, d); |
} |
printf("TLB_DBIG_2 contents:\n"); |
for (i = 0; i < tlb_dbig_size(); i++) { |
d.value = dtlb_data_access_read(TLB_DBIG_1, i); |
t.value = dtlb_tag_read_read(TLB_DBIG_1, i); |
print_tlb_entry(i, t, d); |
} |
} |
#endif |
void do_fast_instruction_access_mmu_miss_fault(istate_t *istate, |
const char *str) |
{ |
fault_if_from_uspace(istate, "%s.", str); |
fault_if_from_uspace(istate, "%s\n", str); |
dump_istate(istate); |
panic("%s.", str); |
panic("%s\n", str); |
} |
void do_fast_data_access_mmu_miss_fault(istate_t *istate, |
450,12 → 379,12 |
va = tag.vpn << MMU_PAGE_WIDTH; |
if (tag.context) { |
fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d).", str, va, |
fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d)\n", str, va, |
tag.context); |
} |
dump_istate(istate); |
printf("Faulting page: %p, ASID=%d.\n", va, tag.context); |
panic("%s.", str); |
printf("Faulting page: %p, ASID=%d\n", va, tag.context); |
panic("%s\n", str); |
} |
void do_fast_data_access_protection_fault(istate_t *istate, |
466,12 → 395,12 |
va = tag.vpn << MMU_PAGE_WIDTH; |
if (tag.context) { |
fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d).", str, va, |
fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d)\n", str, va, |
tag.context); |
} |
printf("Faulting page: %p, ASID=%d\n", va, tag.context); |
dump_istate(istate); |
panic("%s.", str); |
panic("%s\n", str); |
} |
void dump_sfsr_and_sfar(void) |
482,39 → 411,30 |
sfsr.value = dtlb_sfsr_read(); |
sfar = dtlb_sfar_read(); |
#if defined (US) |
printf("DTLB SFSR: asi=%#x, ft=%#x, e=%d, ct=%d, pr=%d, w=%d, ow=%d, " |
"fv=%d\n", sfsr.asi, sfsr.ft, sfsr.e, sfsr.ct, sfsr.pr, sfsr.w, |
sfsr.ow, sfsr.fv); |
#elif defined (US3) |
printf("DTLB SFSR: nf=%d, asi=%#x, tm=%d, ft=%#x, e=%d, ct=%d, pr=%d, " |
"w=%d, ow=%d, fv=%d\n", sfsr.nf, sfsr.asi, sfsr.tm, sfsr.ft, |
sfsr.e, sfsr.ct, sfsr.pr, sfsr.w, sfsr.ow, sfsr.fv); |
#endif |
printf("DTLB SFAR: address=%p\n", sfar); |
dtlb_sfsr_write(0); |
} |
#if defined (US) |
/** Invalidate all unlocked ITLB and DTLB entries. */ |
void tlb_invalidate_all(void) |
{ |
int i; |
tlb_data_t d; |
tlb_tag_read_reg_t t; |
/* |
* Walk all ITLB and DTLB entries and remove all unlocked mappings. |
* |
* The kernel doesn't use global mappings so any locked global mappings |
* found must have been created by someone else. Their only purpose now |
* found must have been created by someone else. Their only purpose now |
* is to collide with proper mappings. Invalidate immediately. It should |
* be safe to invalidate them as late as now. |
*/ |
tlb_data_t d; |
tlb_tag_read_reg_t t; |
for (i = 0; i < ITLB_ENTRY_COUNT; i++) { |
d.value = itlb_data_access_read(i); |
if (!d.l || d.g) { |
524,7 → 444,7 |
itlb_data_access_write(i, d.value); |
} |
} |
for (i = 0; i < DTLB_ENTRY_COUNT; i++) { |
d.value = dtlb_data_access_read(i); |
if (!d.l || d.g) { |
534,20 → 454,9 |
dtlb_data_access_write(i, d.value); |
} |
} |
} |
#elif defined (US3) |
/** Invalidate all unlocked ITLB and DTLB entries. */ |
void tlb_invalidate_all(void) |
{ |
itlb_demap(TLB_DEMAP_ALL, 0, 0); |
dtlb_demap(TLB_DEMAP_ALL, 0, 0); |
} |
#endif |
/** Invalidate all ITLB and DTLB entries that belong to specified ASID |
* (Context). |
* |
575,11 → 484,11 |
/** Invalidate all ITLB and DTLB entries for specified page range in specified |
* address space. |
* |
* @param asid Address Space ID. |
* @param page First page which to sweep out from ITLB and DTLB. |
* @param cnt Number of ITLB and DTLB entries to invalidate. |
* @param asid Address Space ID. |
* @param page First page which to sweep out from ITLB and DTLB. |
* @param cnt Number of ITLB and DTLB entries to invalidate. |
*/ |
void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt) |
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt) |
{ |
unsigned int i; |
tlb_context_reg_t pc_save, ctx; |
/branches/arm/kernel/arch/sparc64/src/mm/frame.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup sparc64mm |
/** @addtogroup sparc64mm |
* @{ |
*/ |
/** @file |
79,8 → 79,7 |
*/ |
frame_mark_unavailable(ADDR2PFN(KA2PA(PFN2ADDR(0))), 1); |
} |
end_of_identity = PA2KA(last_frame); |
} |
/** @} |
/branches/arm/kernel/arch/sparc64/src/mm/page.c |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2009 Jakub Jermar |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup sparc64mm |
/** @addtogroup sparc64mm |
* @{ |
*/ |
/** @file |
42,27 → 42,126 |
#include <align.h> |
#include <config.h> |
#ifdef CONFIG_SMP |
/** Entries locked in DTLB of BSP. |
* |
* Application processors need to have the same locked entries in their DTLBs as |
* the bootstrap processor. |
*/ |
static struct { |
uintptr_t virt_page; |
uintptr_t phys_page; |
int pagesize_code; |
} bsp_locked_dtlb_entry[DTLB_ENTRY_COUNT]; |
/** Number of entries in bsp_locked_dtlb_entry array. */ |
static count_t bsp_locked_dtlb_entries = 0; |
#endif /* CONFIG_SMP */ |
/** Perform sparc64 specific initialization of paging. */ |
void page_arch_init(void) |
{ |
if (config.cpu_active == 1) |
if (config.cpu_active == 1) { |
page_mapping_operations = &ht_mapping_operations; |
} else { |
#ifdef CONFIG_SMP |
unsigned int i; |
/* |
* Copy locked DTLB entries from the BSP. |
*/ |
for (i = 0; i < bsp_locked_dtlb_entries; i++) { |
dtlb_insert_mapping(bsp_locked_dtlb_entry[i].virt_page, |
bsp_locked_dtlb_entry[i].phys_page, |
bsp_locked_dtlb_entry[i].pagesize_code, true, |
false); |
} |
#endif |
} |
} |
/** Map memory-mapped device into virtual memory. |
* |
* We are currently using identity mapping for mapping device registers. |
* So far, only DTLB is used to map devices into memory. Chances are that there |
* will be only a limited amount of devices that the kernel itself needs to |
* lock in DTLB. |
* |
* @param physaddr Physical address of the page where the device is |
* located. |
* @param size Size of the device's registers. |
* @param physaddr Physical address of the page where the device is located. |
* Must be at least page-aligned. |
* @param size Size of the device's registers. Must not exceed 4M and must |
* include extra space caused by the alignment. |
* |
* @return Virtual address of the page where the device is mapped. |
* |
*/ |
uintptr_t hw_map(uintptr_t physaddr, size_t size) |
{ |
return PA2KA(physaddr); |
unsigned int order; |
unsigned int i; |
ASSERT(config.cpu_active == 1); |
struct { |
int pagesize_code; |
size_t increment; |
count_t count; |
} sizemap[] = { |
{ PAGESIZE_8K, 0, 1 }, /* 8K */ |
{ PAGESIZE_8K, MMU_PAGE_SIZE, 2 }, /* 16K */ |
{ PAGESIZE_8K, MMU_PAGE_SIZE, 4 }, /* 32K */ |
{ PAGESIZE_64K, 0, 1}, /* 64K */ |
{ PAGESIZE_64K, 8 * MMU_PAGE_SIZE, 2 }, /* 128K */ |
{ PAGESIZE_64K, 8 * MMU_PAGE_SIZE, 4 }, /* 256K */ |
{ PAGESIZE_512K, 0, 1 }, /* 512K */ |
{ PAGESIZE_512K, 64 * MMU_PAGE_SIZE, 2 }, /* 1M */ |
{ PAGESIZE_512K, 64 * MMU_PAGE_SIZE, 4 }, /* 2M */ |
{ PAGESIZE_4M, 0, 1 }, /* 4M */ |
{ PAGESIZE_4M, 512 * MMU_PAGE_SIZE, 2 } /* 8M */ |
}; |
ASSERT(ALIGN_UP(physaddr, MMU_PAGE_SIZE) == physaddr); |
ASSERT(size <= 8 * 1024 * 1024); |
if (size <= MMU_FRAME_SIZE) |
order = 0; |
else |
order = (fnzb64(size - 1) + 1) - MMU_FRAME_WIDTH; |
/* |
* Use virtual addresses that are beyond the limit of physical memory. |
* Thus, the physical address space will not be wasted by holes created |
* by frame_alloc(). |
*/ |
ASSERT(PA2KA(last_frame)); |
uintptr_t virtaddr = ALIGN_UP(PA2KA(last_frame), |
1 << (order + FRAME_WIDTH)); |
last_frame = ALIGN_UP(KA2PA(virtaddr) + size, |
1 << (order + FRAME_WIDTH)); |
for (i = 0; i < sizemap[order].count; i++) { |
/* |
* First, insert the mapping into DTLB. |
*/ |
dtlb_insert_mapping(virtaddr + i * sizemap[order].increment, |
physaddr + i * sizemap[order].increment, |
sizemap[order].pagesize_code, true, false); |
#ifdef CONFIG_SMP |
/* |
* Second, save the information about the mapping for APs. |
*/ |
bsp_locked_dtlb_entry[bsp_locked_dtlb_entries].virt_page = |
virtaddr + i * sizemap[order].increment; |
bsp_locked_dtlb_entry[bsp_locked_dtlb_entries].phys_page = |
physaddr + i * sizemap[order].increment; |
bsp_locked_dtlb_entry[bsp_locked_dtlb_entries].pagesize_code = |
sizemap[order].pagesize_code; |
bsp_locked_dtlb_entries++; |
#endif |
} |
return virtaddr; |
} |
/** @} |
/branches/arm/kernel/arch/sparc64/src/mm/tsb.c |
---|
50,14 → 50,13 |
* |
* @param as Address space. |
* @param page First page to invalidate in TSB. |
* @param pages Number of pages to invalidate. Value of (size_t) -1 means the |
* @param pages Number of pages to invalidate. Value of (count_t) -1 means the |
* whole TSB. |
*/ |
void tsb_invalidate(as_t *as, uintptr_t page, size_t pages) |
void tsb_invalidate(as_t *as, uintptr_t page, count_t pages) |
{ |
size_t i0; |
size_t i; |
size_t cnt; |
index_t i0, i; |
count_t cnt; |
ASSERT(as->arch.itsb && as->arch.dtsb); |
64,7 → 63,7 |
i0 = (page >> MMU_PAGE_WIDTH) & TSB_INDEX_MASK; |
ASSERT(i0 < ITSB_ENTRY_COUNT && i0 < DTSB_ENTRY_COUNT); |
if (pages == (size_t) -1 || (pages * 2) > ITSB_ENTRY_COUNT) |
if (pages == (count_t) -1 || (pages * 2) > ITSB_ENTRY_COUNT) |
cnt = ITSB_ENTRY_COUNT; |
else |
cnt = pages * 2; |
82,11 → 81,11 |
* @param t Software PTE. |
* @param index Zero if lower 8K-subpage, one if higher 8K subpage. |
*/ |
void itsb_pte_copy(pte_t *t, size_t index) |
void itsb_pte_copy(pte_t *t, index_t index) |
{ |
as_t *as; |
tsb_entry_t *tsb; |
size_t entry; |
index_t entry; |
ASSERT(index <= 1); |
113,9 → 112,9 |
tsb->data.value = 0; |
tsb->data.size = PAGESIZE_8K; |
tsb->data.pfn = (t->frame >> MMU_FRAME_WIDTH) + index; |
tsb->data.cp = t->c; /* cp as cache in phys.-idxed, c as cacheable */ |
tsb->data.p = t->k; /* p as privileged, k as kernel */ |
tsb->data.v = t->p; /* v as valid, p as present */ |
tsb->data.cp = t->c; |
tsb->data.p = t->k; /* p as privileged */ |
tsb->data.v = t->p; |
write_barrier(); |
128,11 → 127,11 |
* @param index Zero if lower 8K-subpage, one if higher 8K-subpage. |
* @param ro If true, the mapping is copied read-only. |
*/ |
void dtsb_pte_copy(pte_t *t, size_t index, bool ro) |
void dtsb_pte_copy(pte_t *t, index_t index, bool ro) |
{ |
as_t *as; |
tsb_entry_t *tsb; |
size_t entry; |
index_t entry; |
ASSERT(index <= 1); |
174,4 → 173,3 |
/** @} |
*/ |
/branches/arm/kernel/arch/sparc64/src/smp/smp.c |
---|
35,7 → 35,6 |
#include <smp/smp.h> |
#include <genarch/ofw/ofw_tree.h> |
#include <cpu.h> |
#include <arch/cpu_family.h> |
#include <arch/cpu.h> |
#include <arch.h> |
#include <config.h> |
44,7 → 43,6 |
#include <synch/synch.h> |
#include <synch/waitq.h> |
#include <print.h> |
#include <arch/cpu_node.h> |
/** |
* This global variable is used to pick-up application processors |
61,57 → 59,17 |
void smp_init(void) |
{ |
ofw_tree_node_t *node; |
size_t cnt = 0; |
count_t cnt = 0; |
if (is_us() || is_us_iii()) { |
node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu"); |
while (node) { |
cnt++; |
node = ofw_tree_find_peer_by_device_type(node, "cpu"); |
} |
} else if (is_us_iv()) { |
node = ofw_tree_find_child(cpus_parent(), "cmp"); |
while (node) { |
cnt += 2; |
node = ofw_tree_find_peer_by_name(node, "cmp"); |
} |
node = ofw_tree_find_child_by_device_type(ofw_tree_lookup("/"), "cpu"); |
while (node) { |
cnt++; |
node = ofw_tree_find_peer_by_device_type(node, "cpu"); |
} |
config.cpu_count = max(1, cnt); |
} |
/** |
* Wakes up the CPU which is represented by the "node" OFW tree node. |
* If "node" represents the current CPU, calling the function has |
* no effect. |
*/ |
static void wakeup_cpu(ofw_tree_node_t *node) |
{ |
uint32_t mid; |
ofw_tree_property_t *prop; |
/* 'upa-portid' for US, 'portid' for US-III, 'cpuid' for US-IV */ |
prop = ofw_tree_getprop(node, "upa-portid"); |
if ((!prop) || (!prop->value)) |
prop = ofw_tree_getprop(node, "portid"); |
if ((!prop) || (!prop->value)) |
prop = ofw_tree_getprop(node, "cpuid"); |
if (!prop || prop->value == NULL) |
return; |
mid = *((uint32_t *) prop->value); |
if (CPU->arch.mid == mid) |
return; |
waking_up_mid = mid; |
if (waitq_sleep_timeout(&ap_completion_wq, 1000000, SYNCH_FLAGS_NONE) == |
ESYNCH_TIMEOUT) |
printf("%s: waiting for processor (mid = %" PRIu32 |
") timed out\n", __func__, mid); |
} |
/** Wake application processors up. */ |
void kmp(void *arg) |
{ |
118,18 → 76,31 |
ofw_tree_node_t *node; |
int i; |
if (is_us() || is_us_iii()) { |
node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu"); |
for (i = 0; node; |
node = ofw_tree_find_peer_by_device_type(node, "cpu"), i++) |
wakeup_cpu(node); |
} else if (is_us_iv()) { |
node = ofw_tree_find_child(cpus_parent(), "cmp"); |
while (node) { |
wakeup_cpu(ofw_tree_find_child(node, "cpu@0")); |
wakeup_cpu(ofw_tree_find_child(node, "cpu@1")); |
node = ofw_tree_find_peer_by_name(node, "cmp"); |
node = ofw_tree_find_child_by_device_type(ofw_tree_lookup("/"), "cpu"); |
for (i = 0; node; node = ofw_tree_find_peer_by_device_type(node, "cpu"), i++) { |
uint32_t mid; |
ofw_tree_property_t *prop; |
prop = ofw_tree_getprop(node, "upa-portid"); |
if (!prop || !prop->value) |
continue; |
mid = *((uint32_t *) prop->value); |
if (CPU->arch.mid == mid) { |
/* |
* Skip the current CPU. |
*/ |
continue; |
} |
/* |
* Processor with ID == mid can proceed with its initialization. |
*/ |
waking_up_mid = mid; |
if (waitq_sleep_timeout(&ap_completion_wq, 1000000, SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT) |
printf("%s: waiting for processor (mid = %" PRIu32 ") timed out\n", |
__func__, mid); |
} |
} |
/branches/arm/kernel/arch/sparc64/src/smp/ipi.c |
---|
46,33 → 46,6 |
#include <time/delay.h> |
#include <panic.h> |
/** Set the contents of the outgoing interrupt vector data. |
* |
* The first data item (data 0) will be set to the value of func, the |
* rest of the vector will contain zeros. |
* |
* This is a helper function used from within the cross_call function. |
* |
* @param func value the first data item of the vector will be set to |
*/ |
static inline void set_intr_w_data(void (* func)(void)) |
{ |
#if defined (US) |
asi_u64_write(ASI_INTR_W, ASI_UDB_INTR_W_DATA_0, (uintptr_t) func); |
asi_u64_write(ASI_INTR_W, ASI_UDB_INTR_W_DATA_1, 0); |
asi_u64_write(ASI_INTR_W, ASI_UDB_INTR_W_DATA_2, 0); |
#elif defined (US3) |
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_0, (uintptr_t) func); |
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_1, 0); |
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_2, 0); |
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_3, 0); |
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_4, 0); |
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_5, 0); |
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_6, 0); |
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_7, 0); |
#endif |
} |
/** Invoke function on another processor. |
* |
* Currently, only functions without arguments are supported. |
98,15 → 71,16 |
status = asi_u64_read(ASI_INTR_DISPATCH_STATUS, 0); |
if (status & INTR_DISPATCH_STATUS_BUSY) |
panic("Interrupt Dispatch Status busy bit set."); |
panic("Interrupt Dispatch Status busy bit set\n"); |
ASSERT(!(pstate_read() & PSTATE_IE_BIT)); |
do { |
set_intr_w_data(func); |
asi_u64_write(ASI_INTR_W, |
asi_u64_write(ASI_UDB_INTR_W, ASI_UDB_INTR_W_DATA_0, |
(uintptr_t) func); |
asi_u64_write(ASI_UDB_INTR_W, ASI_UDB_INTR_W_DATA_1, 0); |
asi_u64_write(ASI_UDB_INTR_W, ASI_UDB_INTR_W_DATA_2, 0); |
asi_u64_write(ASI_UDB_INTR_W, |
(mid << INTR_VEC_DISPATCH_MID_SHIFT) | |
VA_INTR_W_DISPATCH, 0); |
ASI_UDB_INTR_W_DISPATCH, 0); |
membar(); |
151,7 → 125,7 |
func = tlb_shootdown_ipi_recv; |
break; |
default: |
panic("Unknown IPI (%d).", ipi); |
panic("Unknown IPI (%d).\n", ipi); |
break; |
} |
/branches/arm/kernel/arch/sparc64/src/cpu/cpu.c |
---|
32,46 → 32,12 |
/** @file |
*/ |
#include <arch/cpu_family.h> |
#include <cpu.h> |
#include <arch.h> |
#include <genarch/ofw/ofw_tree.h> |
#include <arch/drivers/tick.h> |
#include <print.h> |
#include <arch/cpu_node.h> |
/** |
* Finds out the clock frequency of the current CPU. |
* |
* @param node node representing the current CPU in the OFW tree |
* @return clock frequency if "node" is the current CPU and no error |
* occurs, -1 if "node" is not the current CPU or on error |
*/ |
static int find_cpu_frequency(ofw_tree_node_t *node) |
{ |
ofw_tree_property_t *prop; |
uint32_t mid; |
/* 'upa-portid' for US, 'portid' for US-III, 'cpuid' for US-IV */ |
prop = ofw_tree_getprop(node, "upa-portid"); |
if ((!prop) || (!prop->value)) |
prop = ofw_tree_getprop(node, "portid"); |
if ((!prop) || (!prop->value)) |
prop = ofw_tree_getprop(node, "cpuid"); |
if (prop && prop->value) { |
mid = *((uint32_t *) prop->value); |
if (mid == CPU->arch.mid) { |
prop = ofw_tree_getprop(node, "clock-frequency"); |
if (prop && prop->value) { |
return *((uint32_t *) prop->value); |
} |
} |
} |
return -1; |
} |
/** Perform sparc64 specific initialization of the processor structure for the |
* current processor. |
*/ |
78,37 → 44,34 |
void cpu_arch_init(void) |
{ |
ofw_tree_node_t *node; |
uint32_t mid; |
uint32_t clock_frequency = 0; |
upa_config_t upa_config; |
CPU->arch.mid = read_mid(); |
upa_config.value = upa_config_read(); |
CPU->arch.mid = upa_config.mid; |
/* |
* Detect processor frequency. |
*/ |
if (is_us() || is_us_iii()) { |
node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu"); |
while (node) { |
int f = find_cpu_frequency(node); |
if (f != -1) |
clock_frequency = (uint32_t) f; |
node = ofw_tree_find_peer_by_device_type(node, "cpu"); |
node = ofw_tree_find_child_by_device_type(ofw_tree_lookup("/"), "cpu"); |
while (node) { |
ofw_tree_property_t *prop; |
prop = ofw_tree_getprop(node, "upa-portid"); |
if (prop && prop->value) { |
mid = *((uint32_t *) prop->value); |
if (mid == CPU->arch.mid) { |
prop = ofw_tree_getprop(node, |
"clock-frequency"); |
if (prop && prop->value) |
clock_frequency = *((uint32_t *) |
prop->value); |
} |
} |
} else if (is_us_iv()) { |
node = ofw_tree_find_child(cpus_parent(), "cmp"); |
while (node) { |
int f; |
f = find_cpu_frequency( |
ofw_tree_find_child(node, "cpu@0")); |
if (f != -1) |
clock_frequency = (uint32_t) f; |
f = find_cpu_frequency( |
ofw_tree_find_child(node, "cpu@1")); |
if (f != -1) |
clock_frequency = (uint32_t) f; |
node = ofw_tree_find_peer_by_name(node, "cmp"); |
} |
node = ofw_tree_find_peer_by_device_type(node, "cpu"); |
} |
CPU->arch.clock_frequency = clock_frequency; |
tick_init(); |
} |
161,15 → 124,6 |
case IMPL_ULTRASPARCIII: |
impl = "UltraSPARC III"; |
break; |
case IMPL_ULTRASPARCIII_PLUS: |
impl = "UltraSPARC III+"; |
break; |
case IMPL_ULTRASPARCIII_I: |
impl = "UltraSPARC IIIi"; |
break; |
case IMPL_ULTRASPARCIV: |
impl = "UltraSPARC IV"; |
break; |
case IMPL_ULTRASPARCIV_PLUS: |
impl = "UltraSPARC IV+"; |
break; |
/branches/arm/kernel/arch/sparc64/src/drivers/sgcn.c |
---|
File deleted |
/branches/arm/kernel/arch/sparc64/src/drivers/scr.c |
---|
37,7 → 37,7 |
#include <genarch/fb/fb.h> |
#include <genarch/fb/visuals.h> |
#include <arch/types.h> |
#include <string.h> |
#include <func.h> |
#include <align.h> |
#include <print.h> |
55,30 → 55,23 |
void scr_init(ofw_tree_node_t *node) |
{ |
ofw_tree_property_t *prop; |
ofw_pci_reg_t *pci_reg; |
ofw_pci_reg_t pci_abs_reg; |
ofw_upa_reg_t *upa_reg; |
ofw_sbus_reg_t *sbus_reg; |
const char *name; |
name = ofw_tree_node_name(node); |
if (str_cmp(name, "SUNW,m64B") == 0) |
if (strcmp(name, "SUNW,m64B") == 0) |
scr_type = SCR_ATYFB; |
else if (str_cmp(name, "SUNW,XVR-100") == 0) |
scr_type = SCR_XVR; |
else if (str_cmp(name, "SUNW,ffb") == 0) |
else if (strcmp(name, "SUNW,ffb") == 0) |
scr_type = SCR_FFB; |
else if (str_cmp(name, "cgsix") == 0) |
else if (strcmp(name, "cgsix") == 0) |
scr_type = SCR_CGSIX; |
if (scr_type == SCR_UNKNOWN) { |
printf("Unknown screen device.\n"); |
printf("Unknown keyboard device.\n"); |
return; |
} |
uintptr_t fb_addr; |
unsigned int fb_offset = 0; |
uint32_t fb_width = 0; |
uint32_t fb_height = 0; |
uint32_t fb_depth = 0; |
104,7 → 97,7 |
prop = ofw_tree_getprop(node, "reg"); |
if (!prop) |
panic("Cannot find 'reg' property."); |
panic("Can't find \"reg\" property.\n"); |
switch (scr_type) { |
case SCR_ATYFB: |
113,15 → 106,15 |
return; |
} |
pci_reg = &((ofw_pci_reg_t *) prop->value)[1]; |
ofw_pci_reg_t *fb_reg = &((ofw_pci_reg_t *) prop->value)[1]; |
ofw_pci_reg_t abs_reg; |
if (!ofw_pci_reg_absolutize(node, pci_reg, &pci_abs_reg)) { |
if (!ofw_pci_reg_absolutize(node, fb_reg, &abs_reg)) { |
printf("Failed to absolutize fb register.\n"); |
return; |
} |
if (!ofw_pci_apply_ranges(node->parent, &pci_abs_reg, |
&fb_addr)) { |
if (!ofw_pci_apply_ranges(node->parent, &abs_reg , &fb_addr)) { |
printf("Failed to determine screen address.\n"); |
return; |
} |
149,56 → 142,12 |
} |
break; |
case SCR_XVR: |
if (prop->size / sizeof(ofw_pci_reg_t) < 2) { |
printf("Too few screen registers.\n"); |
return; |
} |
pci_reg = &((ofw_pci_reg_t *) prop->value)[1]; |
if (!ofw_pci_reg_absolutize(node, pci_reg, &pci_abs_reg)) { |
printf("Failed to absolutize fb register.\n"); |
return; |
} |
if (!ofw_pci_apply_ranges(node->parent, &pci_abs_reg, |
&fb_addr)) { |
printf("Failed to determine screen address.\n"); |
return; |
} |
fb_offset = 4 * 0x2000; |
switch (fb_depth) { |
case 8: |
fb_scanline = fb_linebytes * (fb_depth >> 3); |
visual = VISUAL_INDIRECT_8; |
break; |
case 16: |
fb_scanline = fb_linebytes * (fb_depth >> 3); |
visual = VISUAL_RGB_5_6_5; |
break; |
case 24: |
fb_scanline = fb_linebytes * 4; |
visual = VISUAL_RGB_8_8_8_0; |
break; |
case 32: |
fb_scanline = fb_linebytes * (fb_depth >> 3); |
visual = VISUAL_RGB_0_8_8_8; |
break; |
default: |
printf("Unsupported bits per pixel.\n"); |
return; |
} |
break; |
case SCR_FFB: |
fb_scanline = 8192; |
visual = VISUAL_BGR_0_8_8_8; |
upa_reg = &((ofw_upa_reg_t *) prop->value)[FFB_REG_24BPP]; |
if (!ofw_upa_apply_ranges(node->parent, upa_reg, &fb_addr)) { |
ofw_upa_reg_t *reg = &((ofw_upa_reg_t *) prop->value)[FFB_REG_24BPP]; |
if (!ofw_upa_apply_ranges(node->parent, reg, &fb_addr)) { |
printf("Failed to determine screen address.\n"); |
return; |
} |
215,8 → 164,8 |
return; |
} |
sbus_reg = &((ofw_sbus_reg_t *) prop->value)[0]; |
if (!ofw_sbus_apply_ranges(node->parent, sbus_reg, &fb_addr)) { |
ofw_sbus_reg_t *cg6_reg = &((ofw_sbus_reg_t *) prop->value)[0]; |
if (!ofw_sbus_apply_ranges(node->parent, cg6_reg, &fb_addr)) { |
printf("Failed to determine screen address.\n"); |
return; |
} |
223,24 → 172,11 |
break; |
default: |
panic("Unexpected type."); |
panic("Unexpected type.\n"); |
} |
fb_properties_t props = { |
.addr = fb_addr, |
.offset = fb_offset, |
.x = fb_width, |
.y = fb_height, |
.scan = fb_scanline, |
.visual = visual, |
}; |
fb_init(&props); |
fb_init(fb_addr, fb_width, fb_height, fb_scanline, visual); |
} |
void scr_redraw(void) |
{ |
fb_redraw(); |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/sparc64/src/drivers/tick.c |
---|
45,12 → 45,11 |
#define TICK_RESTART_TIME 50 /* Worst case estimate. */ |
/** Initialize tick and stick interrupt. */ |
/** Initialize tick interrupt. */ |
void tick_init(void) |
{ |
/* initialize TICK interrupt */ |
tick_compare_reg_t compare; |
interrupt_register(14, "tick_int", tick_interrupt); |
compare.int_dis = false; |
compare.tick_cmpr = CPU->arch.clock_frequency / HZ; |
57,21 → 56,6 |
CPU->arch.next_tick_cmpr = compare.tick_cmpr; |
tick_compare_write(compare.value); |
tick_write(0); |
#if defined (US3) |
/* disable STICK interrupts and clear any pending ones */ |
tick_compare_reg_t stick_compare; |
softint_reg_t clear; |
stick_compare.value = stick_compare_read(); |
stick_compare.int_dis = true; |
stick_compare.tick_cmpr = 0; |
stick_compare_write(stick_compare.value); |
clear.value = 0; |
clear.stick_int = 1; |
clear_softint_write(clear.value); |
#endif |
} |
/** Process tick interrupt. |
83,7 → 67,7 |
{ |
softint_reg_t softint, clear; |
uint64_t drift; |
softint.value = softint_read(); |
/* |
/branches/arm/kernel/arch/sparc64/src/drivers/fhc.c |
---|
45,7 → 45,6 |
#include <mm/slab.h> |
#include <arch/types.h> |
#include <genarch/ofw/ofw_tree.h> |
#include <sysinfo/sysinfo.h> |
fhc_t *central_fhc = NULL; |
71,7 → 70,7 |
if (!prop || !prop->value) |
return NULL; |
size_t regs = prop->size / sizeof(ofw_central_reg_t); |
count_t regs = prop->size / sizeof(ofw_central_reg_t); |
if (regs + 1 < UART_IMAP_REG) |
return NULL; |
87,13 → 86,6 |
fhc->uart_imap = (uint32_t *) hw_map(paddr, reg->size); |
/* |
* Set sysinfo data needed by the uspace FHC driver. |
*/ |
sysinfo_set_item_val("fhc.uart.size", NULL, reg->size); |
sysinfo_set_item_val("fhc.uart.physical", NULL, paddr); |
sysinfo_set_item_val("kbd.cir.fhc", NULL, 1); |
return fhc; |
} |
104,14 → 96,13 |
fhc->uart_imap[FHC_UART_IMAP] |= IMAP_V_MASK; |
break; |
default: |
panic("Unexpected INR (%d).", inr); |
panic("Unexpected INR (%d)\n", inr); |
break; |
} |
} |
void fhc_clear_interrupt(void *fhcp, int inr) |
void fhc_clear_interrupt(fhc_t *fhc, int inr) |
{ |
fhc_t *fhc = (fhc_t *)fhcp; |
ASSERT(fhc->uart_imap); |
switch (inr) { |
119,7 → 110,7 |
fhc->uart_imap[FHC_UART_ICLR] = 0; |
break; |
default: |
panic("Unexpected INR (%d).", inr); |
panic("Unexpected INR (%d)\n", inr); |
break; |
} |
} |
/branches/arm/kernel/arch/sparc64/src/drivers/kbd.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup sparc64 |
/** @addtogroup sparc64 |
* @{ |
*/ |
/** @file |
34,160 → 34,99 |
#include <arch/drivers/kbd.h> |
#include <genarch/ofw/ofw_tree.h> |
#ifdef CONFIG_SUN_KBD |
#include <genarch/kbrd/kbrd.h> |
#endif |
#ifdef CONFIG_Z8530 |
#include <genarch/drivers/z8530/z8530.h> |
#include <genarch/kbd/z8530.h> |
#endif |
#ifdef CONFIG_NS16550 |
#include <genarch/drivers/ns16550/ns16550.h> |
#include <genarch/kbd/ns16550.h> |
#endif |
#include <console/console.h> |
#include <ddi/device.h> |
#include <ddi/irq.h> |
#include <arch/mm/page.h> |
#include <arch/types.h> |
#include <align.h> |
#include <string.h> |
#include <func.h> |
#include <print.h> |
#include <sysinfo/sysinfo.h> |
#ifdef CONFIG_SUN_KBD |
kbd_type_t kbd_type = KBD_UNKNOWN; |
#ifdef CONFIG_Z8530 |
static bool kbd_z8530_init(ofw_tree_node_t *node) |
/** Initialize keyboard. |
* |
* Traverse OpenFirmware device tree in order to find necessary |
* info about the keyboard device. |
* |
* @param node Keyboard device node. |
*/ |
void kbd_init(ofw_tree_node_t *node) |
{ |
const char *name = ofw_tree_node_name(node); |
size_t offset; |
uintptr_t aligned_addr; |
ofw_tree_property_t *prop; |
const char *name; |
if (str_cmp(name, "zs") != 0) |
return false; |
name = ofw_tree_node_name(node); |
/* |
* Read 'interrupts' property. |
* Determine keyboard serial controller type. |
*/ |
ofw_tree_property_t *prop = ofw_tree_getprop(node, "interrupts"); |
if ((!prop) || (!prop->value)) { |
printf("z8530: Unable to find interrupts property\n"); |
return false; |
} |
if (strcmp(name, "zs") == 0) |
kbd_type = KBD_Z8530; |
else if (strcmp(name, "su") == 0) |
kbd_type = KBD_NS16550; |
uint32_t interrupts = *((uint32_t *) prop->value); |
/* |
* Read 'reg' property. |
*/ |
prop = ofw_tree_getprop(node, "reg"); |
if ((!prop) || (!prop->value)) { |
printf("z8530: Unable to find reg property\n"); |
return false; |
if (kbd_type == KBD_UNKNOWN) { |
printf("Unknown keyboard device.\n"); |
return; |
} |
size_t size = ((ofw_fhc_reg_t *) prop->value)->size; |
uintptr_t pa; |
if (!ofw_fhc_apply_ranges(node->parent, |
((ofw_fhc_reg_t *) prop->value), &pa)) { |
printf("z8530: Failed to determine address\n"); |
return false; |
} |
inr_t inr; |
cir_t cir; |
void *cir_arg; |
if (!ofw_fhc_map_interrupt(node->parent, |
((ofw_fhc_reg_t *) prop->value), interrupts, &inr, &cir, |
&cir_arg)) { |
printf("z8530: Failed to determine interrupt\n"); |
return false; |
} |
/* |
* We need to pass aligned address to hw_map(). |
* However, the physical keyboard address can |
* be pretty much unaligned, depending on the |
* underlying controller. |
* Read 'interrupts' property. |
*/ |
uintptr_t aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE); |
size_t offset = pa - aligned_addr; |
z8530_t *z8530 = (z8530_t *) |
(hw_map(aligned_addr, offset + size) + offset); |
z8530_instance_t *z8530_instance = z8530_init(z8530, inr, cir, cir_arg); |
if (z8530_instance) { |
kbrd_instance_t *kbrd_instance = kbrd_init(); |
if (kbrd_instance) { |
indev_t *sink = stdin_wire(); |
indev_t *kbrd = kbrd_wire(kbrd_instance, sink); |
z8530_wire(z8530_instance, kbrd); |
} |
} |
/* |
* This is the necessary evil until the userspace drivers are |
* entirely self-sufficient. |
*/ |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.inr", NULL, inr); |
sysinfo_set_item_val("kbd.address.kernel", NULL, |
(uintptr_t) z8530); |
sysinfo_set_item_val("kbd.address.physical", NULL, pa); |
sysinfo_set_item_val("kbd.type.z8530", NULL, true); |
return true; |
} |
uint32_t interrupts; |
prop = ofw_tree_getprop(node, "interrupts"); |
if (!prop || !prop->value) |
panic("Can't find \"interrupts\" property.\n"); |
interrupts = *((uint32_t *) prop->value); |
#endif /* CONFIG_Z8530 */ |
#ifdef CONFIG_NS16550 |
static bool kbd_ns16550_init(ofw_tree_node_t *node) |
{ |
const char *name = ofw_tree_node_name(node); |
if (str_cmp(name, "su") != 0) |
return false; |
/* |
* Read 'interrupts' property. |
*/ |
ofw_tree_property_t *prop = ofw_tree_getprop(node, "interrupts"); |
if ((!prop) || (!prop->value)) { |
printf("ns16550: Unable to find interrupts property\n"); |
return false; |
} |
uint32_t interrupts = *((uint32_t *) prop->value); |
/* |
* Read 'reg' property. |
*/ |
prop = ofw_tree_getprop(node, "reg"); |
if ((!prop) || (!prop->value)) { |
printf("ns16550: Unable to find reg property\n"); |
return false; |
} |
if (!prop || !prop->value) |
panic("Can't find \"reg\" property.\n"); |
size_t size = ((ofw_ebus_reg_t *) prop->value)->size; |
uintptr_t pa; |
if (!ofw_ebus_apply_ranges(node->parent, |
((ofw_ebus_reg_t *) prop->value), &pa)) { |
printf("ns16550: Failed to determine address\n"); |
return false; |
} |
size_t size; |
inr_t inr; |
devno_t devno = device_assign_devno(); |
inr_t inr; |
cir_t cir; |
void *cir_arg; |
if (!ofw_ebus_map_interrupt(node->parent, |
((ofw_ebus_reg_t *) prop->value), interrupts, &inr, &cir, |
&cir_arg)) { |
printf("ns16550: Failed to determine interrupt\n"); |
return false; |
switch (kbd_type) { |
case KBD_Z8530: |
size = ((ofw_fhc_reg_t *) prop->value)->size; |
if (!ofw_fhc_apply_ranges(node->parent, ((ofw_fhc_reg_t *) prop->value) , &pa)) { |
printf("Failed to determine keyboard address.\n"); |
return; |
} |
if (!ofw_fhc_map_interrupt(node->parent, ((ofw_fhc_reg_t *) prop->value), interrupts, &inr)) { |
printf("Failed to determine keyboard interrupt.\n"); |
return; |
} |
break; |
case KBD_NS16550: |
size = ((ofw_ebus_reg_t *) prop->value)->size; |
if (!ofw_ebus_apply_ranges(node->parent, ((ofw_ebus_reg_t *) prop->value) , &pa)) { |
printf("Failed to determine keyboard address.\n"); |
return; |
} |
if (!ofw_ebus_map_interrupt(node->parent, ((ofw_ebus_reg_t *) prop->value), interrupts, &inr)) { |
printf("Failed to determine keyboard interrupt.\n"); |
return; |
}; |
break; |
default: |
panic("Unexpected type.\n"); |
} |
/* |
196,58 → 135,25 |
* be pretty much unaligned, depending on the |
* underlying controller. |
*/ |
uintptr_t aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE); |
size_t offset = pa - aligned_addr; |
ns16550_t *ns16550 = (ns16550_t *) |
(hw_map(aligned_addr, offset + size) + offset); |
ns16550_instance_t *ns16550_instance = ns16550_init(ns16550, inr, cir, cir_arg); |
if (ns16550_instance) { |
kbrd_instance_t *kbrd_instance = kbrd_init(); |
if (kbrd_instance) { |
indev_t *sink = stdin_wire(); |
indev_t *kbrd = kbrd_wire(kbrd_instance, sink); |
ns16550_wire(ns16550_instance, kbrd); |
} |
} |
/* |
* This is the necessary evil until the userspace drivers are |
* entirely self-sufficient. |
*/ |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.inr", NULL, inr); |
sysinfo_set_item_val("kbd.address.kernel", NULL, |
(uintptr_t) ns16550); |
sysinfo_set_item_val("kbd.address.physical", NULL, pa); |
sysinfo_set_item_val("kbd.type.ns16550", NULL, true); |
return true; |
} |
aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE); |
offset = pa - aligned_addr; |
uintptr_t vaddr = hw_map(aligned_addr, offset + size) + offset; |
#endif /* CONFIG_NS16550 */ |
/** Initialize keyboard. |
* |
* Traverse OpenFirmware device tree in order to find necessary |
* info about the keyboard device. |
* |
* @param node Keyboard device node. |
* |
*/ |
void kbd_init(ofw_tree_node_t *node) |
{ |
switch (kbd_type) { |
#ifdef CONFIG_Z8530 |
kbd_z8530_init(node); |
case KBD_Z8530: |
z8530_init(devno, inr, vaddr); |
break; |
#endif |
#ifdef CONFIG_NS16550 |
kbd_ns16550_init(node); |
case KBD_NS16550: |
ns16550_init(devno, inr, vaddr); |
break; |
#endif |
default: |
printf("Kernel is not compiled with the necessary keyboard driver this machine requires.\n"); |
} |
} |
#endif /* CONFIG_SUN_KBD */ |
/** @} |
*/ |
/branches/arm/kernel/arch/sparc64/src/drivers/pci.c |
---|
42,41 → 42,43 |
#include <arch/types.h> |
#include <debug.h> |
#include <print.h> |
#include <string.h> |
#include <func.h> |
#include <arch/asm.h> |
#include <sysinfo/sysinfo.h> |
#define SABRE_INTERNAL_REG 0 |
#define PSYCHO_INTERNAL_REG 2 |
#define PCI_SABRE_REGS_REG 0 |
#define OBIO_IMR_BASE 0x200 |
#define OBIO_IMR(ino) (OBIO_IMR_BASE + ((ino) & INO_MASK)) |
#define PCI_SABRE_IMAP_BASE 0x200 |
#define PCI_SABRE_ICLR_BASE 0x300 |
#define OBIO_CIR_BASE 0x300 |
#define OBIO_CIR(ino) (OBIO_CIR_BASE + ((ino) & INO_MASK)) |
#define PCI_PSYCHO_REGS_REG 2 |
static void obio_enable_interrupt(pci_t *, int); |
static void obio_clear_interrupt(pci_t *, int); |
#define PCI_PSYCHO_IMAP_BASE 0x200 |
#define PCI_PSYCHO_ICLR_BASE 0x300 |
static pci_t *pci_sabre_init(ofw_tree_node_t *); |
static pci_t *pci_psycho_init(ofw_tree_node_t *); |
static pci_t *pci_sabre_init(ofw_tree_node_t *node); |
static void pci_sabre_enable_interrupt(pci_t *pci, int inr); |
static void pci_sabre_clear_interrupt(pci_t *pci, int inr); |
static pci_t *pci_psycho_init(ofw_tree_node_t *node); |
static void pci_psycho_enable_interrupt(pci_t *pci, int inr); |
static void pci_psycho_clear_interrupt(pci_t *pci, int inr); |
/** PCI operations for Sabre model. */ |
static pci_operations_t pci_sabre_ops = { |
.enable_interrupt = obio_enable_interrupt, |
.clear_interrupt = obio_clear_interrupt |
.enable_interrupt = pci_sabre_enable_interrupt, |
.clear_interrupt = pci_sabre_clear_interrupt |
}; |
/** PCI operations for Psycho model. */ |
static pci_operations_t pci_psycho_ops = { |
.enable_interrupt = obio_enable_interrupt, |
.clear_interrupt = obio_clear_interrupt |
.enable_interrupt = pci_psycho_enable_interrupt, |
.clear_interrupt = pci_psycho_clear_interrupt |
}; |
/** Initialize PCI controller (model Sabre). |
* |
* @param node OpenFirmware device tree node of the Sabre. |
* @param node OpenFirmware device tree node of the Sabre. |
* |
* @return Address of the initialized PCI structure. |
* @return Address of the initialized PCI structure. |
*/ |
pci_t *pci_sabre_init(ofw_tree_node_t *node) |
{ |
91,14 → 93,13 |
return NULL; |
ofw_upa_reg_t *reg = prop->value; |
size_t regs = prop->size / sizeof(ofw_upa_reg_t); |
count_t regs = prop->size / sizeof(ofw_upa_reg_t); |
if (regs < SABRE_INTERNAL_REG + 1) |
if (regs < PCI_SABRE_REGS_REG + 1) |
return NULL; |
uintptr_t paddr; |
if (!ofw_upa_apply_ranges(node->parent, ®[SABRE_INTERNAL_REG], |
&paddr)) |
if (!ofw_upa_apply_ranges(node->parent, ®[PCI_SABRE_REGS_REG], &paddr)) |
return NULL; |
pci = (pci_t *) malloc(sizeof(pci_t), FRAME_ATOMIC); |
107,14 → 108,8 |
pci->model = PCI_SABRE; |
pci->op = &pci_sabre_ops; |
pci->reg = (uint64_t *) hw_map(paddr, reg[SABRE_INTERNAL_REG].size); |
pci->reg = (uint64_t *) hw_map(paddr, reg[PCI_SABRE_REGS_REG].size); |
/* |
* Set sysinfo data needed by the uspace OBIO driver. |
*/ |
sysinfo_set_item_val("obio.base.physical", NULL, paddr); |
sysinfo_set_item_val("kbd.cir.obio", NULL, 1); |
return pci; |
} |
121,9 → 116,9 |
/** Initialize the Psycho PCI controller. |
* |
* @param node OpenFirmware device tree node of the Psycho. |
* @param node OpenFirmware device tree node of the Psycho. |
* |
* @return Address of the initialized PCI structure. |
* @return Address of the initialized PCI structure. |
*/ |
pci_t *pci_psycho_init(ofw_tree_node_t *node) |
{ |
138,14 → 133,13 |
return NULL; |
ofw_upa_reg_t *reg = prop->value; |
size_t regs = prop->size / sizeof(ofw_upa_reg_t); |
count_t regs = prop->size / sizeof(ofw_upa_reg_t); |
if (regs < PSYCHO_INTERNAL_REG + 1) |
if (regs < PCI_PSYCHO_REGS_REG + 1) |
return NULL; |
uintptr_t paddr; |
if (!ofw_upa_apply_ranges(node->parent, ®[PSYCHO_INTERNAL_REG], |
&paddr)) |
if (!ofw_upa_apply_ranges(node->parent, ®[PCI_PSYCHO_REGS_REG], &paddr)) |
return NULL; |
pci = (pci_t *) malloc(sizeof(pci_t), FRAME_ATOMIC); |
154,27 → 148,31 |
pci->model = PCI_PSYCHO; |
pci->op = &pci_psycho_ops; |
pci->reg = (uint64_t *) hw_map(paddr, reg[PSYCHO_INTERNAL_REG].size); |
pci->reg = (uint64_t *) hw_map(paddr, reg[PCI_PSYCHO_REGS_REG].size); |
/* |
* Set sysinfo data needed by the uspace OBIO driver. |
*/ |
sysinfo_set_item_val("obio.base.physical", NULL, paddr); |
sysinfo_set_item_val("kbd.cir.obio", NULL, 1); |
return pci; |
} |
void obio_enable_interrupt(pci_t *pci, int inr) |
void pci_sabre_enable_interrupt(pci_t *pci, int inr) |
{ |
pci->reg[OBIO_IMR(inr & INO_MASK)] |= IMAP_V_MASK; |
pci->reg[PCI_SABRE_IMAP_BASE + (inr & INO_MASK)] |= IMAP_V_MASK; |
} |
void obio_clear_interrupt(pci_t *pci, int inr) |
void pci_sabre_clear_interrupt(pci_t *pci, int inr) |
{ |
pci->reg[OBIO_CIR(inr & INO_MASK)] = 0; /* set IDLE */ |
pci->reg[PCI_SABRE_ICLR_BASE + (inr & INO_MASK)] = 0; |
} |
void pci_psycho_enable_interrupt(pci_t *pci, int inr) |
{ |
pci->reg[PCI_PSYCHO_IMAP_BASE + (inr & INO_MASK)] |= IMAP_V_MASK; |
} |
void pci_psycho_clear_interrupt(pci_t *pci, int inr) |
{ |
pci->reg[PCI_PSYCHO_ICLR_BASE + (inr & INO_MASK)] = 0; |
} |
/** Initialize PCI controller. */ |
pci_t *pci_init(ofw_tree_node_t *node) |
{ |
183,7 → 181,7 |
/* |
* First, verify this is a PCI node. |
*/ |
ASSERT(str_cmp(ofw_tree_node_name(node), "pci") == 0); |
ASSERT(strcmp(ofw_tree_node_name(node), "pci") == 0); |
/* |
* Determine PCI controller model. |
192,13 → 190,13 |
if (!prop || !prop->value) |
return NULL; |
if (str_cmp(prop->value, "SUNW,sabre") == 0) { |
if (strcmp(prop->value, "SUNW,sabre") == 0) { |
/* |
* PCI controller Sabre. |
* This model is found on UltraSPARC IIi based machines. |
*/ |
return pci_sabre_init(node); |
} else if (str_cmp(prop->value, "SUNW,psycho") == 0) { |
} else if (strcmp(prop->value, "SUNW,psycho") == 0) { |
/* |
* PCI controller Psycho. |
* Used on UltraSPARC II based processors, for instance, |
217,14 → 215,14 |
void pci_enable_interrupt(pci_t *pci, int inr) |
{ |
ASSERT(pci->model); |
ASSERT(pci->op && pci->op->enable_interrupt); |
pci->op->enable_interrupt(pci, inr); |
} |
void pci_clear_interrupt(void *pcip, int inr) |
void pci_clear_interrupt(pci_t *pci, int inr) |
{ |
pci_t *pci = (pci_t *)pcip; |
ASSERT(pci->model); |
ASSERT(pci->op && pci->op->clear_interrupt); |
pci->op->clear_interrupt(pci, inr); |
} |
/branches/arm/kernel/arch/sparc64/src/proc/thread.c |
---|
34,8 → 34,9 |
#include <proc/thread.h> |
#include <arch/proc/thread.h> |
#include <mm/slab.h> |
#include <arch/trap/regwin.h> |
#include <mm/frame.h> |
#include <mm/page.h> |
#include <arch/mm/page.h> |
#include <align.h> |
void thr_constructor_arch(thread_t *t) |
49,12 → 50,12 |
void thr_destructor_arch(thread_t *t) |
{ |
if (t->arch.uspace_window_buffer) { |
uintptr_t uw_buf = (uintptr_t) t->arch.uspace_window_buffer; |
/* |
* Mind the possible alignment of the userspace window buffer |
* belonging to a killed thread. |
*/ |
free((uint8_t *) ALIGN_DOWN(uw_buf, UWB_ALIGNMENT)); |
frame_free(KA2PA(ALIGN_DOWN((uintptr_t) |
t->arch.uspace_window_buffer, PAGE_SIZE))); |
} |
} |
66,7 → 67,7 |
* The thread needs userspace window buffer and the object |
* returned from the slab allocator doesn't have any. |
*/ |
t->arch.uspace_window_buffer = malloc(UWB_ASIZE, 0); |
t->arch.uspace_window_buffer = frame_alloc(ONE_FRAME, FRAME_KA); |
} else { |
uintptr_t uw_buf = (uintptr_t) t->arch.uspace_window_buffer; |
75,7 → 76,7 |
* belonging to a killed thread. |
*/ |
t->arch.uspace_window_buffer = (uint8_t *) ALIGN_DOWN(uw_buf, |
UWB_ASIZE); |
PAGE_SIZE); |
} |
} |
/branches/arm/kernel/arch/sparc64/src/sparc64.c |
---|
37,6 → 37,7 |
#include <config.h> |
#include <arch/trap/trap.h> |
#include <arch/console.h> |
#include <proc/thread.h> |
#include <console/console.h> |
#include <arch/boot/boot.h> |
#include <arch/arch.h> |
46,11 → 47,10 |
#include <genarch/ofw/ofw_tree.h> |
#include <userspace.h> |
#include <ddi/irq.h> |
#include <string.h> |
bootinfo_t bootinfo; |
/** Perform sparc64-specific initialization before main_bsp() is called. */ |
/** Perform sparc64 specific initialization before main_bsp() is called. */ |
void arch_pre_main(void) |
{ |
/* Copy init task info. */ |
61,8 → 61,6 |
for (i = 0; i < bootinfo.taskmap.count; i++) { |
init.tasks[i].addr = (uintptr_t) bootinfo.taskmap.tasks[i].addr; |
init.tasks[i].size = bootinfo.taskmap.tasks[i].size; |
str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN, |
bootinfo.taskmap.tasks[i].name); |
} |
/* Copy boot allocations info. */ |
88,6 → 86,8 |
* But we only create 128 buckets. |
*/ |
irq_init(1 << 11, 128); |
standalone_sparc64_console_init(); |
} |
} |
101,7 → 101,18 |
void arch_post_smp_init(void) |
{ |
standalone_sparc64_console_init(); |
static thread_t *t = NULL; |
if (!t) { |
/* |
* Create thread that polls keyboard. |
*/ |
t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll", true); |
if (!t) |
panic("cannot create kkbdpoll\n"); |
thread_ready(t); |
} |
} |
/** Calibrate delay loop. |
150,19 → 161,5 |
while (1); |
} |
/** Construct function pointer |
* |
* @param fptr function pointer structure |
* @param addr function address |
* @param caller calling function address |
* |
* @return address of the function pointer |
* |
*/ |
void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller) |
{ |
return addr; |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/sparc64/src/ddi/ddi.c |
---|
41,7 → 41,7 |
* Interrupts are disabled and task is locked. |
* |
* @param task Task. |
* @param ioaddr Starting I/O space address. |
* @param ioaddr Startign I/O space address. |
* @param size Size of the enabled I/O range. |
* |
* @return 0 on success or an error code from errno.h. |
/branches/arm/kernel/arch/sparc64/src/console.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup sparc64 |
/** @addtogroup sparc64 |
* @{ |
*/ |
/** @file |
37,8 → 37,14 |
#include <arch/drivers/scr.h> |
#include <arch/drivers/kbd.h> |
#include <arch/drivers/sgcn.h> |
#include <genarch/srln/srln.h> |
#ifdef CONFIG_Z8530 |
#include <genarch/kbd/z8530.h> |
#endif |
#ifdef CONFIG_NS16550 |
#include <genarch/kbd/ns16550.h> |
#endif |
#include <console/chardev.h> |
#include <console/console.h> |
#include <arch/asm.h> |
48,101 → 54,92 |
#include <genarch/ofw/ofw_tree.h> |
#include <arch.h> |
#include <panic.h> |
#include <string.h> |
#include <print.h> |
#define KEYBOARD_POLL_PAUSE 50000 /* 50ms */ |
/** |
* Initialize kernel console to use framebuffer and keyboard directly. |
* Called on UltraSPARC machines with standard keyboard and framebuffer. |
* |
* @param aliases the "/aliases" OBP node |
*/ |
static void standard_console_init(ofw_tree_node_t *aliases) |
/** Initialize kernel console to use framebuffer and keyboard directly. */ |
void standalone_sparc64_console_init(void) |
{ |
#ifdef CONFIG_FB |
ofw_tree_property_t *prop_scr = ofw_tree_getprop(aliases, "screen"); |
if (!prop_scr) |
panic("Cannot find property 'screen'."); |
if (!prop_scr->value) |
panic("Cannot find screen alias."); |
ofw_tree_node_t *screen = ofw_tree_lookup(prop_scr->value); |
stdin = NULL; |
ofw_tree_node_t *aliases; |
ofw_tree_property_t *prop; |
ofw_tree_node_t *screen; |
ofw_tree_node_t *keyboard; |
aliases = ofw_tree_lookup("/aliases"); |
if (!aliases) |
panic("Can't find /aliases.\n"); |
prop = ofw_tree_getprop(aliases, "screen"); |
if (!prop) |
panic("Can't find property \"screen\".\n"); |
if (!prop->value) |
panic("Can't find screen alias.\n"); |
screen = ofw_tree_lookup(prop->value); |
if (!screen) |
panic("Cannot find %s.", prop_scr->value); |
panic("Can't find %s\n", prop->value); |
scr_init(screen); |
#endif |
#ifdef CONFIG_SUN_KBD |
ofw_tree_property_t *prop_kbd = ofw_tree_getprop(aliases, "keyboard"); |
if (!prop_kbd) |
panic("Cannot find property 'keyboard'."); |
if (!prop_kbd->value) |
panic("Cannot find keyboard alias."); |
ofw_tree_node_t *keyboard = ofw_tree_lookup(prop_kbd->value); |
prop = ofw_tree_getprop(aliases, "keyboard"); |
if (!prop) |
panic("Can't find property \"keyboard\".\n"); |
if (!prop->value) |
panic("Can't find keyboard alias.\n"); |
keyboard = ofw_tree_lookup(prop->value); |
if (!keyboard) |
panic("Cannot find %s.", prop_kbd->value); |
panic("Can't find %s\n", prop->value); |
kbd_init(keyboard); |
#endif |
} |
/** Initilize I/O on the Serengeti machine. */ |
static void serengeti_init(void) |
/** Kernel thread for polling keyboard. |
* |
* @param arg Ignored. |
*/ |
void kkbdpoll(void *arg) |
{ |
#ifdef CONFIG_SGCN_KBD |
sgcn_instance_t *sgcn_instance = sgcnin_init(); |
if (sgcn_instance) { |
srln_instance_t *srln_instance = srln_init(); |
if (srln_instance) { |
indev_t *sink = stdin_wire(); |
indev_t *srln = srln_wire(srln_instance, sink); |
sgcnin_wire(sgcn_instance, srln); |
} |
thread_detach(THREAD); |
#ifdef CONFIG_Z8530 |
if (kbd_type == KBD_Z8530) { |
/* |
* The z8530 driver is interrupt-driven. |
*/ |
return; |
} |
#endif |
#ifdef CONFIG_SGCN_PRN |
sgcnout_init(); |
while (1) { |
#ifdef CONFIG_NS16550 |
if (kbd_type == KBD_NS16550) |
ns16550_poll(); |
#endif |
} |
/** |
* Initialize input/output. Auto-detects the type of machine |
* and calls the appropriate I/O init routine. |
*/ |
void standalone_sparc64_console_init(void) |
{ |
ofw_tree_node_t *aliases; |
ofw_tree_property_t *prop; |
aliases = ofw_tree_lookup("/aliases"); |
if (!aliases) |
panic("Cannot find '/aliases'."); |
/* "def-cn" = "default console" */ |
prop = ofw_tree_getprop(aliases, "def-cn"); |
if ((!prop) || (!prop->value) || (str_cmp(prop->value, "/sgcn") != 0)) { |
standard_console_init(aliases); |
} else { |
serengeti_init(); |
thread_usleep(KEYBOARD_POLL_PAUSE); |
} |
} |
/** Acquire console back for kernel |
* |
*/ |
void arch_grab_console(void) |
{ |
#ifdef CONFIG_FB |
scr_redraw(); |
switch (kbd_type) { |
#ifdef CONFIG_Z8530 |
case KBD_Z8530: |
z8530_grab(); |
break; |
#endif |
#ifdef CONFIG_SGCN_KBD |
sgcn_grab(); |
#ifdef CONFIG_NS16550 |
case KBD_NS16550: |
ns16550_grab(); |
break; |
#endif |
default: |
break; |
} |
} |
/** Return console to userspace |
150,9 → 147,20 |
*/ |
void arch_release_console(void) |
{ |
#ifdef CONFIG_SGCN_KBD |
sgcn_release(); |
switch (kbd_type) { |
#ifdef CONFIG_Z8530 |
case KBD_Z8530: |
z8530_release(); |
break; |
#endif |
#ifdef CONFIG_NS16550 |
case KBD_NS16550: |
ns16550_release(); |
break; |
#endif |
default: |
break; |
} |
} |
/** @} |
/branches/arm/kernel/arch/sparc64/src/start.S |
---|
27,7 → 27,6 |
# |
#include <arch/arch.h> |
#include <arch/cpu.h> |
#include <arch/regdef.h> |
#include <arch/boot/boot.h> |
#include <arch/stack.h> |
48,16 → 47,6 |
#define BSP_FLAG 1 |
/* |
* 2^PHYSMEM_ADDR_SIZE is the size of the physical address space on |
* a given processor. |
*/ |
#if defined (US) |
#define PHYSMEM_ADDR_SIZE 41 |
#elif defined (US3) |
#define PHYSMEM_ADDR_SIZE 43 |
#endif |
/* |
* Here is where the kernel is passed control from the boot loader. |
* |
* The registers are expected to be in this state: |
78,13 → 67,11 |
and %o0, %l0, %l7 ! l7 <= bootstrap processor? |
andn %o0, %l0, %l6 ! l6 <= start of physical memory |
! Get bits (PHYSMEM_ADDR_SIZE - 1):13 of physmem_base. |
! Get bits 40:13 of physmem_base. |
srlx %l6, 13, %l5 |
sllx %l5, 13 + (63 - 40), %l5 |
srlx %l5, 63 - 40, %l5 ! l5 <= physmem_base[40:13] |
! l5 <= physmem_base[(PHYSMEM_ADDR_SIZE - 1):13] |
sllx %l5, 13 + (63 - (PHYSMEM_ADDR_SIZE - 1)), %l5 |
srlx %l5, 63 - (PHYSMEM_ADDR_SIZE - 1), %l5 |
/* |
* Setup basic runtime environment. |
*/ |
96,8 → 83,6 |
! consistent |
wrpr %g0, NWINDOWS - 1, %cleanwin ! prevent needless clean_window |
! traps for kernel |
wrpr %g0, 0, %wstate ! use default spill/fill trap |
wrpr %g0, 0, %tl ! TL = 0, primary context |
! register is used |
259,8 → 244,7 |
/* |
* Precompute kernel 8K TLB data template. |
* %l5 contains starting physical address |
* bits [(PHYSMEM_ADDR_SIZE - 1):13] |
* %l5 contains starting physical address bits [40:13] |
*/ |
sethi %hi(kernel_8k_tlb_data_template), %l4 |
ldx [%l4 + %lo(kernel_8k_tlb_data_template)], %l3 |
294,36 → 278,19 |
/* Not reached. */ |
0: |
ba %xcc, 0b |
ba 0b |
nop |
1: |
#ifdef CONFIG_SMP |
/* |
* Determine the width of the MID and save its mask to %g3. The width |
* is |
* * 5 for US and US-IIIi, |
* * 10 for US3 except US-IIIi. |
*/ |
#if defined(US) |
mov 0x1f, %g3 |
#elif defined(US3) |
mov 0x3ff, %g3 |
rdpr %ver, %g2 |
sllx %g2, 16, %g2 |
srlx %g2, 48, %g2 |
cmp %g2, IMPL_ULTRASPARCIII_I |
move %xcc, 0x1f, %g3 |
#endif |
/* |
* Read MID from the processor. |
*/ |
ldxa [%g0] ASI_ICBUS_CONFIG, %g1 |
srlx %g1, ICBUS_CONFIG_MID_SHIFT, %g1 |
and %g1, %g3, %g1 |
1: |
ldxa [%g0] ASI_UPA_CONFIG, %g1 |
srlx %g1, UPA_CONFIG_MID_SHIFT, %g1 |
and %g1, UPA_CONFIG_MID_MASK, %g1 |
#ifdef CONFIG_SMP |
/* |
* Active loop for APs until the BSP picks them up. A processor cannot |
* leave the loop until the global variable 'waking_up_mid' equals its |
333,7 → 300,7 |
2: |
ldx [%g2], %g3 |
cmp %g3, %g1 |
bne %xcc, 2b |
bne 2b |
nop |
/* |
352,7 → 319,7 |
#endif |
0: |
ba %xcc, 0b |
ba 0b |
nop |
381,31 → 348,10 |
.quad 0 |
/* |
* The fast_data_access_mmu_miss_data_hi label and the end_of_identity and |
* kernel_8k_tlb_data_template variables are meant to stay together, |
* aligned on 16B boundary. |
* This variable is used by the fast_data_MMU_miss trap handler. In runtime, it |
* is further modified to reflect the starting address of physical memory. |
*/ |
.global fast_data_access_mmu_miss_data_hi |
.global end_of_identity |
.global kernel_8k_tlb_data_template |
.align 16 |
/* |
* This label is used by the fast_data_access_MMU_miss trap handler. |
*/ |
fast_data_access_mmu_miss_data_hi: |
/* |
* This variable is used by the fast_data_access_MMU_miss trap handler. |
* In runtime, it is modified to contain the address of the end of physical |
* memory. |
*/ |
end_of_identity: |
.quad -1 |
/* |
* This variable is used by the fast_data_access_MMU_miss trap handler. |
* In runtime, it is further modified to reflect the starting address of |
* physical memory. |
*/ |
kernel_8k_tlb_data_template: |
#ifdef CONFIG_VIRT_IDX_DCACHE |
.quad ((1 << TTE_V_SHIFT) | (PAGESIZE_8K << TTE_SIZE_SHIFT) | TTE_CP | \ |
/branches/arm/kernel/arch/sparc64/src/dummy.s |
---|
42,5 → 42,5 |
.global cpu_halt |
cpu_halt: |
ba %xcc, cpu_halt |
b cpu_halt |
nop |
/branches/arm/kernel/arch/sparc64/Makefile.inc |
---|
29,6 → 29,10 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf64-sparc |
BFD_ARCH = sparc |
BFD = binary |
40,58 → 44,82 |
LFLAGS += -no-check-sections -N |
BITS = 64 |
ENDIANESS = BE |
DEFS += -D__64_BITS__ |
ifeq ($(PROCESSOR),us) |
DEFS += -DUS |
endif |
## Own configuration directives |
# |
ifeq ($(PROCESSOR),us3) |
DEFS += -DUS3 |
## Compile with page hash table support. |
# |
CONFIG_PAGE_HT = y |
DEFS += -DCONFIG_PAGE_HT |
## Compile with support for address space identifiers. |
# |
CONFIG_ASID = y |
CONFIG_ASID_FIFO = y |
## Compile with support for framebuffer. |
# |
CONFIG_FB = y |
## Compile with support for Sun keyboard. |
# |
CONFIG_SUN_KBD = y |
## Compile with support for OpenFirmware device tree. |
# |
CONFIG_OFW_TREE = y |
ifeq ($(CONFIG_SMP),y) |
DEFS += -DCONFIG_SMP |
endif |
ARCH_SOURCES = \ |
arch/$(KARCH)/src/cpu/cpu.c \ |
arch/$(KARCH)/src/asm.S \ |
arch/$(KARCH)/src/panic.S \ |
arch/$(KARCH)/src/console.c \ |
arch/$(KARCH)/src/context.S \ |
arch/$(KARCH)/src/fpu_context.c \ |
arch/$(KARCH)/src/dummy.s \ |
arch/$(KARCH)/src/mm/as.c \ |
arch/$(KARCH)/src/mm/cache.S \ |
arch/$(KARCH)/src/mm/frame.c \ |
arch/$(KARCH)/src/mm/page.c \ |
arch/$(KARCH)/src/mm/tlb.c \ |
arch/$(KARCH)/src/sparc64.c \ |
arch/$(KARCH)/src/start.S \ |
arch/$(KARCH)/src/proc/scheduler.c \ |
arch/$(KARCH)/src/proc/thread.c \ |
arch/$(KARCH)/src/trap/mmu.S \ |
arch/$(KARCH)/src/trap/trap_table.S \ |
arch/$(KARCH)/src/trap/trap.c \ |
arch/$(KARCH)/src/trap/exception.c \ |
arch/$(KARCH)/src/trap/interrupt.c \ |
arch/$(KARCH)/src/ddi/ddi.c \ |
arch/$(KARCH)/src/drivers/tick.c \ |
arch/$(KARCH)/src/drivers/kbd.c \ |
arch/$(KARCH)/src/drivers/sgcn.c \ |
arch/$(KARCH)/src/drivers/pci.c \ |
arch/$(KARCH)/src/drivers/fhc.c |
arch/$(ARCH)/src/cpu/cpu.c \ |
arch/$(ARCH)/src/asm.S \ |
arch/$(ARCH)/src/panic.S \ |
arch/$(ARCH)/src/console.c \ |
arch/$(ARCH)/src/context.S \ |
arch/$(ARCH)/src/fpu_context.c \ |
arch/$(ARCH)/src/dummy.s \ |
arch/$(ARCH)/src/mm/as.c \ |
arch/$(ARCH)/src/mm/cache.S \ |
arch/$(ARCH)/src/mm/frame.c \ |
arch/$(ARCH)/src/mm/page.c \ |
arch/$(ARCH)/src/mm/tlb.c \ |
arch/$(ARCH)/src/sparc64.c \ |
arch/$(ARCH)/src/start.S \ |
arch/$(ARCH)/src/proc/scheduler.c \ |
arch/$(ARCH)/src/proc/thread.c \ |
arch/$(ARCH)/src/trap/mmu.S \ |
arch/$(ARCH)/src/trap/trap_table.S \ |
arch/$(ARCH)/src/trap/trap.c \ |
arch/$(ARCH)/src/trap/exception.c \ |
arch/$(ARCH)/src/trap/interrupt.c \ |
arch/$(ARCH)/src/ddi/ddi.c \ |
arch/$(ARCH)/src/drivers/tick.c \ |
arch/$(ARCH)/src/drivers/kbd.c \ |
arch/$(ARCH)/src/drivers/scr.c \ |
arch/$(ARCH)/src/drivers/pci.c |
ifeq ($(CONFIG_FB),y) |
ARCH_SOURCES += \ |
arch/$(KARCH)/src/drivers/scr.c |
endif |
ifeq ($(CONFIG_SMP),y) |
ARCH_SOURCES += \ |
arch/$(KARCH)/src/smp/ipi.c \ |
arch/$(KARCH)/src/smp/smp.c |
ARCH_SOURCES += \ |
arch/$(ARCH)/src/smp/ipi.c \ |
arch/$(ARCH)/src/smp/smp.c |
endif |
ifeq ($(CONFIG_TSB),y) |
ARCH_SOURCES += \ |
arch/$(KARCH)/src/mm/tsb.c |
ARCH_SOURCES += \ |
arch/$(ARCH)/src/mm/tsb.c |
endif |
ifdef CONFIG_Z8530 |
ARCH_SOURCES += \ |
arch/$(ARCH)/src/drivers/fhc.c |
endif |
/branches/arm/kernel/arch/sparc64/_link.ld.in |
---|
1,8 → 1,8 |
/** SPARC64 linker script |
* |
* It is ELF format, but its only section looks like this: |
* kernel text |
* kernel data |
* kernel text |
* kernel data |
* |
*/ |
11,7 → 11,7 |
ENTRY(kernel_image_start) |
SECTIONS { |
.image VMA: AT (LMA) { |
.image VMA: AT (LMA) { |
ktext_start = .; |
*(K_TEXT_START) |
*(.text); |
21,23 → 21,23 |
*(K_DATA_START) |
*(.rodata); |
*(.rodata.*); |
*(.data); /* initialized data */ |
*(.data); /* initialized data */ |
*(.sdata); |
*(.sdata2); |
*(.sbss); |
. = ALIGN(8); |
hardcoded_ktext_size = .; |
QUAD(ktext_end - ktext_start); |
QUAD(ktext_end - ktext_start); |
hardcoded_kdata_size = .; |
QUAD(kdata_end - kdata_start); |
hardcoded_load_address = .; |
QUAD(VMA); |
*(.bss); /* uninitialized static variables */ |
*(COMMON); /* global variables */ |
*(.bss); /* uninitialized static variables */ |
*(COMMON); /* global variables */ |
symbol_table = .; |
*(symtab.*); /* Symbol table, must be LAST symbol!*/ |
*(symtab.*); /* Symbol table, must be LAST symbol!*/ |
kdata_end = .; |
} |
44,5 → 44,5 |
/DISCARD/ : { |
*(*); |
} |
} |
/branches/arm/kernel/arch/ppc32/include/asm/regname.h |
---|
211,9 → 211,6 |
#define dbat2l 541 |
#define dbat3u 542 |
#define dbat3l 543 |
#define tlbmiss 980 |
#define ptehi 981 |
#define ptelo 982 |
#define hid0 1008 |
/* MSR bits */ |
223,7 → 220,6 |
#define msr_ee (1 << 15) |
/* HID0 bits */ |
#define hid0_sten (1 << 24) |
#define hid0_ice (1 << 15) |
#define hid0_dce (1 << 14) |
#define hid0_icfi (1 << 11) |
/branches/arm/kernel/arch/ppc32/include/exception.h |
---|
75,7 → 75,6 |
uint32_t lr; |
uint32_t ctr; |
uint32_t xer; |
uint32_t dar; |
uint32_t r12; |
uint32_t sp; |
} istate_t; |
/branches/arm/kernel/arch/ppc32/include/mm/page.h |
---|
102,25 → 102,25 |
/* Get PTE flags accessors for each level. */ |
#define GET_PTL1_FLAGS_ARCH(ptl0, i) \ |
get_pt_flags((pte_t *) (ptl0), (size_t) (i)) |
get_pt_flags((pte_t *) (ptl0), (index_t) (i)) |
#define GET_PTL2_FLAGS_ARCH(ptl1, i) \ |
PAGE_PRESENT |
#define GET_PTL3_FLAGS_ARCH(ptl2, i) \ |
PAGE_PRESENT |
#define GET_FRAME_FLAGS_ARCH(ptl3, i) \ |
get_pt_flags((pte_t *) (ptl3), (size_t) (i)) |
get_pt_flags((pte_t *) (ptl3), (index_t) (i)) |
/* Set PTE flags accessors for each level. */ |
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \ |
set_pt_flags((pte_t *) (ptl0), (size_t) (i), (x)) |
set_pt_flags((pte_t *) (ptl0), (index_t) (i), (x)) |
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x) |
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x) |
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \ |
set_pt_flags((pte_t *) (ptl3), (size_t) (i), (x)) |
set_pt_flags((pte_t *) (ptl3), (index_t) (i), (x)) |
/* Macros for querying the last-level PTEs. */ |
#define PTE_VALID_ARCH(pte) (*((uint32_t *) (pte)) != 0) |
#define PTE_PRESENT_ARCH(pte) ((pte)->present != 0) |
#define PTE_PRESENT_ARCH(pte) ((pte)->p != 0) |
#define PTE_GET_FRAME_ARCH(pte) ((pte)->pfn << 12) |
#define PTE_WRITABLE_ARCH(pte) 1 |
#define PTE_EXECUTABLE_ARCH(pte) 1 |
130,26 → 130,25 |
#include <mm/mm.h> |
#include <arch/interrupt.h> |
static inline int get_pt_flags(pte_t *pt, size_t i) |
static inline int get_pt_flags(pte_t *pt, index_t i) |
{ |
pte_t *p = &pt[i]; |
return (((!p->page_cache_disable) << PAGE_CACHEABLE_SHIFT) | |
((!p->present) << PAGE_PRESENT_SHIFT) | |
return ((1 << PAGE_CACHEABLE_SHIFT) | |
((!p->p) << PAGE_PRESENT_SHIFT) | |
(1 << PAGE_USER_SHIFT) | |
(1 << PAGE_READ_SHIFT) | |
(1 << PAGE_WRITE_SHIFT) | |
(1 << PAGE_EXEC_SHIFT) | |
(p->global << PAGE_GLOBAL_SHIFT)); |
(p->g << PAGE_GLOBAL_SHIFT)); |
} |
static inline void set_pt_flags(pte_t *pt, size_t i, int flags) |
static inline void set_pt_flags(pte_t *pt, index_t i, int flags) |
{ |
pte_t *p = &pt[i]; |
p->page_cache_disable = !(flags & PAGE_CACHEABLE); |
p->present = !(flags & PAGE_NOT_PRESENT); |
p->global = (flags & PAGE_GLOBAL) != 0; |
p->p = !(flags & PAGE_NOT_PRESENT); |
p->g = (flags & PAGE_GLOBAL) != 0; |
p->valid = 1; |
} |
/branches/arm/kernel/arch/ppc32/include/mm/tlb.h |
---|
39,11 → 39,6 |
#include <arch/types.h> |
#include <typedefs.h> |
#define WIMG_GUARDED 0x01 |
#define WIMG_COHERENT 0x02 |
#define WIMG_NO_CACHE 0x04 |
#define WIMG_WRITETHRU 0x08 |
typedef struct { |
unsigned v : 1; /**< Valid */ |
unsigned vsid : 24; /**< Virtual Segment ID */ |
58,27 → 53,9 |
unsigned pp : 2; /**< Page protection */ |
} phte_t; |
typedef struct { |
unsigned v : 1; |
unsigned vsid : 24; |
unsigned reserved0 : 1; |
unsigned api : 6; |
} ptehi_t; |
typedef struct { |
unsigned rpn : 20; |
unsigned xpn : 3; |
unsigned reserved0 : 1; |
unsigned c : 1; |
unsigned wimg : 4; |
unsigned x : 1; |
unsigned pp : 2; |
} ptelo_t; |
extern void pht_refill(int n, istate_t *istate); |
extern bool pht_real_refill(int n, istate_t *istate) __attribute__ ((section("K_UNMAPPED_TEXT_START"))); |
extern void pht_init(void); |
extern void pht_refill(int n, istate_t *istate); |
extern bool pht_refill_real(int n, istate_t *istate) __attribute__ ((section("K_UNMAPPED_TEXT_START"))); |
extern void tlb_refill_real(int n, uint32_t tlbmiss, ptehi_t ptehi, ptelo_t ptelo, istate_t *istate) __attribute__ ((section("K_UNMAPPED_TEXT_START"))); |
#endif |
/branches/arm/kernel/arch/ppc32/include/mm/frame.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc32mm |
/** @addtogroup ppc32mm |
* @{ |
*/ |
/** @file |
35,13 → 35,13 |
#ifndef KERN_ppc32_FRAME_H_ |
#define KERN_ppc32_FRAME_H_ |
#define FRAME_WIDTH 12 /* 4K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#define FRAME_WIDTH 12 /* 4K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#ifdef KERNEL |
#ifndef __ASM__ |
#include <arch/types.h> |
#include <arch/types.h> |
extern uintptr_t last_frame; |
/branches/arm/kernel/arch/ppc32/include/barrier.h |
---|
55,7 → 55,6 |
"dcbst 0, %0\n" |
"sync\n" |
"icbi 0, %0\n" |
"sync\n" |
"isync\n" |
:: "r" (addr) |
); |
77,10 → 76,7 |
asm volatile ("icbi 0, %0\n" :: "r" (addr + i)); |
} |
asm volatile ( |
"sync\n" |
"isync\n" |
); |
asm volatile ("isync"); |
} |
#endif |
/branches/arm/kernel/arch/ppc32/include/boot/boot.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc32 |
/** @addtogroup ppc32 |
* @{ |
*/ |
/** @file |
35,24 → 35,21 |
#ifndef KERN_ppc32_BOOT_H_ |
#define KERN_ppc32_BOOT_H_ |
#define BOOT_OFFSET 0x8000 |
#define BOOT_OFFSET 0x8000 |
/* Temporary stack size for boot process */ |
#define TEMP_STACK_SIZE 0x1000 |
#define TEMP_STACK_SIZE 0x1000 |
#define TASKMAP_MAX_RECORDS 32 |
#define MEMMAP_MAX_RECORDS 32 |
#define TASKMAP_MAX_RECORDS 32 |
#define MEMMAP_MAX_RECORDS 32 |
#ifndef __ASM__ |
#define BOOTINFO_TASK_NAME_BUFLEN 32 |
#include <arch/types.h> |
typedef struct { |
uintptr_t addr; |
uint32_t size; |
char name[BOOTINFO_TASK_NAME_BUFLEN]; |
} utask_t; |
typedef struct { |
82,13 → 79,13 |
typedef struct { |
uintptr_t addr; |
unsigned int size; |
} macio_t; |
} keyboard_t; |
typedef struct { |
memmap_t memmap; |
taskmap_t taskmap; |
screen_t screen; |
macio_t macio; |
keyboard_t keyboard; |
} bootinfo_t; |
extern bootinfo_t bootinfo; |
/branches/arm/kernel/arch/ppc32/include/drivers/cuda.h |
---|
0,0 → 1,49 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc32 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc32_CUDA_H_ |
#define KERN_ppc32_CUDA_H_ |
#include <arch/types.h> |
#include <typedefs.h> |
extern void cuda_init(devno_t devno, uintptr_t base, size_t size); |
extern int cuda_get_scancode(void); |
extern void cuda_grab(void); |
extern void cuda_release(void); |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc32/include/drivers/pic.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc32 |
/** @addtogroup ppc32 |
* @{ |
*/ |
/** @file |
36,7 → 36,6 |
#define KERN_ppc32_PIC_H_ |
#include <arch/types.h> |
#include <ddi/irq.h> |
#define PIC_PENDING_LOW 8 |
#define PIC_PENDING_HIGH 4 |
45,11 → 44,11 |
#define PIC_ACK_LOW 10 |
#define PIC_ACK_HIGH 6 |
extern void pic_init(uintptr_t base, size_t size, cir_t *cir, void **cir_arg); |
extern void pic_enable_interrupt(inr_t intnum); |
extern void pic_disable_interrupt(inr_t intnum); |
extern void pic_ack_interrupt(void *arg, inr_t intnum); |
extern int pic_get_pending(void); |
void pic_init(uintptr_t base, size_t size); |
void pic_enable_interrupt(int intnum); |
void pic_disable_interrupt(int intnum); |
void pic_ack_interrupt(int intnum); |
int pic_get_pending(void); |
#endif |
/branches/arm/kernel/arch/ppc32/include/types.h |
---|
46,6 → 46,8 |
typedef unsigned long long uint64_t; |
typedef uint32_t size_t; |
typedef uint32_t count_t; |
typedef uint32_t index_t; |
typedef uint32_t uintptr_t; |
typedef uint32_t pfn_t; |
55,12 → 57,11 |
typedef uint32_t unative_t; |
typedef int32_t native_t; |
typedef struct { |
} fncptr_t; |
/**< Formats for uintptr_t, size_t */ |
/**< Formats for uintptr_t, size_t, count_t and index_t */ |
#define PRIp "x" |
#define PRIs "u" |
#define PRIc "u" |
#define PRIi "u" |
/**< Formats for (u)int8_t, (u)int16_t, (u)int32_t, (u)int64_t and (u)native_t */ |
#define PRId8 "d" |
83,13 → 84,11 |
/** Page Table Entry. */ |
typedef struct { |
unsigned present : 1; /**< Present bit. */ |
unsigned page_write_through : 1; /**< Write thought caching. */ |
unsigned page_cache_disable : 1; /**< No caching. */ |
unsigned accessed : 1; /**< Accessed bit. */ |
unsigned global : 1; /**< Global bit. */ |
unsigned valid : 1; /**< Valid content even if not present. */ |
unsigned pfn : 20; /**< Physical frame number. */ |
unsigned p : 1; /**< Present bit. */ |
unsigned a : 1; /**< Accessed bit. */ |
unsigned g : 1; /**< Global bit. */ |
unsigned valid : 1; /**< Valid content even if not present. */ |
unsigned pfn : 20; /**< Physical frame number. */ |
} pte_t; |
#endif |
/branches/arm/kernel/arch/ppc32/include/byteorder.h |
---|
0,0 → 1,43 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc32 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc32_BYTEORDER_H_ |
#define KERN_ppc32_BYTEORDER_H_ |
#define ARCH_IS_BIG_ENDIAN |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc32/include/arch.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc32 |
/** @addtogroup ppc32 |
* @{ |
*/ |
/** @file |
35,7 → 35,7 |
#ifndef KERN_ppc32_ARCH_H_ |
#define KERN_ppc32_ARCH_H_ |
extern void arch_pre_main(void); |
#include <arch/drivers/cuda.h> |
#endif |
/branches/arm/kernel/arch/ppc32/include/asm.h |
---|
36,7 → 36,6 |
#define KERN_ppc32_ASM_H_ |
#include <arch/types.h> |
#include <typedefs.h> |
#include <config.h> |
/** Enable interrupts. |
150,36 → 149,6 |
extern void userspace_asm(uintptr_t uspace_uarg, uintptr_t stack, uintptr_t entry); |
static inline void pio_write_8(ioport8_t *port, uint8_t v) |
{ |
*port = v; |
} |
static inline void pio_write_16(ioport16_t *port, uint16_t v) |
{ |
*port = v; |
} |
static inline void pio_write_32(ioport32_t *port, uint32_t v) |
{ |
*port = v; |
} |
static inline uint8_t pio_read_8(ioport8_t *port) |
{ |
return *port; |
} |
static inline uint16_t pio_read_16(ioport16_t *port) |
{ |
return *port; |
} |
static inline uint32_t pio_read_32(ioport32_t *port) |
{ |
return *port; |
} |
#endif |
/** @} |
/branches/arm/kernel/arch/ppc32/Makefile.inc |
---|
29,6 → 29,10 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf32-powerpc |
BFD_ARCH = powerpc:common |
BFD = binary |
39,24 → 43,46 |
AFLAGS += -a32 |
LFLAGS += -no-check-sections -N |
BITS = 32 |
ENDIANESS = BE |
DEFS += -D__32_BITS__ |
## Own configuration directives |
# |
CONFIG_FB = y |
## Compile with hierarchical page tables support. |
# |
CONFIG_PAGE_PT = y |
DEFS += -DCONFIG_PAGE_PT |
## Compile with support for address space identifiers. |
# |
CONFIG_ASID = y |
CONFIG_ASID_FIFO = y |
## Compile with support for software integer division. |
# |
CONFIG_SOFTINT = y |
ARCH_SOURCES = \ |
arch/$(KARCH)/src/context.S \ |
arch/$(KARCH)/src/debug/panic.s \ |
arch/$(KARCH)/src/fpu_context.S \ |
arch/$(KARCH)/src/boot/boot.S \ |
arch/$(KARCH)/src/ppc32.c \ |
arch/$(KARCH)/src/dummy.s \ |
arch/$(KARCH)/src/exception.S \ |
arch/$(KARCH)/src/interrupt.c \ |
arch/$(KARCH)/src/asm.S \ |
arch/$(KARCH)/src/cpu/cpu.c \ |
arch/$(KARCH)/src/proc/scheduler.c \ |
arch/$(KARCH)/src/ddi/ddi.c \ |
arch/$(KARCH)/src/mm/as.c \ |
arch/$(KARCH)/src/mm/frame.c \ |
arch/$(KARCH)/src/mm/page.c \ |
arch/$(KARCH)/src/mm/tlb.c \ |
arch/$(KARCH)/src/drivers/pic.c |
arch/$(ARCH)/src/context.S \ |
arch/$(ARCH)/src/debug/panic.s \ |
arch/$(ARCH)/src/fpu_context.S \ |
arch/$(ARCH)/src/boot/boot.S \ |
arch/$(ARCH)/src/ppc32.c \ |
arch/$(ARCH)/src/dummy.s \ |
arch/$(ARCH)/src/exception.S \ |
arch/$(ARCH)/src/interrupt.c \ |
arch/$(ARCH)/src/asm.S \ |
arch/$(ARCH)/src/cpu/cpu.c \ |
arch/$(ARCH)/src/proc/scheduler.c \ |
arch/$(ARCH)/src/ddi/ddi.c \ |
arch/$(ARCH)/src/drivers/cuda.c \ |
arch/$(ARCH)/src/mm/as.c \ |
arch/$(ARCH)/src/mm/frame.c \ |
arch/$(ARCH)/src/mm/page.c \ |
arch/$(ARCH)/src/mm/tlb.c \ |
arch/$(ARCH)/src/drivers/pic.c |
/branches/arm/kernel/arch/ppc32/src/asm.S |
---|
34,7 → 34,6 |
.global iret |
.global iret_syscall |
.global memsetb |
.global memsetw |
.global memcpy |
.global memcpy_from_uspace |
.global memcpy_to_uspace |
67,9 → 66,9 |
mr sp, r4 |
# %r6 is defined to hold pcb_ptr - set it to 0 |
# %r3 is defined to hold pcb_ptr - set it to 0 |
xor r6, r6, r6 |
xor r3, r3, r3 |
# jump to userspace |
132,8 → 131,8 |
lwz r12, 148(sp) |
mtxer r12 |
lwz r12, 156(sp) |
lwz sp, 160(sp) |
lwz r12, 152(sp) |
lwz sp, 156(sp) |
rfi |
198,17 → 197,14 |
lwz r12, 148(sp) |
mtxer r12 |
lwz r12, 156(sp) |
lwz sp, 160(sp) |
lwz r12, 152(sp) |
lwz sp, 156(sp) |
rfi |
memsetb: |
b _memsetb |
memsetw: |
b _memsetw |
memcpy: |
memcpy_from_uspace: |
memcpy_to_uspace: |
/branches/arm/kernel/arch/ppc32/src/mm/tlb.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc32mm |
/** @addtogroup ppc32mm |
* @{ |
*/ |
/** @file |
35,22 → 35,12 |
#include <mm/tlb.h> |
#include <arch/mm/tlb.h> |
#include <arch/interrupt.h> |
#include <interrupt.h> |
#include <mm/as.h> |
#include <arch.h> |
#include <print.h> |
#include <macros.h> |
#include <symtab.h> |
static unsigned int seed = 10; |
static unsigned int seed_real __attribute__ ((section("K_UNMAPPED_DATA_START"))) = 42; |
#define TLB_FLUSH \ |
"tlbie %0\n" \ |
"addi %0, %0, 0x1000\n" |
/** Try to find PTE for faulting address |
* |
* Try to find PTE for faulting address. |
75,7 → 65,7 |
* Check if the mapping exists in page tables. |
*/ |
pte_t *pte = page_mapping_find(as, badvaddr); |
if ((pte) && (pte->present)) { |
if ((pte) && (pte->p)) { |
/* |
* Mapping found in page tables. |
* Immediately succeed. |
97,7 → 87,7 |
*/ |
page_table_lock(as, lock); |
pte = page_mapping_find(as, badvaddr); |
ASSERT((pte) && (pte->present)); |
ASSERT((pte) && (pte->p)); |
*pfrc = 0; |
return pte; |
case AS_PF_DEFER: |
106,10 → 96,11 |
return NULL; |
case AS_PF_FAULT: |
page_table_lock(as, lock); |
printf("Page fault.\n"); |
*pfrc = rc; |
return NULL; |
default: |
panic("Unexpected rc (%d).", rc); |
panic("unexpected rc (%d)\n", rc); |
} |
} |
} |
117,20 → 108,21 |
static void pht_refill_fail(uintptr_t badvaddr, istate_t *istate) |
{ |
char *symbol; |
char *sym2; |
char *symbol = ""; |
char *sym2 = ""; |
symbol = symtab_fmt_name_lookup(istate->pc); |
sym2 = symtab_fmt_name_lookup(istate->lr); |
fault_if_from_uspace(istate, |
"PHT Refill Exception on %p.", badvaddr); |
panic("%p: PHT Refill Exception at %p (%s<-%s).", badvaddr, |
char *s = get_symtab_entry(istate->pc); |
if (s) |
symbol = s; |
s = get_symtab_entry(istate->lr); |
if (s) |
sym2 = s; |
panic("%p: PHT Refill Exception at %p (%s<-%s)\n", badvaddr, |
istate->pc, symbol, sym2); |
} |
static void pht_insert(const uintptr_t vaddr, const pte_t *pte) |
static void pht_insert(const uintptr_t vaddr, const pfn_t pfn) |
{ |
uint32_t page = (vaddr >> 12) & 0xffff; |
uint32_t api = (vaddr >> 22) & 0x3f; |
156,12 → 148,11 |
uint32_t i; |
bool found = false; |
/* Find colliding PTE in PTEG */ |
/* Find unused or colliding |
PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if ((phte[base + i].v) |
&& (phte[base + i].vsid == vsid) |
&& (phte[base + i].api == api) |
&& (phte[base + i].h == 0)) { |
if ((!phte[base + i].v) || ((phte[base + i].vsid == vsid) && |
(phte[base + i].api == api))) { |
found = true; |
break; |
} |
168,25 → 159,86 |
} |
if (!found) { |
/* Find unused PTE in PTEG */ |
/* Secondary hash (not) */ |
uint32_t base2 = (~hash & 0x3ff) << 3; |
/* Find unused or colliding |
PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if (!phte[base + i].v) { |
if ((!phte[base2 + i].v) || |
((phte[base2 + i].vsid == vsid) && |
(phte[base2 + i].api == api))) { |
found = true; |
base = base2; |
h = 1; |
break; |
} |
} |
if (!found) { |
// TODO: A/C precedence groups |
i = page % 8; |
} |
} |
phte[base + i].v = 1; |
phte[base + i].vsid = vsid; |
phte[base + i].h = h; |
phte[base + i].api = api; |
phte[base + i].rpn = pfn; |
phte[base + i].r = 0; |
phte[base + i].c = 0; |
phte[base + i].pp = 2; // FIXME |
} |
static void pht_real_insert(const uintptr_t vaddr, const pfn_t pfn) |
{ |
uint32_t page = (vaddr >> 12) & 0xffff; |
uint32_t api = (vaddr >> 22) & 0x3f; |
uint32_t vsid; |
asm volatile ( |
"mfsrin %0, %1\n" |
: "=r" (vsid) |
: "r" (vaddr) |
); |
uint32_t sdr1; |
asm volatile ( |
"mfsdr1 %0\n" |
: "=r" (sdr1) |
); |
phte_t *phte_physical = (phte_t *) (sdr1 & 0xffff0000); |
/* Primary hash (xor) */ |
uint32_t h = 0; |
uint32_t hash = vsid ^ page; |
uint32_t base = (hash & 0x3ff) << 3; |
uint32_t i; |
bool found = false; |
/* Find unused or colliding |
PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if ((!phte_physical[base + i].v) || |
((phte_physical[base + i].vsid == vsid) && |
(phte_physical[base + i].api == api))) { |
found = true; |
break; |
} |
} |
if (!found) { |
/* Secondary hash (not) */ |
uint32_t base2 = (~hash & 0x3ff) << 3; |
/* Find colliding PTE in PTEG */ |
/* Find unused or colliding |
PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if ((phte[base2 + i].v) |
&& (phte[base2 + i].vsid == vsid) |
&& (phte[base2 + i].api == api) |
&& (phte[base2 + i].h == 1)) { |
if ((!phte_physical[base2 + i].v) || |
((phte_physical[base2 + i].vsid == vsid) && |
(phte_physical[base2 + i].api == api))) { |
found = true; |
base = base2; |
h = 1; |
195,37 → 247,26 |
} |
if (!found) { |
/* Find unused PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if (!phte[base2 + i].v) { |
found = true; |
base = base2; |
h = 1; |
break; |
} |
} |
// TODO: A/C precedence groups |
i = page % 8; |
} |
if (!found) |
i = RANDI(seed) % 8; |
} |
phte[base + i].v = 1; |
phte[base + i].vsid = vsid; |
phte[base + i].h = h; |
phte[base + i].api = api; |
phte[base + i].rpn = pte->pfn; |
phte[base + i].r = 0; |
phte[base + i].c = 0; |
phte[base + i].wimg = (pte->page_cache_disable ? WIMG_NO_CACHE : 0); |
phte[base + i].pp = 2; // FIXME |
phte_physical[base + i].v = 1; |
phte_physical[base + i].vsid = vsid; |
phte_physical[base + i].h = h; |
phte_physical[base + i].api = api; |
phte_physical[base + i].rpn = pfn; |
phte_physical[base + i].r = 0; |
phte_physical[base + i].c = 0; |
phte_physical[base + i].pp = 2; // FIXME |
} |
/** Process Instruction/Data Storage Exception |
/** Process Instruction/Data Storage Interrupt |
* |
* @param n Exception vector number. |
* @param istate Interrupted register context. |
* @param n Interrupt vector number. |
* @param istate Interrupted register context. |
* |
*/ |
void pht_refill(int n, istate_t *istate) |
244,9 → 285,12 |
lock = true; |
} |
if (n == VECTOR_DATA_STORAGE) |
badvaddr = istate->dar; |
else |
if (n == VECTOR_DATA_STORAGE) { |
asm volatile ( |
"mfdar %0\n" |
: "=r" (badvaddr) |
); |
} else |
badvaddr = istate->pc; |
page_table_lock(as, lock); |
266,12 → 310,12 |
page_table_unlock(as, lock); |
return; |
default: |
panic("Unexpected pfrc (%d).", pfrc); |
panic("Unexpected pfrc (%d)\n", pfrc); |
} |
} |
pte->accessed = 1; /* Record access to PTE */ |
pht_insert(badvaddr, pte); |
pte->a = 1; /* Record access to PTE */ |
pht_insert(badvaddr, pte->pfn); |
page_table_unlock(as, lock); |
return; |
282,19 → 326,22 |
} |
/** Process Instruction/Data Storage Exception in Real Mode |
/** Process Instruction/Data Storage Interrupt in Real Mode |
* |
* @param n Exception vector number. |
* @param istate Interrupted register context. |
* @param n Interrupt vector number. |
* @param istate Interrupted register context. |
* |
*/ |
bool pht_refill_real(int n, istate_t *istate) |
bool pht_real_refill(int n, istate_t *istate) |
{ |
uintptr_t badvaddr; |
if (n == VECTOR_DATA_STORAGE) |
badvaddr = istate->dar; |
else |
if (n == VECTOR_DATA_STORAGE) { |
asm volatile ( |
"mfdar %0\n" |
: "=r" (badvaddr) |
); |
} else |
badvaddr = istate->pc; |
uint32_t physmem; |
303,140 → 350,15 |
: "=r" (physmem) |
); |
if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem))) |
return false; |
uint32_t page = (badvaddr >> 12) & 0xffff; |
uint32_t api = (badvaddr >> 22) & 0x3f; |
uint32_t vsid; |
asm volatile ( |
"mfsrin %0, %1\n" |
: "=r" (vsid) |
: "r" (badvaddr) |
); |
uint32_t sdr1; |
asm volatile ( |
"mfsdr1 %0\n" |
: "=r" (sdr1) |
); |
phte_t *phte_real = (phte_t *) (sdr1 & 0xffff0000); |
/* Primary hash (xor) */ |
uint32_t h = 0; |
uint32_t hash = vsid ^ page; |
uint32_t base = (hash & 0x3ff) << 3; |
uint32_t i; |
bool found = false; |
/* Find colliding PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if ((phte_real[base + i].v) |
&& (phte_real[base + i].vsid == vsid) |
&& (phte_real[base + i].api == api) |
&& (phte_real[base + i].h == 0)) { |
found = true; |
break; |
} |
if ((badvaddr >= PA2KA(0)) && (badvaddr < PA2KA(physmem))) { |
pht_real_insert(badvaddr, KA2PA(badvaddr) >> 12); |
return true; |
} |
if (!found) { |
/* Find unused PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if (!phte_real[base + i].v) { |
found = true; |
break; |
} |
} |
} |
if (!found) { |
/* Secondary hash (not) */ |
uint32_t base2 = (~hash & 0x3ff) << 3; |
/* Find colliding PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if ((phte_real[base2 + i].v) |
&& (phte_real[base2 + i].vsid == vsid) |
&& (phte_real[base2 + i].api == api) |
&& (phte_real[base2 + i].h == 1)) { |
found = true; |
base = base2; |
h = 1; |
break; |
} |
} |
if (!found) { |
/* Find unused PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if (!phte_real[base2 + i].v) { |
found = true; |
base = base2; |
h = 1; |
break; |
} |
} |
} |
if (!found) { |
/* Use secondary hash to avoid collisions |
with usual PHT refill handler. */ |
i = RANDI(seed_real) % 8; |
base = base2; |
h = 1; |
} |
} |
phte_real[base + i].v = 1; |
phte_real[base + i].vsid = vsid; |
phte_real[base + i].h = h; |
phte_real[base + i].api = api; |
phte_real[base + i].rpn = KA2PA(badvaddr) >> 12; |
phte_real[base + i].r = 0; |
phte_real[base + i].c = 0; |
phte_real[base + i].wimg = 0; |
phte_real[base + i].pp = 2; // FIXME |
return true; |
return false; |
} |
/** Process ITLB/DTLB Miss Exception in Real Mode |
* |
* |
*/ |
void tlb_refill_real(int n, uint32_t tlbmiss, ptehi_t ptehi, ptelo_t ptelo, istate_t *istate) |
{ |
uint32_t badvaddr = tlbmiss & 0xfffffffc; |
uint32_t physmem; |
asm volatile ( |
"mfsprg3 %0\n" |
: "=r" (physmem) |
); |
if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem))) |
return; // FIXME |
ptelo.rpn = KA2PA(badvaddr) >> 12; |
ptelo.wimg = 0; |
ptelo.pp = 2; // FIXME |
uint32_t index = 0; |
asm volatile ( |
"mtspr 981, %0\n" |
"mtspr 982, %1\n" |
"tlbld %2\n" |
"tlbli %2\n" |
: "=r" (index) |
: "r" (ptehi), |
"r" (ptelo) |
); |
} |
void tlb_arch_init(void) |
{ |
tlb_invalidate_all(); |
445,87 → 367,9 |
void tlb_invalidate_all(void) |
{ |
uint32_t index; |
asm volatile ( |
"li %0, 0\n" |
"sync\n" |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
"eieio\n" |
"tlbia\n" |
"tlbsync\n" |
"sync\n" |
: "=r" (index) |
); |
} |
549,7 → 393,7 |
} |
void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt) |
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt) |
{ |
// TODO |
tlb_invalidate_all(); |
594,7 → 438,7 |
: "=r" (vsid) |
: "r" (sr << 28) |
); |
printf("sr[%02u]: vsid=%.*p (asid=%u)%s%s\n", sr, |
printf("vsid[%d]: VSID=%.*p (ASID=%d)%s%s\n", sr, |
sizeof(vsid) * 2, vsid & 0xffffff, (vsid & 0xffffff) >> 4, |
((vsid >> 30) & 1) ? " supervisor" : "", |
((vsid >> 29) & 1) ? " user" : ""); |
/branches/arm/kernel/arch/ppc32/src/mm/page.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc32mm |
/** @addtogroup ppc32mm |
* @{ |
*/ |
/** @file |
49,7 → 49,7 |
{ |
if (last_frame + ALIGN_UP(size, PAGE_SIZE) > |
KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) |
panic("Unable to map physical memory %p (%" PRIs " bytes).", |
panic("Unable to map physical memory %p (%" PRIs " bytes)", |
physaddr, size) |
uintptr_t virtaddr = PA2KA(last_frame); |
/branches/arm/kernel/arch/ppc32/src/mm/frame.c |
---|
57,7 → 57,7 |
void frame_arch_init(void) |
{ |
pfn_t minconf = 2; |
size_t i; |
count_t i; |
pfn_t start, conf; |
size_t size; |
74,7 → 74,7 |
if (last_frame < ALIGN_UP(bootinfo.memmap.zones[i].start + bootinfo.memmap.zones[i].size, FRAME_SIZE)) |
last_frame = ALIGN_UP(bootinfo.memmap.zones[i].start + bootinfo.memmap.zones[i].size, FRAME_SIZE); |
} |
/* First is exception vector, second is 'implementation specific', |
third and fourth is reserved, other contain real mode code */ |
frame_mark_unavailable(0, 8); |
/branches/arm/kernel/arch/ppc32/src/interrupt.c |
---|
60,6 → 60,7 |
int inum; |
while ((inum = pic_get_pending()) != -1) { |
bool ack = false; |
irq_t *irq = irq_dispatch_and_lock(inum); |
if (irq) { |
/* |
68,17 → 69,11 |
if (irq->preack) { |
/* Acknowledge the interrupt before processing */ |
if (irq->cir) |
irq->cir(irq->cir_arg, irq->inr); |
pic_ack_interrupt(inum); |
ack = true; |
} |
irq->handler(irq); |
if (!irq->preack) { |
if (irq->cir) |
irq->cir(irq->cir_arg, irq->inr); |
} |
irq->handler(irq, irq->arg); |
spinlock_unlock(&irq->lock); |
} else { |
/* |
88,6 → 83,9 |
printf("cpu%u: spurious interrupt (inum=%d)\n", CPU->id, inum); |
#endif |
} |
if (!ack) |
pic_ack_interrupt(inum); |
} |
} |
94,8 → 92,8 |
static void exception_decrementer(int n, istate_t *istate) |
{ |
clock(); |
start_decrementer(); |
clock(); |
} |
/branches/arm/kernel/arch/ppc32/src/ppc32.c |
---|
35,8 → 35,7 |
#include <config.h> |
#include <arch.h> |
#include <arch/boot/boot.h> |
#include <genarch/drivers/via-cuda/cuda.h> |
#include <genarch/kbrd/kbrd.h> |
#include <arch/drivers/cuda.h> |
#include <arch/interrupt.h> |
#include <genarch/fb/fb.h> |
#include <genarch/fb/visuals.h> |
43,29 → 42,24 |
#include <userspace.h> |
#include <proc/uarg.h> |
#include <console/console.h> |
#include <ddi/device.h> |
#include <ddi/irq.h> |
#include <arch/drivers/pic.h> |
#include <align.h> |
#include <macros.h> |
#include <string.h> |
#define IRQ_COUNT 64 |
#define IRQ_CUDA 10 |
#define IRQ_COUNT 64 |
bootinfo_t bootinfo; |
/** Performs ppc32-specific initialization before main_bsp() is called. */ |
void arch_pre_main(void) |
{ |
/* Setup usermode */ |
init.cnt = bootinfo.taskmap.count; |
uint32_t i; |
for (i = 0; i < min3(bootinfo.taskmap.count, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS); i++) { |
for (i = 0; i < bootinfo.taskmap.count; i++) { |
init.tasks[i].addr = PA2KA(bootinfo.taskmap.tasks[i].addr); |
init.tasks[i].size = bootinfo.taskmap.tasks[i].size; |
str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN, |
bootinfo.taskmap.tasks[i].name); |
} |
} |
81,43 → 75,36 |
void arch_post_mm_init(void) |
{ |
if (config.cpu_active == 1) { |
#ifdef CONFIG_FB |
/* Initialize framebuffer */ |
if (bootinfo.screen.addr) { |
unsigned int visual; |
switch (bootinfo.screen.bpp) { |
case 8: |
visual = VISUAL_INDIRECT_8; |
break; |
case 16: |
visual = VISUAL_RGB_5_5_5; |
break; |
case 24: |
visual = VISUAL_RGB_8_8_8; |
break; |
case 32: |
visual = VISUAL_RGB_0_8_8_8; |
break; |
default: |
panic("Unsupported bits per pixel."); |
} |
fb_properties_t prop = { |
.addr = bootinfo.screen.addr, |
.offset = 0, |
.x = bootinfo.screen.width, |
.y = bootinfo.screen.height, |
.scan = bootinfo.screen.scanline, |
.visual = visual, |
}; |
fb_init(&prop); |
unsigned int visual; |
switch (bootinfo.screen.bpp) { |
case 8: |
visual = VISUAL_INDIRECT_8; |
break; |
case 16: |
visual = VISUAL_RGB_5_5_5; |
break; |
case 24: |
visual = VISUAL_RGB_8_8_8; |
break; |
case 32: |
visual = VISUAL_RGB_0_8_8_8; |
break; |
default: |
panic("Unsupported bits per pixel"); |
} |
#endif |
fb_init(bootinfo.screen.addr, bootinfo.screen.width, bootinfo.screen.height, bootinfo.screen.scanline, visual); |
/* Initialize IRQ routing */ |
irq_init(IRQ_COUNT, IRQ_COUNT); |
/* Initialize PIC */ |
pic_init(bootinfo.keyboard.addr, PAGE_SIZE); |
/* Initialize I/O controller */ |
cuda_init(device_assign_devno(), bootinfo.keyboard.addr + 0x16000, 2 * PAGE_SIZE); |
/* Merge all zones to 1 big zone */ |
zone_merge_all(); |
} |
133,35 → 120,6 |
void arch_post_smp_init(void) |
{ |
if (bootinfo.macio.addr) { |
/* Initialize PIC */ |
cir_t cir; |
void *cir_arg; |
pic_init(bootinfo.macio.addr, PAGE_SIZE, &cir, &cir_arg); |
#ifdef CONFIG_MAC_KBD |
uintptr_t pa = bootinfo.macio.addr + 0x16000; |
uintptr_t aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE); |
size_t offset = pa - aligned_addr; |
size_t size = 2 * PAGE_SIZE; |
cuda_t *cuda = (cuda_t *) |
(hw_map(aligned_addr, offset + size) + offset); |
/* Initialize I/O controller */ |
cuda_instance_t *cuda_instance = |
cuda_init(cuda, IRQ_CUDA, cir, cir_arg); |
if (cuda_instance) { |
kbrd_instance_t *kbrd_instance = kbrd_init(); |
if (kbrd_instance) { |
indev_t *sink = stdin_wire(); |
indev_t *kbrd = kbrd_wire(kbrd_instance, sink); |
cuda_wire(cuda_instance, kbrd); |
pic_enable_interrupt(IRQ_CUDA); |
} |
} |
#endif |
} |
} |
void calibrate_delay_loop(void) |
170,13 → 128,11 |
void userspace(uspace_arg_t *kernel_uarg) |
{ |
userspace_asm((uintptr_t) kernel_uarg->uspace_uarg, |
(uintptr_t) kernel_uarg->uspace_stack + |
THREAD_STACK_SIZE - SP_DELTA, |
(uintptr_t) kernel_uarg->uspace_entry); |
userspace_asm((uintptr_t) kernel_uarg->uspace_uarg, (uintptr_t) kernel_uarg->uspace_stack + THREAD_STACK_SIZE - SP_DELTA, (uintptr_t) kernel_uarg->uspace_entry); |
/* Unreachable */ |
while (true); |
for (;;) |
; |
} |
/** Acquire console back for kernel |
184,9 → 140,7 |
*/ |
void arch_grab_console(void) |
{ |
#ifdef CONFIG_FB |
fb_redraw(); |
#endif |
cuda_grab(); |
} |
/** Return console to userspace |
194,27 → 148,8 |
*/ |
void arch_release_console(void) |
{ |
cuda_release(); |
} |
/** Construct function pointer |
* |
* @param fptr function pointer structure |
* @param addr function address |
* @param caller calling function address |
* |
* @return address of the function pointer |
* |
*/ |
void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller) |
{ |
return addr; |
} |
void arch_reboot(void) |
{ |
// TODO |
while (1); |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc32/src/drivers/cuda.c |
---|
0,0 → 1,355 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc32 |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/drivers/cuda.h> |
#include <ipc/irq.h> |
#include <arch/asm.h> |
#include <console/console.h> |
#include <console/chardev.h> |
#include <arch/drivers/pic.h> |
#include <sysinfo/sysinfo.h> |
#include <interrupt.h> |
#include <stdarg.h> |
#define CUDA_IRQ 10 |
#define SPECIAL '?' |
#define PACKET_ADB 0x00 |
#define PACKET_CUDA 0x01 |
#define CUDA_POWERDOWN 0x0a |
#define CUDA_RESET 0x11 |
#define RS 0x200 |
#define B (0 * RS) |
#define A (1 * RS) |
#define SR (10 * RS) |
#define ACR (11 * RS) |
#define SR_OUT 0x10 |
#define TACK 0x10 |
#define TIP 0x20 |
static volatile uint8_t *cuda = NULL; |
static irq_t cuda_irq; /**< Cuda's IRQ. */ |
static char lchars[0x80] = { |
'a', |
's', |
'd', |
'f', |
'h', |
'g', |
'z', |
'x', |
'c', |
'v', |
SPECIAL, |
'b', |
'q', |
'w', |
'e', |
'r', |
'y', |
't', |
'1', |
'2', |
'3', |
'4', |
'6', |
'5', |
'=', |
'9', |
'7', |
'-', |
'8', |
'0', |
']', |
'o', |
'u', |
'[', |
'i', |
'p', |
'\n', /* Enter */ |
'l', |
'j', |
'\'', |
'k', |
';', |
'\\', |
',', |
'/', |
'n', |
'm', |
'.', |
'\t', /* Tab */ |
' ', |
'`', |
'\b', /* Backspace */ |
SPECIAL, |
SPECIAL, /* Escape */ |
SPECIAL, /* Ctrl */ |
SPECIAL, /* Alt */ |
SPECIAL, /* Shift */ |
SPECIAL, /* Caps-Lock */ |
SPECIAL, /* RAlt */ |
SPECIAL, /* Left */ |
SPECIAL, /* Right */ |
SPECIAL, /* Down */ |
SPECIAL, /* Up */ |
SPECIAL, |
SPECIAL, |
'.', /* Keypad . */ |
SPECIAL, |
'*', /* Keypad * */ |
SPECIAL, |
'+', /* Keypad + */ |
SPECIAL, |
SPECIAL, /* NumLock */ |
SPECIAL, |
SPECIAL, |
SPECIAL, |
'/', /* Keypad / */ |
'\n', /* Keypad Enter */ |
SPECIAL, |
'-', /* Keypad - */ |
SPECIAL, |
SPECIAL, |
SPECIAL, |
'0', /* Keypad 0 */ |
'1', /* Keypad 1 */ |
'2', /* Keypad 2 */ |
'3', /* Keypad 3 */ |
'4', /* Keypad 4 */ |
'5', /* Keypad 5 */ |
'6', /* Keypad 6 */ |
'7', /* Keypad 7 */ |
SPECIAL, |
'8', /* Keypad 8 */ |
'9', /* Keypad 9 */ |
SPECIAL, |
SPECIAL, |
SPECIAL, |
SPECIAL, /* F5 */ |
SPECIAL, /* F6 */ |
SPECIAL, /* F7 */ |
SPECIAL, /* F3 */ |
SPECIAL, /* F8 */ |
SPECIAL, /* F9 */ |
SPECIAL, |
SPECIAL, /* F11 */ |
SPECIAL, |
SPECIAL, /* F13 */ |
SPECIAL, |
SPECIAL, /* ScrollLock */ |
SPECIAL, |
SPECIAL, /* F10 */ |
SPECIAL, |
SPECIAL, /* F12 */ |
SPECIAL, |
SPECIAL, /* Pause */ |
SPECIAL, /* Insert */ |
SPECIAL, /* Home */ |
SPECIAL, /* PageUp */ |
SPECIAL, /* Delete */ |
SPECIAL, /* F4 */ |
SPECIAL, /* End */ |
SPECIAL, /* F2 */ |
SPECIAL, /* PageDown */ |
SPECIAL /* F1 */ |
}; |
static void receive_packet(uint8_t *kind, index_t count, uint8_t data[]) |
{ |
cuda[B] = cuda[B] & ~TIP; |
*kind = cuda[SR]; |
index_t i; |
for (i = 0; i < count; i++) |
data[i] = cuda[SR]; |
cuda[B] = cuda[B] | TIP; |
} |
/* Called from getc(). */ |
static void cuda_resume(chardev_t *d) |
{ |
} |
/* Called from getc(). */ |
static void cuda_suspend(chardev_t *d) |
{ |
} |
static char key_read(chardev_t *d) |
{ |
char ch; |
ch = 0; |
return ch; |
} |
static chardev_t kbrd; |
static chardev_operations_t ops = { |
.suspend = cuda_suspend, |
.resume = cuda_resume, |
.read = key_read |
}; |
int cuda_get_scancode(void) |
{ |
uint8_t kind; |
uint8_t data[4]; |
receive_packet(&kind, 4, data); |
if ((kind == PACKET_ADB) && (data[0] == 0x40) && (data[1] == 0x2c)) |
return data[2]; |
return -1; |
} |
static void cuda_irq_handler(irq_t *irq, void *arg, ...) |
{ |
if ((irq->notif_cfg.notify) && (irq->notif_cfg.answerbox)) |
ipc_irq_send_notif(irq); |
else { |
int scan_code = cuda_get_scancode(); |
if (scan_code != -1) { |
uint8_t scancode = (uint8_t) scan_code; |
if ((scancode & 0x80) != 0x80) |
chardev_push_character(&kbrd, lchars[scancode & 0x7f]); |
} |
} |
} |
static irq_ownership_t cuda_claim(void) |
{ |
return IRQ_ACCEPT; |
} |
/** Initialize keyboard and service interrupts using kernel routine */ |
void cuda_grab(void) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&cuda_irq.lock); |
cuda_irq.notif_cfg.notify = false; |
spinlock_unlock(&cuda_irq.lock); |
interrupts_restore(ipl); |
} |
/** Resume the former interrupt vector */ |
void cuda_release(void) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&cuda_irq.lock); |
if (cuda_irq.notif_cfg.answerbox) |
cuda_irq.notif_cfg.notify = true; |
spinlock_unlock(&cuda_irq.unlock); |
interrupts_restore(ipl); |
} |
void cuda_init(devno_t devno, uintptr_t base, size_t size) |
{ |
cuda = (uint8_t *) hw_map(base, size); |
chardev_initialize("cuda_kbd", &kbrd, &ops); |
stdin = &kbrd; |
irq_initialize(&cuda_irq); |
cuda_irq.devno = devno; |
cuda_irq.inr = CUDA_IRQ; |
cuda_irq.claim = cuda_claim; |
cuda_irq.handler = cuda_irq_handler; |
irq_register(&cuda_irq); |
pic_enable_interrupt(CUDA_IRQ); |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.devno", NULL, devno); |
sysinfo_set_item_val("kbd.inr", NULL, CUDA_IRQ); |
sysinfo_set_item_val("kbd.address.virtual", NULL, base); |
} |
static void send_packet(const uint8_t kind, count_t count, ...) |
{ |
index_t i; |
va_list va; |
cuda[B] = cuda[B] | TIP; |
cuda[ACR] = cuda[ACR] | SR_OUT; |
cuda[SR] = kind; |
cuda[B] = cuda[B] & ~TIP; |
va_start(va, count); |
for (i = 0; i < count; i++) { |
cuda[ACR] = cuda[ACR] | SR_OUT; |
cuda[SR] = va_arg(va, int); |
cuda[B] = cuda[B] | TACK; |
} |
va_end(va); |
cuda[B] = cuda[B] | TIP; |
} |
void cpu_halt(void) { |
asm volatile ( |
"b 0\n" |
); |
} |
void arch_reboot(void) { |
send_packet(PACKET_CUDA, 1, CUDA_RESET); |
asm volatile ( |
"b 0\n" |
); |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc32/src/drivers/pic.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc32 |
/** @addtogroup ppc32 |
* @{ |
*/ |
/** @file |
38,61 → 38,53 |
#include <byteorder.h> |
#include <bitops.h> |
static volatile uint32_t *pic = NULL; |
static volatile uint32_t *pic; |
void pic_init(uintptr_t base, size_t size, cir_t *cir, void **cir_arg) |
void pic_init(uintptr_t base, size_t size) |
{ |
pic = (uint32_t *) hw_map(base, size); |
*cir = pic_ack_interrupt; |
*cir_arg = NULL; |
} |
void pic_enable_interrupt(inr_t intnum) |
void pic_enable_interrupt(int intnum) |
{ |
if (pic) { |
if (intnum < 32) |
pic[PIC_MASK_LOW] = pic[PIC_MASK_LOW] | (1 << intnum); |
else |
pic[PIC_MASK_HIGH] = pic[PIC_MASK_HIGH] | (1 << (intnum - 32)); |
if (intnum < 32) { |
pic[PIC_MASK_LOW] = pic[PIC_MASK_LOW] | (1 << intnum); |
} else { |
pic[PIC_MASK_HIGH] = pic[PIC_MASK_HIGH] | (1 << (intnum - 32)); |
} |
} |
void pic_disable_interrupt(inr_t intnum) |
void pic_disable_interrupt(int intnum) |
{ |
if (pic) { |
if (intnum < 32) |
pic[PIC_MASK_LOW] = pic[PIC_MASK_LOW] & (~(1 << intnum)); |
else |
pic[PIC_MASK_HIGH] = pic[PIC_MASK_HIGH] & (~(1 << (intnum - 32))); |
if (intnum < 32) { |
pic[PIC_MASK_LOW] = pic[PIC_MASK_LOW] & (~(1 << intnum)); |
} else { |
pic[PIC_MASK_HIGH] = pic[PIC_MASK_HIGH] & (~(1 << (intnum - 32))); |
} |
} |
void pic_ack_interrupt(void *arg, inr_t intnum) |
void pic_ack_interrupt(int intnum) |
{ |
if (pic) { |
if (intnum < 32) |
pic[PIC_ACK_LOW] = 1 << intnum; |
else |
pic[PIC_ACK_HIGH] = 1 << (intnum - 32); |
} |
if (intnum < 32) |
pic[PIC_ACK_LOW] = 1 << intnum; |
else |
pic[PIC_ACK_HIGH] = 1 << (intnum - 32); |
} |
/** Return number of pending interrupt */ |
int pic_get_pending(void) |
{ |
if (pic) { |
int pending; |
pending = pic[PIC_PENDING_LOW]; |
if (pending) |
return fnzb32(pending); |
pending = pic[PIC_PENDING_HIGH]; |
if (pending) |
return fnzb32(pending) + 32; |
} |
int pending; |
pending = pic[PIC_PENDING_LOW]; |
if (pending) |
return fnzb32(pending); |
pending = pic[PIC_PENDING_HIGH]; |
if (pending) |
return fnzb32(pending) + 32; |
return -1; |
} |
/branches/arm/kernel/arch/ppc32/src/exception.S |
---|
60,7 → 60,7 |
2: |
subi sp, sp, 164 |
subi sp, sp, 160 |
stw r0, 8(sp) |
stw r2, 12(sp) |
stw r3, 16(sp) |
109,14 → 109,11 |
mfxer r12 |
stw r12, 148(sp) |
mfdar r12 |
mfsprg1 r12 |
stw r12, 152(sp) |
mfsprg1 r12 |
mfsprg2 r12 |
stw r12, 156(sp) |
mfsprg2 r12 |
stw r12, 160(sp) |
.endm |
.org 0x100 |
140,7 → 137,16 |
exc_data_storage: |
CONTEXT_STORE |
b data_storage |
li r3, 2 |
mr r4, sp |
addi r4, r4, 8 |
bl pht_real_refill |
cmpwi r3, 0 |
bne iret_real |
li r3, 2 |
b jump_to_kernel |
.org 0x400 |
.global exc_instruction_storage |
147,8 → 153,17 |
exc_instruction_storage: |
CONTEXT_STORE |
b instruction_storage |
li r3, 3 |
mr r4, sp |
addi r4, r4, 8 |
bl pht_real_refill |
cmpwi r3, 0 |
bne iret_real |
li r3, 3 |
b jump_to_kernel |
.org 0x500 |
.global exc_external |
exc_external: |
208,7 → 223,7 |
.org 0xc00 |
.global exc_syscall |
exc_syscall: |
CONTEXT_STORE |
CONTEXT_STORE |
b jump_to_kernel_syscall |
220,63 → 235,7 |
li r3, 12 |
b jump_to_kernel |
.org 0x1000 |
.global exc_itlb_miss |
exc_itlb_miss: |
CONTEXT_STORE |
b tlb_miss |
.org 0x1100 |
.global exc_dtlb_miss_load |
exc_dtlb_miss_load: |
CONTEXT_STORE |
b tlb_miss |
.org 0x1200 |
.global exc_dtlb_miss_store |
exc_dtlb_miss_store: |
CONTEXT_STORE |
b tlb_miss |
.org 0x4000 |
data_storage: |
li r3, 2 |
mr r4, sp |
addi r4, r4, 8 |
bl pht_refill_real |
cmpwi r3, 0 |
bne iret_real |
li r3, 2 |
b jump_to_kernel |
instruction_storage: |
li r3, 3 |
mr r4, sp |
addi r4, r4, 8 |
bl pht_refill_real |
cmpwi r3, 0 |
bne iret_real |
li r3, 3 |
b jump_to_kernel |
tlb_miss: |
li r3, 16 |
mfspr r4, tlbmiss |
mfspr r5, ptehi |
mfspr r6, ptelo |
mr r7, sp |
addi r7, r7, 20 |
bl tlb_refill_real |
b iret_real |
jump_to_kernel: |
lis r12, iret@ha |
addi r12, r12, iret@l |
313,6 → 272,7 |
rfi |
iret_real: |
lwz r0, 8(sp) |
lwz r2, 12(sp) |
lwz r3, 16(sp) |
362,7 → 322,7 |
lwz r12, 148(sp) |
mtxer r12 |
lwz r12, 156(sp) |
lwz sp, 160(sp) |
lwz r12, 152(sp) |
lwz sp, 156(sp) |
rfi |
/branches/arm/kernel/arch/ppc32/src/boot/boot.S |
---|
33,7 → 33,7 |
.global kernel_image_start |
kernel_image_start: |
# load temporal kernel stack |
lis sp, kernel_stack@ha |
52,7 → 52,7 |
beq bootinfo_end |
addis r3, r3, 0x8000 |
lis r31, bootinfo@ha |
addi r31, r31, bootinfo@l # r31 = bootinfo |
/branches/arm/kernel/arch/ppc32/src/dummy.s |
---|
30,7 → 30,6 |
.global asm_delay_loop |
.global sys_tls_set |
.global cpu_halt |
sys_tls_set: |
b sys_tls_set |
37,6 → 36,3 |
asm_delay_loop: |
blr |
cpu_halt: |
b cpu_halt |
/branches/arm/kernel/arch/ppc32/_link.ld.in |
---|
1,11 → 1,11 |
/** PPC32 linker script |
* |
* umapped section: |
* kernel text |
* kernel data |
* kernel text |
* kernel data |
* mapped section: |
* kernel text |
* kernel data |
* kernel text |
* kernel data |
* |
*/ |
27,7 → 27,7 |
unmapped_kdata_start = .; |
} |
.mapped PA2KA(BOOT_OFFSET): AT (BOOT_OFFSET) { |
.mapped PA2KA(BOOT_OFFSET): AT (BOOT_OFFSET) { |
ktext_start = .; |
*(K_TEXT_START); |
*(.text); |
37,22 → 37,22 |
*(K_DATA_START); |
*(.rodata); |
*(.rodata.*); |
*(.data); /* initialized data */ |
*(.data); /* initialized data */ |
*(.sdata); |
*(.sdata2); |
*(.sbss); |
hardcoded_ktext_size = .; |
LONG(ktext_end - ktext_start); |
LONG(ktext_end - ktext_start); |
hardcoded_kdata_size = .; |
LONG(kdata_end - kdata_start); |
hardcoded_load_address = .; |
LONG(PA2KA(BOOT_OFFSET)); |
*(.bss); /* uninitialized static variables */ |
*(COMMON); /* global variables */ |
*(.bss); /* uninitialized static variables */ |
*(COMMON); /* global variables */ |
symbol_table = .; |
*(symtab.*); /* Symbol table, must be LAST symbol!*/ |
*(symtab.*); /* Symbol table, must be LAST symbol!*/ |
kdata_end = .; |
} |
} |
/branches/arm/kernel/arch/mips32/src/mm/tlb.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup mips32mm |
/** @addtogroup mips32mm |
* @{ |
*/ |
/** @file |
40,12 → 40,12 |
#include <arch/cp0.h> |
#include <panic.h> |
#include <arch.h> |
#include <synch/mutex.h> |
#include <symtab.h> |
#include <synch/spinlock.h> |
#include <print.h> |
#include <debug.h> |
#include <align.h> |
#include <interrupt.h> |
#include <symtab.h> |
static void tlb_refill_fail(istate_t *); |
static void tlb_invalid_fail(istate_t *); |
92,15 → 92,15 |
uintptr_t badvaddr; |
pte_t *pte; |
int pfrc; |
badvaddr = cp0_badvaddr_read(); |
mutex_lock(&AS->lock); |
spinlock_lock(&AS->lock); |
asid = AS->asid; |
mutex_unlock(&AS->lock); |
spinlock_unlock(&AS->lock); |
page_table_lock(AS, true); |
pte = find_mapping_and_check(badvaddr, PF_ACCESS_READ, istate, &pfrc); |
if (!pte) { |
switch (pfrc) { |
115,7 → 115,7 |
page_table_unlock(AS, true); |
return; |
default: |
panic("Unexpected pfrc (%d).", pfrc); |
panic("unexpected pfrc (%d)\n", pfrc); |
} |
} |
199,7 → 199,7 |
page_table_unlock(AS, true); |
return; |
default: |
panic("Unexpected pfrc (%d).", pfrc); |
panic("unexpected pfrc (%d)\n", pfrc); |
} |
} |
282,7 → 282,7 |
page_table_unlock(AS, true); |
return; |
default: |
panic("Unexpected pfrc (%d).", pfrc); |
panic("unexpected pfrc (%d)\n", pfrc); |
} |
} |
320,14 → 320,19 |
void tlb_refill_fail(istate_t *istate) |
{ |
char *symbol, *sym2; |
char *symbol = ""; |
char *sym2 = ""; |
symbol = symtab_fmt_name_lookup(istate->epc); |
sym2 = symtab_fmt_name_lookup(istate->ra); |
fault_if_from_uspace(istate, "TLB Refill Exception on %p.", |
char *s = get_symtab_entry(istate->epc); |
if (s) |
symbol = s; |
s = get_symtab_entry(istate->ra); |
if (s) |
sym2 = s; |
fault_if_from_uspace(istate, "TLB Refill Exception on %p", |
cp0_badvaddr_read()); |
panic("%x: TLB Refill Exception at %x (%s<-%s).", cp0_badvaddr_read(), |
panic("%x: TLB Refill Exception at %x(%s<-%s)\n", cp0_badvaddr_read(), |
istate->epc, symbol, sym2); |
} |
334,25 → 339,27 |
void tlb_invalid_fail(istate_t *istate) |
{ |
char *symbol; |
char *symbol = ""; |
symbol = symtab_fmt_name_lookup(istate->epc); |
fault_if_from_uspace(istate, "TLB Invalid Exception on %p.", |
char *s = get_symtab_entry(istate->epc); |
if (s) |
symbol = s; |
fault_if_from_uspace(istate, "TLB Invalid Exception on %p", |
cp0_badvaddr_read()); |
panic("%x: TLB Invalid Exception at %x (%s).", cp0_badvaddr_read(), |
panic("%x: TLB Invalid Exception at %x(%s)\n", cp0_badvaddr_read(), |
istate->epc, symbol); |
} |
void tlb_modified_fail(istate_t *istate) |
{ |
char *symbol; |
char *symbol = ""; |
symbol = symtab_fmt_name_lookup(istate->epc); |
fault_if_from_uspace(istate, "TLB Modified Exception on %p.", |
char *s = get_symtab_entry(istate->epc); |
if (s) |
symbol = s; |
fault_if_from_uspace(istate, "TLB Modified Exception on %p", |
cp0_badvaddr_read()); |
panic("%x: TLB Modified Exception at %x (%s).", cp0_badvaddr_read(), |
panic("%x: TLB Modified Exception at %x(%s)\n", cp0_badvaddr_read(), |
istate->epc, symbol); |
} |
422,11 → 429,12 |
break; |
case AS_PF_FAULT: |
page_table_lock(AS, true); |
printf("Page fault.\n"); |
*pfrc = AS_PF_FAULT; |
return NULL; |
break; |
default: |
panic("Unexpected rc (%d).", rc); |
panic("unexpected rc (%d)\n", rc); |
} |
} |
560,7 → 568,7 |
* @param page First page whose TLB entry is to be invalidated. |
* @param cnt Number of entries to invalidate. |
*/ |
void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt) |
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt) |
{ |
unsigned int i; |
ipl_t ipl; |
/branches/arm/kernel/arch/mips32/src/mm/frame.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup mips32mm |
/** @addtogroup mips32mm |
* @{ |
*/ |
/** @file |
40,22 → 40,22 |
#include <mm/asid.h> |
#include <config.h> |
#include <arch/drivers/msim.h> |
#include <arch/drivers/serial.h> |
#include <print.h> |
#define ZERO_PAGE_MASK TLB_PAGE_MASK_256K |
#define ZERO_FRAMES 2048 |
#define ZERO_PAGE_WIDTH 18 /* 256K */ |
#define ZERO_PAGE_SIZE (1 << ZERO_PAGE_WIDTH) |
#define ZERO_PAGE_ASID ASID_INVALID |
#define ZERO_PAGE_TLBI 0 |
#define ZERO_PAGE_ADDR 0 |
#define ZERO_PAGE_OFFSET (ZERO_PAGE_SIZE / sizeof(uint32_t) - 1) |
#define ZERO_PAGE_VALUE (((volatile uint32_t *) ZERO_PAGE_ADDR)[ZERO_PAGE_OFFSET]) |
#define ZERO_PAGE_MASK TLB_PAGE_MASK_256K |
#define ZERO_FRAMES 2048 |
#define ZERO_PAGE_WIDTH 18 /* 256K */ |
#define ZERO_PAGE_SIZE (1 << ZERO_PAGE_WIDTH) |
#define ZERO_PAGE_ASID ASID_INVALID |
#define ZERO_PAGE_TLBI 0 |
#define ZERO_PAGE_ADDR 0 |
#define ZERO_PAGE_OFFSET (ZERO_PAGE_SIZE / sizeof(uint32_t) - 1) |
#define ZERO_PAGE_VALUE (((volatile uint32_t *) ZERO_PAGE_ADDR)[ZERO_PAGE_OFFSET]) |
#define ZERO_PAGE_VALUE_KSEG1(frame) \ |
(((volatile uint32_t *) (0xa0000000 + (frame << ZERO_PAGE_WIDTH)))[ZERO_PAGE_OFFSET]) |
#define ZERO_PAGE_VALUE_KSEG1(frame) (((volatile uint32_t *) (0xa0000000 + (frame << ZERO_PAGE_WIDTH)))[ZERO_PAGE_OFFSET]) |
#define MAX_REGIONS 32 |
#define MAX_REGIONS 32 |
typedef struct { |
pfn_t start; |
62,9 → 62,10 |
pfn_t count; |
} phys_region_t; |
static size_t phys_regions_count = 0; |
static count_t phys_regions_count = 0; |
static phys_region_t phys_regions[MAX_REGIONS]; |
/** Check whether frame is available |
* |
* Returns true if given frame is generally available for use. |
74,7 → 75,7 |
*/ |
static bool frame_available(pfn_t frame) |
{ |
#ifdef MACHINE_msim |
#if MACHINE == msim |
/* MSIM device (dprinter) */ |
if (frame == (KA2PA(MSIM_VIDEORAM) >> ZERO_PAGE_WIDTH)) |
return false; |
83,8 → 84,14 |
if (frame == (KA2PA(MSIM_KBD_ADDRESS) >> ZERO_PAGE_WIDTH)) |
return false; |
#endif |
#if defined(MACHINE_lgxemul) || defined(MACHINE_bgxemul) |
#if MACHINE == simics |
/* Simics device (serial line) */ |
if (frame == (KA2PA(SERIAL_ADDRESS) >> ZERO_PAGE_WIDTH)) |
return false; |
#endif |
#if (MACHINE == lgxemul) || (MACHINE == bgxemul) |
/* gxemul devices */ |
if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE, |
0x10000000, MB2SIZE(256))) |
119,7 → 126,7 |
/* Init tasks */ |
bool safe = true; |
size_t i; |
count_t i; |
for (i = 0; i < init.cnt; i++) |
if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE, |
KA2PA(init.tasks[i].addr), init.tasks[i].size)) { |
174,7 → 181,7 |
cp0_entry_lo1_write(0); |
cp0_entry_hi_write(0); |
size_t i; |
count_t i; |
for (i = 0; i < TLB_ENTRY_COUNT; i++) { |
cp0_index_write(i); |
tlbwi(); |
211,7 → 218,7 |
ZERO_PAGE_VALUE = 0xdeadbeef; |
if (ZERO_PAGE_VALUE != 0xdeadbeef) |
avail = false; |
#if defined(MACHINE_lgxemul) || defined(MACHINE_bgxemul) |
#if (MACHINE == lgxemul) || (MACHINE == bgxemul) |
else { |
ZERO_PAGE_VALUE_KSEG1(frame) = 0xaabbccdd; |
if (ZERO_PAGE_VALUE_KSEG1(frame) != 0xaabbccdd) |
251,7 → 258,7 |
printf("Base Size\n"); |
printf("---------- ----------\n"); |
size_t i; |
count_t i; |
for (i = 0; i < phys_regions_count; i++) { |
printf("%#010x %10u\n", |
PFN2ADDR(phys_regions[i].start), PFN2ADDR(phys_regions[i].count)); |
/branches/arm/kernel/arch/mips32/src/mm/page.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup mips32mm |
/** @addtogroup mips32mm |
* @{ |
*/ |
/** @file |
35,7 → 35,6 |
#include <arch/mm/page.h> |
#include <genarch/mm/page_pt.h> |
#include <mm/page.h> |
#include <mm/frame.h> |
void page_arch_init(void) |
{ |
/branches/arm/kernel/arch/mips32/src/asm.S |
---|
27,17 → 27,17 |
# |
#include <arch/asm/regname.h> |
.text |
.macro cp0_read reg |
mfc0 $2, \reg |
mfc0 $2,\reg |
j $31 |
nop |
.endm |
.macro cp0_write reg |
mtc0 $4, \reg |
mtc0 $4,\reg |
j $31 |
nop |
.endm |
46,11 → 46,6 |
.set noreorder |
.set nomacro |
.global asm_delay_loop |
asm_delay_loop: |
j $31 |
nop |
.global cpu_halt |
cpu_halt: |
j cpu_halt |
63,12 → 58,6 |
nop |
.global memsetw |
memsetw: |
j _memsetw |
nop |
.global memcpy |
.global memcpy_from_uspace |
.global memcpy_to_uspace |
77,238 → 66,235 |
memcpy: |
memcpy_from_uspace: |
memcpy_to_uspace: |
move $t2, $a0 # save dst |
addiu $v0, $a1, 3 |
li $v1, -4 # 0xfffffffffffffffc |
and $v0, $v0, $v1 |
beq $a1, $v0, 3f |
move $t0, $a0 |
0: |
beq $a2, $zero, 2f |
move $a3, $zero |
1: |
addu $v0, $a1, $a3 |
lbu $a0, 0($v0) |
addu $v1, $t0, $a3 |
addiu $a3, $a3, 1 |
bne $a3, $a2, 1b |
sb $a0, 0($v1) |
2: |
jr $ra |
move $v0, $t2 |
3: |
addiu $v0, $a0, 3 |
and $v0, $v0, $v1 |
bne $a0, $v0, 0b |
srl $t1, $a2, 2 |
beq $t1, $zero, 5f |
move $a3, $zero |
move $a3, $zero |
move $a0, $zero |
4: |
addu $v0, $a1, $a0 |
lw $v1, 0($v0) |
addiu $a3, $a3, 1 |
addu $v0, $t0, $a0 |
sw $v1, 0($v0) |
bne $a3, $t1, 4b |
addiu $a0, $a0, 4 |
5: |
andi $a2, $a2, 0x3 |
beq $a2, $zero, 2b |
nop |
sll $v0, $a3, 2 |
addu $t1, $v0, $t0 |
move $a3, $zero |
addu $t0, $v0, $a1 |
6: |
addu $v0, $t0, $a3 |
lbu $a0, 0($v0) |
addu $v1, $t1, $a3 |
addiu $a3, $a3, 1 |
bne $a3, $a2, 6b |
sb $a0, 0($v1) |
jr $ra |
move $v0, $t2 |
addiu $v0,$a1,3 |
li $v1,-4 # 0xfffffffffffffffc |
and $v0,$v0,$v1 |
beq $a1,$v0,3f |
move $t0,$a0 |
move $t2,$a0 # save dst |
0: |
beq $a2,$zero,2f |
move $a3,$zero |
1: |
addu $v0,$a1,$a3 |
lbu $a0,0($v0) |
addu $v1,$t0,$a3 |
addiu $a3,$a3,1 |
bne $a3,$a2,1b |
sb $a0,0($v1) |
2: |
jr $ra |
move $v0,$t2 |
3: |
addiu $v0,$a0,3 |
and $v0,$v0,$v1 |
bne $a0,$v0,0b |
srl $t1,$a2,2 |
beq $t1,$zero,5f |
move $a3,$zero |
move $a3,$zero |
move $a0,$zero |
4: |
addu $v0,$a1,$a0 |
lw $v1,0($v0) |
addiu $a3,$a3,1 |
addu $v0,$t0,$a0 |
sw $v1,0($v0) |
bne $a3,$t1,4b |
addiu $a0,$a0,4 |
5: |
andi $a2,$a2,0x3 |
beq $a2,$zero,2b |
nop |
sll $v0,$a3,2 |
addu $t1,$v0,$t0 |
move $a3,$zero |
addu $t0,$v0,$a1 |
6: |
addu $v0,$t0,$a3 |
lbu $a0,0($v0) |
addu $v1,$t1,$a3 |
addiu $a3,$a3,1 |
bne $a3,$a2,6b |
sb $a0,0($v1) |
jr $ra |
move $v0,$t2 |
memcpy_from_uspace_failover_address: |
memcpy_to_uspace_failover_address: |
jr $ra |
move $v0, $zero |
jr $ra |
move $v0, $zero |
.macro fpu_gp_save reg ctx |
mfc1 $t0, $\reg |
sw $t0, \reg * 4(\ctx) |
mfc1 $t0,$\reg |
sw $t0, \reg*4(\ctx) |
.endm |
.macro fpu_gp_restore reg ctx |
lw $t0, \reg * 4(\ctx) |
mtc1 $t0, $\reg |
lw $t0, \reg*4(\ctx) |
mtc1 $t0,$\reg |
.endm |
.macro fpu_ct_save reg ctx |
cfc1 $t0, $1 |
sw $t0, (\reg + 32) * 4(\ctx) |
cfc1 $t0,$1 |
sw $t0, (\reg+32)*4(\ctx) |
.endm |
.macro fpu_ct_restore reg ctx |
lw $t0, (\reg + 32) * 4(\ctx) |
ctc1 $t0, $\reg |
lw $t0, (\reg+32)*4(\ctx) |
ctc1 $t0,$\reg |
.endm |
.global fpu_context_save |
fpu_context_save: |
#ifdef CONFIG_FPU |
fpu_gp_save 0, $a0 |
fpu_gp_save 1, $a0 |
fpu_gp_save 2, $a0 |
fpu_gp_save 3, $a0 |
fpu_gp_save 4, $a0 |
fpu_gp_save 5, $a0 |
fpu_gp_save 6, $a0 |
fpu_gp_save 7, $a0 |
fpu_gp_save 8, $a0 |
fpu_gp_save 9, $a0 |
fpu_gp_save 10, $a0 |
fpu_gp_save 11, $a0 |
fpu_gp_save 12, $a0 |
fpu_gp_save 13, $a0 |
fpu_gp_save 14, $a0 |
fpu_gp_save 15, $a0 |
fpu_gp_save 16, $a0 |
fpu_gp_save 17, $a0 |
fpu_gp_save 18, $a0 |
fpu_gp_save 19, $a0 |
fpu_gp_save 20, $a0 |
fpu_gp_save 21, $a0 |
fpu_gp_save 22, $a0 |
fpu_gp_save 23, $a0 |
fpu_gp_save 24, $a0 |
fpu_gp_save 25, $a0 |
fpu_gp_save 26, $a0 |
fpu_gp_save 27, $a0 |
fpu_gp_save 28, $a0 |
fpu_gp_save 29, $a0 |
fpu_gp_save 30, $a0 |
fpu_gp_save 31, $a0 |
fpu_ct_save 1, $a0 |
fpu_ct_save 2, $a0 |
fpu_ct_save 3, $a0 |
fpu_ct_save 4, $a0 |
fpu_ct_save 5, $a0 |
fpu_ct_save 6, $a0 |
fpu_ct_save 7, $a0 |
fpu_ct_save 8, $a0 |
fpu_ct_save 9, $a0 |
fpu_ct_save 10, $a0 |
fpu_ct_save 11, $a0 |
fpu_ct_save 12, $a0 |
fpu_ct_save 13, $a0 |
fpu_ct_save 14, $a0 |
fpu_ct_save 15, $a0 |
fpu_ct_save 16, $a0 |
fpu_ct_save 17, $a0 |
fpu_ct_save 18, $a0 |
fpu_ct_save 19, $a0 |
fpu_ct_save 20, $a0 |
fpu_ct_save 21, $a0 |
fpu_ct_save 22, $a0 |
fpu_ct_save 23, $a0 |
fpu_ct_save 24, $a0 |
fpu_ct_save 25, $a0 |
fpu_ct_save 26, $a0 |
fpu_ct_save 27, $a0 |
fpu_ct_save 28, $a0 |
fpu_ct_save 29, $a0 |
fpu_ct_save 30, $a0 |
fpu_ct_save 31, $a0 |
#endif |
#ifdef ARCH_HAS_FPU |
fpu_gp_save 0,$a0 |
fpu_gp_save 1,$a0 |
fpu_gp_save 2,$a0 |
fpu_gp_save 3,$a0 |
fpu_gp_save 4,$a0 |
fpu_gp_save 5,$a0 |
fpu_gp_save 6,$a0 |
fpu_gp_save 7,$a0 |
fpu_gp_save 8,$a0 |
fpu_gp_save 9,$a0 |
fpu_gp_save 10,$a0 |
fpu_gp_save 11,$a0 |
fpu_gp_save 12,$a0 |
fpu_gp_save 13,$a0 |
fpu_gp_save 14,$a0 |
fpu_gp_save 15,$a0 |
fpu_gp_save 16,$a0 |
fpu_gp_save 17,$a0 |
fpu_gp_save 18,$a0 |
fpu_gp_save 19,$a0 |
fpu_gp_save 20,$a0 |
fpu_gp_save 21,$a0 |
fpu_gp_save 22,$a0 |
fpu_gp_save 23,$a0 |
fpu_gp_save 24,$a0 |
fpu_gp_save 25,$a0 |
fpu_gp_save 26,$a0 |
fpu_gp_save 27,$a0 |
fpu_gp_save 28,$a0 |
fpu_gp_save 29,$a0 |
fpu_gp_save 30,$a0 |
fpu_gp_save 31,$a0 |
fpu_ct_save 1,$a0 |
fpu_ct_save 2,$a0 |
fpu_ct_save 3,$a0 |
fpu_ct_save 4,$a0 |
fpu_ct_save 5,$a0 |
fpu_ct_save 6,$a0 |
fpu_ct_save 7,$a0 |
fpu_ct_save 8,$a0 |
fpu_ct_save 9,$a0 |
fpu_ct_save 10,$a0 |
fpu_ct_save 11,$a0 |
fpu_ct_save 12,$a0 |
fpu_ct_save 13,$a0 |
fpu_ct_save 14,$a0 |
fpu_ct_save 15,$a0 |
fpu_ct_save 16,$a0 |
fpu_ct_save 17,$a0 |
fpu_ct_save 18,$a0 |
fpu_ct_save 19,$a0 |
fpu_ct_save 20,$a0 |
fpu_ct_save 21,$a0 |
fpu_ct_save 22,$a0 |
fpu_ct_save 23,$a0 |
fpu_ct_save 24,$a0 |
fpu_ct_save 25,$a0 |
fpu_ct_save 26,$a0 |
fpu_ct_save 27,$a0 |
fpu_ct_save 28,$a0 |
fpu_ct_save 29,$a0 |
fpu_ct_save 30,$a0 |
fpu_ct_save 31,$a0 |
#endif |
j $ra |
nop |
.global fpu_context_restore |
fpu_context_restore: |
#ifdef CONFIG_FPU |
fpu_gp_restore 0, $a0 |
fpu_gp_restore 1, $a0 |
fpu_gp_restore 2, $a0 |
fpu_gp_restore 3, $a0 |
fpu_gp_restore 4, $a0 |
fpu_gp_restore 5, $a0 |
fpu_gp_restore 6, $a0 |
fpu_gp_restore 7, $a0 |
fpu_gp_restore 8, $a0 |
fpu_gp_restore 9, $a0 |
fpu_gp_restore 10, $a0 |
fpu_gp_restore 11, $a0 |
fpu_gp_restore 12, $a0 |
fpu_gp_restore 13, $a0 |
fpu_gp_restore 14, $a0 |
fpu_gp_restore 15, $a0 |
fpu_gp_restore 16, $a0 |
fpu_gp_restore 17, $a0 |
fpu_gp_restore 18, $a0 |
fpu_gp_restore 19, $a0 |
fpu_gp_restore 20, $a0 |
fpu_gp_restore 21, $a0 |
fpu_gp_restore 22, $a0 |
fpu_gp_restore 23, $a0 |
fpu_gp_restore 24, $a0 |
fpu_gp_restore 25, $a0 |
fpu_gp_restore 26, $a0 |
fpu_gp_restore 27, $a0 |
fpu_gp_restore 28, $a0 |
fpu_gp_restore 29, $a0 |
fpu_gp_restore 30, $a0 |
fpu_gp_restore 31, $a0 |
fpu_ct_restore 1, $a0 |
fpu_ct_restore 2, $a0 |
fpu_ct_restore 3, $a0 |
fpu_ct_restore 4, $a0 |
fpu_ct_restore 5, $a0 |
fpu_ct_restore 6, $a0 |
fpu_ct_restore 7, $a0 |
fpu_ct_restore 8, $a0 |
fpu_ct_restore 9, $a0 |
fpu_ct_restore 10, $a0 |
fpu_ct_restore 11, $a0 |
fpu_ct_restore 12, $a0 |
fpu_ct_restore 13, $a0 |
fpu_ct_restore 14, $a0 |
fpu_ct_restore 15, $a0 |
fpu_ct_restore 16, $a0 |
fpu_ct_restore 17, $a0 |
fpu_ct_restore 18, $a0 |
fpu_ct_restore 19, $a0 |
fpu_ct_restore 20, $a0 |
fpu_ct_restore 21, $a0 |
fpu_ct_restore 22, $a0 |
fpu_ct_restore 23, $a0 |
fpu_ct_restore 24, $a0 |
fpu_ct_restore 25, $a0 |
fpu_ct_restore 26, $a0 |
fpu_ct_restore 27, $a0 |
fpu_ct_restore 28, $a0 |
fpu_ct_restore 29, $a0 |
fpu_ct_restore 30, $a0 |
fpu_ct_restore 31, $a0 |
#endif |
#ifdef ARCH_HAS_FPU |
fpu_gp_restore 0,$a0 |
fpu_gp_restore 1,$a0 |
fpu_gp_restore 2,$a0 |
fpu_gp_restore 3,$a0 |
fpu_gp_restore 4,$a0 |
fpu_gp_restore 5,$a0 |
fpu_gp_restore 6,$a0 |
fpu_gp_restore 7,$a0 |
fpu_gp_restore 8,$a0 |
fpu_gp_restore 9,$a0 |
fpu_gp_restore 10,$a0 |
fpu_gp_restore 11,$a0 |
fpu_gp_restore 12,$a0 |
fpu_gp_restore 13,$a0 |
fpu_gp_restore 14,$a0 |
fpu_gp_restore 15,$a0 |
fpu_gp_restore 16,$a0 |
fpu_gp_restore 17,$a0 |
fpu_gp_restore 18,$a0 |
fpu_gp_restore 19,$a0 |
fpu_gp_restore 20,$a0 |
fpu_gp_restore 21,$a0 |
fpu_gp_restore 22,$a0 |
fpu_gp_restore 23,$a0 |
fpu_gp_restore 24,$a0 |
fpu_gp_restore 25,$a0 |
fpu_gp_restore 26,$a0 |
fpu_gp_restore 27,$a0 |
fpu_gp_restore 28,$a0 |
fpu_gp_restore 29,$a0 |
fpu_gp_restore 30,$a0 |
fpu_gp_restore 31,$a0 |
fpu_ct_restore 1,$a0 |
fpu_ct_restore 2,$a0 |
fpu_ct_restore 3,$a0 |
fpu_ct_restore 4,$a0 |
fpu_ct_restore 5,$a0 |
fpu_ct_restore 6,$a0 |
fpu_ct_restore 7,$a0 |
fpu_ct_restore 8,$a0 |
fpu_ct_restore 9,$a0 |
fpu_ct_restore 10,$a0 |
fpu_ct_restore 11,$a0 |
fpu_ct_restore 12,$a0 |
fpu_ct_restore 13,$a0 |
fpu_ct_restore 14,$a0 |
fpu_ct_restore 15,$a0 |
fpu_ct_restore 16,$a0 |
fpu_ct_restore 17,$a0 |
fpu_ct_restore 18,$a0 |
fpu_ct_restore 19,$a0 |
fpu_ct_restore 20,$a0 |
fpu_ct_restore 21,$a0 |
fpu_ct_restore 22,$a0 |
fpu_ct_restore 23,$a0 |
fpu_ct_restore 24,$a0 |
fpu_ct_restore 25,$a0 |
fpu_ct_restore 26,$a0 |
fpu_ct_restore 27,$a0 |
fpu_ct_restore 28,$a0 |
fpu_ct_restore 29,$a0 |
fpu_ct_restore 30,$a0 |
fpu_ct_restore 31,$a0 |
#endif |
j $ra |
nop |
/branches/arm/kernel/arch/mips32/src/drivers/msim.c |
---|
0,0 → 1,171 |
/* |
* Copyright (c) 2005 Ondrej Palkovsky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup mips32 |
* @{ |
*/ |
/** @file |
*/ |
#include <interrupt.h> |
#include <ipc/irq.h> |
#include <console/chardev.h> |
#include <arch/drivers/msim.h> |
#include <arch/cp0.h> |
#include <console/console.h> |
#include <sysinfo/sysinfo.h> |
#include <ddi/ddi.h> |
static parea_t msim_parea; |
static chardev_t console; |
static irq_t msim_irq; |
static void msim_write(chardev_t *dev, const char ch); |
static void msim_enable(chardev_t *dev); |
static void msim_disable(chardev_t *dev); |
static char msim_do_read(chardev_t *dev); |
static chardev_operations_t msim_ops = { |
.resume = msim_enable, |
.suspend = msim_disable, |
.write = msim_write, |
.read = msim_do_read, |
}; |
/** Putchar that works with MSIM & gxemul */ |
void msim_write(chardev_t *dev, const char ch) |
{ |
*((char *) MSIM_VIDEORAM) = ch; |
} |
/* Called from getc(). */ |
void msim_enable(chardev_t *dev) |
{ |
cp0_unmask_int(MSIM_KBD_IRQ); |
} |
/* Called from getc(). */ |
void msim_disable(chardev_t *dev) |
{ |
cp0_mask_int(MSIM_KBD_IRQ); |
} |
#include <print.h> |
/** Read character using polling, assume interrupts disabled */ |
static char msim_do_read(chardev_t *dev) |
{ |
char ch; |
while (1) { |
ch = *((volatile char *) MSIM_KBD_ADDRESS); |
if (ch) { |
if (ch == '\r') |
return '\n'; |
if (ch == 0x7f) |
return '\b'; |
return ch; |
} |
} |
} |
/** Process keyboard interrupt. */ |
static void msim_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 *) MSIM_KBD_ADDRESS); |
if (ch =='\r') |
ch = '\n'; |
if (ch == 0x7f) |
ch = '\b'; |
chardev_push_character(&console, ch); |
} |
} |
static irq_ownership_t msim_claim(void) |
{ |
return IRQ_ACCEPT; |
} |
void msim_kbd_grab(void) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&msim_irq.lock); |
msim_irq.notif_cfg.notify = false; |
spinlock_unlock(&msim_irq.lock); |
interrupts_restore(ipl); |
} |
void msim_kbd_release(void) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&msim_irq.lock); |
if (msim_irq.notif_cfg.answerbox) |
msim_irq.notif_cfg.notify = true; |
spinlock_unlock(&msim_irq.lock); |
interrupts_restore(ipl); |
} |
/* Return console object representing msim console */ |
void msim_console(devno_t devno) |
{ |
chardev_initialize("msim_console", &console, &msim_ops); |
stdin = &console; |
stdout = &console; |
irq_initialize(&msim_irq); |
msim_irq.devno = devno; |
msim_irq.inr = MSIM_KBD_IRQ; |
msim_irq.claim = msim_claim; |
msim_irq.handler = msim_irq_handler; |
irq_register(&msim_irq); |
cp0_unmask_int(MSIM_KBD_IRQ); |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.devno", NULL, devno); |
sysinfo_set_item_val("kbd.inr", NULL, MSIM_KBD_IRQ); |
sysinfo_set_item_val("kbd.address.virtual", NULL, MSIM_KBD_ADDRESS); |
msim_parea.pbase = KA2PA(MSIM_VIDEORAM); |
msim_parea.vbase = MSIM_VIDEORAM; |
msim_parea.frames = 1; |
msim_parea.cacheable = false; |
ddi_parea_register(&msim_parea); |
sysinfo_set_item_val("fb", NULL, true); |
sysinfo_set_item_val("fb.kind", NULL, 3); |
sysinfo_set_item_val("fb.address.physical", NULL, KA2PA(MSIM_VIDEORAM)); |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/mips32/src/drivers/serial.c |
---|
0,0 → 1,159 |
/* |
* Copyright (c) 2005 Ondrej Palkovsky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup mips32 |
* @{ |
*/ |
/** @file |
*/ |
#include <interrupt.h> |
#include <arch/cp0.h> |
#include <ipc/irq.h> |
#include <arch/drivers/serial.h> |
#include <console/chardev.h> |
#include <console/console.h> |
#define SERIAL_IRQ 2 |
static irq_t serial_irq; |
static chardev_t console; |
static serial_t sconf[SERIAL_MAX]; |
static bool kb_enabled; |
static void serial_write(chardev_t *d, const char ch) |
{ |
serial_t *sd = (serial_t *)d->data; |
if (ch == '\n') |
serial_write(d, '\r'); |
/* Wait until transmit buffer empty */ |
while (! (SERIAL_READ_LSR(sd->port) & (1<<TRANSMIT_EMPTY_BIT))) |
; |
SERIAL_WRITE(sd->port, ch); |
} |
static void serial_enable(chardev_t *d) |
{ |
kb_enabled = true; |
} |
static void serial_disable(chardev_t *d) |
{ |
kb_enabled = false; |
} |
int serial_init(void) |
{ |
int i = 0; |
if (SERIAL_READ_LSR(SERIAL_COM1) == 0x60) { |
sconf[i].port = SERIAL_COM1; |
sconf[i].irq = SERIAL_COM1_IRQ; |
/* Enable interrupt on available data */ |
i++; |
} |
return i; |
} |
/** Read character from serial port, wait until available */ |
static char serial_do_read(chardev_t *dev) |
{ |
serial_t *sd = (serial_t *)dev->data; |
char ch; |
while (!(SERIAL_READ_LSR(sd->port) & 1)) |
; |
ch = SERIAL_READ(sd->port); |
if (ch =='\r') |
ch = '\n'; |
return ch; |
} |
static void serial_handler(void) |
{ |
serial_t *sd = (serial_t *) console.data; |
char ch; |
if (!(SERIAL_READ_LSR(sd->port) & 1)) |
return; |
ch = SERIAL_READ(sd->port); |
if (ch =='\r') |
ch = '\n'; |
chardev_push_character(&console, ch); |
} |
/** Process keyboard interrupt. Does not work in simics? */ |
static void serial_irq_handler(irq_t *irq, void *arg, ...) |
{ |
if ((irq->notif_cfg.notify) && (irq->notif_cfg.answerbox)) |
ipc_irq_send_notif(irq); |
else |
serial_handler(); |
} |
static irq_ownership_t serial_claim(void) |
{ |
return IRQ_ACCEPT; |
} |
static chardev_operations_t serial_ops = { |
.resume = serial_enable, |
.suspend = serial_disable, |
.write = serial_write, |
.read = serial_do_read |
}; |
void serial_console(devno_t devno) |
{ |
serial_t *sd = &sconf[0]; |
chardev_initialize("serial_console", &console, &serial_ops); |
console.data = sd; |
kb_enabled = true; |
irq_initialize(&serial_irq); |
serial_irq.devno = devno; |
serial_irq.inr = SERIAL_IRQ; |
serial_irq.claim = serial_claim; |
serial_irq.handler = serial_irq_handler; |
irq_register(&serial_irq); |
/* I don't know why, but the serial interrupts simply |
* don't work on simics |
*/ |
virtual_timer_fnc = &serial_handler; |
stdin = &console; |
stdout = &console; |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/mips32/src/console.c |
---|
0,0 → 1,65 |
/* |
* Copyright (c) 2005 Ondrej Palkovsky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup mips32 |
* @{ |
*/ |
/** @file |
*/ |
#include <console/console.h> |
#include <arch/console.h> |
#include <arch/drivers/serial.h> |
#include <arch/drivers/msim.h> |
void console_init(devno_t devno) |
{ |
if (serial_init()) |
serial_console(devno); |
else |
msim_console(devno); |
} |
/** Acquire console back for kernel |
* |
*/ |
void arch_grab_console(void) |
{ |
msim_kbd_grab(); |
} |
/** Return console to userspace |
* |
*/ |
void arch_release_console(void) |
{ |
msim_kbd_release(); |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/mips32/src/mips32.c |
---|
33,17 → 33,20 |
*/ |
#include <arch.h> |
#include <arch/boot.h> |
#include <arch/cp0.h> |
#include <arch/exception.h> |
#include <mm/as.h> |
#include <userspace.h> |
#include <arch/console.h> |
#include <memstr.h> |
#include <proc/thread.h> |
#include <proc/uarg.h> |
#include <print.h> |
#include <console/console.h> |
#include <syscall/syscall.h> |
#include <sysinfo/sysinfo.h> |
#include <arch/interrupt.h> |
#include <console/chardev.h> |
#include <arch/barrier.h> |
50,51 → 53,39 |
#include <arch/debugger.h> |
#include <genarch/fb/fb.h> |
#include <genarch/fb/visuals.h> |
#include <genarch/drivers/dsrln/dsrlnin.h> |
#include <genarch/drivers/dsrln/dsrlnout.h> |
#include <genarch/srln/srln.h> |
#include <macros.h> |
#include <config.h> |
#include <string.h> |
#include <arch/drivers/msim.h> |
#include <ddi/device.h> |
#include <arch/asm/regname.h> |
/* Size of the code jumping to the exception handler code |
* - J+NOP |
/* Size of the code jumping to the exception handler code |
* - J+NOP |
*/ |
#define EXCEPTION_JUMP_SIZE 8 |
#define EXCEPTION_JUMP_SIZE 8 |
#define TLB_EXC ((char *) 0x80000000) |
#define NORM_EXC ((char *) 0x80000180) |
#define CACHE_EXC ((char *) 0x80000100) |
#define TLB_EXC ((char *) 0x80000000) |
#define NORM_EXC ((char *) 0x80000180) |
#define CACHE_EXC ((char *) 0x80000100) |
/* Why the linker moves the variable 64K away in assembler |
* when not in .text section? |
* when not in .text section ???????? |
*/ |
uintptr_t supervisor_sp __attribute__ ((section (".text"))); |
/* Stack pointer saved when entering user mode */ |
uintptr_t supervisor_sp __attribute__ ((section (".text"))); |
/* TODO: How do we do it on SMP system???? */ |
bootinfo_t bootinfo __attribute__ ((section (".text"))); |
size_t cpu_count = 0; |
/** Performs mips32-specific initialization before main_bsp() is called. */ |
void arch_pre_main(void *entry __attribute__((unused)), bootinfo_t *bootinfo) |
void arch_pre_main(void) |
{ |
/* Setup usermode */ |
init.cnt = bootinfo->cnt; |
init.cnt = bootinfo.cnt; |
size_t i; |
for (i = 0; i < min3(bootinfo->cnt, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS); i++) { |
init.tasks[i].addr = bootinfo->tasks[i].addr; |
init.tasks[i].size = bootinfo->tasks[i].size; |
str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN, |
bootinfo->tasks[i].name); |
} |
uint32_t i; |
for (i = 0; i < CPUMAP_MAX_RECORDS; i++) { |
if ((bootinfo->cpumap & (1 << i)) != 0) |
cpu_count++; |
for (i = 0; i < bootinfo.cnt; i++) { |
init.tasks[i].addr = bootinfo.tasks[i].addr; |
init.tasks[i].size = bootinfo.tasks[i].size; |
} |
} |
120,12 → 111,12 |
*/ |
cp0_status_write(cp0_status_read() & |
~(cp0_status_bev_bootstrap_bit | cp0_status_erl_error_bit)); |
/* |
* Mask all interrupts |
/* |
* Mask all interrupts |
*/ |
cp0_mask_all_int(); |
debugger_init(); |
} |
132,23 → 123,12 |
void arch_post_mm_init(void) |
{ |
interrupt_init(); |
console_init(device_assign_devno()); |
#ifdef CONFIG_FB |
/* GXemul framebuffer */ |
fb_properties_t gxemul_prop = { |
.addr = 0x12000000, |
.offset = 0, |
.x = 640, |
.y = 480, |
.scan = 1920, |
.visual = VISUAL_BGR_8_8_8, |
}; |
fb_init(&gxemul_prop); |
#else |
#ifdef CONFIG_MIPS_PRN |
dsrlnout_init((ioport8_t *) MSIM_KBD_ADDRESS); |
#endif /* CONFIG_MIPS_PRN */ |
#endif /* CONFIG_FB */ |
fb_init(0x12000000, 640, 480, 1920, VISUAL_RGB_8_8_8); |
#endif |
sysinfo_set_item_val("machine." STRING(MACHINE), NULL, 1); |
} |
void arch_post_cpu_init(void) |
161,37 → 141,8 |
void arch_post_smp_init(void) |
{ |
#ifdef CONFIG_MIPS_KBD |
/* |
* Initialize the msim/GXemul keyboard port. Then initialize the serial line |
* module and connect it to the msim/GXemul keyboard. Enable keyboard interrupts. |
*/ |
dsrlnin_instance_t *dsrlnin_instance |
= dsrlnin_init((dsrlnin_t *) MSIM_KBD_ADDRESS, MSIM_KBD_IRQ); |
if (dsrlnin_instance) { |
srln_instance_t *srln_instance = srln_init(); |
if (srln_instance) { |
indev_t *sink = stdin_wire(); |
indev_t *srln = srln_wire(srln_instance, sink); |
dsrlnin_wire(dsrlnin_instance, srln); |
cp0_unmask_int(MSIM_KBD_IRQ); |
} |
} |
/* |
* This is the necessary evil until the userspace driver is entirely |
* self-sufficient. |
*/ |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.inr", NULL, MSIM_KBD_IRQ); |
sysinfo_set_item_val("kbd.address.virtual", NULL, MSIM_KBD_ADDRESS); |
#endif |
} |
void calibrate_delay_loop(void) |
{ |
} |
void userspace(uspace_arg_t *kernel_uarg) |
{ |
/* EXL = 1, UM = 1, IE = 1 */ |
202,7 → 153,8 |
(uintptr_t) kernel_uarg->uspace_uarg, |
(uintptr_t) kernel_uarg->uspace_entry); |
while (1); |
while (1) |
; |
} |
/** Perform mips32 specific tasks needed before the new task is run. */ |
234,36 → 186,10 |
void arch_reboot(void) |
{ |
___halt(); |
while (1); |
while (1) |
; |
} |
/** Construct function pointer |
* |
* @param fptr function pointer structure |
* @param addr function address |
* @param caller calling function address |
* |
* @return address of the function pointer |
* |
*/ |
void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller) |
{ |
return addr; |
} |
void arch_grab_console(void) |
{ |
#ifdef CONFIG_FB |
fb_redraw(); |
#endif |
} |
/** Return console to userspace |
* |
*/ |
void arch_release_console(void) |
{ |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/mips32/src/interrupt.c |
---|
41,9 → 41,8 |
#include <ipc/sysipc.h> |
#include <ddi/device.h> |
#define IRQ_COUNT 8 |
#define TIMER_IRQ 7 |
#define DORDER_IRQ 5 |
#define IRQ_COUNT 8 |
#define TIMER_IRQ 7 |
function virtual_timer_fnc = NULL; |
static irq_t timer_irq; |
101,12 → 100,12 |
cp0_compare_write(nextcount); |
} |
static irq_ownership_t timer_claim(irq_t *irq) |
static irq_ownership_t timer_claim(void) |
{ |
return IRQ_ACCEPT; |
} |
static void timer_irq_handler(irq_t *irq) |
static void timer_irq_handler(irq_t *irq, void *arg, ...) |
{ |
unsigned long drift; |
/branches/arm/kernel/arch/mips32/src/start.S |
---|
31,7 → 31,7 |
#include <arch/asm/boot.h> |
#include <arch/context_offset.h> |
#include <arch/stack.h> |
.text |
.set noat |
75,6 → 75,18 |
mfhi $at |
sw $at, EOFFSET_HI(\r) |
#ifdef CONFIG_DEBUG_ALLREGS |
sw $s0, EOFFSET_S0(\r) |
sw $s1, EOFFSET_S1(\r) |
sw $s2, EOFFSET_S2(\r) |
sw $s3, EOFFSET_S3(\r) |
sw $s4, EOFFSET_S4(\r) |
sw $s5, EOFFSET_S5(\r) |
sw $s6, EOFFSET_S6(\r) |
sw $s7, EOFFSET_S7(\r) |
sw $s8, EOFFSET_S8(\r) |
#endif |
sw $gp, EOFFSET_GP(\r) |
sw $ra, EOFFSET_RA(\r) |
sw $k1, EOFFSET_K1(\r) |
120,6 → 132,17 |
lw $t8, EOFFSET_T8(\r) |
lw $t9, EOFFSET_T9(\r) |
#ifdef CONFIG_DEBUG_ALLREGS |
lw $s0, EOFFSET_S0(\r) |
lw $s1, EOFFSET_S1(\r) |
lw $s2, EOFFSET_S2(\r) |
lw $s3, EOFFSET_S3(\r) |
lw $s4, EOFFSET_S4(\r) |
lw $s5, EOFFSET_S5(\r) |
lw $s6, EOFFSET_S6(\r) |
lw $s7, EOFFSET_S7(\r) |
lw $s8, EOFFSET_S8(\r) |
#endif |
lw $gp, EOFFSET_GP(\r) |
lw $ra, EOFFSET_RA(\r) |
lw $k1, EOFFSET_K1(\r) |
152,9 → 175,9 |
ori $k0, $k0, %lo(supervisor_sp) |
# Move $k0 (superveisor_sp) |
lw $k0, 0($k0) |
1: |
1: |
.endm |
.org 0x0 |
kernel_image_start: |
/* Load temporary stack */ |
161,12 → 184,31 |
lui $sp, %hi(end_stack) |
ori $sp, $sp, %lo(end_stack) |
/* Not sure about this, but might |
be needed for PIC code */ |
/* $a1 contains physical address of bootinfo_t */ |
/* $a2 contains size of bootinfo_t */ |
beq $a2, $0, bootinfo_end |
/* Not sure about this, but might be needed for PIC code???? */ |
lui $gp, 0x8000 |
/* $a1 contains physical address of bootinfo_t */ |
lui $a3, %hi(bootinfo) |
ori $a3, $a3, %lo(bootinfo) |
bootinfo_loop: |
lw $v0, 0($a1) |
sw $v0, 0($a3) |
addi $a1, $a1, 4 |
addi $a3, $a3, 4 |
addi $a2, $a2, -4 |
bgtz $a2, bootinfo_loop |
nop |
bootinfo_end: |
jal arch_pre_main |
nop |
186,8 → 228,8 |
exception_entry: |
j exception_handler |
nop |
nop |
exception_handler: |
KERNEL_STACK_TO_K0 |
sub $k0, REGISTER_SPACE |
196,17 → 238,17 |
mfc0 $k0, $cause |
sra $k0, $k0, 0x2 # cp0_exc_cause() part 1 |
andi $k0, $k0, 0x1f # cp0_exc_cause() part 2 |
sub $k0, 8 # 8 = SYSCALL |
sra $k0, $k0, 0x2 # cp0_exc_cause() part 1 |
andi $k0, $k0, 0x1f # cp0_exc_cause() part 2 |
sub $k0, 8 # 8 = SYSCALL |
beqz $k0, syscall_shortcut |
add $k0, 8 # Revert $k0 back to correct exc number |
add $k0, 8 # Revert $k0 back to correct exc number |
REGISTERS_STORE_AND_EXC_RESET $sp |
move $a1, $sp |
jal exc_dispatch # exc_dispatch(excno, register_space) |
jal exc_dispatch # exc_dispatch(excno, register_space) |
move $a0, $k0 |
REGISTERS_LOAD $sp |
/branches/arm/kernel/arch/mips32/src/debugger.c |
---|
37,18 → 37,16 |
#include <memstr.h> |
#include <console/kconsole.h> |
#include <console/cmd.h> |
#include <symtab.h> |
#include <print.h> |
#include <panic.h> |
#include <arch.h> |
#include <arch/cp0.h> |
#include <func.h> |
#include <symtab.h> |
bpinfo_t breakpoints[BKPOINTS_MAX]; |
SPINLOCK_INITIALIZE(bkpoint_lock); |
#ifdef CONFIG_KCONSOLE |
static int cmd_print_breakpoints(cmd_arg_t *argv); |
static cmd_info_t bkpts_info = { |
.name = "bkpts", |
125,12 → 123,10 |
{0, 0} /* EndOfTable */ |
}; |
/** Test, if the given instruction is a jump or branch instruction |
* |
* @param instr Instruction code |
* @return true - it is jump instruction, false otherwise |
* |
*/ |
static bool is_jump(unative_t instr) |
{ |
162,7 → 158,7 |
for (i = 0; i < BKPOINTS_MAX; i++) { |
if (breakpoints[i].address == (uintptr_t)argv->intval) { |
printf("Duplicate breakpoint %d.\n", i); |
spinlock_unlock(&bkpoint_lock); |
spinlock_unlock(&bkpoints_lock); |
return 0; |
} else if (breakpoints[i].address == (uintptr_t)argv->intval + |
sizeof(unative_t) || breakpoints[i].address == |
169,10 → 165,10 |
(uintptr_t)argv->intval - sizeof(unative_t)) { |
printf("Adjacent breakpoints not supported, conflict " |
"with %d.\n", i); |
spinlock_unlock(&bkpoint_lock); |
spinlock_unlock(&bkpoints_lock); |
return 0; |
} |
} |
for (i = 0; i < BKPOINTS_MAX; i++) |
259,9 → 255,8 |
for (i = 0; i < BKPOINTS_MAX; i++) |
if (breakpoints[i].address) { |
symbol = symtab_fmt_name_lookup( |
breakpoints[i].address); |
symbol = get_symtab_entry(breakpoints[i].address); |
printf("%-2u %-5d %#10zx %-6s %-7s %-8s %s\n", i, |
breakpoints[i].counter, breakpoints[i].address, |
((breakpoints[i].flags & BKPOINT_INPROG) ? "true" : |
272,8 → 267,6 |
return 1; |
} |
#endif |
/** Initialize debugger */ |
void debugger_init() |
{ |
281,24 → 274,22 |
for (i = 0; i < BKPOINTS_MAX; i++) |
breakpoints[i].address = NULL; |
#ifdef CONFIG_KCONSOLE |
cmd_initialize(&bkpts_info); |
if (!cmd_register(&bkpts_info)) |
printf("Cannot register command %s\n", bkpts_info.name); |
panic("could not register command %s\n", bkpts_info.name); |
cmd_initialize(&delbkpt_info); |
if (!cmd_register(&delbkpt_info)) |
printf("Cannot register command %s\n", delbkpt_info.name); |
panic("could not register command %s\n", delbkpt_info.name); |
cmd_initialize(&addbkpt_info); |
if (!cmd_register(&addbkpt_info)) |
printf("Cannot register command %s\n", addbkpt_info.name); |
panic("could not register command %s\n", addbkpt_info.name); |
cmd_initialize(&addbkpte_info); |
if (!cmd_register(&addbkpte_info)) |
printf("Cannot register command %s\n", addbkpte_info.name); |
#endif |
panic("could not register command %s\n", addbkpte_info.name); |
} |
/** Handle breakpoint |
317,7 → 308,7 |
/* test branch delay slot */ |
if (cp0_cause_read() & 0x80000000) |
panic("Breakpoint in branch delay slot not supported."); |
panic("Breakpoint in branch delay slot not supported.\n"); |
spinlock_lock(&bkpoint_lock); |
for (i = 0; i < BKPOINTS_MAX; i++) { |
349,10 → 340,9 |
if (cur->flags & BKPOINT_INPROG) |
printf("Warning: breakpoint recursion\n"); |
if (!(cur->flags & BKPOINT_FUNCCALL)) { |
if (!(cur->flags & BKPOINT_FUNCCALL)) |
printf("***Breakpoint %d: %p in %s.\n", i, fireaddr, |
symtab_fmt_name_lookup(istate->epc)); |
} |
get_symtab_entry(istate->epc)); |
/* Return first instruction back */ |
((uint32_t *)cur->address)[0] = cur->instruction; |
365,9 → 355,8 |
} |
cur->flags |= BKPOINT_INPROG; |
} else { |
printf("***Breakpoint %d: %p in %s.\n", i, fireaddr, |
symtab_fmt_name_lookup(fireaddr)); |
printf("***Breakpoint %p in %s.\n", fireaddr, |
get_symtab_entry(fireaddr)); |
/* Move on to next instruction */ |
istate->epc += 4; |
} |
378,20 → 367,19 |
if (cur->bkfunc) |
cur->bkfunc(cur, istate); |
} else { |
#ifdef CONFIG_KCONSOLE |
printf("***Type 'exit' to exit kconsole.\n"); |
/* This disables all other processors - we are not SMP, |
* actually this gets us to cpu_halt, if scheduler() is run |
* - we generally do not want scheduler to be run from debug, |
* so this is a good idea |
*/ |
atomic_set(&haltstate, 1); |
atomic_set(&haltstate,1); |
spinlock_unlock(&bkpoint_lock); |
kconsole("debug", "Debug console ready.\n", false); |
kconsole("debug"); |
spinlock_lock(&bkpoint_lock); |
atomic_set(&haltstate, 0); |
#endif |
atomic_set(&haltstate,0); |
} |
if (cur && cur->address == fireaddr && (cur->flags & BKPOINT_INPROG)) { |
/* Remove one-shot breakpoint */ |
/branches/arm/kernel/arch/mips32/src/exception.c |
---|
41,12 → 41,13 |
#include <arch.h> |
#include <debug.h> |
#include <proc/thread.h> |
#include <symtab.h> |
#include <print.h> |
#include <interrupt.h> |
#include <func.h> |
#include <console/kconsole.h> |
#include <ddi/irq.h> |
#include <arch/debugger.h> |
#include <symtab.h> |
static char * exctable[] = { |
"Interrupt", |
73,21 → 74,25 |
static void print_regdump(istate_t *istate) |
{ |
char *pcsymbol, *rasymbol; |
char *pcsymbol = ""; |
char *rasymbol = ""; |
pcsymbol = symtab_fmt_name_lookup(istate->epc); |
rasymbol = symtab_fmt_name_lookup(istate->ra); |
printf("PC: %#x(%s) RA: %#x(%s), SP(%p)\n", istate->epc, pcsymbol, |
istate->ra, rasymbol, istate->sp); |
char *s = get_symtab_entry(istate->epc); |
if (s) |
pcsymbol = s; |
s = get_symtab_entry(istate->ra); |
if (s) |
rasymbol = s; |
printf("PC: %#x(%s) RA: %#x(%s), SP(%p)\n", istate->epc, pcsymbol, istate->ra, rasymbol, istate->sp); |
} |
static void unhandled_exception(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "Unhandled exception %s.", exctable[n]); |
fault_if_from_uspace(istate, "unhandled exception %s", exctable[n]); |
print_regdump(istate); |
panic("Unhandled exception %s.", exctable[n]); |
panic("unhandled exception %s\n", exctable[n]); |
} |
static void reserved_instr_exception(int n, istate_t *istate) |
128,8 → 133,8 |
if (cp0_cause_coperr(cp0_cause_read()) == fpu_cop_id) |
scheduler_fpu_lazy_request(); |
else { |
fault_if_from_uspace(istate, "Unhandled Coprocessor Unusable Exception."); |
panic("Unhandled Coprocessor Unusable Exception."); |
fault_if_from_uspace(istate, "unhandled Coprocessor Unusable Exception"); |
panic("unhandled Coprocessor Unusable Exception\n"); |
} |
} |
#endif |
140,7 → 145,7 |
int i; |
/* decode interrupt number and process the interrupt */ |
cause = (cp0_cause_read() >> 8) & 0xff; |
cause = (cp0_cause_read() >> 8) &0xff; |
for (i = 0; i < 8; i++) { |
if (cause & (1 << i)) { |
149,7 → 154,7 |
/* |
* The IRQ handler was found. |
*/ |
irq->handler(irq); |
irq->handler(irq, irq->arg); |
spinlock_unlock(&irq->lock); |
} else { |
/* |
156,8 → 161,7 |
* Spurious interrupt. |
*/ |
#ifdef CONFIG_DEBUG |
printf("cpu%u: spurious interrupt (inum=%d)\n", |
CPU->id, i); |
printf("cpu%u: spurious interrupt (inum=%d)\n", CPU->id, i); |
#endif |
} |
} |
167,7 → 171,7 |
/** Handle syscall userspace call */ |
static void syscall_exception(int n, istate_t *istate) |
{ |
panic("Syscall is handled through shortcut."); |
panic("Syscall is handled through shortcut"); |
} |
void exception_init(void) |
/branches/arm/kernel/arch/mips32/src/cpu/cpu.c |
---|
48,7 → 48,7 |
{ "MIPS", "R2000" }, /* 0x01 */ |
{ "MIPS", "R3000" }, /* 0x02 */ |
{ "MIPS", "R6000" }, /* 0x03 */ |
{ "MIPS", "R4000/R4400" }, /* 0x04 */ |
{ "MIPS", " R4000/R4400" }, /* 0x04 */ |
{ "LSI Logic", "R3000" }, /* 0x05 */ |
{ "MIPS", "R6000A" }, /* 0x06 */ |
{ "IDT", "3051/3052" }, /* 0x07 */ |
123,9 → 123,9 |
data = &imp_data[m->arch.imp_num]; |
} |
printf("cpu%u: %s %s (rev=%d.%d, imp=%d)\n", |
printf("cpu%d: %s %s (rev=%d.%d, imp=%d)\n", |
m->id, data->vendor, data->model, m->arch.rev_num >> 4, |
m->arch.rev_num & 0x0f, m->arch.imp_num); |
m->arch.rev_num & 0xf, m->arch.imp_num); |
} |
/** @} |
/branches/arm/kernel/arch/mips32/src/smp/dorder.c |
---|
File deleted |
/branches/arm/kernel/arch/mips32/src/smp/smp.c |
---|
File deleted |
/branches/arm/kernel/arch/mips32/src/smp/order.c |
---|
0,0 → 1,45 |
/* |
* Copyright (c) 2007 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup mips32 |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/smp/order.h> |
#define MSIM_ORDER_ADDRESS 0xB0000004 |
void ipi_broadcast_arch(int ipi) |
{ |
*((volatile unsigned int *) MSIM_ORDER_ADDRESS) = 0x7FFFFFFF; |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/mips32/src/cache.c |
---|
38,7 → 38,7 |
void cache_error(istate_t *istate) |
{ |
panic("cache_error exception (epc=%p).", istate->epc); |
panic("cache_error exception (epc=%p)\n", istate->epc); |
} |
/** @} |
/branches/arm/kernel/arch/mips32/src/fpu_context.c |
---|
40,7 → 40,7 |
void fpu_disable(void) |
{ |
#ifdef CONFIG_FPU |
#ifdef ARCH_HAS_FPU |
cp0_status_write(cp0_status_read() & ~cp0_status_fpu_bit); |
#endif |
} |
47,7 → 47,7 |
void fpu_enable(void) |
{ |
#ifdef CONFIG_FPU |
#ifdef ARCH_HAS_FPU |
cp0_status_write(cp0_status_read() | cp0_status_fpu_bit); |
#endif |
} |
/branches/arm/kernel/arch/mips32/src/dummy.S |
---|
0,0 → 1,41 |
# |
# Copyright (c) 2003-2004 Jakub Jermar |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
.text |
.set noat |
.global calibrate_delay_loop |
.global asm_delay_loop |
.global dummy |
calibrate_delay_loop: |
asm_delay_loop: |
dummy: |
j $31 |
nop |
/branches/arm/kernel/arch/mips32/Makefile.inc |
---|
29,51 → 29,87 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_ARCH = mips |
BFD = binary |
TARGET = mipsel-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mipsel |
GCC_CFLAGS += -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mips3 |
KERNEL_LOAD_ADDRESS = 0x80100000 |
BITS = 32 |
GCC_CFLAGS += -mno-abicalls -G 0 -fno-zero-initialized-in-bss |
DEFS += -D__32_BITS__ -DMACHINE=$(MACHINE) -DKERNEL_LOAD_ADDRESS=${KERNEL_LOAD_ADDRESS} |
## Compile with hierarchical page tables support. |
# |
CONFIG_PAGE_PT = y |
DEFS += -DCONFIG_PAGE_PT |
## Compile with support for address space identifiers. |
# |
CONFIG_ASID = y |
CONFIG_ASID_FIFO = y |
## Accepted MACHINEs |
# |
ifeq ($(MACHINE),lgxemul) |
BFD_NAME = elf32-tradlittlemips |
ENDIANESS = LE |
BFD = binary |
GCC_CFLAGS += -DFB_INVERT_ENDIAN -DARCH_HAS_FPU -mips3 |
endif |
ifeq ($(MACHINE),bgxemul) |
BFD_NAME = elf32-tradbigmips |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips |
TARGET = mips-linux-gnu |
ENDIANESS = BE |
GCC_CFLAGS += -D__BE__ |
BFD_NAME = elf32-bigmips |
BFD = ecoff-bigmips |
TARGET = mips-sgi-irix5 |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips/bin |
GCC_CFLAGS += -EB -DBIG_ENDIAN -DARCH_HAS_FPU -mips3 |
endif |
ifeq ($(MACHINE),simics) |
# SIMICS 4kc emulation is broken, although for instructions |
# that do not bother us |
BFD_NAME = elf32-tradlittlemips |
BFD = elf32-tradlittlemips |
GCC_CFLAGS += -mhard-float -mips3 -DTLBCNT=16 |
TLBCNT = 16 |
endif |
ifeq ($(MACHINE),msim) |
BFD_NAME = elf32-tradlittlemips |
ENDIANESS = LE |
GCC_CFLAGS += -mhard-float |
BFD = binary |
GCC_CFLAGS += -mhard-float -mips3 |
endif |
## Compile with support for software integer division. |
# |
CONFIG_SOFTINT = y |
ARCH_SOURCES = \ |
arch/$(KARCH)/src/start.S \ |
arch/$(KARCH)/src/context.S \ |
arch/$(KARCH)/src/panic.S \ |
arch/$(KARCH)/src/mips32.c \ |
arch/$(KARCH)/src/asm.S \ |
arch/$(KARCH)/src/exception.c \ |
arch/$(KARCH)/src/interrupt.c \ |
arch/$(KARCH)/src/cache.c \ |
arch/$(KARCH)/src/debugger.c \ |
arch/$(KARCH)/src/cpu/cpu.c \ |
arch/$(KARCH)/src/mm/frame.c \ |
arch/$(KARCH)/src/mm/page.c \ |
arch/$(KARCH)/src/mm/tlb.c \ |
arch/$(KARCH)/src/mm/as.c \ |
arch/$(KARCH)/src/fpu_context.c \ |
arch/$(KARCH)/src/ddi/ddi.c \ |
arch/$(KARCH)/src/smp/dorder.c \ |
arch/$(KARCH)/src/smp/smp.c |
arch/$(ARCH)/src/start.S \ |
arch/$(ARCH)/src/context.S \ |
arch/$(ARCH)/src/panic.S \ |
arch/$(ARCH)/src/mips32.c \ |
arch/$(ARCH)/src/dummy.S \ |
arch/$(ARCH)/src/console.c \ |
arch/$(ARCH)/src/asm.S \ |
arch/$(ARCH)/src/exception.c \ |
arch/$(ARCH)/src/interrupt.c \ |
arch/$(ARCH)/src/cache.c \ |
arch/$(ARCH)/src/debugger.c \ |
arch/$(ARCH)/src/cpu/cpu.c \ |
arch/$(ARCH)/src/mm/frame.c \ |
arch/$(ARCH)/src/mm/page.c \ |
arch/$(ARCH)/src/mm/tlb.c \ |
arch/$(ARCH)/src/mm/as.c \ |
arch/$(ARCH)/src/fpu_context.c \ |
arch/$(ARCH)/src/ddi/ddi.c \ |
arch/$(ARCH)/src/drivers/msim.c \ |
arch/$(ARCH)/src/drivers/serial.c \ |
arch/$(ARCH)/src/smp/order.c |
/branches/arm/kernel/arch/mips32/include/drivers/serial.h |
---|
0,0 → 1,76 |
/* |
* Copyright (c) 2005 Ondrej Palkovsky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup mips32 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_mips32_SERIAL_H_ |
#define KERN_mips32_SERIAL_H_ |
#include <console/chardev.h> |
#define SERIAL_ADDRESS 0x98000000 |
#define SERIAL_MAX 4 |
#define SERIAL_COM1 0x3f8 |
#define SERIAL_COM1_IRQ 4 |
#define SERIAL_COM2 0x2f8 |
#define SERIAL_COM2_IRQ 3 |
#define P_WRITEB(where, what) (*((volatile char *) (SERIAL_ADDRESS + where)) = what) |
#define P_READB(where) (*((volatile char *) (SERIAL_ADDRESS + where))) |
#define SERIAL_READ(x) P_READB(x) |
#define SERIAL_WRITE(x, c) P_WRITEB(x, c) |
/* Interrupt enable register */ |
#define SERIAL_READ_IER(x) (P_READB((x) + 1)) |
#define SERIAL_WRITE_IER(x,c) (P_WRITEB((x) + 1, c)) |
/* Interrupt identification register */ |
#define SERIAL_READ_IIR(x) (P_READB((x) + 2)) |
/* Line status register */ |
#define SERIAL_READ_LSR(x) (P_READB((x) + 5)) |
#define TRANSMIT_EMPTY_BIT 5 |
typedef struct { |
int port; |
int irq; |
}serial_t; |
extern void serial_console(devno_t devno); |
extern int serial_init(void); |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/mips32/include/drivers/msim.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup mips32 |
/** @addtogroup mips32 |
* @{ |
*/ |
/** @file |
36,10 → 36,16 |
#define KERN_mips32_MSIM_H_ |
/** Address of devices. */ |
#define MSIM_VIDEORAM 0x90000000 |
#define MSIM_KBD_ADDRESS 0x90000000 |
#define MSIM_KBD_IRQ 2 |
#define MSIM_VIDEORAM 0x90000000 |
#define MSIM_KBD_ADDRESS 0x90000000 |
#define MSIM_KBD_IRQ 2 |
#include <console/chardev.h> |
void msim_console(devno_t devno); |
void msim_kbd_release(void); |
void msim_kbd_grab(void); |
#endif |
/** @} |
/branches/arm/kernel/arch/mips32/include/mm/page.h |
---|
112,21 → 112,21 |
/* Get PTE flags accessors for each level. */ |
#define GET_PTL1_FLAGS_ARCH(ptl0, i) \ |
get_pt_flags((pte_t *) (ptl0), (size_t) (i)) |
get_pt_flags((pte_t *) (ptl0), (index_t) (i)) |
#define GET_PTL2_FLAGS_ARCH(ptl1, i) \ |
PAGE_PRESENT |
#define GET_PTL3_FLAGS_ARCH(ptl2, i) \ |
PAGE_PRESENT |
#define GET_FRAME_FLAGS_ARCH(ptl3, i) \ |
get_pt_flags((pte_t *) (ptl3), (size_t) (i)) |
get_pt_flags((pte_t *) (ptl3), (index_t) (i)) |
/* Set PTE flags accessors for each level. */ |
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \ |
set_pt_flags((pte_t *) (ptl0), (size_t) (i), (x)) |
set_pt_flags((pte_t *) (ptl0), (index_t) (i), (x)) |
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x) |
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x) |
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \ |
set_pt_flags((pte_t *) (ptl3), (size_t) (i), (x)) |
set_pt_flags((pte_t *) (ptl3), (index_t) (i), (x)) |
/* Last-level info macros. */ |
#define PTE_VALID_ARCH(pte) (*((uint32_t *) (pte)) != 0) |
140,7 → 140,7 |
#include <mm/mm.h> |
#include <arch/exception.h> |
static inline int get_pt_flags(pte_t *pt, size_t i) |
static inline int get_pt_flags(pte_t *pt, index_t i) |
{ |
pte_t *p = &pt[i]; |
153,7 → 153,7 |
(p->g << PAGE_GLOBAL_SHIFT)); |
} |
static inline void set_pt_flags(pte_t *pt, size_t i, int flags) |
static inline void set_pt_flags(pte_t *pt, index_t i, int flags) |
{ |
pte_t *p = &pt[i]; |
/branches/arm/kernel/arch/mips32/include/mm/tlb.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup mips32mm |
/** @addtogroup mips32mm |
* @{ |
*/ |
/** @file |
40,38 → 40,42 |
#include <arch/mm/asid.h> |
#include <arch/exception.h> |
#define TLB_ENTRY_COUNT 48 |
#ifdef TLBCNT |
# define TLB_ENTRY_COUNT TLBCNT |
#else |
# define TLB_ENTRY_COUNT 48 |
#endif |
#define TLB_WIRED 1 |
#define TLB_KSTACK_WIRED_INDEX 0 |
#define TLB_WIRED 1 |
#define TLB_KSTACK_WIRED_INDEX 0 |
#define TLB_PAGE_MASK_4K (0x000 << 13) |
#define TLB_PAGE_MASK_16K (0x003 << 13) |
#define TLB_PAGE_MASK_64K (0x00f << 13) |
#define TLB_PAGE_MASK_256K (0x03f << 13) |
#define TLB_PAGE_MASK_1M (0x0ff << 13) |
#define TLB_PAGE_MASK_4M (0x3ff << 13) |
#define TLB_PAGE_MASK_16M (0xfff << 13) |
#define TLB_PAGE_MASK_4K (0x000 << 13) |
#define TLB_PAGE_MASK_16K (0x003 << 13) |
#define TLB_PAGE_MASK_64K (0x00f << 13) |
#define TLB_PAGE_MASK_256K (0x03f << 13) |
#define TLB_PAGE_MASK_1M (0x0ff << 13) |
#define TLB_PAGE_MASK_4M (0x3ff << 13) |
#define TLB_PAGE_MASK_16M (0xfff << 13) |
#define PAGE_UNCACHED 2 |
#define PAGE_CACHEABLE_EXC_WRITE 5 |
#define PAGE_UNCACHED 2 |
#define PAGE_CACHEABLE_EXC_WRITE 5 |
typedef union { |
struct { |
#ifdef BIG_ENDIAN |
unsigned : 2; /* zero */ |
unsigned pfn : 24; /* frame number */ |
unsigned c : 3; /* cache coherency attribute */ |
unsigned d : 1; /* dirty/write-protect bit */ |
unsigned v : 1; /* valid bit */ |
unsigned g : 1; /* global bit */ |
unsigned : 2; /* zero */ |
unsigned pfn : 24; /* frame number */ |
unsigned c : 3; /* cache coherency attribute */ |
unsigned d : 1; /* dirty/write-protect bit */ |
unsigned v : 1; /* valid bit */ |
unsigned g : 1; /* global bit */ |
#else |
unsigned g : 1; /* global bit */ |
unsigned v : 1; /* valid bit */ |
unsigned d : 1; /* dirty/write-protect bit */ |
unsigned c : 3; /* cache coherency attribute */ |
unsigned pfn : 24; /* frame number */ |
unsigned : 2; /* zero */ |
unsigned g : 1; /* global bit */ |
unsigned v : 1; /* valid bit */ |
unsigned d : 1; /* dirty/write-protect bit */ |
unsigned c : 3; /* cache coherency attribute */ |
unsigned pfn : 24; /* frame number */ |
unsigned : 2; /* zero */ |
#endif |
} __attribute__ ((packed)); |
uint32_t value; |
159,7 → 163,7 |
asm volatile ("tlbwr\n\t"); |
} |
#define tlb_invalidate(asid) tlb_invalidate_asid(asid) |
#define tlb_invalidate(asid) tlb_invalidate_asid(asid) |
extern void tlb_invalid(istate_t *istate); |
extern void tlb_refill(istate_t *istate); |
/branches/arm/kernel/arch/mips32/include/mm/frame.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup mips32mm |
/** @addtogroup mips32mm |
* @{ |
*/ |
/** @file |
35,14 → 35,12 |
#ifndef KERN_mips32_FRAME_H_ |
#define KERN_mips32_FRAME_H_ |
#define FRAME_WIDTH 14 /* 16K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#define FRAME_WIDTH 14 /* 16K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#ifdef KERNEL |
#ifndef __ASM__ |
#include <typedefs.h> |
extern void frame_arch_init(void); |
extern void physmem_print(void); |
/branches/arm/kernel/arch/mips32/include/mm/asid.h |
---|
37,7 → 37,7 |
#include <arch/types.h> |
#define ASID_MAX_ARCH 255 /* 2^8 - 1 */ |
#define ASID_MAX_ARCH 255 /* 2^8 - 1 */ |
typedef uint8_t asid_t; |
/branches/arm/kernel/arch/mips32/include/atomic.h |
---|
35,14 → 35,14 |
#ifndef KERN_mips32_ATOMIC_H_ |
#define KERN_mips32_ATOMIC_H_ |
#define atomic_inc(x) ((void) atomic_add(x, 1)) |
#define atomic_dec(x) ((void) atomic_add(x, -1)) |
#define atomic_inc(x) ((void) atomic_add(x, 1)) |
#define atomic_dec(x) ((void) atomic_add(x, -1)) |
#define atomic_postinc(x) (atomic_add(x, 1) - 1) |
#define atomic_postdec(x) (atomic_add(x, -1) + 1) |
#define atomic_postinc(x) (atomic_add(x, 1) - 1) |
#define atomic_postdec(x) (atomic_add(x, -1) + 1) |
#define atomic_preinc(x) atomic_add(x, 1) |
#define atomic_predec(x) atomic_add(x, -1) |
#define atomic_preinc(x) atomic_add(x, 1) |
#define atomic_predec(x) atomic_add(x, -1) |
/* Atomic addition of immediate value. |
* |
54,37 → 54,19 |
static inline long atomic_add(atomic_t *val, int i) |
{ |
long tmp, v; |
asm volatile ( |
"1:\n" |
" ll %0, %1\n" |
" addu %0, %0, %3\n" /* same as addi, but never traps on overflow */ |
" move %2, %0\n" |
" addu %0, %0, %3\n" /* same as addi, but never traps on overflow */ |
" move %2, %0\n" |
" sc %0, %1\n" |
" beq %0, %4, 1b\n" /* if the atomic operation failed, try again */ |
" beq %0, %4, 1b\n" /* if the atomic operation failed, try again */ |
" nop\n" |
: "=&r" (tmp), "+m" (val->count), "=&r" (v) |
: "r" (i), "i" (0) |
); |
return v; |
} |
); |
static inline uint32_t test_and_set(atomic_t *val) { |
uint32_t tmp, v; |
asm volatile ( |
"1:\n" |
" ll %2, %1\n" |
" bnez %2, 2f\n" |
" li %0, %3\n" |
" sc %0, %1\n" |
" beqz %0, 1b\n" |
"2:\n" |
: "=&r" (tmp), "+m" (val->count), "=&r" (v) |
: "i" (1) |
); |
return v; |
} |
/branches/arm/kernel/arch/mips32/include/types.h |
---|
46,6 → 46,8 |
typedef unsigned long long uint64_t; |
typedef uint32_t size_t; |
typedef uint32_t count_t; |
typedef uint32_t index_t; |
typedef uint32_t uintptr_t; |
typedef uint32_t pfn_t; |
55,11 → 57,10 |
typedef uint32_t unative_t; |
typedef int32_t native_t; |
typedef struct { |
} fncptr_t; |
#define PRIp "x" /**< Format for uintptr_t. */ |
#define PRIs "u" /**< Format for size_t. */ |
#define PRIc "u" /**< Format for count_t. */ |
#define PRIi "u" /**< Format for index_t. */ |
#define PRId8 "d" /**< Format for int8_t. */ |
#define PRId16 "d" /**< Format for int16_t. */ |
/branches/arm/kernel/arch/mips32/include/byteorder.h |
---|
0,0 → 1,47 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup mips32 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_mips32_BYTEORDER_H_ |
#define KERN_mips32_BYTEORDER_H_ |
#ifdef BIG_ENDIAN |
#define ARCH_IS_BIG_ENDIAN |
#else |
#define ARCH_IS_LITTLE_ENDIAN |
#endif |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/mips32/include/context_offset.h |
---|
76,17 → 76,26 |
#define EOFFSET_T5 0x30 |
#define EOFFSET_T6 0x34 |
#define EOFFSET_T7 0x38 |
#define EOFFSET_T8 0x3c |
#define EOFFSET_T9 0x40 |
#define EOFFSET_GP 0x44 |
#define EOFFSET_SP 0x48 |
#define EOFFSET_RA 0x4c |
#define EOFFSET_LO 0x50 |
#define EOFFSET_HI 0x54 |
#define EOFFSET_STATUS 0x58 |
#define EOFFSET_EPC 0x5c |
#define EOFFSET_K1 0x60 |
#define REGISTER_SPACE 104 /* respect stack alignment */ |
#define EOFFSET_S0 0x3c |
#define EOFFSET_S1 0x40 |
#define EOFFSET_S2 0x44 |
#define EOFFSET_S3 0x48 |
#define EOFFSET_S4 0x4c |
#define EOFFSET_S5 0x50 |
#define EOFFSET_S6 0x54 |
#define EOFFSET_S7 0x58 |
#define EOFFSET_T8 0x5c |
#define EOFFSET_T9 0x60 |
#define EOFFSET_GP 0x64 |
#define EOFFSET_SP 0x68 |
#define EOFFSET_S8 0x6c |
#define EOFFSET_RA 0x70 |
#define EOFFSET_LO 0x74 |
#define EOFFSET_HI 0x78 |
#define EOFFSET_STATUS 0x7c |
#define EOFFSET_EPC 0x80 |
#define EOFFSET_K1 0x84 |
#define REGISTER_SPACE 136 |
#ifdef __ASM__ |
105,10 → 114,10 |
sw $s8,OFFSET_S8(\ctx) |
sw $gp,OFFSET_GP(\ctx) |
#ifndef KERNEL |
#ifndef KERNEL |
sw $k1,OFFSET_TLS(\ctx) |
#ifdef CONFIG_FPU |
# ifdef CONFIG_MIPS_FPU |
mfc1 $t0,$20 |
sw $t0, OFFSET_F20(\ctx) |
141,7 → 150,7 |
mfc1 $t0,$30 |
sw $t0, OFFSET_F30(\ctx) |
#endif /* CONFIG_FPU */ |
# endif /* CONFIG_MIPS_FPU */ |
#endif /* KERNEL */ |
sw $ra,OFFSET_PC(\ctx) |
163,7 → 172,7 |
#ifndef KERNEL |
lw $k1,OFFSET_TLS(\ctx) |
#ifdef CONFIG_FPU |
# ifdef CONFIG_MIPS_FPU |
lw $t0, OFFSET_F20(\ctx) |
mtc1 $t0,$20 |
196,9 → 205,9 |
lw $t0, OFFSET_F30(\ctx) |
mtc1 $t0,$30 |
#endif /* CONFIG_FPU */ |
# endif /* CONFIG_MIPS_FPU */ |
#endif /* KERNEL */ |
lw $ra,OFFSET_PC(\ctx) |
lw $sp,OFFSET_SP(\ctx) |
.endm |
/branches/arm/kernel/arch/mips32/include/smp/dorder.h |
---|
File deleted |
/branches/arm/kernel/arch/mips32/include/smp/order.h |
---|
0,0 → 1,34 |
/* |
* Copyright (c) 2007 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#ifndef KERN_mips32_ORDER_H_ |
#define KERN_mips32_ORDER_H_ |
extern void ipi_broadcast_arch(int ipi); |
#endif |
/branches/arm/kernel/arch/mips32/include/interrupt.h |
---|
38,11 → 38,9 |
#include <typedefs.h> |
#include <arch/exception.h> |
#define IVT_ITEMS 32 |
#define IVT_FIRST 0 |
#define IVT_ITEMS 32 |
#define IVT_FIRST 0 |
#define VECTOR_TLB_SHOOTDOWN_IPI EXC_Int |
extern function virtual_timer_fnc; |
extern uint32_t count_hi; |
/branches/arm/kernel/arch/mips32/include/exception.h |
---|
73,10 → 73,19 |
uint32_t t5; |
uint32_t t6; |
uint32_t t7; |
uint32_t s0; |
uint32_t s1; |
uint32_t s2; |
uint32_t s3; |
uint32_t s4; |
uint32_t s5; |
uint32_t s6; |
uint32_t s7; |
uint32_t t8; |
uint32_t t9; |
uint32_t gp; |
uint32_t sp; |
uint32_t s8; |
uint32_t ra; |
uint32_t lo; |
/branches/arm/kernel/arch/mips32/include/asm.h |
---|
36,7 → 36,6 |
#define KERN_mips32_ASM_H_ |
#include <arch/types.h> |
#include <typedefs.h> |
#include <config.h> |
56,11 → 55,7 |
{ |
uintptr_t v; |
asm volatile ( |
"and %0, $29, %1\n" |
: "=r" (v) |
: "r" (~(STACK_SIZE-1)) |
); |
asm volatile ("and %0, $29, %1\n" : "=r" (v) : "r" (~(STACK_SIZE-1))); |
return v; |
} |
68,44 → 63,13 |
extern void cpu_halt(void); |
extern void asm_delay_loop(uint32_t t); |
extern void userspace_asm(uintptr_t ustack, uintptr_t uspace_uarg, |
uintptr_t entry); |
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); |
extern void asm_delay_loop(uint32_t t); |
static inline void pio_write_8(ioport8_t *port, uint8_t v) |
{ |
*port = v; |
} |
static inline void pio_write_16(ioport16_t *port, uint16_t v) |
{ |
*port = v; |
} |
static inline void pio_write_32(ioport32_t *port, uint32_t v) |
{ |
*port = v; |
} |
static inline uint8_t pio_read_8(ioport8_t *port) |
{ |
return *port; |
} |
static inline uint16_t pio_read_16(ioport16_t *port) |
{ |
return *port; |
} |
static inline uint32_t pio_read_32(ioport32_t *port) |
{ |
return *port; |
} |
#endif |
/** @} |
/branches/arm/kernel/arch/mips32/include/debugger.h |
---|
53,7 → 53,7 |
unative_t instruction; /**< Original instruction */ |
unative_t nextinstruction; /**< Original instruction following break */ |
int flags; /**< Flags regarding breakpoint */ |
size_t counter; |
count_t counter; |
void (*bkfunc)(void *b, istate_t *istate); |
} bpinfo_t; |
/branches/arm/kernel/arch/mips32/include/cpu.h |
---|
42,7 → 42,7 |
uint32_t imp_num; |
uint32_t rev_num; |
} cpu_arch_t; |
#endif |
/** @} |
/branches/arm/kernel/arch/mips32/include/asm/boot.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup mips32 |
/** @addtogroup mips32 |
* @{ |
*/ |
/** @file |
/branches/arm/kernel/arch/mips32/include/console.h |
---|
0,0 → 1,43 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup mips32 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_mips32_CONSOLE_H_ |
#define KERN_mips32_CONSOLE_H_ |
extern void console_init(devno_t devno); |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/mips32/include/boot.h |
---|
0,0 → 1,48 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#ifndef KERN_mips32_BOOT_H_ |
#define KERN_mips32_BOOT_H_ |
#define TASKMAP_MAX_RECORDS 32 |
#include <arch/types.h> |
typedef struct { |
uintptr_t addr; |
uint32_t size; |
} utask_t; |
typedef struct { |
uint32_t cnt; |
utask_t tasks[TASKMAP_MAX_RECORDS]; |
} bootinfo_t; |
extern bootinfo_t bootinfo; |
#endif |
/branches/arm/kernel/arch/mips32/include/elf.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup mips32 |
/** @addtogroup mips32 |
* @{ |
*/ |
/** @file |
35,15 → 35,15 |
#ifndef KERN_mips32_ELF_H_ |
#define KERN_mips32_ELF_H_ |
#define ELF_MACHINE EM_MIPS |
#define ELF_MACHINE EM_MIPS |
#ifdef __BE__ |
#define ELF_DATA_ENCODING ELFDATA2MSB |
#ifdef BIG_ENDIAN |
# define ELF_DATA_ENCODING ELFDATA2MSB |
#else |
#define ELF_DATA_ENCODING ELFDATA2LSB |
# define ELF_DATA_ENCODING ELFDATA2LSB |
#endif |
#define ELF_CLASS ELFCLASS32 |
#define ELF_CLASS ELFCLASS32 |
#endif |
/branches/arm/kernel/arch/mips32/include/arch.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup mips32 |
/** @addtogroup mips32 |
* @{ |
*/ |
/** @file |
35,29 → 35,6 |
#ifndef KERN_mips32_ARCH_H_ |
#define KERN_mips32_ARCH_H_ |
#define TASKMAP_MAX_RECORDS 32 |
#define CPUMAP_MAX_RECORDS 32 |
#define BOOTINFO_TASK_NAME_BUFLEN 32 |
#include <typedefs.h> |
extern size_t cpu_count; |
typedef struct { |
uintptr_t addr; |
uint32_t size; |
char name[BOOTINFO_TASK_NAME_BUFLEN]; |
} utask_t; |
typedef struct { |
uint32_t cpumap; |
uint32_t cnt; |
utask_t tasks[TASKMAP_MAX_RECORDS]; |
} bootinfo_t; |
extern void arch_pre_main(void *entry, bootinfo_t *bootinfo); |
#endif |
/** @} |
/branches/arm/kernel/arch/mips32/_link.ld.in |
---|
1,17 → 1,15 |
/* |
* MIPS32 linker script |
* |
* MIPS32 linker script |
* |
* kernel text |
* kernel data |
* |
* |
*/ |
#undef mips |
#define mips mips |
#define KERNEL_LOAD_ADDRESS 0x80100000 |
OUTPUT_ARCH(mips) |
OUTPUT_ARCH(mips) |
ENTRY(kernel_image_start) |
SECTIONS { |
23,9 → 21,9 |
} |
.data : { |
kdata_start = .; |
*(.data); /* initialized data */ |
*(.data); /* initialized data */ |
hardcoded_ktext_size = .; |
LONG(ktext_end - ktext_start); |
LONG(ktext_end - ktext_start); |
hardcoded_kdata_size = .; |
LONG(kdata_end - kdata_start); |
hardcoded_load_address = .; |
35,21 → 33,21 |
*(.reginfo); |
*(.sbss); |
*(.scommon); |
*(.bss); /* uninitialized static variables */ |
*(COMMON); /* global variables */ |
*(.bss); /* uninitialized static variables */ |
*(COMMON); /* global variables */ |
symbol_table = .; |
*(symtab.*); |
*(symtab.*); |
} |
_gp = . + 0x8000; |
.lit8 : { *(.lit8) } |
.lit4 : { *(.lit4) } |
kdata_end = .; |
/DISCARD/ : { |
*(.mdebug*); |
*(.pdr); |
*(.comment); |
*(.note); |
*(.mdebug*); |
*(.pdr); |
*(.comment); |
*(.note); |
} |
} |
/branches/arm/kernel/arch/ia64/Makefile.inc |
---|
29,6 → 29,10 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf64-little |
BFD_ARCH = ia64-elf64 |
TARGET = ia64-pc-linux-gnu |
41,35 → 45,56 |
LFLAGS += -EL |
AFLAGS += -mconstant-gp |
BITS = 64 |
ENDIANESS = LE |
DEFS += -D__64_BITS__ -D$(MACHINE) |
## Compile with page hash table support. |
# |
CONFIG_PAGE_HT = y |
DEFS += -DCONFIG_PAGE_HT |
## Compile with support for address space identifiers. |
# |
CONFIG_ASID = y |
CONFIG_ASID_FIFO = y |
## Compile with support for software integer division. |
# |
CONFIG_SOFTINT = y |
ARCH_SOURCES = \ |
arch/$(KARCH)/src/start.S \ |
arch/$(KARCH)/src/asm.S \ |
arch/$(KARCH)/src/dummy.s \ |
arch/$(KARCH)/src/ia64.c \ |
arch/$(KARCH)/src/fpu_context.c \ |
arch/$(KARCH)/src/context.S \ |
arch/$(KARCH)/src/cpu/cpu.c \ |
arch/$(KARCH)/src/ivt.S \ |
arch/$(KARCH)/src/interrupt.c \ |
arch/$(KARCH)/src/mm/as.c \ |
arch/$(KARCH)/src/mm/frame.c \ |
arch/$(KARCH)/src/mm/page.c \ |
arch/$(KARCH)/src/mm/tlb.c \ |
arch/$(KARCH)/src/mm/vhpt.c \ |
arch/$(KARCH)/src/proc/scheduler.c \ |
arch/$(KARCH)/src/ddi/ddi.c \ |
arch/$(KARCH)/src/smp/smp.c \ |
arch/$(KARCH)/src/drivers/it.c |
arch/$(ARCH)/src/start.S \ |
arch/$(ARCH)/src/asm.S \ |
arch/$(ARCH)/src/dummy.s \ |
arch/$(ARCH)/src/ia64.c \ |
arch/$(ARCH)/src/fpu_context.c \ |
arch/$(ARCH)/src/context.S \ |
arch/$(ARCH)/src/cpu/cpu.c \ |
arch/$(ARCH)/src/ivt.S \ |
arch/$(ARCH)/src/interrupt.c \ |
arch/$(ARCH)/src/mm/as.c \ |
arch/$(ARCH)/src/mm/frame.c \ |
arch/$(ARCH)/src/mm/page.c \ |
arch/$(ARCH)/src/mm/tlb.c \ |
arch/$(ARCH)/src/mm/vhpt.c \ |
arch/$(ARCH)/src/proc/scheduler.c \ |
arch/$(ARCH)/src/ddi/ddi.c \ |
arch/$(ARCH)/src/drivers/it.c |
ifeq ($(MACHINE),ski) |
ARCH_SOURCES += arch/$(KARCH)/src/drivers/ski.c |
ARCH_SOURCES += arch/$(ARCH)/src/ski/ski.c |
DEFS += -DSKI |
# BFD = elf64-ia64-little |
BFD = binary |
endif |
ifeq ($(MACHINE),i460GX) |
DEFS += -DI460GX |
ARCH_SOURCES += arch/$(ARCH)/src/drivers/ega.c |
CONFIG_I8042 = y |
DEFS += -DI460GX -DCONFIG_I8042 |
BFD = binary |
endif |
/branches/arm/kernel/arch/ia64/src/smp/smp.c |
---|
File deleted |
/branches/arm/kernel/arch/ia64/src/asm.S |
---|
51,7 → 51,7 |
adds r14 = 7, in1 |
mov r2 = ar.lc |
mov r8 = in0 ;; |
mov r8 = in0 |
and r14 = -8, r14 ;; |
cmp.ne p6, p7 = r14, in1 |
(p7) br.cond.dpnt 3f ;; |
128,10 → 128,6 |
memsetb: |
br _memsetb |
.global memsetw |
memsetw: |
br _memsetw |
.global cpu_halt |
cpu_halt: |
br cpu_halt |
/branches/arm/kernel/arch/ia64/src/mm/vhpt.c |
---|
41,8 → 41,7 |
uintptr_t vhpt_set_up(void) |
{ |
vhpt_base = frame_alloc(VHPT_WIDTH - FRAME_WIDTH, |
FRAME_KA | FRAME_ATOMIC); |
vhpt_base = frame_alloc(VHPT_WIDTH - FRAME_WIDTH, FRAME_KA | FRAME_ATOMIC); |
if (!vhpt_base) |
panic("Kernel configured with VHPT but no memory for table."); |
vhpt_invalidate_all(); |
53,7 → 52,7 |
void vhpt_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry) |
{ |
region_register rr_save, rr; |
size_t vrn; |
index_t vrn; |
rid_t rid; |
uint64_t tag; |
/branches/arm/kernel/arch/ia64/src/mm/tlb.c |
---|
92,7 → 92,7 |
/** Invalidate entries belonging to an address space. |
* |
* @param asid Address space identifier. |
* @param asid Address space identifier. |
*/ |
void tlb_invalidate_asid(asid_t asid) |
{ |
100,7 → 100,7 |
} |
void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt) |
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt) |
{ |
region_register rr; |
bool restore_rr = false; |
131,45 → 131,59 |
uint64_t ps; |
switch (b) { |
case 0: /* cnt 1 - 3 */ |
case 0: /*cnt 1-3*/ |
ps = PAGE_WIDTH; |
break; |
case 1: /* cnt 4 - 15 */ |
ps = PAGE_WIDTH + 2; |
va &= ~((1 << ps) - 1); |
case 1: /*cnt 4-15*/ |
/*cnt=((cnt-1)/4)+1;*/ |
ps = PAGE_WIDTH+2; |
va &= ~((1<<ps)-1); |
break; |
case 2: /* cnt 16 - 63 */ |
ps = PAGE_WIDTH + 4; |
va &= ~((1 << ps) - 1); |
case 2: /*cnt 16-63*/ |
/*cnt=((cnt-1)/16)+1;*/ |
ps = PAGE_WIDTH+4; |
va &= ~((1<<ps)-1); |
break; |
case 3: /* cnt 64 - 255 */ |
ps = PAGE_WIDTH + 6; |
va &= ~((1 << ps) - 1); |
case 3: /*cnt 64-255*/ |
/*cnt=((cnt-1)/64)+1;*/ |
ps = PAGE_WIDTH+6; |
va &= ~((1<<ps)-1); |
break; |
case 4: /* cnt 256 - 1023 */ |
ps = PAGE_WIDTH + 8; |
va &= ~((1 << ps) - 1); |
case 4: /*cnt 256-1023*/ |
/*cnt=((cnt-1)/256)+1;*/ |
ps = PAGE_WIDTH+8; |
va &= ~((1<<ps)-1); |
break; |
case 5: /* cnt 1024 - 4095 */ |
ps = PAGE_WIDTH + 10; |
va &= ~((1 << ps) - 1); |
case 5: /*cnt 1024-4095*/ |
/*cnt=((cnt-1)/1024)+1;*/ |
ps = PAGE_WIDTH+10; |
va &= ~((1<<ps)-1); |
break; |
case 6: /* cnt 4096 - 16383 */ |
ps = PAGE_WIDTH + 12; |
va &= ~((1 << ps) - 1); |
case 6: /*cnt 4096-16383*/ |
/*cnt=((cnt-1)/4096)+1;*/ |
ps = PAGE_WIDTH+12; |
va &= ~((1<<ps)-1); |
break; |
case 7: /* cnt 16384 - 65535 */ |
case 8: /* cnt 65536 - (256K - 1) */ |
ps = PAGE_WIDTH + 14; |
va &= ~((1 << ps) - 1); |
case 7: /*cnt 16384-65535*/ |
case 8: /*cnt 65536-(256K-1)*/ |
/*cnt=((cnt-1)/16384)+1;*/ |
ps = PAGE_WIDTH+14; |
va &= ~((1<<ps)-1); |
break; |
default: |
ps = PAGE_WIDTH + 18; |
va &= ~((1 << ps) - 1); |
/*cnt=((cnt-1)/(16384*16))+1;*/ |
ps=PAGE_WIDTH+18; |
va&=~((1<<ps)-1); |
break; |
} |
for(; va < (page + cnt * PAGE_SIZE); va += (1 << ps)) |
asm volatile ("ptc.l %0, %1;;" :: "r" (va), "r" (ps << 2)); |
/*cnt+=(page!=va);*/ |
for(; va<(page+cnt*(PAGE_SIZE)); va += (1<<ps)) { |
asm volatile ( |
"ptc.l %0,%1;;" |
: |
: "r" (va), "r" (ps<<2) |
); |
} |
srlz_d(); |
srlz_i(); |
182,10 → 196,9 |
/** Insert data into data translation cache. |
* |
* @param va Virtual page address. |
* @param asid Address space identifier. |
* @param entry The rest of TLB entry as required by TLB insertion |
* format. |
* @param va Virtual page address. |
* @param asid Address space identifier. |
* @param entry The rest of TLB entry as required by TLB insertion format. |
*/ |
void dtc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry) |
{ |
194,10 → 207,9 |
/** Insert data into instruction translation cache. |
* |
* @param va Virtual page address. |
* @param asid Address space identifier. |
* @param entry The rest of TLB entry as required by TLB insertion |
* format. |
* @param va Virtual page address. |
* @param asid Address space identifier. |
* @param entry The rest of TLB entry as required by TLB insertion format. |
*/ |
void itc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry) |
{ |
206,12 → 218,10 |
/** Insert data into instruction or data translation cache. |
* |
* @param va Virtual page address. |
* @param asid Address space identifier. |
* @param entry The rest of TLB entry as required by TLB insertion |
* format. |
* @param dtc If true, insert into data translation cache, use |
* instruction translation cache otherwise. |
* @param va Virtual page address. |
* @param asid Address space identifier. |
* @param entry The rest of TLB entry as required by TLB insertion format. |
* @param dtc If true, insert into data translation cache, use instruction translation cache otherwise. |
*/ |
void tc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtc) |
{ |
234,20 → 244,19 |
} |
asm volatile ( |
"mov r8 = psr;;\n" |
"mov r8=psr;;\n" |
"rsm %0;;\n" /* PSR_IC_MASK */ |
"srlz.d;;\n" |
"srlz.i;;\n" |
"mov cr.ifa = %1\n" /* va */ |
"mov cr.itir = %2;;\n" /* entry.word[1] */ |
"cmp.eq p6,p7 = %4,r0;;\n" /* decide between itc and dtc */ |
"mov cr.ifa=%1\n" /* va */ |
"mov cr.itir=%2;;\n" /* entry.word[1] */ |
"cmp.eq p6,p7 = %4,r0;;\n" /* decide between itc and dtc */ |
"(p6) itc.i %3;;\n" |
"(p7) itc.d %3;;\n" |
"mov psr.l = r8;;\n" |
"mov psr.l=r8;;\n" |
"srlz.d;;\n" |
: |
: "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]), |
"r" (entry.word[0]), "r" (dtc) |
: "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]), "r" (entry.word[0]), "r" (dtc) |
: "p6", "p7", "r8" |
); |
260,14 → 269,12 |
/** Insert data into instruction translation register. |
* |
* @param va Virtual page address. |
* @param asid Address space identifier. |
* @param entry The rest of TLB entry as required by TLB insertion |
* format. |
* @param tr Translation register. |
* @param va Virtual page address. |
* @param asid Address space identifier. |
* @param entry The rest of TLB entry as required by TLB insertion format. |
* @param tr Translation register. |
*/ |
void |
itr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, size_t tr) |
void itr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, index_t tr) |
{ |
tr_mapping_insert(va, asid, entry, false, tr); |
} |
274,14 → 281,12 |
/** Insert data into data translation register. |
* |
* @param va Virtual page address. |
* @param asid Address space identifier. |
* @param entry The rest of TLB entry as required by TLB insertion |
* format. |
* @param tr Translation register. |
* @param va Virtual page address. |
* @param asid Address space identifier. |
* @param entry The rest of TLB entry as required by TLB insertion format. |
* @param tr Translation register. |
*/ |
void |
dtr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, size_t tr) |
void dtr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, index_t tr) |
{ |
tr_mapping_insert(va, asid, entry, true, tr); |
} |
288,17 → 293,13 |
/** Insert data into instruction or data translation register. |
* |
* @param va Virtual page address. |
* @param asid Address space identifier. |
* @param entry The rest of TLB entry as required by TLB insertion |
* format. |
* @param dtr If true, insert into data translation register, use |
* instruction translation register otherwise. |
* @param tr Translation register. |
* @param va Virtual page address. |
* @param asid Address space identifier. |
* @param entry The rest of TLB entry as required by TLB insertion format. |
* @param dtr If true, insert into data translation register, use instruction translation register otherwise. |
* @param tr Translation register. |
*/ |
void |
tr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtr, |
size_t tr) |
void tr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtr, index_t tr) |
{ |
region_register rr; |
bool restore_rr = false; |
319,20 → 320,19 |
} |
asm volatile ( |
"mov r8 = psr;;\n" |
"mov r8=psr;;\n" |
"rsm %0;;\n" /* PSR_IC_MASK */ |
"srlz.d;;\n" |
"srlz.i;;\n" |
"mov cr.ifa = %1\n" /* va */ |
"mov cr.itir = %2;;\n" /* entry.word[1] */ |
"cmp.eq p6,p7 = %5,r0;;\n" /* decide between itr and dtr */ |
"(p6) itr.i itr[%4] = %3;;\n" |
"(p7) itr.d dtr[%4] = %3;;\n" |
"mov psr.l = r8;;\n" |
"mov cr.ifa=%1\n" /* va */ |
"mov cr.itir=%2;;\n" /* entry.word[1] */ |
"cmp.eq p6,p7=%5,r0;;\n" /* decide between itr and dtr */ |
"(p6) itr.i itr[%4]=%3;;\n" |
"(p7) itr.d dtr[%4]=%3;;\n" |
"mov psr.l=r8;;\n" |
"srlz.d;;\n" |
: |
: "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]), |
"r" (entry.word[0]), "r" (tr), "r" (dtr) |
: "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]), "r" (entry.word[0]), "r" (tr), "r" (dtr) |
: "p6", "p7", "r8" |
); |
345,15 → 345,12 |
/** Insert data into DTLB. |
* |
* @param page Virtual page address including VRN bits. |
* @param frame Physical frame address. |
* @param dtr If true, insert into data translation register, use data |
* translation cache otherwise. |
* @param tr Translation register if dtr is true, ignored otherwise. |
* @param page Virtual page address including VRN bits. |
* @param frame Physical frame address. |
* @param dtr If true, insert into data translation register, use data translation cache otherwise. |
* @param tr Translation register if dtr is true, ignored otherwise. |
*/ |
void |
dtlb_kernel_mapping_insert(uintptr_t page, uintptr_t frame, bool dtr, |
size_t tr) |
void dtlb_kernel_mapping_insert(uintptr_t page, uintptr_t frame, bool dtr, index_t tr) |
{ |
tlb_entry_t entry; |
379,18 → 376,18 |
* |
* Purge DTR entries used by the kernel. |
* |
* @param page Virtual page address including VRN bits. |
* @param width Width of the purge in bits. |
* @param page Virtual page address including VRN bits. |
* @param width Width of the purge in bits. |
*/ |
void dtr_purge(uintptr_t page, size_t width) |
void dtr_purge(uintptr_t page, count_t width) |
{ |
asm volatile ("ptr.d %0, %1\n" : : "r" (page), "r" (width << 2)); |
asm volatile ("ptr.d %0, %1\n" : : "r" (page), "r" (width<<2)); |
} |
/** Copy content of PTE into data translation cache. |
* |
* @param t PTE. |
* @param t PTE. |
*/ |
void dtc_pte_copy(pte_t *t) |
{ |
416,7 → 413,7 |
/** Copy content of PTE into instruction translation cache. |
* |
* @param t PTE. |
* @param t PTE. |
*/ |
void itc_pte_copy(pte_t *t) |
{ |
443,8 → 440,8 |
/** Instruction TLB fault handler for faults with VHPT turned off. |
* |
* @param vector Interruption vector. |
* @param istate Structure with saved interruption state. |
* @param vector Interruption vector. |
* @param istate Structure with saved interruption state. |
*/ |
void alternate_instruction_tlb_fault(uint64_t vector, istate_t *istate) |
{ |
472,77 → 469,16 |
*/ |
page_table_unlock(AS, true); |
if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) { |
fault_if_from_uspace(istate,"Page fault at %p.",va); |
panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid, |
istate->cr_iip); |
fault_if_from_uspace(istate,"Page fault at %p",va); |
panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, istate->cr_iip); |
} |
} |
} |
static int is_io_page_accessible(int page) |
{ |
if (TASK->arch.iomap) |
return bitmap_get(TASK->arch.iomap, page); |
else |
return 0; |
} |
#define IO_FRAME_BASE 0xFFFFC000000 |
/** |
* There is special handling of memory mapped legacy io, because of 4KB sized |
* access for userspace. |
* |
* @param va Virtual address of page fault. |
* @param istate Structure with saved interruption state. |
* |
* @return One on success, zero on failure. |
*/ |
static int try_memmap_io_insertion(uintptr_t va, istate_t *istate) |
{ |
if ((va >= IO_OFFSET ) && (va < IO_OFFSET + (1 << IO_PAGE_WIDTH))) { |
if (TASK) { |
uint64_t io_page = (va & ((1 << IO_PAGE_WIDTH) - 1)) >> |
USPACE_IO_PAGE_WIDTH; |
if (is_io_page_accessible(io_page)) { |
uint64_t page, frame; |
page = IO_OFFSET + |
(1 << USPACE_IO_PAGE_WIDTH) * io_page; |
frame = IO_FRAME_BASE + |
(1 << USPACE_IO_PAGE_WIDTH) * io_page; |
tlb_entry_t entry; |
entry.word[0] = 0; |
entry.word[1] = 0; |
entry.p = true; /* present */ |
entry.ma = MA_UNCACHEABLE; |
entry.a = true; /* already accessed */ |
entry.d = true; /* already dirty */ |
entry.pl = PL_USER; |
entry.ar = AR_READ | AR_WRITE; |
entry.ppn = frame >> PPN_SHIFT; |
entry.ps = USPACE_IO_PAGE_WIDTH; |
dtc_mapping_insert(page, TASK->as->asid, entry); |
return 1; |
} else { |
fault_if_from_uspace(istate, |
"IO access fault at %p.", va); |
} |
} |
} |
return 0; |
} |
/** Data TLB fault handler for faults with VHPT turned off. |
* |
* @param vector Interruption vector. |
* @param istate Structure with saved interruption state. |
* @param vector Interruption vector. |
* @param istate Structure with saved interruption state. |
*/ |
void alternate_data_tlb_fault(uint64_t vector, istate_t *istate) |
{ |
575,17 → 511,13 |
dtc_pte_copy(t); |
page_table_unlock(AS, true); |
} else { |
page_table_unlock(AS, true); |
if (try_memmap_io_insertion(va, istate)) |
return; |
/* |
* Forward the page fault to the address space page fault |
* handler. |
* Forward the page fault to the address space page fault handler. |
*/ |
page_table_unlock(AS, true); |
if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) { |
fault_if_from_uspace(istate,"Page fault at %p.",va); |
panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid, |
istate->cr_iip); |
fault_if_from_uspace(istate,"Page fault at %p",va); |
panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, istate->cr_iip); |
} |
} |
} |
594,18 → 526,18 |
* |
* This fault should not occur. |
* |
* @param vector Interruption vector. |
* @param istate Structure with saved interruption state. |
* @param vector Interruption vector. |
* @param istate Structure with saved interruption state. |
*/ |
void data_nested_tlb_fault(uint64_t vector, istate_t *istate) |
{ |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Data Dirty bit fault handler. |
* |
* @param vector Interruption vector. |
* @param istate Structure with saved interruption state. |
* @param vector Interruption vector. |
* @param istate Structure with saved interruption state. |
*/ |
void data_dirty_bit_fault(uint64_t vector, istate_t *istate) |
{ |
630,9 → 562,10 |
dtc_pte_copy(t); |
} else { |
if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) { |
fault_if_from_uspace(istate,"Page fault at %p.",va); |
panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid, |
istate->cr_iip); |
fault_if_from_uspace(istate,"Page fault at %p",va); |
panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, istate->cr_iip); |
t->d = true; |
dtc_pte_copy(t); |
} |
} |
page_table_unlock(AS, true); |
640,8 → 573,8 |
/** Instruction access bit fault handler. |
* |
* @param vector Interruption vector. |
* @param istate Structure with saved interruption state. |
* @param vector Interruption vector. |
* @param istate Structure with saved interruption state. |
*/ |
void instruction_access_bit_fault(uint64_t vector, istate_t *istate) |
{ |
666,9 → 599,10 |
itc_pte_copy(t); |
} else { |
if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) { |
fault_if_from_uspace(istate, "Page fault at %p.", va); |
panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid, |
istate->cr_iip); |
fault_if_from_uspace(istate,"Page fault at %p",va); |
panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, istate->cr_iip); |
t->a = true; |
itc_pte_copy(t); |
} |
} |
page_table_unlock(AS, true); |
702,45 → 636,15 |
dtc_pte_copy(t); |
} else { |
if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) { |
fault_if_from_uspace(istate, "Page fault at %p.", va); |
panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid, |
istate->cr_iip); |
fault_if_from_uspace(istate,"Page fault at %p",va); |
panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, istate->cr_iip); |
t->a = true; |
itc_pte_copy(t); |
} |
} |
page_table_unlock(AS, true); |
} |
/** Data access rights fault handler. |
* |
* @param vector Interruption vector. |
* @param istate Structure with saved interruption state. |
*/ |
void data_access_rights_fault(uint64_t vector, istate_t *istate) |
{ |
region_register rr; |
rid_t rid; |
uintptr_t va; |
pte_t *t; |
va = istate->cr_ifa; /* faulting address */ |
rr.word = rr_read(VA2VRN(va)); |
rid = rr.map.rid; |
/* |
* Assume a write to a read-only page. |
*/ |
page_table_lock(AS, true); |
t = page_mapping_find(AS, va); |
ASSERT(t && t->p); |
ASSERT(!t->w); |
if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) { |
fault_if_from_uspace(istate, "Page fault at %p.", va); |
panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid, |
istate->cr_iip); |
} |
page_table_unlock(AS, true); |
} |
/** Page not present fault handler. |
* |
* @param vector Interruption vector. |
774,19 → 678,11 |
} else { |
page_table_unlock(AS, true); |
if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) { |
fault_if_from_uspace(istate, "Page fault at %p.", va); |
panic("%s: va=%p, rid=%d.", __func__, va, rid); |
fault_if_from_uspace(istate,"Page fault at %p",va); |
panic("%s: va=%p, rid=%d\n", __func__, va, rid); |
} |
} |
} |
void tlb_arch_init(void) |
{ |
} |
void tlb_print(void) |
{ |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ia64/src/mm/frame.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia64mm |
/** @addtogroup ia64mm |
* @{ |
*/ |
/** @file |
36,55 → 36,26 |
#include <mm/frame.h> |
#include <config.h> |
#include <panic.h> |
#include <arch/bootinfo.h> |
#include <align.h> |
#include <macros.h> |
#define KERNEL_RESERVED_AREA_BASE (0x4400000) |
#define KERNEL_RESERVED_AREA_SIZE (16 * 1024 * 1024) |
/* |
* This is Ski-specific and certainly not sufficient |
* for real ia64 systems that provide memory map. |
*/ |
#define MEMORY_SIZE (64 * 1024 * 1024) |
#define MEMORY_BASE (64 * 1024 * 1024) |
#define ROM_BASE 0xa0000 /* for simulators */ |
#define ROM_SIZE (384 * 1024) /* for simulators */ |
#define MIN_ZONE_SIZE (64 * 1024) |
#define MINCONF 1 |
uintptr_t last_frame = 0; |
#define ROM_BASE 0xa0000 //For ski |
#define ROM_SIZE (384 * 1024) //For ski |
void poke_char(int x,int y,char ch, char c); |
void frame_arch_init(void) |
{ |
if (config.cpu_active == 1) { |
unsigned int i; |
for (i = 0; i < bootinfo->memmap_items; i++) { |
if (bootinfo->memmap[i].type == EFI_MEMMAP_FREE_MEM) { |
uint64_t base = bootinfo->memmap[i].base; |
uint64_t size = bootinfo->memmap[i].size; |
uint64_t abase = ALIGN_UP(base, FRAME_SIZE); |
if (size > FRAME_SIZE) |
size -= abase - base; |
if (size > MIN_ZONE_SIZE) { |
zone_create(abase >> FRAME_WIDTH, |
size >> FRAME_WIDTH, |
max(MINCONF, abase >> FRAME_WIDTH), |
0); |
} |
if (abase + size > last_frame) |
last_frame = abase + size; |
} |
} |
/* |
* Blacklist ROM regions. |
*/ |
frame_mark_unavailable(ADDR2PFN(ROM_BASE), |
SIZE2FRAMES(ROM_SIZE)); |
frame_mark_unavailable(ADDR2PFN(KERNEL_RESERVED_AREA_BASE), |
SIZE2FRAMES(KERNEL_RESERVED_AREA_SIZE)); |
} |
zone_create(MEMORY_BASE >> FRAME_WIDTH, SIZE2FRAMES(MEMORY_SIZE), (MEMORY_SIZE) >> FRAME_WIDTH, 0); |
/* |
* Blacklist ROM regions. |
*/ |
frame_mark_unavailable(ADDR2PFN(ROM_BASE), SIZE2FRAMES(ROM_SIZE)); |
} |
/** @} |
/branches/arm/kernel/arch/ia64/src/mm/as.c |
---|
68,7 → 68,7 |
continue; |
rr.word = rr_read(i); |
rr.map.ve = false; /* disable VHPT walker */ |
rr.map.ve = false; /* disable VHPT walker */ |
rr.map.rid = ASID2RID(as->asid, i); |
rr.map.ps = PAGE_WIDTH; |
rr_write(i, rr.word); |
/branches/arm/kernel/arch/ia64/src/mm/page.c |
---|
27,7 → 27,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia64mm |
/** @addtogroup ia64mm |
* @{ |
*/ |
/** @file |
47,7 → 47,6 |
#include <arch/asm.h> |
#include <arch/barrier.h> |
#include <memstr.h> |
#include <align.h> |
static void set_environment(void); |
63,9 → 62,9 |
void set_environment(void) |
{ |
region_register rr; |
pta_register pta; |
pta_register pta; |
int i; |
#ifdef CONFIG_VHPT |
#ifdef CONFIG_VHPT |
uintptr_t vhpt_base; |
#endif |
123,15 → 122,15 |
* |
* Interrupts must be disabled. |
* |
* @param page Address of virtual page including VRN bits. |
* @param asid Address space identifier. |
* @param page Address of virtual page including VRN bits. |
* @param asid Address space identifier. |
* |
* @return VHPT entry address. |
* @return VHPT entry address. |
*/ |
vhpt_entry_t *vhpt_hash(uintptr_t page, asid_t asid) |
{ |
region_register rr_save, rr; |
size_t vrn; |
index_t vrn; |
rid_t rid; |
vhpt_entry_t *v; |
167,16 → 166,15 |
* |
* Interrupts must be disabled. |
* |
* @param page Address of virtual page including VRN bits. |
* @param asid Address space identifier. |
* @param page Address of virtual page including VRN bits. |
* @param asid Address space identifier. |
* |
* @return True if page and asid match the page and asid of t, |
* false otherwise. |
* @return True if page and asid match the page and asid of t, false otherwise. |
*/ |
bool vhpt_compare(uintptr_t page, asid_t asid, vhpt_entry_t *v) |
{ |
region_register rr_save, rr; |
size_t vrn; |
index_t vrn; |
rid_t rid; |
bool match; |
212,18 → 210,15 |
/** Set up one VHPT entry. |
* |
* @param v VHPT entry to be set up. |
* @param page Virtual address of the page mapped by the entry. |
* @param asid Address space identifier of the address space to which |
* page belongs. |
* @param frame Physical address of the frame to wich page is mapped. |
* @param flags Different flags for the mapping. |
* @param page Virtual address of the page mapped by the entry. |
* @param asid Address space identifier of the address space to which page belongs. |
* @param frame Physical address of the frame to wich page is mapped. |
* @param flags Different flags for the mapping. |
*/ |
void |
vhpt_set_record(vhpt_entry_t *v, uintptr_t page, asid_t asid, uintptr_t frame, |
int flags) |
void vhpt_set_record(vhpt_entry_t *v, uintptr_t page, asid_t asid, uintptr_t frame, int flags) |
{ |
region_register rr_save, rr; |
size_t vrn; |
index_t vrn; |
rid_t rid; |
uint64_t tag; |
254,8 → 249,7 |
v->word[3] = 0; |
v->present.p = true; |
v->present.ma = (flags & PAGE_CACHEABLE) ? |
MA_WRITEBACK : MA_UNCACHEABLE; |
v->present.ma = (flags & PAGE_CACHEABLE) ? MA_WRITEBACK : MA_UNCACHEABLE; |
v->present.a = false; /* not accessed */ |
v->present.d = false; /* not dirty */ |
v->present.pl = (flags & PAGE_USER) ? PL_USER : PL_KERNEL; |
268,11 → 262,5 |
v->present.tag.tag_word = tag; |
} |
uintptr_t hw_map(uintptr_t physaddr, size_t size __attribute__ ((unused))) |
{ |
/* THIS is a dirty hack. */ |
return (uintptr_t)((uint64_t)(PA2KA(physaddr)) + VIO_OFFSET); |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ia64/src/drivers/ski.c |
---|
File deleted |
Property changes: |
Deleted: svn:mergeinfo |
/branches/arm/kernel/arch/ia64/src/drivers/ega.c |
---|
0,0 → 1,139 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
* @{ |
*/ |
/** |
* @file |
* @brief EGA driver. |
*/ |
#include <putchar.h> |
#include <mm/page.h> |
#include <mm/as.h> |
#include <arch/mm/page.h> |
#include <synch/spinlock.h> |
#include <arch/types.h> |
#include <arch/asm.h> |
#include <memstr.h> |
#include <console/chardev.h> |
#include <console/console.h> |
#include <sysinfo/sysinfo.h> |
#include <arch/drivers/ega.h> |
/* |
* The EGA driver. |
* Simple and short. Function for displaying characters and "scrolling". |
*/ |
SPINLOCK_INITIALIZE(egalock); |
static uint32_t ega_cursor; |
static uint8_t *videoram; |
static void ega_putchar(chardev_t *d, const char ch); |
chardev_t ega_console; |
static chardev_operations_t ega_ops = { |
.write = ega_putchar |
}; |
void ega_init(void) |
{ |
videoram = (uint8_t *) (VIDEORAM); |
/* |
* Clear the screen. |
*/ |
_memsetw(videoram, SCREEN, 0x0720); |
chardev_initialize("ega_out", &ega_console, &ega_ops); |
stdout = &ega_console; |
sysinfo_set_item_val("fb", NULL, true); |
sysinfo_set_item_val("fb.kind", NULL, 2); |
sysinfo_set_item_val("fb.width", NULL, ROW); |
sysinfo_set_item_val("fb.height", NULL, ROWS); |
sysinfo_set_item_val("fb.address.physical", NULL, VIDEORAM); |
#ifndef CONFIG_FB |
putchar('\n'); |
#endif |
} |
static void ega_display_char(char ch) |
{ |
videoram[ega_cursor * 2] = ch; |
videoram[ega_cursor * 2 + 1] = 7; |
} |
/* |
* This function takes care of scrolling. |
*/ |
static void ega_check_cursor(void) |
{ |
if (ega_cursor < SCREEN) |
return; |
memcpy((void *) videoram, (void *) (videoram + ROW * 2), (SCREEN - ROW) * 2); |
_memsetw(videoram + (SCREEN - ROW) * 2, ROW, 0x0720); |
ega_cursor = ega_cursor - ROW; |
} |
void ega_putchar(chardev_t *d, const char ch) |
{ |
ipl_t ipl; |
ipl = interrupts_disable(); |
spinlock_lock(&egalock); |
switch (ch) { |
case '\n': |
ega_cursor = (ega_cursor + ROW) - ega_cursor % ROW; |
break; |
case '\t': |
ega_cursor = (ega_cursor + 8) - ega_cursor % 8; |
break; |
case '\b': |
if (ega_cursor % ROW) |
ega_cursor--; |
break; |
default: |
ega_display_char(ch); |
ega_cursor++; |
break; |
} |
ega_check_cursor(); |
spinlock_unlock(&egalock); |
interrupts_restore(ipl); |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ia64/src/drivers/it.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia64 |
/** @addtogroup ia64 |
* @{ |
*/ |
/** @file |
44,44 → 44,25 |
#include <ddi/device.h> |
#include <arch.h> |
#define IT_SERVICE_CLOCKS 64 |
#define IT_SERVICE_CLOCKS 64 |
#define FREQ_NUMERATOR_SHIFT 32 |
#define FREQ_NUMERATOR_MASK 0xffffffff00000000ULL |
#define FREQ_DENOMINATOR_SHIFT 0 |
#define FREQ_DENOMINATOR_MASK 0xffffffffULL |
uint64_t it_delta; |
static irq_t it_irq; |
static irq_ownership_t it_claim(irq_t *); |
static void it_interrupt(irq_t *); |
static irq_ownership_t it_claim(void); |
static void it_interrupt(irq_t *irq, void *arg, ...); |
/** Initialize Interval Timer. */ |
void it_init(void) |
{ |
cr_itv_t itv; |
if (config.cpu_active == 1) { |
irq_initialize(&it_irq); |
it_irq.inr = INTERRUPT_TIMER; |
it_irq.devno = device_assign_devno(); |
it_irq.claim = it_claim; |
it_irq.handler = it_interrupt; |
irq_register(&it_irq); |
uint64_t base_freq; |
base_freq = ((bootinfo->freq_scale) & FREQ_NUMERATOR_MASK) >> |
FREQ_NUMERATOR_SHIFT; |
base_freq *= bootinfo->sys_freq; |
base_freq /= ((bootinfo->freq_scale) & FREQ_DENOMINATOR_MASK) >> |
FREQ_DENOMINATOR_SHIFT; |
it_delta = base_freq / HZ; |
} |
irq_initialize(&it_irq); |
it_irq.inr = INTERRUPT_TIMER; |
it_irq.devno = device_assign_devno(); |
it_irq.claim = it_claim; |
it_irq.handler = it_interrupt; |
irq_register(&it_irq); |
/* initialize Interval Timer external interrupt vector */ |
itv.value = itv_read(); |
itv.vector = INTERRUPT_TIMER; |
104,13 → 85,13 |
* |
* @return Always IRQ_ACCEPT. |
*/ |
irq_ownership_t it_claim(irq_t *irq) |
irq_ownership_t it_claim(void) |
{ |
return IRQ_ACCEPT; |
} |
/** Process Interval Timer interrupt. */ |
void it_interrupt(irq_t *irq) |
void it_interrupt(irq_t *irq, void *arg, ...) |
{ |
int64_t c; |
int64_t m; |
/branches/arm/kernel/arch/ia64/src/ia64.c |
---|
33,7 → 33,7 |
*/ |
#include <arch.h> |
#include <arch/drivers/ski.h> |
#include <arch/ski/ski.h> |
#include <arch/drivers/it.h> |
#include <arch/interrupt.h> |
#include <arch/barrier.h> |
50,91 → 50,64 |
#include <proc/uarg.h> |
#include <syscall/syscall.h> |
#include <ddi/irq.h> |
#include <ddi/device.h> |
#include <arch/drivers/ega.h> |
#include <arch/bootinfo.h> |
#include <genarch/drivers/legacy/ia32/io.h> |
#include <genarch/drivers/ega/ega.h> |
#include <genarch/kbrd/kbrd.h> |
#include <genarch/srln/srln.h> |
#include <genarch/drivers/i8042/i8042.h> |
#include <genarch/drivers/ns16550/ns16550.h> |
#include <arch/drivers/kbd.h> |
#include <smp/smp.h> |
#include <smp/ipi.h> |
#include <arch/atomic.h> |
#include <panic.h> |
#include <print.h> |
#include <sysinfo/sysinfo.h> |
#include <string.h> |
#include <genarch/kbd/i8042.h> |
/* NS16550 as a COM 1 */ |
#define NS16550_IRQ (4 + LEGACY_INTERRUPT_BASE) |
bootinfo_t *bootinfo; |
static uint64_t iosapic_base = 0xfec00000; |
/** Performs ia64-specific initialization before main_bsp() is called. */ |
void arch_pre_main(void) |
{ |
/* Setup usermode init tasks. */ |
//#ifdef I460GX |
unsigned int i; |
init.cnt = bootinfo->taskmap.count; |
for (i = 0; i < init.cnt; i++) { |
init.tasks[i].addr = |
((unsigned long) bootinfo->taskmap.tasks[i].addr) | |
VRN_MASK; |
init.tasks[i].addr = ((unsigned long) bootinfo->taskmap.tasks[i].addr) | VRN_MASK; |
init.tasks[i].size = bootinfo->taskmap.tasks[i].size; |
str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN, |
bootinfo->taskmap.tasks[i].name); |
} |
/* |
#else |
init.cnt = 8; |
init.tasks[0].addr = INIT0_ADDRESS; |
init.tasks[0].size = INIT0_SIZE; |
init.tasks[1].addr = INIT0_ADDRESS + 0x400000; |
init.tasks[1].size = INIT0_SIZE; |
init.tasks[2].addr = INIT0_ADDRESS + 0x800000; |
init.tasks[2].size = INIT0_SIZE; |
init.tasks[3].addr = INIT0_ADDRESS + 0xc00000; |
init.tasks[3].size = INIT0_SIZE; |
init.tasks[4].addr = INIT0_ADDRESS + 0x1000000; |
init.tasks[4].size = INIT0_SIZE; |
init.tasks[5].addr = INIT0_ADDRESS + 0x1400000; |
init.tasks[5].size = INIT0_SIZE; |
init.tasks[6].addr = INIT0_ADDRESS + 0x1800000; |
init.tasks[6].size = INIT0_SIZE; |
init.tasks[7].addr = INIT0_ADDRESS + 0x1c00000; |
init.tasks[7].size = INIT0_SIZE; |
#endif*/ |
} |
void arch_pre_mm_init(void) |
{ |
/* |
* Set Interruption Vector Address (i.e. location of interruption vector |
* table). |
*/ |
/* Set Interruption Vector Address (i.e. location of interruption vector table). */ |
iva_write((uintptr_t) &ivt); |
srlz_d(); |
} |
static void iosapic_init(void) |
{ |
uint64_t IOSAPIC = PA2KA((unative_t)(iosapic_base)) | FW_OFFSET; |
int i; |
int myid, myeid; |
myid = ia64_get_cpu_id(); |
myeid = ia64_get_cpu_eid(); |
for (i = 0; i < 16; i++) { |
if (i == 2) |
continue; /* Disable Cascade interrupt */ |
((uint32_t *)(IOSAPIC + 0x00))[0] = 0x10 + 2 * i; |
srlz_d(); |
((uint32_t *)(IOSAPIC + 0x10))[0] = LEGACY_INTERRUPT_BASE + i; |
srlz_d(); |
((uint32_t *)(IOSAPIC + 0x00))[0] = 0x10 + 2 * i + 1; |
srlz_d(); |
((uint32_t *)(IOSAPIC + 0x10))[0] = myid << (56 - 32) | |
myeid << (48 - 32); |
srlz_d(); |
} |
} |
void arch_post_mm_init(void) |
{ |
if (config.cpu_active == 1) { |
iosapic_init(); |
irq_init(INR_COUNT, INR_COUNT); |
} |
irq_init(INR_COUNT, INR_COUNT); |
#ifdef SKI |
ski_init_console(); |
#else |
ega_init(); |
#endif |
it_init(); |
} |
146,73 → 119,51 |
{ |
} |
void arch_post_smp_init(void) |
#ifdef I460GX |
#define POLL_INTERVAL 50000 /* 50 ms */ |
/** Kernel thread for polling keyboard. */ |
static void i8042_kkbdpoll(void *arg) |
{ |
#ifdef MACHINE_ski |
ski_instance_t *ski_instance = skiin_init(); |
if (ski_instance) { |
srln_instance_t *srln_instance = srln_init(); |
if (srln_instance) { |
indev_t *sink = stdin_wire(); |
indev_t *srln = srln_wire(srln_instance, sink); |
skiin_wire(ski_instance, srln); |
} |
while (1) { |
i8042_poll(); |
thread_usleep(POLL_INTERVAL); |
} |
skiout_init(); |
} |
#endif |
#ifdef CONFIG_EGA |
ega_init(EGA_BASE, EGA_VIDEORAM); |
void arch_post_smp_init(void) |
{ |
if (config.cpu_active == 1) { |
/* |
* Create thread that polls keyboard. |
*/ |
#ifdef SKI |
thread_t *t; |
t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll", true); |
if (!t) |
panic("cannot create kkbdpoll\n"); |
thread_ready(t); |
#endif |
#ifdef I460GX |
devno_t kbd = device_assign_devno(); |
devno_t mouse = device_assign_devno(); |
/* keyboard controller */ |
i8042_init(kbd, IRQ_KBD, mouse, IRQ_MOUSE); |
thread_t *t; |
t = thread_create(i8042_kkbdpoll, NULL, TASK, 0, "kkbdpoll", true); |
if (!t) |
panic("cannot create kkbdpoll\n"); |
thread_ready(t); |
#endif |
#ifdef CONFIG_NS16550 |
ns16550_instance_t *ns16550_instance |
= ns16550_init((ns16550_t *) NS16550_BASE, NS16550_IRQ, NULL, NULL); |
if (ns16550_instance) { |
srln_instance_t *srln_instance = srln_init(); |
if (srln_instance) { |
indev_t *sink = stdin_wire(); |
indev_t *srln = srln_wire(srln_instance, sink); |
ns16550_wire(ns16550_instance, srln); |
} |
} |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.inr", NULL, NS16550_IRQ); |
sysinfo_set_item_val("kbd.type", NULL, KBD_NS16550); |
sysinfo_set_item_val("kbd.address.physical", NULL, |
(uintptr_t) NS16550_BASE); |
sysinfo_set_item_val("kbd.address.kernel", NULL, |
(uintptr_t) NS16550_BASE); |
#endif |
#ifdef CONFIG_I8042 |
i8042_instance_t *i8042_instance = i8042_init((i8042_t *) I8042_BASE, IRQ_KBD); |
if (i8042_instance) { |
kbrd_instance_t *kbrd_instance = kbrd_init(); |
if (kbrd_instance) { |
indev_t *sink = stdin_wire(); |
indev_t *kbrd = kbrd_wire(kbrd_instance, sink); |
i8042_wire(i8042_instance, kbrd); |
} |
} |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.inr", NULL, IRQ_KBD); |
sysinfo_set_item_val("kbd.type", NULL, KBD_LEGACY); |
sysinfo_set_item_val("kbd.address.physical", NULL, |
(uintptr_t) I8042_BASE); |
sysinfo_set_item_val("kbd.address.kernel", NULL, |
(uintptr_t) I8042_BASE); |
#endif |
sysinfo_set_item_val("ia64_iospace", NULL, true); |
sysinfo_set_item_val("ia64_iospace.address", NULL, true); |
sysinfo_set_item_val("ia64_iospace.address.virtual", NULL, IO_OFFSET); |
} |
/** Enter userspace and never return. */ |
void userspace(uspace_arg_t *kernel_uarg) |
{ |
221,25 → 172,26 |
psr.value = psr_read(); |
psr.cpl = PL_USER; |
psr.i = true; /* start with interrupts enabled */ |
psr.i = true; /* start with interrupts enabled */ |
psr.ic = true; |
psr.ri = 0; /* start with instruction #0 */ |
psr.bn = 1; /* start in bank 0 */ |
psr.ri = 0; /* start with instruction #0 */ |
psr.bn = 1; /* start in bank 0 */ |
asm volatile ("mov %0 = ar.rsc\n" : "=r" (rsc.value)); |
rsc.loadrs = 0; |
rsc.be = false; |
rsc.pl = PL_USER; |
rsc.mode = 3; /* eager mode */ |
rsc.mode = 3; /* eager mode */ |
switch_to_userspace((uintptr_t) kernel_uarg->uspace_entry, |
((uintptr_t) kernel_uarg->uspace_stack) + PAGE_SIZE - |
ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT), |
((uintptr_t) kernel_uarg->uspace_stack) + PAGE_SIZE, |
(uintptr_t) kernel_uarg->uspace_uarg, psr.value, rsc.value); |
((uintptr_t) kernel_uarg->uspace_stack)+PAGE_SIZE-ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT), |
((uintptr_t) kernel_uarg->uspace_stack)+PAGE_SIZE, |
(uintptr_t) kernel_uarg->uspace_uarg, |
psr.value, rsc.value); |
while (1) |
while (1) { |
; |
} |
} |
/** Set thread-local-storage pointer. |
256,17 → 208,16 |
*/ |
void arch_grab_console(void) |
{ |
#ifdef MACHINE_ski |
#ifdef SKI |
ski_kbd_grab(); |
#endif |
#endif |
} |
/** Return console to userspace |
* |
*/ |
void arch_release_console(void) |
{ |
#ifdef MACHINE_ski |
#ifdef SKI |
ski_kbd_release(); |
#endif |
} |
273,27 → 224,9 |
void arch_reboot(void) |
{ |
pio_write_8((ioport8_t *)0x64, 0xfe); |
while (1) |
; |
// TODO |
while (1); |
} |
/** Construct function pointer |
* |
* @param fptr function pointer structure |
* @param addr function address |
* @param caller calling function address |
* |
* @return address of the function pointer |
* |
*/ |
void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller) |
{ |
fptr->fnc = (unative_t) addr; |
fptr->gp = ((unative_t *) caller)[1]; |
return (void *) fptr; |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ia64/src/start.S |
---|
32,15 → 32,19 |
#include <mm/asid.h> |
#define RR_MASK (0xFFFFFFFF00000002) |
#define RID_SHIFT 8 |
#define PS_SHIFT 2 |
#define RID_SHIFT 8 |
#define PS_SHIFT 2 |
#define KERNEL_TRANSLATION_I 0x0010000000000661 |
#define KERNEL_TRANSLATION_D 0x0010000000000661 |
#define KERNEL_TRANSLATION_VIO 0x0010000000000671 |
#define KERNEL_TRANSLATION_IO 0x00100FFFFC000671 |
#define KERNEL_TRANSLATION_FW 0x00100000F0000671 |
#define KERNEL_TRANSLATION_I 0x0010000000000661 |
#define KERNEL_TRANSLATION_D 0x0010000000000661 |
#define KERNEL_TRANSLATION_VIO 0x0010000000000671 |
#define KERNEL_TRANSLATION_IO 0x00100FFFFC000671 |
#define VIO_OFFSET 0x0002000000000000 |
#define IO_OFFSET 0x0001000000000000 |
.section K_TEXT_START, "ax" |
.global kernel_image_start |
49,19 → 53,6 |
kernel_image_start: |
.auto |
#ifdef CONFIG_SMP |
# Identify self(CPU) in OS structures by ID / EID |
mov r9 = cr64 |
mov r10 = 1 |
movl r12 = 0xffffffff |
movl r8 = cpu_by_id_eid_list |
and r8 = r8, r12 |
shr r9 = r9, 16 |
add r8 = r8, r9 |
st1 [r8] = r10 |
#endif |
mov psr.l = r0 |
srlz.i |
srlz.d |
68,29 → 59,39 |
# Fill TR.i and TR.d using Region Register #VRN_KERNEL |
movl r8 = (VRN_KERNEL << VRN_SHIFT) |
mov r9 = rr[r8] |
movl r10 = (RR_MASK) |
and r9 = r10, r9 |
movl r10 = ((RID_KERNEL << RID_SHIFT) | (KERNEL_PAGE_WIDTH << PS_SHIFT)) |
or r9 = r10, r9 |
mov rr[r8] = r9 |
movl r8 = (VRN_KERNEL << VRN_SHIFT) |
mov cr.ifa = r8 |
mov r11 = cr.itir |
movl r10 = (KERNEL_PAGE_WIDTH << PS_SHIFT) |
or r10 = r10, r11 |
mov cr.itir = r10 |
mov r11 = cr.itir ;; |
movl r10 = (KERNEL_PAGE_WIDTH << PS_SHIFT);; |
or r10 =r10 , r11 ;; |
mov cr.itir = r10;; |
movl r10 = (KERNEL_TRANSLATION_I) |
itr.i itr[r0] = r10 |
movl r10 = (KERNEL_TRANSLATION_D) |
itr.d dtr[r0] = r10 |
movl r7 = 1 |
movl r8 = (VRN_KERNEL << VRN_SHIFT) | VIO_OFFSET |
mov cr.ifa = r8 |
97,13 → 98,15 |
movl r10 = (KERNEL_TRANSLATION_VIO) |
itr.d dtr[r7] = r10 |
mov r11 = cr.itir |
movl r10 = ~0xfc |
and r10 = r10, r11 |
movl r11 = (IO_PAGE_WIDTH << PS_SHIFT) |
or r10 = r10, r11 |
mov cr.itir = r10 |
mov r11 = cr.itir ;; |
movl r10 = ~0xfc;; |
and r10 =r10 , r11 ;; |
movl r11 = (IO_PAGE_WIDTH << PS_SHIFT);; |
or r10 =r10 , r11 ;; |
mov cr.itir = r10;; |
movl r7 = 2 |
movl r8 = (VRN_KERNEL << VRN_SHIFT) | IO_OFFSET |
mov cr.ifa = r8 |
110,26 → 113,12 |
movl r10 = (KERNEL_TRANSLATION_IO) |
itr.d dtr[r7] = r10 |
# Setup mapping for fimware arrea (also SAPIC) |
mov r11 = cr.itir |
movl r10 = ~0xfc |
and r10 = r10, r11 |
movl r11 = (FW_PAGE_WIDTH << PS_SHIFT) |
or r10 = r10, r11 |
mov cr.itir = r10 |
movl r7 = 3 |
movl r8 = (VRN_KERNEL << VRN_SHIFT) | FW_OFFSET |
mov cr.ifa = r8 |
movl r10 = (KERNEL_TRANSLATION_FW) |
itr.d dtr[r7] = r10 |
# Initialize PSR |
# initialize PSR |
movl r10 = (PSR_DT_MASK | PSR_RT_MASK | PSR_IT_MASK | PSR_IC_MASK) /* Enable paging */ |
mov r9 = psr |
or r10 = r10, r9 |
mov cr.ipsr = r10 |
mov cr.ifs = r0 |
139,14 → 128,11 |
srlz.i |
.explicit |
/* |
* Return From Interrupt is the only way to |
* fill the upper half word of PSR. |
* Return From Interupt is the only the way to fill upper half word of PSR. |
*/ |
rfi ;; |
rfi;; |
.global paging_start |
paging_start: |
154,64 → 140,45 |
* Now we are paging. |
*/ |
# Switch to register bank 1 |
# switch to register bank 1 |
bsw.1 |
#ifdef CONFIG_SMP |
# Am I BSP or AP? |
movl r20 = bsp_started ;; |
ld8 r20 = [r20] ;; |
cmp.eq p3, p2 = r20, r0 ;; |
#else |
cmp.eq p3, p2 = r0, r0 ;; /* you are BSP */ |
#endif /* CONFIG_SMP */ |
# Initialize register stack |
# initialize register stack |
mov ar.rsc = r0 |
movl r8 = (VRN_KERNEL << VRN_SHIFT) ;; |
mov ar.bspstore = r8 |
loadrs |
# Initialize memory stack to some sane value |
# initialize memory stack to some sane value |
movl r12 = stack0 ;; |
add r12 = -16, r12 /* allocate a scratch area on the stack */ |
# Initialize gp (Global Pointer) register |
# initialize gp (Global Pointer) register |
movl r20 = (VRN_KERNEL << VRN_SHIFT);; |
or r20 = r20,r1;; |
movl r1 = _hardcoded_load_address |
/* |
* Initialize hardcoded_* variables. Do only BSP |
* Initialize hardcoded_* variables. |
*/ |
(p3) movl r14 = _hardcoded_ktext_size |
(p3) movl r15 = _hardcoded_kdata_size |
(p3) movl r16 = _hardcoded_load_address ;; |
(p3) addl r17 = @gprel(hardcoded_ktext_size), gp |
(p3) addl r18 = @gprel(hardcoded_kdata_size), gp |
(p3) addl r19 = @gprel(hardcoded_load_address), gp |
(p3) addl r21 = @gprel(bootinfo), gp |
movl r14 = _hardcoded_ktext_size |
movl r15 = _hardcoded_kdata_size |
movl r16 = _hardcoded_load_address ;; |
addl r17 = @gprel(hardcoded_ktext_size), gp |
addl r18 = @gprel(hardcoded_kdata_size), gp |
addl r19 = @gprel(hardcoded_load_address), gp |
addl r21 = @gprel(bootinfo), gp |
;; |
(p3) st8 [r17] = r14 |
(p3) st8 [r18] = r15 |
(p3) st8 [r19] = r16 |
(p3) st8 [r21] = r20 |
st8 [r17] = r14 |
st8 [r18] = r15 |
st8 [r19] = r16 |
st8 [r21] = r20 |
ssm (1 << 19) ;; /* Disable f32 - f127 */ |
srlz.i |
srlz.d ;; |
#ifdef CONFIG_SMP |
(p2) movl r18 = main_ap ;; |
(p2) mov b1 = r18 ;; |
(p2) br.call.sptk.many b0 = b1 |
# Mark that BSP is on |
mov r20 = 1 ;; |
movl r21 = bsp_started ;; |
st8 [r21] = r20 ;; |
#endif |
br.call.sptk.many b0 = arch_pre_main |
movl r18 = main_bsp ;; |
218,51 → 185,6 |
mov b1 = r18 ;; |
br.call.sptk.many b0 = b1 |
0: |
br 0b |
#ifdef CONFIG_SMP |
.align 4096 |
kernel_image_ap_start: |
.auto |
# Identify self(CPU) in OS structures by ID / EID |
mov r9 = cr64 |
mov r10 = 1 |
movl r12 = 0xffffffff |
movl r8 = cpu_by_id_eid_list |
and r8 = r8, r12 |
shr r9 = r9, 16 |
add r8 = r8, r9 |
st1 [r8] = r10 |
# Wait for wakeup synchro signal (#3 in cpu_by_id_eid_list) |
kernel_image_ap_start_loop: |
movl r11 = kernel_image_ap_start_loop |
and r11 = r11, r12 |
mov b1 = r11 |
ld1 r20 = [r8] ;; |
movl r21 = 3 ;; |
cmp.eq p2, p3 = r20, r21 ;; |
(p3) br.call.sptk.many b0 = b1 |
movl r11 = kernel_image_start |
and r11 = r11, r12 |
mov b1 = r11 |
br.call.sptk.many b0 = b1 |
.align 16 |
.global bsp_started |
bsp_started: |
.space 8 |
.align 4096 |
.global cpu_by_id_eid_list |
cpu_by_id_eid_list: |
.space 65536 |
#endif /* CONFIG_SMP */ |
/branches/arm/kernel/arch/ia64/src/ivt.S |
---|
536,7 → 536,7 |
HEAVYWEIGHT_HANDLER 0x5000 page_not_present |
HEAVYWEIGHT_HANDLER 0x5100 |
HEAVYWEIGHT_HANDLER 0x5200 |
HEAVYWEIGHT_HANDLER 0x5300 data_access_rights_fault |
HEAVYWEIGHT_HANDLER 0x5300 |
HEAVYWEIGHT_HANDLER 0x5400 general_exception |
HEAVYWEIGHT_HANDLER 0x5500 disabled_fp_register |
HEAVYWEIGHT_HANDLER 0x5600 |
/branches/arm/kernel/arch/ia64/src/interrupt.c |
---|
38,6 → 38,7 |
#include <ddi/irq.h> |
#include <panic.h> |
#include <print.h> |
#include <symtab.h> |
#include <debug.h> |
#include <console/console.h> |
#include <arch/types.h> |
52,9 → 53,6 |
#include <ipc/irq.h> |
#include <ipc/ipc.h> |
#include <synch/spinlock.h> |
#include <mm/tlb.h> |
#include <symtab.h> |
#include <putchar.h> |
#define VECTORS_64_BUNDLE 20 |
#define VECTORS_16_BUNDLE 48 |
138,9 → 136,9 |
{ |
char *ifa, *iipa, *iip; |
ifa = symtab_fmt_name_lookup(istate->cr_ifa); |
iipa = symtab_fmt_name_lookup(istate->cr_iipa); |
iip = symtab_fmt_name_lookup(istate->cr_iip); |
ifa = get_symtab_entry(istate->cr_ifa); |
iipa = get_symtab_entry(istate->cr_iipa); |
iip = get_symtab_entry(istate->cr_iip); |
putchar('\n'); |
printf("Interrupted context dump:\n"); |
187,21 → 185,21 |
break; |
} |
fault_if_from_uspace(istate, "General Exception (%s).", desc); |
fault_if_from_uspace(istate, "General Exception (%s)", desc); |
dump_interrupted_context(istate); |
panic("General Exception (%s).", desc); |
panic("General Exception (%s)\n", desc); |
} |
void disabled_fp_register(uint64_t vector, istate_t *istate) |
{ |
#ifdef CONFIG_FPU_LAZY |
scheduler_fpu_lazy_request(); |
#ifdef CONFIG_FPU_LAZY |
scheduler_fpu_lazy_request(); |
#else |
fault_if_from_uspace(istate, "Interruption: %#hx (%s).", |
fault_if_from_uspace(istate, "Interruption: %#hx (%s)", |
(uint16_t) vector, vector_to_string(vector)); |
dump_interrupted_context(istate); |
panic("Interruption: %#hx (%s).", (uint16_t) vector, |
panic("Interruption: %#hx (%s)\n", (uint16_t) vector, |
vector_to_string(vector)); |
#endif |
} |
229,82 → 227,40 |
void universal_handler(uint64_t vector, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "Interruption: %#hx (%s).", |
fault_if_from_uspace(istate, "Interruption: %#hx (%s)\n", |
(uint16_t) vector, vector_to_string(vector)); |
dump_interrupted_context(istate); |
panic("Interruption: %#hx (%s).", (uint16_t) vector, |
panic("Interruption: %#hx (%s)\n", (uint16_t) vector, |
vector_to_string(vector)); |
} |
static void end_of_local_irq(void) |
{ |
asm volatile ("mov cr.eoi=r0;;"); |
} |
void external_interrupt(uint64_t vector, istate_t *istate) |
{ |
irq_t *irq; |
cr_ivr_t ivr; |
irq_t *irq; |
ivr.value = ivr_read(); |
srlz_d(); |
switch (ivr.vector) { |
case INTERRUPT_SPURIOUS: |
irq = irq_dispatch_and_lock(ivr.vector); |
if (irq) { |
irq->handler(irq, irq->arg); |
spinlock_unlock(&irq->lock); |
} else { |
switch (ivr.vector) { |
case INTERRUPT_SPURIOUS: |
#ifdef CONFIG_DEBUG |
printf("cpu%d: spurious interrupt\n", CPU->id); |
printf("cpu%d: spurious interrupt\n", CPU->id); |
#endif |
break; |
break; |
#ifdef CONFIG_SMP |
case VECTOR_TLB_SHOOTDOWN_IPI: |
tlb_shootdown_ipi_recv(); |
end_of_local_irq(); |
break; |
#endif |
case INTERRUPT_TIMER: |
irq = irq_dispatch_and_lock(ivr.vector); |
if (irq) { |
irq->handler(irq); |
spinlock_unlock(&irq->lock); |
} else { |
panic("Unhandled Internal Timer Interrupt (%d).", |
default: |
panic("\nUnhandled External Interrupt Vector %d\n", |
ivr.vector); |
break; |
} |
break; |
default: |
irq = irq_dispatch_and_lock(ivr.vector); |
if (irq) { |
/* |
* The IRQ handler was found. |
*/ |
if (irq->preack) { |
/* Send EOI before processing the interrupt */ |
end_of_local_irq(); |
} |
irq->handler(irq); |
if (!irq->preack) |
end_of_local_irq(); |
spinlock_unlock(&irq->lock); |
} else { |
/* |
* Unhandled interrupt. |
*/ |
end_of_local_irq(); |
#ifdef CONFIG_DEBUG |
printf("\nUnhandled External Interrupt Vector %d\n", |
ivr.vector); |
#endif |
} |
break; |
} |
} |
void trap_virtual_enable_irqs(uint16_t irqmask) |
{ |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ia64/src/cpu/cpu.c |
---|
55,7 → 55,7 |
*((uint64_t *) &vendor[0 * sizeof(uint64_t)]) = CPU->arch.cpuid0; |
*((uint64_t *) &vendor[1 * sizeof(uint64_t)]) = CPU->arch.cpuid1; |
vendor[sizeof(vendor) - 1] = 0; |
vendor[sizeof(vendor) - 1] = '\0'; |
switch(m->arch.cpuid3.family) { |
case FAMILY_ITANIUM: |
70,8 → 70,8 |
} |
printf("cpu%d: %s (%s), archrev=%d, model=%d, revision=%d\n", CPU->id, |
family_str, vendor, CPU->arch.cpuid3.archrev, |
CPU->arch.cpuid3.model, CPU->arch.cpuid3.revision); |
family_str, vendor, CPU->arch.cpuid3.archrev, CPU->arch.cpuid3.model, |
CPU->arch.cpuid3.revision); |
} |
/** @} |
/branches/arm/kernel/arch/ia64/src/ski/ski.c |
---|
0,0 → 1,264 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia64 |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/ski/ski.h> |
#include <console/console.h> |
#include <console/chardev.h> |
#include <arch/interrupt.h> |
#include <sysinfo/sysinfo.h> |
#include <arch/types.h> |
#include <ddi/device.h> |
#include <ddi/irq.h> |
#include <ipc/irq.h> |
#include <proc/thread.h> |
#include <synch/spinlock.h> |
#include <arch/asm.h> |
#define SKI_KBD_INR 0 |
static irq_t ski_kbd_irq; |
static devno_t ski_kbd_devno; |
chardev_t ski_console; |
chardev_t ski_uconsole; |
static bool kbd_disabled; |
static void ski_putchar(chardev_t *d, const char ch); |
static int32_t ski_getchar(void); |
/** Display character on debug console |
* |
* Use SSC (Simulator System Call) to |
* display character on debug console. |
* |
* @param d Character device. |
* @param ch Character to be printed. |
*/ |
void ski_putchar(chardev_t *d, const char ch) |
{ |
asm volatile ( |
"mov r15 = %0\n" |
"mov r32 = %1\n" /* r32 is in0 */ |
"break 0x80000\n" /* modifies r8 */ |
: |
: "i" (SKI_PUTCHAR), "r" (ch) |
: "r15", "in0", "r8" |
); |
if (ch == '\n') |
ski_putchar(d, '\r'); |
} |
/** Ask debug console if a key was pressed. |
* |
* Use SSC (Simulator System Call) to |
* get character from debug console. |
* |
* This call is non-blocking. |
* |
* @return ASCII code of pressed key or 0 if no key pressed. |
*/ |
int32_t ski_getchar(void) |
{ |
uint64_t ch; |
asm volatile ( |
"mov r15 = %1\n" |
"break 0x80000;;\n" /* modifies r8 */ |
"mov %0 = r8;;\n" |
: "=r" (ch) |
: "i" (SKI_GETCHAR) |
: "r15", "r8" |
); |
return (int32_t) ch; |
} |
/** |
* This is a blocking wrapper for ski_getchar(). |
* To be used when the kernel crashes. |
*/ |
static char ski_getchar_blocking(chardev_t *d) |
{ |
int ch; |
while(!(ch = ski_getchar())) |
; |
if(ch == '\r') |
ch = '\n'; |
return (char) ch; |
} |
/** Ask keyboard if a key was pressed. */ |
static void poll_keyboard(void) |
{ |
char ch; |
static char last; |
ipl_t ipl; |
ipl = interrupts_disable(); |
if (kbd_disabled) { |
interrupts_restore(ipl); |
return; |
} |
spinlock_lock(&ski_kbd_irq.lock); |
ch = ski_getchar(); |
if(ch == '\r') |
ch = '\n'; |
if (ch) { |
if (ski_kbd_irq.notif_cfg.notify && ski_kbd_irq.notif_cfg.answerbox) { |
chardev_push_character(&ski_uconsole, ch); |
ipc_irq_send_notif(&ski_kbd_irq); |
} else { |
chardev_push_character(&ski_console, ch); |
} |
last = ch; |
spinlock_unlock(&ski_kbd_irq.lock); |
interrupts_restore(ipl); |
return; |
} |
if (last) { |
if (ski_kbd_irq.notif_cfg.notify && ski_kbd_irq.notif_cfg.answerbox) { |
chardev_push_character(&ski_uconsole, 0); |
ipc_irq_send_notif(&ski_kbd_irq); |
} |
last = 0; |
} |
spinlock_unlock(&ski_kbd_irq.lock); |
interrupts_restore(ipl); |
} |
/* Called from getc(). */ |
static void ski_kbd_enable(chardev_t *d) |
{ |
kbd_disabled = false; |
} |
/* Called from getc(). */ |
static void ski_kbd_disable(chardev_t *d) |
{ |
kbd_disabled = true; |
} |
/** Decline to service hardware IRQ. |
* |
* This is only a virtual IRQ, so always decline. |
* |
* @return Always IRQ_DECLINE. |
*/ |
static irq_ownership_t ski_kbd_claim(void) |
{ |
return IRQ_DECLINE; |
} |
static chardev_operations_t ski_ops = { |
.resume = ski_kbd_enable, |
.suspend = ski_kbd_disable, |
.write = ski_putchar, |
.read = ski_getchar_blocking |
}; |
/** Initialize debug console |
* |
* Issue SSC (Simulator System Call) to |
* to open debug console. |
*/ |
void ski_init_console(void) |
{ |
asm volatile ( |
"mov r15 = %0\n" |
"break 0x80000\n" |
: |
: "i" (SKI_INIT_CONSOLE) |
: "r15", "r8" |
); |
chardev_initialize("ski_console", &ski_console, &ski_ops); |
chardev_initialize("ski_uconsole", &ski_uconsole, &ski_ops); |
stdin = &ski_console; |
stdout = &ski_console; |
ski_kbd_devno = device_assign_devno(); |
irq_initialize(&ski_kbd_irq); |
ski_kbd_irq.inr = SKI_KBD_INR; |
ski_kbd_irq.devno = ski_kbd_devno; |
ski_kbd_irq.claim = ski_kbd_claim; |
irq_register(&ski_kbd_irq); |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.inr", NULL, SKI_KBD_INR); |
sysinfo_set_item_val("kbd.devno", NULL, ski_kbd_devno); |
} |
void ski_kbd_grab(void) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&ski_kbd_irq.lock); |
ski_kbd_irq.notif_cfg.notify = false; |
spinlock_unlock(&ski_kbd_irq.lock); |
interrupts_restore(ipl); |
} |
void ski_kbd_release(void) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&ski_kbd_irq.lock); |
if (ski_kbd_irq.notif_cfg.answerbox) |
ski_kbd_irq.notif_cfg.notify = true; |
spinlock_unlock(&ski_kbd_irq.lock); |
interrupts_restore(ipl); |
} |
#define POLL_INTERVAL 50000 /* 50 ms */ |
/** Kernel thread for polling keyboard. */ |
void kkbdpoll(void *arg) |
{ |
while (1) { |
poll_keyboard(); |
thread_usleep(POLL_INTERVAL); |
} |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ia64/src/ddi/ddi.c |
---|
1,6 → 1,5 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* Copyright (c) 2008 Jakub vana |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
36,39 → 35,19 |
#include <ddi/ddi.h> |
#include <proc/task.h> |
#include <arch/types.h> |
#include <mm/slab.h> |
#include <errno.h> |
#define IO_MEMMAP_PAGES 16384 |
#define PORTS_PER_PAGE 4 |
/** Enable I/O space range for task. |
* |
* Interrupts are disabled and task is locked. |
* |
* @param task Task. |
* @param ioaddr Starting I/O space address. |
* @param size Size of the enabled I/O range. |
* @param task Task. |
* @param ioaddr Startign I/O space address. |
* @param size Size of the enabled I/O range. |
* |
* @return 0 on success or an error code from errno.h. |
*/ |
int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size) |
{ |
if (!task->arch.iomap) { |
uint8_t *map; |
task->arch.iomap = malloc(sizeof(bitmap_t), 0); |
map = malloc(BITS2BYTES(IO_MEMMAP_PAGES), 0); |
if(!map) |
return ENOMEM; |
bitmap_initialize(task->arch.iomap, map, IO_MEMMAP_PAGES); |
bitmap_clear_range(task->arch.iomap, 0, IO_MEMMAP_PAGES); |
} |
uintptr_t iopage = ioaddr / PORTS_PER_PAGE; |
size = ALIGN_UP(size + ioaddr - 4 * iopage, PORTS_PER_PAGE); |
bitmap_set_range(task->arch.iomap, iopage, size / 4); |
return 0; |
} |
/branches/arm/kernel/arch/ia64/src/proc/scheduler.c |
---|
47,17 → 47,14 |
{ |
} |
/** Prepare kernel stack pointers in bank 0 r22 and r23 and make sure the stack |
* is mapped in DTR. |
*/ |
/** Prepare kernel stack pointers in bank 0 r22 and r23 and make sure the stack is mapped in DTR. */ |
void before_thread_runs_arch(void) |
{ |
uintptr_t base; |
base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH); |
base = ALIGN_DOWN(config.base, 1<<KERNEL_PAGE_WIDTH); |
if ((uintptr_t) THREAD->kstack < base || |
(uintptr_t) THREAD->kstack > base + (1 << (KERNEL_PAGE_WIDTH))) { |
if ((uintptr_t) THREAD->kstack < base || (uintptr_t) THREAD->kstack > base + (1<<(KERNEL_PAGE_WIDTH))) { |
/* |
* Kernel stack of this thread is not mapped by DTR[TR_KERNEL]. |
* Use DTR[TR_KSTACK1] and DTR[TR_KSTACK2] to map it. |
67,11 → 64,8 |
dtr_purge((uintptr_t) THREAD->kstack, PAGE_WIDTH+1); |
/* insert DTR[TR_STACK1] and DTR[TR_STACK2] */ |
dtlb_kernel_mapping_insert((uintptr_t) THREAD->kstack, |
KA2PA(THREAD->kstack), true, DTR_KSTACK1); |
dtlb_kernel_mapping_insert((uintptr_t) THREAD->kstack + |
PAGE_SIZE, KA2PA(THREAD->kstack) + FRAME_SIZE, true, |
DTR_KSTACK2); |
dtlb_kernel_mapping_insert((uintptr_t) THREAD->kstack, KA2PA(THREAD->kstack), true, DTR_KSTACK1); |
dtlb_kernel_mapping_insert((uintptr_t) THREAD->kstack + PAGE_SIZE, KA2PA(THREAD->kstack) + FRAME_SIZE, true, DTR_KSTACK2); |
} |
/* |
/branches/arm/kernel/arch/ia64/src/fpu_context.c |
---|
149,10 → 149,8 |
"stf.spill [%7] = f127, 0x80\n;;" |
: |
: "r" (&((fctx->fr)[0])), "r" (&((fctx->fr)[1])), |
"r" (&((fctx->fr)[2])), "r" (&((fctx->fr)[3])), |
"r" (&((fctx->fr)[4])), "r" (&((fctx->fr)[5])), |
"r" (&((fctx->fr)[6])), "r" (&((fctx->fr)[7])) |
: "r" (&((fctx->fr)[0])), "r" (&((fctx->fr)[1])), "r" (&((fctx->fr)[2])), "r" (&((fctx->fr)[3])), |
"r" (&((fctx->fr)[4])), "r" (&((fctx->fr)[5])), "r" (&((fctx->fr)[6])), "r" (&((fctx->fr)[7])) |
); |
} |
269,16 → 267,14 |
"ldf.fill f127 = [%7], 0x80\n;;" |
: |
: "r" (&((fctx->fr)[0])), "r" (&((fctx->fr)[1])), |
"r" (&((fctx->fr)[2])), "r" (&((fctx->fr)[3])), |
"r" (&((fctx->fr)[4])), "r" (&((fctx->fr)[5])), |
"r" (&((fctx->fr)[6])), "r" (&((fctx->fr)[7])) |
: "r" (&((fctx->fr)[0])), "r" (&((fctx->fr)[1])), "r" (&((fctx->fr)[2])), "r" (&((fctx->fr)[3])), |
"r" (&((fctx->fr)[4])), "r" (&((fctx->fr)[5])), "r" (&((fctx->fr)[6])), "r" (&((fctx->fr)[7])) |
); |
} |
void fpu_enable(void) |
{ |
uint64_t a = 0; |
uint64_t a = 0 ; |
asm volatile ( |
"rsm %0 ;;" |
/branches/arm/kernel/arch/ia64/src/putchar.c |
---|
0,0 → 1,44 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia64 |
* @{ |
*/ |
/** @file |
*/ |
#include <putchar.h> |
#include <arch/ski/ski.h> |
void putchar(const char ch) |
{ |
ski_write(ch); |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ia64/include/mm/page.h |
---|
46,25 → 46,8 |
/** Bit width of the TLB-locked portion of kernel address space. */ |
#define KERNEL_PAGE_WIDTH 28 /* 256M */ |
#define IO_PAGE_WIDTH 26 /* 64M */ |
#define FW_PAGE_WIDTH 28 /* 256M */ |
#define USPACE_IO_PAGE_WIDTH 12 /* 4K */ |
/* |
* Statically mapped IO spaces - offsets to 0xe...00 of virtual addresses |
* because of "minimal virtual bits implemented is 51" it is possible to |
* have values up to 0x0007000000000000 |
*/ |
/* Firmware area (bellow 4GB in phys mem) */ |
#define FW_OFFSET 0x00000000F0000000 |
/* Legacy IO space */ |
#define IO_OFFSET 0x0001000000000000 |
/* Videoram - now mapped to 0 as VGA text mode vram on 0xb8000 */ |
#define VIO_OFFSET 0x0002000000000000 |
#define PPN_SHIFT 12 |
#define VRN_SHIFT 61 |
79,8 → 62,8 |
#define REGION_REGISTERS 8 |
#define KA2PA(x) ((uintptr_t) (x - (VRN_KERNEL << VRN_SHIFT))) |
#define PA2KA(x) ((uintptr_t) (x + (VRN_KERNEL << VRN_SHIFT))) |
#define KA2PA(x) ((uintptr_t) (x-(VRN_KERNEL<<VRN_SHIFT))) |
#define PA2KA(x) ((uintptr_t) (x+(VRN_KERNEL<<VRN_SHIFT))) |
#define VHPT_WIDTH 20 /* 1M */ |
#define VHPT_SIZE (1 << VHPT_WIDTH) |
240,7 → 223,7 |
* |
* @return Current contents of rr[i]. |
*/ |
static inline uint64_t rr_read(size_t i) |
static inline uint64_t rr_read(index_t i) |
{ |
uint64_t ret; |
ASSERT(i < REGION_REGISTERS); |
253,7 → 236,7 |
* @param i Region register index. |
* @param v Value to be written to rr[i]. |
*/ |
static inline void rr_write(size_t i, uint64_t v) |
static inline void rr_write(index_t i, uint64_t v) |
{ |
ASSERT(i < REGION_REGISTERS); |
asm volatile ( |
/branches/arm/kernel/arch/ia64/include/mm/frame.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia64mm |
/** @addtogroup ia64mm |
* @{ |
*/ |
/** @file |
35,16 → 35,12 |
#ifndef KERN_ia64_FRAME_H_ |
#define KERN_ia64_FRAME_H_ |
#define FRAME_WIDTH 14 /* 16K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#define FRAME_WIDTH 14 /* 16K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#ifdef KERNEL |
#ifndef __ASM__ |
#include <arch/types.h> |
extern uintptr_t last_frame; |
extern void frame_arch_init(void); |
#define physmem_print() |
/branches/arm/kernel/arch/ia64/include/mm/tlb.h |
---|
35,6 → 35,9 |
#ifndef KERN_ia64_TLB_H_ |
#define KERN_ia64_TLB_H_ |
#define tlb_arch_init() |
#define tlb_print() |
#include <arch/mm/page.h> |
#include <arch/mm/asid.h> |
#include <arch/interrupt.h> |
43,8 → 46,8 |
/** Data and instruction Translation Register indices. */ |
#define DTR_KERNEL 0 |
#define ITR_KERNEL 0 |
#define DTR_KSTACK1 4 |
#define DTR_KSTACK2 5 |
#define DTR_KSTACK1 1 |
#define DTR_KSTACK2 2 |
/** Portion of TLB insertion format data structure. */ |
union tlb_entry { |
76,12 → 79,12 |
extern void dtc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry); |
extern void itc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry); |
extern void tr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtr, size_t tr); |
extern void dtr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, size_t tr); |
extern void itr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, size_t tr); |
extern void tr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtr, index_t tr); |
extern void dtr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, index_t tr); |
extern void itr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, index_t tr); |
extern void dtlb_kernel_mapping_insert(uintptr_t page, uintptr_t frame, bool dtr, size_t tr); |
extern void dtr_purge(uintptr_t page, size_t width); |
extern void dtlb_kernel_mapping_insert(uintptr_t page, uintptr_t frame, bool dtr, index_t tr); |
extern void dtr_purge(uintptr_t page, count_t width); |
extern void dtc_pte_copy(pte_t *t); |
extern void itc_pte_copy(pte_t *t); |
92,7 → 95,6 |
extern void data_dirty_bit_fault(uint64_t vector, istate_t *istate); |
extern void instruction_access_bit_fault(uint64_t vector, istate_t *istate); |
extern void data_access_bit_fault(uint64_t vector, istate_t *istate); |
extern void data_access_rights_fault(uint64_t vector, istate_t *istate); |
extern void page_not_present(uint64_t vector, istate_t *istate); |
#endif |
/branches/arm/kernel/arch/ia64/include/mm/vhpt.h |
---|
44,8 → 44,8 |
{ |
vhpt_entry_t ventry; |
ventry.word[0] = tentry.word[0]; |
ventry.word[1] = tentry.word[1]; |
ventry.word[0]=tentry.word[0]; |
ventry.word[1]=tentry.word[1]; |
return ventry; |
} |
/branches/arm/kernel/arch/ia64/include/types.h |
---|
54,6 → 54,8 |
} uint128_t; |
typedef uint64_t size_t; |
typedef uint64_t count_t; |
typedef uint64_t index_t; |
typedef uint64_t uintptr_t; |
typedef uint64_t pfn_t; |
63,13 → 65,10 |
typedef uint64_t unative_t; |
typedef int64_t native_t; |
typedef struct { |
unative_t fnc; |
unative_t gp; |
} fncptr_t; |
#define PRIp "lx" /**< Format for uintptr_t. */ |
#define PRIs "lu" /**< Format for size_t. */ |
#define PRIc "lu" /**< Format for count_t. */ |
#define PRIi "lu" /**< Format for index_t. */ |
#define PRId8 "d" /**< Format for int8_t. */ |
#define PRId16 "d" /**< Format for int16_t. */ |
/branches/arm/kernel/arch/ia64/include/byteorder.h |
---|
0,0 → 1,44 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia64_BYTEORDER_H_ |
#define KERN_ia64_BYTEORDER_H_ |
/* IA-64 is little-endian */ |
#define ARCH_IS_LITTLE_ENDIAN |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ia64/include/asm.h |
---|
36,72 → 36,29 |
#define KERN_ia64_ASM_H_ |
#include <config.h> |
#include <typedefs.h> |
#include <arch/types.h> |
#include <arch/register.h> |
#define IA64_IOSPACE_ADDRESS 0xE001000000000000ULL |
static inline void pio_write_8(ioport8_t *port, uint8_t v) |
static inline void outb(uint64_t port,uint8_t v) |
{ |
uintptr_t prt = (uintptr_t) port; |
*((char *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))) = v; |
*((ioport8_t *)(IA64_IOSPACE_ADDRESS + |
((prt & 0xfff) | ((prt >> 2) << 12)))) = v; |
asm volatile ("mf\n" ::: "memory"); |
} |
static inline void pio_write_16(ioport16_t *port, uint16_t v) |
{ |
uintptr_t prt = (uintptr_t) port; |
*((ioport16_t *)(IA64_IOSPACE_ADDRESS + |
((prt & 0xfff) | ((prt >> 2) << 12)))) = v; |
asm volatile ("mf\n" ::: "memory"); |
} |
static inline void pio_write_32(ioport32_t *port, uint32_t v) |
static inline uint8_t inb(uint64_t port) |
{ |
uintptr_t prt = (uintptr_t) port; |
*((ioport32_t *)(IA64_IOSPACE_ADDRESS + |
((prt & 0xfff) | ((prt >> 2) << 12)))) = v; |
asm volatile ("mf\n" ::: "memory"); |
} |
static inline uint8_t pio_read_8(ioport8_t *port) |
{ |
uintptr_t prt = (uintptr_t) port; |
asm volatile ("mf\n" ::: "memory"); |
return *((ioport8_t *)(IA64_IOSPACE_ADDRESS + |
((prt & 0xfff) | ((prt >> 2) << 12)))); |
return *((char *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))); |
} |
static inline uint16_t pio_read_16(ioport16_t *port) |
{ |
uintptr_t prt = (uintptr_t) port; |
asm volatile ("mf\n" ::: "memory"); |
return *((ioport16_t *)(IA64_IOSPACE_ADDRESS + |
((prt & 0xfff) | ((prt >> 2) << 12)))); |
} |
static inline uint32_t pio_read_32(ioport32_t *port) |
{ |
uintptr_t prt = (uintptr_t) port; |
asm volatile ("mf\n" ::: "memory"); |
return *((ioport32_t *)(IA64_IOSPACE_ADDRESS + |
((prt & 0xfff) | ((prt >> 2) << 12)))); |
} |
/** Return base address of current stack |
* |
* Return the base address of the current stack. |
112,14 → 69,9 |
{ |
uint64_t v; |
//I'm not sure why but this code bad inlines in scheduler, |
//so THE shifts about 16B and causes kernel panic |
//asm volatile ("and %0 = %1, r12" : "=r" (v) : "r" (~(STACK_SIZE-1))); |
//return v; |
asm volatile ("and %0 = %1, r12" : "=r" (v) : "r" (~(STACK_SIZE-1))); |
//this code have the same meaning but inlines well |
asm volatile ("mov %0 = r12" : "=r" (v) ); |
return v & (~(STACK_SIZE-1)); |
return v; |
} |
/** Return Processor State Register. |
171,16 → 123,6 |
return v; |
} |
static inline uint64_t cr64_read(void) |
{ |
uint64_t v; |
asm volatile ("mov %0 = cr64\n" : "=r" (v)); |
return v; |
} |
/** Write ITC (Interval Timer Counter) register. |
* |
* @param v New counter value. |
355,8 → 297,7 |
extern void cpu_sleep(void); |
extern void asm_delay_loop(uint32_t t); |
extern void switch_to_userspace(uintptr_t, uintptr_t, uintptr_t, uintptr_t, |
uint64_t, uint64_t); |
extern void switch_to_userspace(uintptr_t entry, uintptr_t sp, uintptr_t bsp, uintptr_t uspace_uarg, uint64_t ipsr, uint64_t rsc); |
#endif |
/branches/arm/kernel/arch/ia64/include/drivers/kbd.h |
---|
File deleted |
/branches/arm/kernel/arch/ia64/include/drivers/ski.h |
---|
File deleted |
Property changes: |
Deleted: svn:mergeinfo |
/branches/arm/kernel/arch/ia64/include/drivers/ega.h |
---|
0,0 → 1,50 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* 2007 Jakub Vana |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia64_EGA_H |
#define KERN_ia64_EGA_H |
#define VIDEORAM (0xe0020000000B8000LL) |
#define ROW 80 |
#define ROWS 25 |
#define SCREEN (ROW * ROWS) |
extern void ega_init(void); |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ia64/include/drivers/i8042.h |
---|
0,0 → 1,71 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
*/ |
/** |
* This file implements ia32 specific access to i8042 registers. |
*/ |
#ifndef KERN_ia64_I8042_H_ |
#define KERN_ia64_I8042_H_ |
#include <arch/asm.h> |
#include <arch/types.h> |
#define i8042_DATA 0x60 |
#define i8042_STATUS 0x64 |
static inline void i8042_data_write(uint8_t data) |
{ |
outb(i8042_DATA, data); |
} |
static inline uint8_t i8042_data_read(void) |
{ |
return inb(i8042_DATA); |
} |
static inline uint8_t i8042_status_read(void) |
{ |
return inb(i8042_STATUS); |
} |
static inline void i8042_command_write(uint8_t command) |
{ |
outb(i8042_STATUS, command); |
} |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ia64/include/drivers/it.h |
---|
41,7 → 41,7 |
* from firmware. |
* |
*/ |
#define IT_DELTA it_delta |
#define IT_DELTA 100000 |
extern void it_init(void); |
/branches/arm/kernel/arch/ia64/include/interrupt.h |
---|
50,13 → 50,10 |
#define IVT_FIRST 0 |
/** External Interrupt vectors. */ |
#define VECTOR_TLB_SHOOTDOWN_IPI 0xf0 |
#define INTERRUPT_TIMER 255 |
#define IRQ_KBD (0x01 + LEGACY_INTERRUPT_BASE) |
#define IRQ_MOUSE (0x0c + LEGACY_INTERRUPT_BASE) |
#define IRQ_KBD 241 |
#define IRQ_MOUSE 252 |
#define INTERRUPT_SPURIOUS 15 |
#define LEGACY_INTERRUPT_BASE 0x20 |
/** General Exception codes. */ |
#define GE_ILLEGALOP 0 |
117,7 → 114,7 |
/* |
* The following variables are defined only for break_instruction |
* handler. |
* handler. |
*/ |
uint64_t in0; |
uint64_t in1; |
153,8 → 150,6 |
extern void external_interrupt(uint64_t vector, istate_t *istate); |
extern void disabled_fp_register(uint64_t vector, istate_t *istate); |
extern void trap_virtual_enable_irqs(uint16_t irqmask); |
#endif |
/** @} |
/branches/arm/kernel/arch/ia64/include/bootinfo.h |
---|
29,23 → 29,13 |
#ifndef KERN_ia64_BOOTINFO_H_ |
#define KERN_ia64_BOOTINFO_H_ |
#define BOOTINFO_ADDRESS 0x4401000 |
#define CONFIG_INIT_TASKS 32 |
#define MEMMAP_ITEMS 128 |
#define EFI_MEMMAP_FREE_MEM 0 |
#define EFI_MEMMAP_IO 1 |
#define EFI_MEMMAP_IO_PORTS 2 |
/** Size of buffer for storing task name in binit_task_t. */ |
#define BOOTINFO_TASK_NAME_BUFLEN 32 |
typedef struct { |
void *addr; |
unsigned long size; |
char name[BOOTINFO_TASK_NAME_BUFLEN]; |
} binit_task_t; |
typedef struct { |
53,24 → 43,9 |
binit_task_t tasks[CONFIG_INIT_TASKS]; |
} binit_t; |
typedef struct { |
unsigned int type; |
unsigned long base; |
unsigned long size; |
}efi_memmap_item_t; |
typedef struct { |
binit_t taskmap; |
efi_memmap_item_t memmap[MEMMAP_ITEMS]; |
unsigned int memmap_items; |
unsigned long * sapic; |
unsigned long sys_freq; |
unsigned long freq_scale; |
unsigned int wakeup_intno; |
int hello_configured; |
} bootinfo_t; |
extern bootinfo_t *bootinfo; |
/branches/arm/kernel/arch/ia64/include/fpu_context.h |
---|
35,6 → 35,7 |
#ifndef KERN_ia64_FPU_CONTEXT_H_ |
#define KERN_ia64_FPU_CONTEXT_H_ |
#define ARCH_HAS_FPU 1 |
#define FPU_CONTEXT_ALIGN 16 |
#include <arch/types.h> |
/branches/arm/kernel/arch/ia64/include/cpu.h |
---|
38,7 → 38,6 |
#include <arch/types.h> |
#include <arch/register.h> |
#include <arch/asm.h> |
#include <arch/bootinfo.h> |
#define FAMILY_ITANIUM 0x7 |
#define FAMILY_ITANIUM2 0x1f |
64,32 → 63,6 |
return v; |
} |
#define CR64_ID_SHIFT 24 |
#define CR64_ID_MASK 0xff000000 |
#define CR64_EID_SHIFT 16 |
#define CR64_EID_MASK 0xff0000 |
static inline int ia64_get_cpu_id(void) |
{ |
uint64_t cr64=cr64_read(); |
return ((CR64_ID_MASK)&cr64)>>CR64_ID_SHIFT; |
} |
static inline int ia64_get_cpu_eid(void) |
{ |
uint64_t cr64=cr64_read(); |
return ((CR64_EID_MASK)&cr64)>>CR64_EID_SHIFT; |
} |
static inline void ipi_send_ipi(int id, int eid, int intno) |
{ |
(bootinfo->sapic)[2 * (id * 256 + eid)] = intno; |
srlz_d(); |
} |
#endif |
/** @} |
/branches/arm/kernel/arch/ia64/include/atomic.h |
---|
37,65 → 37,29 |
/** Atomic addition. |
* |
* @param val Atomic value. |
* @param imm Value to add. |
* @param val Atomic value. |
* @param imm Value to add. |
* |
* @return Value before addition. |
* @return Value before addition. |
*/ |
static inline long atomic_add(atomic_t *val, int imm) |
{ |
long v; |
asm volatile ("fetchadd8.rel %0 = %1, %2\n" : "=r" (v), |
"+m" (val->count) : "i" (imm)); |
asm volatile ("fetchadd8.rel %0 = %1, %2\n" : "=r" (v), "+m" (val->count) : "i" (imm)); |
return v; |
} |
static inline void atomic_inc(atomic_t *val) { atomic_add(val, 1); } |
static inline void atomic_dec(atomic_t *val) { atomic_add(val, -1); } |
static inline uint64_t test_and_set(atomic_t *val) { |
uint64_t v; |
asm volatile ( |
"movl %0 = 0x01;;\n" |
"xchg8 %0 = %1, %0;;\n" |
: "=r" (v), "+m" (val->count) |
); |
return v; |
} |
static inline long atomic_preinc(atomic_t *val) { return atomic_add(val, 1) + 1; } |
static inline long atomic_predec(atomic_t *val) { return atomic_add(val, -1) - 1; } |
static inline long atomic_postinc(atomic_t *val) { return atomic_add(val, 1); } |
static inline long atomic_postdec(atomic_t *val) { return atomic_add(val, -1); } |
static inline void atomic_inc(atomic_t *val) |
{ |
atomic_add(val, 1); |
} |
static inline void atomic_dec(atomic_t *val) |
{ |
atomic_add(val, -1); |
} |
static inline long atomic_preinc(atomic_t *val) |
{ |
return atomic_add(val, 1) + 1; |
} |
static inline long atomic_predec(atomic_t *val) |
{ |
return atomic_add(val, -1) - 1; |
} |
static inline long atomic_postinc(atomic_t *val) |
{ |
return atomic_add(val, 1); |
} |
static inline long atomic_postdec(atomic_t *val) |
{ |
return atomic_add(val, -1); |
} |
#endif |
/** @} |
/branches/arm/kernel/arch/ia64/include/ski/ski.h |
---|
0,0 → 1,57 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia64_SKI_H_ |
#define KERN_ia64_SKI_H_ |
#include <arch/types.h> |
#include <console/console.h> |
#define SKI_INIT_CONSOLE 20 |
#define SKI_GETCHAR 21 |
#define SKI_PUTCHAR 31 |
extern chardev_t ski_uconsole; |
extern void ski_init_console(void); |
extern void ski_kbd_grab(void); |
extern void ski_kbd_release(void); |
extern void kkbdpoll(void *arg); |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ia64/include/arch.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia64 |
/** @addtogroup ia64 |
* @{ |
*/ |
/** @file |
37,10 → 37,8 |
#define LOADED_PROG_STACK_PAGES_NO 2 |
#include <arch/drivers/ski.h> |
#include <arch/ski/ski.h> |
extern void arch_pre_main(void); |
#endif |
/** @} |
/branches/arm/kernel/arch/ia64/include/proc/task.h |
---|
31,19 → 31,14 |
*/ |
/** @file |
*/ |
#include <proc/task.h> |
#ifndef KERN_ia64_TASK_H_ |
#define KERN_ia64_TASK_H_ |
#include <adt/bitmap.h> |
typedef struct { |
bitmap_t *iomap; |
} task_arch_t; |
#define task_create_arch(t) { (t)->arch.iomap = NULL; } |
#define task_create_arch(t) |
#define task_destroy_arch(t) |
#endif |
/branches/arm/kernel/arch/ia64/include/register.h |
---|
40,11 → 40,11 |
#define PSR_I_MASK 0x4000 |
#define PSR_PK_MASK 0x8000 |
#define PSR_DT_MASK (1 << 17) |
#define PSR_RT_MASK (1 << 27) |
#define PSR_DT_MASK (1<<17) |
#define PSR_RT_MASK (1<<27) |
#define PSR_DFL_MASK (1 << 18) |
#define PSR_DFH_MASK (1 << 19) |
#define PSR_DFL_MASK (1<<18) |
#define PSR_DFH_MASK (1<<19) |
#define PSR_IT_MASK 0x0000001000000000 |
/branches/arm/kernel/arch/ia64/include/debug.h |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2005 Ondrej Palkovsky |
* Copyright (c) 2005 |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
/branches/arm/kernel/arch/ia32/include/syscall.h |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/branches/arm/kernel/arch/ia32/include/atomic.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
41,29 → 41,17 |
static inline void atomic_inc(atomic_t *val) { |
#ifdef CONFIG_SMP |
asm volatile ( |
"lock incl %[count]\n" |
: [count] "+m" (val->count) |
); |
asm volatile ("lock incl %0\n" : "+m" (val->count)); |
#else |
asm volatile ( |
"incl %[count]\n" |
: [count] "+m" (val->count) |
); |
asm volatile ("incl %0\n" : "+m" (val->count)); |
#endif /* CONFIG_SMP */ |
} |
static inline void atomic_dec(atomic_t *val) { |
#ifdef CONFIG_SMP |
asm volatile ( |
"lock decl %[count]\n" |
: [count] "+m" (val->count) |
); |
asm volatile ("lock decl %0\n" : "+m" (val->count)); |
#else |
asm volatile ( |
"decl %[count]\n" |
: [count] "+m" (val->count) |
); |
asm volatile ("decl %0\n" : "+m" (val->count)); |
#endif /* CONFIG_SMP */ |
} |
70,12 → 58,12 |
static inline long atomic_postinc(atomic_t *val) |
{ |
long r = 1; |
asm volatile ( |
"lock xaddl %[r], %[count]\n" |
: [count] "+m" (val->count), [r] "+r" (r) |
"lock xaddl %1, %0\n" |
: "+m" (val->count), "+r" (r) |
); |
return r; |
} |
84,23 → 72,23 |
long r = -1; |
asm volatile ( |
"lock xaddl %[r], %[count]\n" |
: [count] "+m" (val->count), [r] "+r"(r) |
"lock xaddl %1, %0\n" |
: "+m" (val->count), "+r"(r) |
); |
return r; |
} |
#define atomic_preinc(val) (atomic_postinc(val) + 1) |
#define atomic_predec(val) (atomic_postdec(val) - 1) |
#define atomic_preinc(val) (atomic_postinc(val) + 1) |
#define atomic_predec(val) (atomic_postdec(val) - 1) |
static inline uint32_t test_and_set(atomic_t *val) { |
uint32_t v; |
asm volatile ( |
"movl $1, %[v]\n" |
"xchgl %[v], %[count]\n" |
: [v] "=r" (v), [count] "+m" (val->count) |
"movl $1, %0\n" |
"xchgl %0, %1\n" |
: "=r" (v),"+m" (val->count) |
); |
return v; |
110,20 → 98,22 |
static inline void atomic_lock_arch(atomic_t *val) |
{ |
uint32_t tmp; |
preemption_disable(); |
asm volatile ( |
"0:\n" |
"pause\n" /* Pentium 4's HT love this instruction */ |
"mov %[count], %[tmp]\n" |
"testl %[tmp], %[tmp]\n" |
#ifdef CONFIG_HT |
"pause\n" /* Pentium 4's HT love this instruction */ |
#endif |
"mov %0, %1\n" |
"testl %1, %1\n" |
"jnz 0b\n" /* lightweight looping on locked spinlock */ |
"incl %[tmp]\n" /* now use the atomic operation */ |
"xchgl %[count], %[tmp]\n" |
"testl %[tmp], %[tmp]\n" |
"incl %1\n" /* now use the atomic operation */ |
"xchgl %0, %1\n" |
"testl %1, %1\n" |
"jnz 0b\n" |
: [count] "+m" (val->count), [tmp] "=&r" (tmp) |
: "+m" (val->count), "=&r"(tmp) |
); |
/* |
* Prevent critical section code from bleeding out this way up. |
/branches/arm/kernel/arch/ia32/include/mm/page.h |
---|
95,21 → 95,21 |
/* Get PTE flags accessors for each level. */ |
#define GET_PTL1_FLAGS_ARCH(ptl0, i) \ |
get_pt_flags((pte_t *) (ptl0), (size_t) (i)) |
get_pt_flags((pte_t *) (ptl0), (index_t) (i)) |
#define GET_PTL2_FLAGS_ARCH(ptl1, i) \ |
PAGE_PRESENT |
#define GET_PTL3_FLAGS_ARCH(ptl2, i) \ |
PAGE_PRESENT |
#define GET_FRAME_FLAGS_ARCH(ptl3, i) \ |
get_pt_flags((pte_t *) (ptl3), (size_t) (i)) |
get_pt_flags((pte_t *) (ptl3), (index_t) (i)) |
/* Set PTE flags accessors for each level. */ |
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \ |
set_pt_flags((pte_t *) (ptl0), (size_t) (i), (x)) |
set_pt_flags((pte_t *) (ptl0), (index_t) (i), (x)) |
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x) |
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x) |
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \ |
set_pt_flags((pte_t *) (ptl3), (size_t) (i), (x)) |
set_pt_flags((pte_t *) (ptl3), (index_t) (i), (x)) |
/* Macros for querying the last level entries. */ |
#define PTE_VALID_ARCH(p) \ |
145,7 → 145,7 |
/** When bit on this position is 1, a reserved bit was set in page directory. */ |
#define PFERR_CODE_RSVD (1 << 3) |
static inline int get_pt_flags(pte_t *pt, size_t i) |
static inline int get_pt_flags(pte_t *pt, index_t i) |
{ |
pte_t *p = &pt[i]; |
158,7 → 158,7 |
p->global << PAGE_GLOBAL_SHIFT); |
} |
static inline void set_pt_flags(pte_t *pt, size_t i, int flags) |
static inline void set_pt_flags(pte_t *pt, index_t i, int flags) |
{ |
pte_t *p = &pt[i]; |
/branches/arm/kernel/arch/ia32/include/mm/frame.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32mm |
/** @addtogroup ia32mm |
* @{ |
*/ |
/** @file |
35,8 → 35,8 |
#ifndef KERN_ia32_FRAME_H_ |
#define KERN_ia32_FRAME_H_ |
#define FRAME_WIDTH 12 /* 4K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#define FRAME_WIDTH 12 /* 4K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#ifdef KERNEL |
#ifndef __ASM__ |
/branches/arm/kernel/arch/ia32/include/mm/as.h |
---|
42,7 → 42,7 |
#define USER_ADDRESS_SPACE_START_ARCH ((unsigned long) 0x00000000) |
#define USER_ADDRESS_SPACE_END_ARCH ((unsigned long) 0x7fffffff) |
#define USTACK_ADDRESS_ARCH (USER_ADDRESS_SPACE_END_ARCH - (PAGE_SIZE - 1)) |
#define USTACK_ADDRESS_ARCH (USER_ADDRESS_SPACE_END_ARCH-(PAGE_SIZE-1)) |
typedef struct { |
} as_arch_t; |
/branches/arm/kernel/arch/ia32/include/mm/tlb.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32mm |
/** @addtogroup ia32mm |
* @{ |
*/ |
/** @file |
35,6 → 35,9 |
#ifndef KERN_ia32_TLB_H_ |
#define KERN_ia32_TLB_H_ |
#define tlb_arch_init() |
#define tlb_print() |
#endif |
/** @} |
/branches/arm/kernel/arch/ia32/include/barrier.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
46,8 → 46,8 |
* Provisions are made to prevent compiler from reordering instructions itself. |
*/ |
#define CS_ENTER_BARRIER() asm volatile ("" ::: "memory") |
#define CS_LEAVE_BARRIER() asm volatile ("" ::: "memory") |
#define CS_ENTER_BARRIER() asm volatile ("" ::: "memory") |
#define CS_LEAVE_BARRIER() asm volatile ("" ::: "memory") |
static inline void cpuid_serialization(void) |
{ |
58,30 → 58,30 |
); |
} |
#if defined(CONFIG_FENCES_P4) |
#define memory_barrier() asm volatile ("mfence\n" ::: "memory") |
#define read_barrier() asm volatile ("lfence\n" ::: "memory") |
#ifdef CONFIG_WEAK_MEMORY |
#define write_barrier() asm volatile ("sfence\n" ::: "memory") |
#else |
#define write_barrier() asm volatile ("" ::: "memory"); |
#endif |
#elif defined(CONFIG_FENCES_P3) |
#define memory_barrier() cpuid_serialization() |
#define read_barrier() cpuid_serialization() |
#ifdef CONFIG_WEAK_MEMORY |
#define write_barrier() asm volatile ("sfence\n" ::: "memory") |
#else |
#define write_barrier() asm volatile ("" ::: "memory"); |
#endif |
#ifdef CONFIG_FENCES_P4 |
# define memory_barrier() asm volatile ("mfence\n" ::: "memory") |
# define read_barrier() asm volatile ("lfence\n" ::: "memory") |
# ifdef CONFIG_WEAK_MEMORY |
# define write_barrier() asm volatile ("sfence\n" ::: "memory") |
# else |
# define write_barrier() asm volatile( "" ::: "memory"); |
# endif |
#elif CONFIG_FENCES_P3 |
# define memory_barrier() cpuid_serialization() |
# define read_barrier() cpuid_serialization() |
# ifdef CONFIG_WEAK_MEMORY |
# define write_barrier() asm volatile ("sfence\n" ::: "memory") |
# else |
# define write_barrier() asm volatile( "" ::: "memory"); |
# endif |
#else |
#define memory_barrier() cpuid_serialization() |
#define read_barrier() cpuid_serialization() |
#ifdef CONFIG_WEAK_MEMORY |
#define write_barrier() cpuid_serialization() |
#else |
#define write_barrier() asm volatile ("" ::: "memory"); |
#endif |
# define memory_barrier() cpuid_serialization() |
# define read_barrier() cpuid_serialization() |
# ifdef CONFIG_WEAK_MEMORY |
# define write_barrier() cpuid_serialization() |
# else |
# define write_barrier() asm volatile( "" ::: "memory"); |
# endif |
#endif |
/* |
90,8 → 90,8 |
* queueing in the store buffer drain to the memory (even though it would be |
* sufficient for them to drain to the D-cache). |
*/ |
#define smc_coherence(a) write_barrier() |
#define smc_coherence_block(a, l) write_barrier() |
#define smc_coherence(a) write_barrier() |
#define smc_coherence_block(a, l) write_barrier() |
#endif |
/branches/arm/kernel/arch/ia32/include/types.h |
---|
46,6 → 46,8 |
typedef unsigned long long uint64_t; |
typedef uint32_t size_t; |
typedef uint32_t count_t; |
typedef uint32_t index_t; |
typedef uint32_t uintptr_t; |
typedef uint32_t pfn_t; |
55,11 → 57,10 |
typedef uint32_t unative_t; |
typedef int32_t native_t; |
typedef struct { |
} fncptr_t; |
#define PRIp "x" /**< Format for uintptr_t. */ |
#define PRIs "u" /**< Format for size_t. */ |
#define PRIc "u" /**< Format for count_t. */ |
#define PRIi "u" /**< Format for index_t. */ |
#define PRId8 "d" /**< Format for int8_t. */ |
#define PRId16 "d" /**< Format for int16_t. */ |
/branches/arm/kernel/arch/ia32/include/smp/smp.h |
---|
39,10 → 39,10 |
/** SMP config opertaions interface. */ |
struct smp_config_operations { |
size_t (* cpu_count)(void); /**< Return number of detected processors. */ |
bool (* cpu_enabled)(size_t i); /**< Check whether the processor of index i is enabled. */ |
bool (*cpu_bootstrap)(size_t i); /**< Check whether the processor of index i is BSP. */ |
uint8_t (*cpu_apic_id)(size_t i); /**< Return APIC ID of the processor of index i. */ |
count_t (* cpu_count)(void); /**< Return number of detected processors. */ |
bool (* cpu_enabled)(index_t i); /**< Check whether the processor of index i is enabled. */ |
bool (*cpu_bootstrap)(index_t i); /**< Check whether the processor of index i is BSP. */ |
uint8_t (*cpu_apic_id)(index_t i); /**< Return APIC ID of the processor of index i. */ |
int (*irq_to_pin)(unsigned int irq); /**< Return mapping between irq and APIC pin. */ |
}; |
/branches/arm/kernel/arch/ia32/include/byteorder.h |
---|
0,0 → 1,44 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia32_BYTEORDER_H_ |
#define KERN_ia32_BYTEORDER_H_ |
/* IA-32 is little-endian */ |
#define ARCH_IS_LITTLE_ENDIAN |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32/include/boot/memmap.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
35,29 → 35,24 |
#ifndef KERN_ia32_MEMMAP_H_ |
#define KERN_ia32_MEMMAP_H_ |
/* E820h memory range types */ |
/* E820h memory range types - other values*/ |
/* Free memory */ |
#define MEMMAP_MEMORY_AVAILABLE 1 |
/* Not available for OS */ |
#define MEMMAP_MEMORY_RESERVED 2 |
/* OS may use it after reading ACPI table */ |
#define MEMMAP_MEMORY_ACPI 3 |
/* Unusable, required to be saved and restored across an NVS sleep */ |
#define MEMMAP_MEMORY_NVS 4 |
/* Corrupted memory */ |
#define MEMMAP_MEMORY_UNUSABLE 5 |
/* Free memory */ |
#define MEMMAP_MEMORY_AVAILABLE 1 |
/* size of one entry */ |
#define MEMMAP_E820_RECORD_SIZE 20 |
/* maximum entries */ |
#define MEMMAP_E820_MAX_RECORDS 32 |
/* Not available for OS */ |
#define MEMMAP_MEMORY_RESERVED 2 |
/* OS may use it after reading ACPI table */ |
#define MEMMAP_MEMORY_ACPI 3 |
/* Unusable, required to be saved and restored across an NVS sleep */ |
#define MEMMAP_MEMORY_NVS 4 |
/* Corrupted memory */ |
#define MEMMAP_MEMORY_UNUSABLE 5 |
/* Size of one entry */ |
#define MEMMAP_E820_RECORD_SIZE 20 |
/* Maximum entries */ |
#define MEMMAP_E820_MAX_RECORDS 32 |
#ifndef __ASM__ |
#include <arch/types.h> |
/branches/arm/kernel/arch/ia32/include/boot/boot.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
35,24 → 35,15 |
#ifndef KERN_ia32_BOOT_H_ |
#define KERN_ia32_BOOT_H_ |
#define BOOT_OFFSET 0x108000 |
#define AP_BOOT_OFFSET 0x8000 |
#define BOOT_STACK_SIZE 0x400 |
#define BOOT_OFFSET 0x108000 |
#define AP_BOOT_OFFSET 0x8000 |
#define BOOT_STACK_SIZE 0x400 |
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 |
#define MULTIBOOT_HEADER_FLAGS 0x00010003 |
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 |
#define MULTIBOOT_HEADER_FLAGS 0x00010003 |
#ifndef __ASM__ |
#define MULTIBOOT_LOADER_MAGIC 0x2BADB002 |
#ifdef CONFIG_SMP |
/* This is only a symbol so the type is dummy. Obtain the value using &. */ |
extern int _hardcoded_unmapped_size; |
#endif /* CONFIG_SMP */ |
#endif /* __ASM__ */ |
#endif |
/** @} |
/branches/arm/kernel/arch/ia32/include/proc/task.h |
---|
40,7 → 40,7 |
typedef struct { |
/** I/O Permission bitmap Generation counter. */ |
size_t iomapver; |
count_t iomapver; |
/** I/O Permission bitmap. */ |
bitmap_t iomap; |
} task_arch_t; |
/branches/arm/kernel/arch/ia32/include/interrupt.h |
---|
72,6 → 72,10 |
uint32_t eax; |
uint32_t ecx; |
uint32_t edx; |
uint32_t esi; |
uint32_t edi; |
uint32_t ebp; |
uint32_t ebx; |
uint32_t gs; |
uint32_t fs; |
/branches/arm/kernel/arch/ia32/include/pm.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
35,59 → 35,61 |
#ifndef KERN_ia32_PM_H_ |
#define KERN_ia32_PM_H_ |
#define IDT_ITEMS 64 |
#define GDT_ITEMS 7 |
#define IDT_ITEMS 64 |
#define GDT_ITEMS 7 |
#define NULL_DES 0 |
#define KTEXT_DES 1 |
#define KDATA_DES 2 |
#define UTEXT_DES 3 |
#define UDATA_DES 4 |
#define TSS_DES 5 |
#define TLS_DES 6 /* Pointer to Thread-Local-Storage data */ |
#define VESA_INIT_SEGMENT 0x8000 |
#define NULL_DES 0 |
#define KTEXT_DES 1 |
#define KDATA_DES 2 |
#define UTEXT_DES 3 |
#define UDATA_DES 4 |
#define TSS_DES 5 |
#define TLS_DES 6 /* Pointer to Thread-Local-Storage data */ |
#ifdef CONFIG_FB |
#define VESA_INIT_SEGMENT 0x8000 |
#define VESA_INIT_DES 7 |
#define KTEXT32_DES KTEXT_DES |
#define VESA_INIT_SEGMENT 0x8000 |
#define VESA_INIT_DES 7 |
#undef GDT_ITEMS |
#define GDT_ITEMS 8 |
#define GDT_ITEMS 8 |
#endif /* CONFIG_FB */ |
#define gdtselector(des) ((des) << 3) |
#define PL_KERNEL 0 |
#define PL_USER 3 |
#define selector(des) ((des) << 3) |
#define AR_PRESENT (1 << 7) |
#define AR_DATA (2 << 3) |
#define AR_CODE (3 << 3) |
#define AR_WRITABLE (1 << 1) |
#define AR_INTERRUPT (0x0e) |
#define AR_TSS (0x09) |
#define PL_KERNEL 0 |
#define PL_USER 3 |
#define DPL_KERNEL (PL_KERNEL << 5) |
#define DPL_USER (PL_USER << 5) |
#define AR_PRESENT (1 << 7) |
#define AR_DATA (2 << 3) |
#define AR_CODE (3 << 3) |
#define AR_WRITABLE (1 << 1) |
#define AR_INTERRUPT (0xe) |
#define AR_TSS (0x9) |
#define TSS_BASIC_SIZE 104 |
#define TSS_IOMAP_SIZE (16 * 1024 + 1) /* 16K for bitmap + 1 terminating byte for convenience */ |
#define DPL_KERNEL (PL_KERNEL << 5) |
#define DPL_USER (PL_USER << 5) |
#define IO_PORTS (64 * 1024) |
#define TSS_BASIC_SIZE 104 |
#define TSS_IOMAP_SIZE (16 * 1024 + 1) /* 16K for bitmap + 1 terminating byte for convenience */ |
#define IO_PORTS (64 * 1024) |
#ifndef __ASM__ |
#include <arch/types.h> |
#include <arch/context.h> |
typedef struct { |
struct ptr_16_32 { |
uint16_t limit; |
uint32_t base; |
} __attribute__ ((packed)) ptr_16_32_t; |
} __attribute__ ((packed)); |
typedef struct ptr_16_32 ptr_16_32_t; |
typedef struct { |
struct descriptor { |
unsigned limit_0_15: 16; |
unsigned base_0_15: 16; |
unsigned base_16_23: 8; |
98,17 → 100,19 |
unsigned special: 1; |
unsigned granularity : 1; |
unsigned base_24_31: 8; |
} __attribute__ ((packed)) descriptor_t; |
} __attribute__ ((packed)); |
typedef struct descriptor descriptor_t; |
typedef struct { |
struct idescriptor { |
unsigned offset_0_15: 16; |
unsigned selector: 16; |
unsigned unused: 8; |
unsigned access: 8; |
unsigned offset_16_31: 16; |
} __attribute__ ((packed)) idescriptor_t; |
} __attribute__ ((packed)); |
typedef struct idescriptor idescriptor_t; |
typedef struct { |
struct tss { |
uint16_t link; |
unsigned : 16; |
uint32_t esp0; |
148,12 → 152,13 |
unsigned : 16; |
uint16_t iomap_base; |
uint8_t iomap[TSS_IOMAP_SIZE]; |
} __attribute__ ((packed)) tss_t; |
} __attribute__ ((packed)); |
typedef struct tss tss_t; |
extern ptr_16_32_t gdtr; |
extern ptr_16_32_t bootstrap_gdtr; |
extern ptr_16_32_t protected_ap_gdtr; |
extern tss_t *tss_p; |
extern struct tss *tss_p; |
extern descriptor_t gdt[]; |
/branches/arm/kernel/arch/ia32/include/asm.h |
---|
27,7 → 27,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
38,7 → 38,6 |
#include <arch/pm.h> |
#include <arch/types.h> |
#include <typedefs.h> |
#include <config.h> |
extern uint32_t interrupt_handler_size; |
56,16 → 55,11 |
/** Halt CPU |
* |
* Halt the current CPU. |
* |
* Halt the current CPU until interrupt event. |
*/ |
static inline void cpu_halt(void) |
{ |
asm volatile ( |
"0:\n" |
" hlt\n" |
" jmp 0b\n" |
); |
asm volatile ("hlt\n"); |
} |
static inline void cpu_sleep(void) |
74,22 → 68,16 |
} |
#define GEN_READ_REG(reg) static inline unative_t read_ ##reg (void) \ |
{ \ |
unative_t res; \ |
asm volatile ( \ |
"movl %%" #reg ", %[res]" \ |
: [res] "=r" (res) \ |
); \ |
return res; \ |
} |
{ \ |
unative_t res; \ |
asm volatile ("movl %%" #reg ", %0" : "=r" (res) ); \ |
return res; \ |
} |
#define GEN_WRITE_REG(reg) static inline void write_ ##reg (unative_t regn) \ |
{ \ |
asm volatile ( \ |
"movl %[regn], %%" #reg \ |
:: [regn] "r" (regn) \ |
); \ |
} |
{ \ |
asm volatile ("movl %0, %%" #reg : : "r" (regn)); \ |
} |
GEN_READ_REG(cr0) |
GEN_READ_REG(cr2) |
116,14 → 104,10 |
* |
* @param port Port to write to |
* @param val Value to write |
* |
*/ |
static inline void pio_write_8(ioport8_t *port, uint8_t val) |
static inline void outb(uint16_t port, uint8_t val) |
{ |
asm volatile ( |
"outb %b[val], %w[port]\n" |
:: [val] "a" (val), [port] "d" (port) |
); |
asm volatile ("outb %b0, %w1\n" : : "a" (val), "d" (port) ); |
} |
/** Word to port |
132,14 → 116,10 |
* |
* @param port Port to write to |
* @param val Value to write |
* |
*/ |
static inline void pio_write_16(ioport16_t *port, uint16_t val) |
static inline void outw(uint16_t port, uint16_t val) |
{ |
asm volatile ( |
"outw %w[val], %w[port]\n" |
:: [val] "a" (val), [port] "d" (port) |
); |
asm volatile ("outw %w0, %w1\n" : : "a" (val), "d" (port) ); |
} |
/** Double word to port |
148,14 → 128,10 |
* |
* @param port Port to write to |
* @param val Value to write |
* |
*/ |
static inline void pio_write_32(ioport32_t *port, uint32_t val) |
static inline void outl(uint16_t port, uint32_t val) |
{ |
asm volatile ( |
"outl %[val], %w[port]\n" |
:: [val] "a" (val), [port] "d" (port) |
); |
asm volatile ("outl %l0, %w1\n" : : "a" (val), "d" (port) ); |
} |
/** Byte from port |
164,18 → 140,12 |
* |
* @param port Port to read from |
* @return Value read |
* |
*/ |
static inline uint8_t pio_read_8(ioport8_t *port) |
static inline uint8_t inb(uint16_t port) |
{ |
uint8_t val; |
asm volatile ( |
"inb %w[port], %b[val]\n" |
: [val] "=a" (val) |
: [port] "d" (port) |
); |
asm volatile ("inb %w1, %b0 \n" : "=a" (val) : "d" (port) ); |
return val; |
} |
185,18 → 155,12 |
* |
* @param port Port to read from |
* @return Value read |
* |
*/ |
static inline uint16_t pio_read_16(ioport16_t *port) |
static inline uint16_t inw(uint16_t port) |
{ |
uint16_t val; |
asm volatile ( |
"inw %w[port], %w[val]\n" |
: [val] "=a" (val) |
: [port] "d" (port) |
); |
asm volatile ("inw %w1, %w0 \n" : "=a" (val) : "d" (port) ); |
return val; |
} |
206,18 → 170,12 |
* |
* @param port Port to read from |
* @return Value read |
* |
*/ |
static inline uint32_t pio_read_32(ioport32_t *port) |
static inline uint32_t inl(uint16_t port) |
{ |
uint32_t val; |
asm volatile ( |
"inl %w[port], %[val]\n" |
: [val] "=a" (val) |
: [port] "d" (port) |
); |
asm volatile ("inl %w1, %l0 \n" : "=a" (val) : "d" (port) ); |
return val; |
} |
227,19 → 185,16 |
* value of EFLAGS. |
* |
* @return Old interrupt priority level. |
* |
*/ |
static inline ipl_t interrupts_enable(void) |
{ |
ipl_t v; |
asm volatile ( |
"pushf\n" |
"popl %[v]\n" |
"pushf\n\t" |
"popl %0\n\t" |
"sti\n" |
: [v] "=r" (v) |
: "=r" (v) |
); |
return v; |
} |
249,19 → 204,16 |
* value of EFLAGS. |
* |
* @return Old interrupt priority level. |
* |
*/ |
static inline ipl_t interrupts_disable(void) |
{ |
ipl_t v; |
asm volatile ( |
"pushf\n" |
"popl %[v]\n" |
"pushf\n\t" |
"popl %0\n\t" |
"cli\n" |
: [v] "=r" (v) |
: "=r" (v) |
); |
return v; |
} |
270,14 → 222,13 |
* Restore EFLAGS. |
* |
* @param ipl Saved interrupt priority level. |
* |
*/ |
static inline void interrupts_restore(ipl_t ipl) |
{ |
asm volatile ( |
"pushl %[ipl]\n" |
"pushl %0\n\t" |
"popf\n" |
:: [ipl] "r" (ipl) |
: : "r" (ipl) |
); |
} |
284,51 → 235,23 |
/** Return interrupt priority level. |
* |
* @return EFLAFS. |
* |
*/ |
static inline ipl_t interrupts_read(void) |
{ |
ipl_t v; |
asm volatile ( |
"pushf\n" |
"popl %[v]\n" |
: [v] "=r" (v) |
"pushf\n\t" |
"popl %0\n" |
: "=r" (v) |
); |
return v; |
} |
/** Write to MSR */ |
static inline void write_msr(uint32_t msr, uint64_t value) |
{ |
asm volatile ( |
"wrmsr" |
:: "c" (msr), "a" ((uint32_t) (value)), |
"d" ((uint32_t) (value >> 32)) |
); |
} |
static inline uint64_t read_msr(uint32_t msr) |
{ |
uint32_t ax, dx; |
asm volatile ( |
"rdmsr" |
: "=a" (ax), "=d" (dx) |
: "c" (msr) |
); |
return ((uint64_t) dx << 32) | ax; |
} |
/** Return base address of current stack |
* |
* Return the base address of the current stack. |
* The stack is assumed to be STACK_SIZE bytes long. |
* The stack must start on page boundary. |
* |
*/ |
static inline uintptr_t get_stack_base(void) |
{ |
335,8 → 258,8 |
uintptr_t v; |
asm volatile ( |
"andl %%esp, %[v]\n" |
: [v] "=r" (v) |
"andl %%esp, %0\n" |
: "=r" (v) |
: "0" (~(STACK_SIZE - 1)) |
); |
347,12 → 270,11 |
static inline uintptr_t * get_ip() |
{ |
uintptr_t *ip; |
asm volatile ( |
"mov %%eip, %[ip]" |
: [ip] "=r" (ip) |
); |
"mov %%eip, %0" |
: "=r" (ip) |
); |
return ip; |
} |
359,66 → 281,46 |
/** Invalidate TLB Entry. |
* |
* @param addr Address on a page whose TLB entry is to be invalidated. |
* |
*/ |
static inline void invlpg(uintptr_t addr) |
{ |
asm volatile ( |
"invlpg %[addr]\n" |
:: [addr] "m" (*(unative_t *) addr) |
); |
asm volatile ("invlpg %0\n" :: "m" (*(unative_t *)addr)); |
} |
/** Load GDTR register from memory. |
* |
* @param gdtr_reg Address of memory from where to load GDTR. |
* |
*/ |
static inline void gdtr_load(ptr_16_32_t *gdtr_reg) |
{ |
asm volatile ( |
"lgdtl %[gdtr_reg]\n" |
:: [gdtr_reg] "m" (*gdtr_reg) |
); |
asm volatile ("lgdtl %0\n" : : "m" (*gdtr_reg)); |
} |
/** Store GDTR register to memory. |
* |
* @param gdtr_reg Address of memory to where to load GDTR. |
* |
*/ |
static inline void gdtr_store(ptr_16_32_t *gdtr_reg) |
{ |
asm volatile ( |
"sgdtl %[gdtr_reg]\n" |
:: [gdtr_reg] "m" (*gdtr_reg) |
); |
asm volatile ("sgdtl %0\n" : : "m" (*gdtr_reg)); |
} |
/** Load IDTR register from memory. |
* |
* @param idtr_reg Address of memory from where to load IDTR. |
* |
*/ |
static inline void idtr_load(ptr_16_32_t *idtr_reg) |
{ |
asm volatile ( |
"lidtl %[idtr_reg]\n" |
:: [idtr_reg] "m" (*idtr_reg) |
); |
asm volatile ("lidtl %0\n" : : "m" (*idtr_reg)); |
} |
/** Load TR from descriptor table. |
* |
* @param sel Selector specifying descriptor of TSS segment. |
* |
*/ |
static inline void tr_load(uint16_t sel) |
{ |
asm volatile ( |
"ltr %[sel]" |
:: [sel] "r" (sel) |
); |
asm volatile ("ltr %0" : : "r" (sel)); |
} |
#endif |
/branches/arm/kernel/arch/ia32/include/cpuid.h |
---|
35,13 → 35,6 |
#ifndef KERN_ia32_CPUID_H_ |
#define KERN_ia32_CPUID_H_ |
#define INTEL_CPUID_LEVEL 0x00000000 |
#define INTEL_CPUID_STANDARD 0x00000001 |
#define INTEL_PSE 3 |
#define INTEL_SEP 11 |
#ifndef __ASM__ |
#include <arch/types.h> |
typedef struct { |
81,21 → 74,21 |
uint32_t val, ret; |
asm volatile ( |
"pushf\n" /* read flags */ |
"popl %[ret]\n" |
"movl %[ret], %[val]\n" |
"pushf\n" /* read flags */ |
"popl %0\n" |
"movl %0, %1\n" |
"btcl $21, %[val]\n" /* swap the ID bit */ |
"btcl $21, %1\n" /* swap the ID bit */ |
"pushl %[val]\n" /* propagate the change into flags */ |
"pushl %1\n" /* propagate the change into flags */ |
"popf\n" |
"pushf\n" |
"popl %[val]\n" |
"popl %1\n" |
"andl $(1 << 21), %[ret]\n" /* interrested only in ID bit */ |
"andl $(1 << 21), %[val]\n" |
"xorl %[val], %[ret]\n" |
: [ret] "=r" (ret), [val] "=r" (val) |
"andl $(1 << 21), %0\n" /* interrested only in ID bit */ |
"andl $(1 << 21), %1\n" |
"xorl %1, %0\n" |
: "=r" (ret), "=r" (val) |
); |
return ret; |
105,13 → 98,11 |
{ |
asm volatile ( |
"cpuid\n" |
: "=a" (info->cpuid_eax), "=b" (info->cpuid_ebx), |
"=c" (info->cpuid_ecx), "=d" (info->cpuid_edx) |
: "=a" (info->cpuid_eax), "=b" (info->cpuid_ebx), "=c" (info->cpuid_ecx), "=d" (info->cpuid_edx) |
: "a" (cmd) |
); |
} |
#endif /* !def __ASM__ */ |
#endif |
/** @} |
/branches/arm/kernel/arch/ia32/include/cpu.h |
---|
35,33 → 35,25 |
#ifndef KERN_ia32_CPU_H_ |
#define KERN_ia32_CPU_H_ |
#include <arch/pm.h> |
#include <arch/asm.h> |
#define EFLAGS_IF (1 << 9) |
#define EFLAGS_RF (1 << 16) |
#define CR4_OSFXSR_MASK (1<<9) |
/* Support for SYSENTER and SYSEXIT */ |
#define IA32_MSR_SYSENTER_CS 0x174 |
#define IA32_MSR_SYSENTER_ESP 0x175 |
#define IA32_MSR_SYSENTER_EIP 0x176 |
#ifndef __ASM__ |
#include <arch/pm.h> |
#include <arch/asm.h> |
typedef struct { |
unsigned int vendor; |
unsigned int family; |
unsigned int model; |
unsigned int stepping; |
tss_t *tss; |
int vendor; |
int family; |
int model; |
int stepping; |
struct tss *tss; |
size_t iomapver_copy; /** Copy of TASK's I/O Permission bitmap generation count. */ |
count_t iomapver_copy; /** Copy of TASK's I/O Permission bitmap generation count. */ |
} cpu_arch_t; |
#endif |
#define CR4_OSFXSR_MASK (1<<9) |
#endif |
/** @} |
/branches/arm/kernel/arch/ia32/include/fpu_context.h |
---|
37,6 → 37,7 |
#include <arch/types.h> |
#define ARCH_HAS_FPU |
#define FPU_CONTEXT_ALIGN 16 |
void fpu_fxsr(void); |
/branches/arm/kernel/arch/ia32/include/arch.h |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2009 Martin Decky |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
35,10 → 35,6 |
#ifndef KERN_ia32_ARCH_H_ |
#define KERN_ia32_ARCH_H_ |
#include <genarch/multiboot/multiboot.h> |
extern void arch_pre_main(uint32_t, const multiboot_info_t *); |
#endif |
/** @} |
/branches/arm/kernel/arch/ia32/include/drivers/i8254.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
/branches/arm/kernel/arch/ia32/include/drivers/ega.h |
---|
0,0 → 1,48 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia32_EGA_H_ |
#define KERN_ia32_EGA_H_ |
#define VIDEORAM 0xb8000 |
#define ROW 80 |
#define ROWS 25 |
#define SCREEN (ROW * ROWS) |
extern void ega_init(void); |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32/include/drivers/vesa.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
36,7 → 36,6 |
#define KERN_ia32_VESA_H_ |
extern int vesa_present(void); |
extern void vesa_redraw(void); |
extern void vesa_init(void); |
#endif |
/branches/arm/kernel/arch/ia32/include/drivers/i8259.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
38,13 → 38,13 |
#include <arch/types.h> |
#include <arch/interrupt.h> |
#define PIC_PIC0PORT1 ((ioport8_t *) 0x20) |
#define PIC_PIC0PORT2 ((ioport8_t *) 0x21) |
#define PIC_PIC1PORT1 ((ioport8_t *) 0xa0) |
#define PIC_PIC1PORT2 ((ioport8_t *) 0xa1) |
#define PIC_PIC0PORT1 0x20 |
#define PIC_PIC0PORT2 0x21 |
#define PIC_PIC1PORT1 0xa0 |
#define PIC_PIC1PORT2 0xa1 |
#define PIC_NEEDICW4 (1 << 0) |
#define PIC_ICW1 (1 << 4) |
#define PIC_NEEDICW4 (1<<0) |
#define PIC_ICW1 (1<<4) |
extern void i8259_init(void); |
extern void pic_enable_irqs(uint16_t irqmask); |
/branches/arm/kernel/arch/ia32/include/drivers/i8042.h |
---|
0,0 → 1,71 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
*/ |
/** |
* This file implements ia32 specific access to i8042 registers. |
*/ |
#ifndef KERN_ia32_I8042_H_ |
#define KERN_ia32_I8042_H_ |
#include <arch/asm.h> |
#include <arch/types.h> |
#define i8042_DATA 0x60 |
#define i8042_STATUS 0x64 |
static inline void i8042_data_write(uint8_t data) |
{ |
outb(i8042_DATA, data); |
} |
static inline uint8_t i8042_data_read(void) |
{ |
return inb(i8042_DATA); |
} |
static inline uint8_t i8042_status_read(void) |
{ |
return inb(i8042_STATUS); |
} |
static inline void i8042_command_write(uint8_t command) |
{ |
outb(i8042_STATUS, command); |
} |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32/Makefile.inc |
---|
29,6 → 29,10 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf32-i386 |
BFD_ARCH = i386 |
BFD = binary |
35,8 → 39,7 |
TARGET = i686-pc-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/i686 |
BITS = 32 |
ENDIANESS = LE |
DEFS += -DMACHINE=$(MACHINE) -D__32_BITS__ |
CMN1 = -m32 |
GCC_CFLAGS += $(CMN1) |
46,61 → 49,115 |
## Accepted CPUs |
# |
ifeq ($(PROCESSOR),athlon_xp) |
ifeq ($(MACHINE),athlon-xp) |
FPU_NO_CFLAGS = -mno-mmx -mno-sse -mno-3dnow |
CMN2 = -march=athlon-xp |
GCC_CFLAGS += $(CMN2) |
ICC_CFLAGS += $(CMN2) |
SUNCC_CFLAGS += -xarch=ssea |
DEFS += -DCONFIG_FENCES_P3 |
CONFIG_SMP = n |
CONFIG_HT = n |
endif |
ifeq ($(PROCESSOR),athlon_mp) |
ifeq ($(MACHINE),athlon-mp) |
FPU_NO_CFLAGS = -mno-mmx -mno-sse -mno-3dnow |
CMN2 = -march=athlon-mp |
GCC_CFLAGS += $(CMN2) |
ICC_CFLAGS += $(CMN2) |
SUNCC_CFLAGS += xarch=ssea |
DEFS += -DCONFIG_FENCES_P3 |
CONFIG_HT = n |
endif |
ifeq ($(PROCESSOR),pentium3) |
ifeq ($(MACHINE),pentium3) |
FPU_NO_CFLAGS = -mno-mmx -mno-sse |
CMN2 = -march=pentium3 |
GCC_CFLAGS += $(CMN2) |
ICC_CFLAGS += $(CMN2) |
SUNCC_CFLAGS += -xarch=sse |
DEFS += -DCONFIG_FENCES_P3 |
CONFIG_HT = n |
endif |
ifeq ($(PROCESSOR),pentium4) |
CMN2 = -march=pentium4 |
SUNCC_CFLAGS += -xarch=sse2 |
endif |
ifeq ($(PROCESSOR),core) |
ifeq ($(MACHINE),core) |
FPU_NO_CFLAGS = -mno-mmx -mno-sse -mno-sse2 -mno-sse3 |
CMN2 = -march=prescott |
GCC_CFLAGS += $(CMN2) |
ICC_CFLAGS += $(CMN2) |
SUNCC_CFLAGS += -xarch=sse3 |
DEFS += -DCONFIG_FENCES_P4 |
endif |
ifeq ($(MACHINE),pentium4) |
FPU_NO_CFLAGS = -mno-mmx -mno-sse -mno-sse2 |
GCC_CFLAGS += -march=pentium4 |
ICC_CFLAGS += -march=pentium4 |
SUNCC_CFLAGS += -xarch=sse2 |
DEFS += -DCONFIG_FENCES_P4 |
endif |
FPU_NO_CFLAGS = -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow |
GCC_CFLAGS += $(CMN2) |
ICC_CFLAGS += $(CMN2) |
## Own configuration directives |
# |
CONFIG_ACPI = y |
## Compile with hierarchical page tables support. |
# |
CONFIG_PAGE_PT = y |
DEFS += -DCONFIG_PAGE_PT |
## Compile with i8042 controller support |
# |
CONFIG_I8042 = y |
DEFS += -DCONFIG_I8042 |
## Accepted configuration directives |
# |
ifeq ($(CONFIG_SMP),y) |
DEFS += -DCONFIG_SMP |
endif |
ifeq ($(CONFIG_HT),y) |
DEFS += -DCONFIG_HT |
endif |
ifeq ($(CONFIG_SIMICS_FIX),y) |
DEFS += -DCONFIG_SIMICS_FIX |
endif |
## Compile with support for software integer division. |
# |
CONFIG_SOFTINT = y |
ARCH_SOURCES = \ |
arch/$(KARCH)/src/context.S \ |
arch/$(KARCH)/src/debug/panic.s \ |
arch/$(KARCH)/src/delay.s \ |
arch/$(KARCH)/src/asm.S \ |
arch/$(KARCH)/src/proc/scheduler.c \ |
arch/$(KARCH)/src/proc/task.c \ |
arch/$(KARCH)/src/proc/thread.c \ |
arch/$(KARCH)/src/bios/bios.c \ |
arch/$(KARCH)/src/smp/ap.S \ |
arch/$(KARCH)/src/smp/apic.c \ |
arch/$(KARCH)/src/smp/mps.c \ |
arch/$(KARCH)/src/smp/smp.c \ |
arch/$(KARCH)/src/atomic.S \ |
arch/$(KARCH)/src/smp/ipi.c \ |
arch/$(KARCH)/src/ia32.c \ |
arch/$(KARCH)/src/interrupt.c \ |
arch/$(KARCH)/src/pm.c \ |
arch/$(KARCH)/src/userspace.c \ |
arch/$(KARCH)/src/cpu/cpu.c \ |
arch/$(KARCH)/src/mm/as.c \ |
arch/$(KARCH)/src/mm/frame.c \ |
arch/$(KARCH)/src/mm/page.c \ |
arch/$(KARCH)/src/mm/tlb.c \ |
arch/$(KARCH)/src/ddi/ddi.c \ |
arch/$(KARCH)/src/drivers/i8254.c \ |
arch/$(KARCH)/src/drivers/i8259.c \ |
arch/$(KARCH)/src/drivers/vesa.c \ |
arch/$(KARCH)/src/boot/boot.S \ |
arch/$(KARCH)/src/boot/memmap.c \ |
arch/$(KARCH)/src/fpu_context.c \ |
arch/$(KARCH)/src/debugger.c \ |
arch/$(KARCH)/src/syscall.c |
arch/$(ARCH)/src/context.S \ |
arch/$(ARCH)/src/debug/panic.s \ |
arch/$(ARCH)/src/delay.s \ |
arch/$(ARCH)/src/asm.S \ |
arch/$(ARCH)/src/proc/scheduler.c \ |
arch/$(ARCH)/src/proc/task.c \ |
arch/$(ARCH)/src/proc/thread.c \ |
arch/$(ARCH)/src/bios/bios.c \ |
arch/$(ARCH)/src/smp/ap.S \ |
arch/$(ARCH)/src/smp/apic.c \ |
arch/$(ARCH)/src/smp/mps.c \ |
arch/$(ARCH)/src/smp/smp.c \ |
arch/$(ARCH)/src/atomic.S \ |
arch/$(ARCH)/src/smp/ipi.c \ |
arch/$(ARCH)/src/ia32.c \ |
arch/$(ARCH)/src/interrupt.c \ |
arch/$(ARCH)/src/pm.c \ |
arch/$(ARCH)/src/userspace.c \ |
arch/$(ARCH)/src/cpu/cpu.c \ |
arch/$(ARCH)/src/mm/as.c \ |
arch/$(ARCH)/src/mm/frame.c \ |
arch/$(ARCH)/src/mm/page.c \ |
arch/$(ARCH)/src/mm/tlb.c \ |
arch/$(ARCH)/src/ddi/ddi.c \ |
arch/$(ARCH)/src/drivers/i8254.c \ |
arch/$(ARCH)/src/drivers/i8259.c \ |
arch/$(ARCH)/src/drivers/ega.c \ |
arch/$(ARCH)/src/drivers/vesa.c \ |
arch/$(ARCH)/src/boot/boot.S \ |
arch/$(ARCH)/src/boot/memmap.c \ |
arch/$(ARCH)/src/fpu_context.c \ |
arch/$(ARCH)/src/debugger.c |
/branches/arm/kernel/arch/ia32/src/syscall.c |
---|
File deleted |
/branches/arm/kernel/arch/ia32/src/asm.S |
---|
147,46 → 147,6 |
popfl |
.endm |
/* |
* The SYSENTER syscall mechanism can be used for syscalls with |
* four or fewer arguments. To pass these four arguments, we |
* use four registers: EDX, ECX, EBX, ESI. The syscall number |
* is passed in EAX. We use EDI to remember the return address |
* and EBP to remember the stack. The INT-based syscall mechanism |
* can actually handle six arguments plus the syscall number |
* entirely in registers. |
*/ |
.global sysenter_handler |
sysenter_handler: |
sti |
pushl %ebp # remember user stack |
pushl %edi # remember return user address |
pushl %gs # remember TLS |
pushl %eax # syscall number |
subl $8, %esp # unused sixth and fifth argument |
pushl %esi # fourth argument |
pushl %ebx # third argument |
pushl %ecx # second argument |
pushl %edx # first argument |
movw $16, %ax |
movw %ax, %ds |
movw %ax, %es |
cld |
call syscall_handler |
addl $28, %esp # remove arguments from stack |
pop %gs # restore TLS |
pop %edx # prepare return EIP for SYSEXIT |
pop %ecx # prepare userspace ESP for SYSEXIT |
sysexit # return to userspace |
## Declare interrupt handlers |
# |
# Declare interrupt handlers for n interrupt |
268,6 → 228,14 |
pushl %fs |
pushl %gs |
#ifdef CONFIG_DEBUG_ALLREGS |
pushl %ebx |
pushl %ebp |
pushl %edi |
pushl %esi |
#else |
subl $16, %esp |
#endif |
pushl %edx |
pushl %ecx |
pushl %eax |
289,6 → 257,14 |
popl %eax |
popl %ecx |
popl %edx |
#ifdef CONFIG_DEBUG_ALLREGS |
popl %esi |
popl %edi |
popl %ebp |
popl %ebx |
#else |
addl $16, %esp |
#endif |
popl %gs |
popl %fs |
/branches/arm/kernel/arch/ia32/src/mm/frame.c |
---|
54,57 → 54,26 |
static void init_e820_memory(pfn_t minconf) |
{ |
unsigned int i; |
pfn_t start, conf; |
size_t size; |
for (i = 0; i < e820counter; i++) { |
uint64_t base = e820table[i].base_address; |
uint64_t size = e820table[i].size; |
#ifdef __32_BITS__ |
/* Ignore physical memory above 4 GB */ |
if ((base >> 32) != 0) |
continue; |
/* Clip regions above 4 GB */ |
if (((base + size) >> 32) != 0) |
size = 0xffffffff - base; |
#endif |
pfn_t pfn; |
size_t count; |
if (e820table[i].type == MEMMAP_MEMORY_AVAILABLE) { |
/* To be safe, make available zone possibly smaller */ |
pfn = ADDR2PFN(ALIGN_UP(base, FRAME_SIZE)); |
count = SIZE2FRAMES(ALIGN_DOWN(size, FRAME_SIZE)); |
start = ADDR2PFN(ALIGN_UP(e820table[i].base_address, FRAME_SIZE)); |
size = SIZE2FRAMES(ALIGN_DOWN(e820table[i].size, FRAME_SIZE)); |
pfn_t conf; |
if ((minconf < pfn) || (minconf >= pfn + count)) |
conf = pfn; |
if ((minconf < start) || (minconf >= start + size)) |
conf = start; |
else |
conf = minconf; |
zone_create(pfn, count, conf, ZONE_AVAILABLE); |
zone_create(start, size, conf, 0); |
// XXX this has to be removed |
if (last_frame < ALIGN_UP(base + size, FRAME_SIZE)) |
last_frame = ALIGN_UP(base + size, FRAME_SIZE); |
} |
if (e820table[i].type == MEMMAP_MEMORY_RESERVED) { |
/* To be safe, make reserved zone possibly larger */ |
pfn = ADDR2PFN(ALIGN_DOWN(base, FRAME_SIZE)); |
count = SIZE2FRAMES(ALIGN_UP(size, FRAME_SIZE)); |
zone_create(pfn, count, 0, ZONE_RESERVED); |
} |
if (e820table[i].type == MEMMAP_MEMORY_ACPI) { |
/* To be safe, make firmware zone possibly larger */ |
pfn = ADDR2PFN(ALIGN_DOWN(base, (uintptr_t) FRAME_SIZE)); |
count = SIZE2FRAMES(ALIGN_UP(size, (uintptr_t) FRAME_SIZE)); |
zone_create(pfn, count, 0, ZONE_FIRMWARE); |
} |
if (last_frame < ALIGN_UP(e820table[i].base_address + |
e820table[i].size, FRAME_SIZE)) |
last_frame = |
ALIGN_UP(e820table[i].base_address + e820table[i].size, FRAME_SIZE); |
} |
} |
} |
144,14 → 113,16 |
if (config.cpu_active == 1) { |
minconf = 1; |
#ifdef CONFIG_SMP |
minconf = max(minconf, |
ADDR2PFN(AP_BOOT_OFFSET + hardcoded_unmapped_ktext_size + |
hardcoded_unmapped_kdata_size)); |
#endif |
#ifdef CONFIG_SIMICS_FIX |
minconf = max(minconf, ADDR2PFN(0x10000)); |
#endif |
init_e820_memory(minconf); |
/* Reserve frame 0 (BIOS data) */ |
frame_mark_unavailable(0, 1); |
160,7 → 131,12 |
frame_mark_unavailable(AP_BOOT_OFFSET >> FRAME_WIDTH, |
(hardcoded_unmapped_ktext_size + |
hardcoded_unmapped_kdata_size) >> FRAME_WIDTH); |
#ifdef CONFIG_SIMICS_FIX |
/* Don't know why, but these addresses help */ |
frame_mark_unavailable(0xd000 >> FRAME_WIDTH, 3); |
#endif |
#endif |
} |
} |
/branches/arm/kernel/arch/ia32/src/mm/page.c |
---|
53,7 → 53,7 |
{ |
uintptr_t cur; |
int flags; |
if (config.cpu_active == 1) { |
page_mapping_operations = &pt_mapping_operations; |
66,12 → 66,12 |
flags |= PAGE_GLOBAL; |
page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags); |
} |
exc_register(14, "page_fault", (iroutine) page_fault); |
write_cr3((uintptr_t) AS_KERNEL->genarch.page_table); |
} else |
write_cr3((uintptr_t) AS_KERNEL->genarch.page_table); |
paging_on(); |
} |
79,7 → 79,7 |
uintptr_t hw_map(uintptr_t physaddr, size_t size) |
{ |
if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) |
panic("Unable to map physical memory %p (%d bytes).", physaddr, size) |
panic("Unable to map physical memory %p (%d bytes)", physaddr, size) |
uintptr_t virtaddr = PA2KA(last_frame); |
pfn_t i; |
101,8 → 101,8 |
page = read_cr2(); |
if (istate->error_word & PFERR_CODE_RSVD) |
panic("Reserved bit set in page directory."); |
panic("Reserved bit set in page directory.\n"); |
if (istate->error_word & PFERR_CODE_RW) |
access = PF_ACCESS_WRITE; |
else |
109,11 → 109,11 |
access = PF_ACCESS_READ; |
if (as_page_fault(page, access, istate) == AS_PF_FAULT) { |
fault_if_from_uspace(istate, "Page fault: %#x.", page); |
fault_if_from_uspace(istate, "Page fault: %#x", page); |
decode_istate(istate); |
printf("page fault address: %#lx\n", page); |
panic("Page fault."); |
panic("page fault\n"); |
} |
} |
/branches/arm/kernel/arch/ia32/src/mm/tlb.c |
---|
59,7 → 59,7 |
* @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 __attribute__((unused)), uintptr_t page, size_t cnt) |
void tlb_invalidate_pages(asid_t asid __attribute__((unused)), uintptr_t page, count_t cnt) |
{ |
unsigned int i; |
67,13 → 67,5 |
invlpg(page + i * PAGE_SIZE); |
} |
void tlb_arch_init(void) |
{ |
} |
void tlb_print(void) |
{ |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32/src/drivers/ega.c |
---|
0,0 → 1,155 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
* @{ |
*/ |
/** |
* @file |
* @brief EGA driver. |
*/ |
#include <arch/drivers/ega.h> |
#include <putchar.h> |
#include <mm/page.h> |
#include <mm/as.h> |
#include <arch/mm/page.h> |
#include <synch/spinlock.h> |
#include <arch/types.h> |
#include <arch/asm.h> |
#include <memstr.h> |
#include <console/chardev.h> |
#include <console/console.h> |
#include <sysinfo/sysinfo.h> |
#include <ddi/ddi.h> |
/* |
* The EGA driver. |
* Simple and short. Function for displaying characters and "scrolling". |
*/ |
static parea_t ega_parea; /**< Physical memory area for EGA video RAM. */ |
SPINLOCK_INITIALIZE(egalock); |
static uint32_t ega_cursor; |
static uint8_t *videoram; |
static void ega_putchar(chardev_t *d, const char ch); |
chardev_t ega_console; |
static chardev_operations_t ega_ops = { |
.write = ega_putchar |
}; |
static void ega_move_cursor(void); |
void ega_init(void) |
{ |
uint8_t hi, lo; |
videoram = (uint8_t *) hw_map(VIDEORAM, SCREEN * 2); |
outb(0x3d4, 0xe); |
hi = inb(0x3d5); |
outb(0x3d4, 0xf); |
lo = inb(0x3d5); |
ega_cursor = (hi << 8) | lo; |
chardev_initialize("ega_out", &ega_console, &ega_ops); |
stdout = &ega_console; |
ega_parea.pbase = VIDEORAM; |
ega_parea.vbase = (uintptr_t) videoram; |
ega_parea.frames = 1; |
ega_parea.cacheable = false; |
ddi_parea_register(&ega_parea); |
sysinfo_set_item_val("fb", NULL, true); |
sysinfo_set_item_val("fb.kind", NULL, 2); |
sysinfo_set_item_val("fb.width", NULL, ROW); |
sysinfo_set_item_val("fb.height", NULL, ROWS); |
sysinfo_set_item_val("fb.address.physical", NULL, VIDEORAM); |
} |
static void ega_display_char(char ch) |
{ |
videoram[ega_cursor * 2] = ch; |
} |
/* |
* This function takes care of scrolling. |
*/ |
static void ega_check_cursor(void) |
{ |
if (ega_cursor < SCREEN) |
return; |
memcpy((void *) videoram, (void *) (videoram + ROW * 2), (SCREEN - ROW) * 2); |
memsetw(videoram + (SCREEN - ROW) * 2, ROW, 0x0720); |
ega_cursor = ega_cursor - ROW; |
} |
void ega_putchar(chardev_t *d __attribute__((unused)), const char ch) |
{ |
ipl_t ipl; |
ipl = interrupts_disable(); |
spinlock_lock(&egalock); |
switch (ch) { |
case '\n': |
ega_cursor = (ega_cursor + ROW) - ega_cursor % ROW; |
break; |
case '\t': |
ega_cursor = (ega_cursor + 8) - ega_cursor % 8; |
break; |
case '\b': |
if (ega_cursor % ROW) |
ega_cursor--; |
break; |
default: |
ega_display_char(ch); |
ega_cursor++; |
break; |
} |
ega_check_cursor(); |
ega_move_cursor(); |
spinlock_unlock(&egalock); |
interrupts_restore(ipl); |
} |
void ega_move_cursor(void) |
{ |
outb(0x3d4, 0xe); |
outb(0x3d5, (uint8_t) ((ega_cursor >> 8) & 0xff)); |
outb(0x3d4, 0xf); |
outb(0x3d5, (uint8_t) (ega_cursor & 0xff)); |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32/src/drivers/i8259.c |
---|
49,28 → 49,28 |
void i8259_init(void) |
{ |
/* ICW1: this is ICW1, ICW4 to follow */ |
pio_write_8(PIC_PIC0PORT1, PIC_ICW1 | PIC_NEEDICW4); |
outb(PIC_PIC0PORT1, PIC_ICW1 | PIC_NEEDICW4); |
/* ICW2: IRQ 0 maps to INT IRQBASE */ |
pio_write_8(PIC_PIC0PORT2, IVT_IRQBASE); |
outb(PIC_PIC0PORT2, IVT_IRQBASE); |
/* ICW3: pic1 using IRQ IRQ_PIC1 */ |
pio_write_8(PIC_PIC0PORT2, 1 << IRQ_PIC1); |
outb(PIC_PIC0PORT2, 1 << IRQ_PIC1); |
/* ICW4: i8086 mode */ |
pio_write_8(PIC_PIC0PORT2, 1); |
outb(PIC_PIC0PORT2, 1); |
/* ICW1: ICW1, ICW4 to follow */ |
pio_write_8(PIC_PIC1PORT1, PIC_ICW1 | PIC_NEEDICW4); |
outb(PIC_PIC1PORT1, PIC_ICW1 | PIC_NEEDICW4); |
/* ICW2: IRQ 8 maps to INT (IVT_IRQBASE + 8) */ |
pio_write_8(PIC_PIC1PORT2, IVT_IRQBASE + 8); |
outb(PIC_PIC1PORT2, IVT_IRQBASE + 8); |
/* ICW3: pic1 is known as IRQ_PIC1 */ |
pio_write_8(PIC_PIC1PORT2, IRQ_PIC1); |
outb(PIC_PIC1PORT2, IRQ_PIC1); |
/* ICW4: i8086 mode */ |
pio_write_8(PIC_PIC1PORT2, 1); |
outb(PIC_PIC1PORT2, 1); |
/* |
* Register interrupt handler for the PIC spurious interrupt. |
94,12 → 94,12 |
uint8_t x; |
if (irqmask & 0xff) { |
x = pio_read_8(PIC_PIC0PORT2); |
pio_write_8(PIC_PIC0PORT2, (uint8_t) (x & (~(irqmask & 0xff)))); |
x = inb(PIC_PIC0PORT2); |
outb(PIC_PIC0PORT2, (uint8_t) (x & (~(irqmask & 0xff)))); |
} |
if (irqmask >> 8) { |
x = pio_read_8(PIC_PIC1PORT2); |
pio_write_8(PIC_PIC1PORT2, (uint8_t) (x & (~(irqmask >> 8)))); |
x = inb(PIC_PIC1PORT2); |
outb(PIC_PIC1PORT2, (uint8_t) (x & (~(irqmask >> 8)))); |
} |
} |
108,19 → 108,19 |
uint8_t x; |
if (irqmask & 0xff) { |
x = pio_read_8(PIC_PIC0PORT2); |
pio_write_8(PIC_PIC0PORT2, (uint8_t) (x | (irqmask & 0xff))); |
x = inb(PIC_PIC0PORT2); |
outb(PIC_PIC0PORT2, (uint8_t) (x | (irqmask & 0xff))); |
} |
if (irqmask >> 8) { |
x = pio_read_8(PIC_PIC1PORT2); |
pio_write_8(PIC_PIC1PORT2, (uint8_t) (x | (irqmask >> 8))); |
x = inb(PIC_PIC1PORT2); |
outb(PIC_PIC1PORT2, (uint8_t) (x | (irqmask >> 8))); |
} |
} |
void pic_eoi(void) |
{ |
pio_write_8((ioport8_t *)0x20, 0x20); |
pio_write_8((ioport8_t *)0xa0, 0x20); |
outb(0x20, 0x20); |
outb(0xa0, 0x20); |
} |
void pic_spurious(int n __attribute__((unused)), istate_t *istate __attribute__((unused))) |
/branches/arm/kernel/arch/ia32/src/drivers/i8254.c |
---|
26,12 → 26,12 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** |
* @file |
* @brief i8254 chip driver. |
* @brief i8254 chip driver. |
* |
* Low level time functions. |
*/ |
53,8 → 53,8 |
#include <ddi/irq.h> |
#include <ddi/device.h> |
#define CLK_PORT1 ((ioport8_t *)0x40) |
#define CLK_PORT4 ((ioport8_t *)0x43) |
#define CLK_PORT1 0x40 |
#define CLK_PORT4 0x43 |
#define CLK_CONST 1193180 |
#define MAGIC_NUMBER 1194 |
61,12 → 61,12 |
static irq_t i8254_irq; |
static irq_ownership_t i8254_claim(irq_t *irq) |
static irq_ownership_t i8254_claim(void) |
{ |
return IRQ_ACCEPT; |
} |
static void i8254_irq_handler(irq_t *irq) |
static void i8254_irq_handler(irq_t *irq, void *arg __attribute__((unused)), ...) |
{ |
/* |
* This IRQ is responsible for kernel preemption. |
94,10 → 94,10 |
void i8254_normal_operation(void) |
{ |
pio_write_8(CLK_PORT4, 0x36); |
outb(CLK_PORT4, 0x36); |
pic_disable_irqs(1 << IRQ_CLK); |
pio_write_8(CLK_PORT1, (CLK_CONST / HZ) & 0xf); |
pio_write_8(CLK_PORT1, (CLK_CONST / HZ) >> 8); |
outb(CLK_PORT1, (CLK_CONST / HZ) & 0xf); |
outb(CLK_PORT1, (CLK_CONST / HZ) >> 8); |
pic_enable_irqs(1 << IRQ_CLK); |
} |
114,36 → 114,36 |
* One-shot timer. Count-down from 0xffff at 1193180Hz |
* MAGIC_NUMBER is the magic value for 1ms. |
*/ |
pio_write_8(CLK_PORT4, 0x30); |
pio_write_8(CLK_PORT1, 0xff); |
pio_write_8(CLK_PORT1, 0xff); |
outb(CLK_PORT4, 0x30); |
outb(CLK_PORT1, 0xff); |
outb(CLK_PORT1, 0xff); |
do { |
/* will read both status and count */ |
pio_write_8(CLK_PORT4, 0xc2); |
not_ok = (uint8_t) ((pio_read_8(CLK_PORT1) >> 6) & 1); |
t1 = pio_read_8(CLK_PORT1); |
t1 |= pio_read_8(CLK_PORT1) << 8; |
outb(CLK_PORT4, 0xc2); |
not_ok = (uint8_t) ((inb(CLK_PORT1) >> 6) & 1); |
t1 = inb(CLK_PORT1); |
t1 |= inb(CLK_PORT1) << 8; |
} while (not_ok); |
asm_delay_loop(LOOPS); |
pio_write_8(CLK_PORT4, 0xd2); |
t2 = pio_read_8(CLK_PORT1); |
t2 |= pio_read_8(CLK_PORT1) << 8; |
outb(CLK_PORT4, 0xd2); |
t2 = inb(CLK_PORT1); |
t2 |= inb(CLK_PORT1) << 8; |
/* |
* We want to determine the overhead of the calibrating mechanism. |
*/ |
pio_write_8(CLK_PORT4, 0xd2); |
o1 = pio_read_8(CLK_PORT1); |
o1 |= pio_read_8(CLK_PORT1) << 8; |
outb(CLK_PORT4, 0xd2); |
o1 = inb(CLK_PORT1); |
o1 |= inb(CLK_PORT1) << 8; |
asm_fake_loop(LOOPS); |
pio_write_8(CLK_PORT4, 0xd2); |
o2 = pio_read_8(CLK_PORT1); |
o2 |= pio_read_8(CLK_PORT1) << 8; |
outb(CLK_PORT4, 0xd2); |
o2 = inb(CLK_PORT1); |
o2 |= inb(CLK_PORT1) << 8; |
CPU->delay_loop_const = |
((MAGIC_NUMBER * LOOPS) / 1000) / ((t1 - t2) - (o1 - o2)) + |
/branches/arm/kernel/arch/ia32/src/drivers/vesa.c |
---|
56,20 → 56,12 |
uint16_t vesa_bpp; |
uint16_t vesa_scanline; |
uint8_t vesa_red_mask; |
uint8_t vesa_red_pos; |
uint8_t vesa_green_mask; |
uint8_t vesa_green_pos; |
uint8_t vesa_blue_mask; |
uint8_t vesa_blue_pos; |
int vesa_present(void) |
{ |
if ((vesa_width != 0xffff) && (vesa_height != 0xffff)) |
if (vesa_width != 0xffff) |
return true; |
if (vesa_height != 0xffff) |
return true; |
return false; |
} |
82,12 → 74,7 |
visual = VISUAL_INDIRECT_8; |
break; |
case 16: |
if ((vesa_red_mask == 5) && (vesa_red_pos == 10) |
&& (vesa_green_mask == 5) && (vesa_green_pos == 5) |
&& (vesa_blue_mask == 5) && (vesa_blue_pos == 0)) |
visual = VISUAL_RGB_5_5_5; |
else |
visual = VISUAL_RGB_5_6_5; |
visual = VISUAL_RGB_5_6_5; |
break; |
case 24: |
visual = VISUAL_RGB_8_8_8; |
96,25 → 83,12 |
visual = VISUAL_RGB_0_8_8_8; |
break; |
default: |
panic("Unsupported bits per pixel."); |
panic("Unsupported bits per pixel"); |
} |
fb_properties_t vesa_props = { |
.addr = vesa_ph_addr, |
.offset = 0, |
.x = vesa_width, |
.y = vesa_height, |
.scan = vesa_scanline, |
.visual = visual, |
}; |
fb_init(&vesa_props); |
fb_init(vesa_ph_addr, vesa_width, vesa_height, vesa_scanline, visual); |
} |
void vesa_redraw(void) |
{ |
fb_redraw(); |
} |
#endif |
/** @} |
/branches/arm/kernel/arch/ia32/src/userspace.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
47,8 → 47,10 |
*/ |
void userspace(uspace_arg_t *kernel_uarg) |
{ |
ipl_t ipl = interrupts_disable(); |
ipl_t ipl; |
ipl = interrupts_disable(); |
asm volatile ( |
/* |
* Clear nested task flag. |
58,33 → 60,35 |
"and $0xffffbfff, %%eax\n" |
"push %%eax\n" |
"popfl\n" |
/* Set up GS register (TLS) */ |
"movl %[tls_des], %%gs\n" |
"pushl %[udata_des]\n" |
"pushl %[stack_size]\n" |
"pushl %[ipl]\n" |
"pushl %[utext_des]\n" |
"pushl %[entry]\n" |
"movl %[uarg], %%eax\n" |
"movl %6, %%gs\n" |
"pushl %0\n" |
"pushl %1\n" |
"pushl %2\n" |
"pushl %3\n" |
"pushl %4\n" |
"movl %5, %%eax\n" |
/* %ebx is defined to hold pcb_ptr - set it to 0 */ |
"xorl %%ebx, %%ebx\n" |
"xorl %%ebx, %%ebx\n" |
"iret\n" |
: |
: [udata_des] "i" (gdtselector(UDATA_DES) | PL_USER), |
[stack_size] "r" ((uint8_t *) kernel_uarg->uspace_stack + THREAD_STACK_SIZE), |
[ipl] "r" (ipl), |
[utext_des] "i" (gdtselector(UTEXT_DES) | PL_USER), |
[entry] "r" (kernel_uarg->uspace_entry), |
[uarg] "r" (kernel_uarg->uspace_uarg), |
[tls_des] "r" (gdtselector(TLS_DES)) |
: |
: "i" (selector(UDATA_DES) | PL_USER), |
"r" ((uint8_t *) kernel_uarg->uspace_stack + |
THREAD_STACK_SIZE), |
"r" (ipl), |
"i" (selector(UTEXT_DES) | PL_USER), |
"r" (kernel_uarg->uspace_entry), |
"r" (kernel_uarg->uspace_uarg), |
"r" (selector(TLS_DES)) |
: "eax"); |
/* Unreachable */ |
while (1); |
for(;;) |
; |
} |
/** @} |
/branches/arm/kernel/arch/ia32/src/smp/smp.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
75,12 → 75,12 |
l_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, |
FRAME_ATOMIC | FRAME_KA); |
if (!l_apic_address) |
panic("Cannot allocate address for l_apic."); |
panic("cannot allocate address for l_apic\n"); |
io_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, |
FRAME_ATOMIC | FRAME_KA); |
if (!io_apic_address) |
panic("Cannot allocate address for io_apic."); |
panic("cannot allocate address for io_apic\n"); |
if (config.cpu_count > 1) { |
page_mapping_insert(AS_KERNEL, l_apic_address, |
122,8 → 122,8 |
* Save 0xa to address 0xf of the CMOS RAM. |
* BIOS will not do the POST after the INIT signal. |
*/ |
pio_write_8((ioport8_t *)0x70, 0xf); |
pio_write_8((ioport8_t *)0x71, 0xa); |
outb(0x70, 0xf); |
outb(0x71, 0xa); |
pic_disable_irqs(0xffff); |
apic_init(); |
131,8 → 131,8 |
uint8_t apic = l_apic_id(); |
for (i = 0; i < ops->cpu_count(); i++) { |
descriptor_t *gdt_new; |
struct descriptor *gdt_new; |
/* |
* Skip processors marked unusable. |
*/ |
154,19 → 154,14 |
/* |
* Prepare new GDT for CPU in question. |
*/ |
/* XXX Flag FRAME_LOW_4_GiB was removed temporarily, |
* it needs to be replaced by a generic fuctionality of |
* the memory subsystem |
*/ |
gdt_new = (descriptor_t *) malloc(GDT_ITEMS * |
sizeof(descriptor_t), FRAME_ATOMIC); |
gdt_new = (struct descriptor *) malloc(GDT_ITEMS * |
sizeof(struct descriptor), FRAME_ATOMIC | FRAME_LOW_4_GiB); |
if (!gdt_new) |
panic("Cannot allocate memory for GDT."); |
panic("couldn't allocate memory for GDT\n"); |
memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(descriptor_t)); |
memsetb(&gdt_new[TSS_DES], sizeof(descriptor_t), 0); |
protected_ap_gdtr.limit = GDT_ITEMS * sizeof(descriptor_t); |
memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(struct descriptor)); |
memsetb(&gdt_new[TSS_DES], sizeof(struct descriptor), 0); |
protected_ap_gdtr.limit = GDT_ITEMS * sizeof(struct descriptor); |
protected_ap_gdtr.base = KA2PA((uintptr_t) gdt_new); |
gdtr.base = (uintptr_t) gdt_new; |
/branches/arm/kernel/arch/ia32/src/smp/mps.c |
---|
86,10 → 86,10 |
/* |
* Implementation of IA-32 SMP configuration interface. |
*/ |
static size_t get_cpu_count(void); |
static bool is_cpu_enabled(size_t i); |
static bool is_bsp(size_t i); |
static uint8_t get_cpu_apic_id(size_t i); |
static count_t get_cpu_count(void); |
static bool is_cpu_enabled(index_t i); |
static bool is_bsp(index_t i); |
static uint8_t get_cpu_apic_id(index_t i); |
static int mps_irq_to_pin(unsigned int irq); |
struct smp_config_operations mps_config_operations = { |
100,24 → 100,24 |
.irq_to_pin = mps_irq_to_pin |
}; |
size_t get_cpu_count(void) |
count_t get_cpu_count(void) |
{ |
return processor_entry_cnt; |
} |
bool is_cpu_enabled(size_t i) |
bool is_cpu_enabled(index_t i) |
{ |
ASSERT(i < processor_entry_cnt); |
return (bool) ((processor_entries[i].cpu_flags & 0x01) == 0x01); |
} |
bool is_bsp(size_t i) |
bool is_bsp(index_t i) |
{ |
ASSERT(i < processor_entry_cnt); |
return (bool) ((processor_entries[i].cpu_flags & 0x02) == 0x02); |
} |
uint8_t get_cpu_apic_id(size_t i) |
uint8_t get_cpu_apic_id(index_t i) |
{ |
ASSERT(i < processor_entry_cnt); |
return processor_entries[i].l_apic_id; |
/branches/arm/kernel/arch/ia32/src/smp/apic.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
132,12 → 132,12 |
#endif |
} |
static irq_ownership_t l_apic_timer_claim(irq_t *irq) |
static irq_ownership_t l_apic_timer_claim(void) |
{ |
return IRQ_ACCEPT; |
} |
static void l_apic_timer_irq_handler(irq_t *irq) |
static void l_apic_timer_irq_handler(irq_t *irq, void *arg __attribute__((unused)), ...) |
{ |
/* |
* Holding a spinlock could prevent clock() from preempting |
/branches/arm/kernel/arch/ia32/src/pm.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
112,7 → 112,7 |
void tss_initialize(tss_t *t) |
{ |
memsetb(t, sizeof(tss_t), 0); |
memsetb(t, sizeof(struct tss), 0); |
} |
/* |
127,7 → 127,7 |
d = &idt[i]; |
d->unused = 0; |
d->selector = gdtselector(KTEXT_DES); |
d->selector = selector(KTEXT_DES); |
d->access = AR_PRESENT | AR_INTERRUPT; /* masking interrupt */ |
154,7 → 154,7 |
"and $0xffff8fff, %%eax\n" |
"push %%eax\n" |
"popfl\n" |
::: "eax" |
: : : "eax" |
); |
} |
165,7 → 165,7 |
"mov %%cr0, %%eax\n" |
"and $0xfffbffff, %%eax\n" |
"mov %%eax, %%cr0\n" |
::: "eax" |
: : : "eax" |
); |
} |
198,7 → 198,7 |
else { |
tss_p = (tss_t *) malloc(sizeof(tss_t), FRAME_ATOMIC); |
if (!tss_p) |
panic("Cannot allocate TSS."); |
panic("could not allocate TSS\n"); |
} |
tss_initialize(tss_p); |
214,7 → 214,7 |
* As of this moment, the current CPU has its own GDT pointing |
* to its own TSS. We just need to load the TR register. |
*/ |
tr_load(gdtselector(TSS_DES)); |
tr_load(selector(TSS_DES)); |
clean_IOPL_NT_flags(); /* Disable I/O on nonprivileged levels and clear NT flag. */ |
clean_AM_flag(); /* Disable alignment check */ |
232,5 → 232,28 |
gdtr_load(&cpugdtr); |
} |
/* Reboot the machine by initiating |
* a triple fault |
*/ |
void arch_reboot(void) |
{ |
preemption_disable(); |
ipl_t ipl = interrupts_disable(); |
memsetb(idt, sizeof(idt), 0); |
ptr_16_32_t idtr; |
idtr.limit = sizeof(idt); |
idtr.base = (uintptr_t) idt; |
idtr_load(&idtr); |
interrupts_restore(ipl); |
asm volatile ( |
"int $0x03\n" |
"cli\n" |
"hlt\n" |
); |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32/src/boot/vesa_prot.inc |
---|
File deleted |
/branches/arm/kernel/arch/ia32/src/boot/vesa_real.inc |
---|
File deleted |
/branches/arm/kernel/arch/ia32/src/boot/vesa_ret.inc |
---|
File deleted |
/branches/arm/kernel/arch/ia32/src/boot/boot.S |
---|
31,7 → 31,6 |
#include <arch/boot/memmap.h> |
#include <arch/mm/page.h> |
#include <arch/pm.h> |
#include <arch/cpuid.h> |
#define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE) |
43,41 → 42,40 |
multiboot_header: |
.long MULTIBOOT_HEADER_MAGIC |
.long MULTIBOOT_HEADER_FLAGS |
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) # checksum |
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) # checksum |
.long multiboot_header |
.long unmapped_ktext_start |
.long 0 |
.long 0 |
.long multiboot_image_start |
multiboot_image_start: |
cld |
movl $START_STACK, %esp # initialize stack pointer |
lgdt KA2PA(bootstrap_gdtr) # initialize Global Descriptor Table register |
movw $gdtselector(KDATA_DES), %cx |
movl $START_STACK, %esp # initialize stack pointer |
lgdt KA2PA(bootstrap_gdtr) # initialize Global Descriptor Table register |
movw $selector(KDATA_DES), %cx |
movw %cx, %es |
movw %cx, %fs |
movw %cx, %gs |
movw %cx, %ds # kernel data + stack |
movw %cx, %ds # kernel data + stack |
movw %cx, %ss |
jmpl $gdtselector(KTEXT_DES), $multiboot_meeting_point |
jmpl $selector(KTEXT_DES), $multiboot_meeting_point |
multiboot_meeting_point: |
movl %eax, grub_eax # save parameters from GRUB |
movl %eax, grub_eax # save parameters from GRUB |
movl %ebx, grub_ebx |
movl $(INTEL_CPUID_LEVEL), %eax |
cpuid |
cmp $0x0, %eax # any function > 0? |
xorl %eax, %eax |
cpuid |
cmp $0x0, %eax # any function > 0? |
jbe pse_unsupported |
movl $(INTEL_CPUID_STANDARD), %eax |
movl $0x1, %eax # Basic function code 1 |
cpuid |
bt $(INTEL_PSE), %edx |
bt $3, %edx # Test if PSE is supported |
jc pse_supported |
pse_unsupported: |
movl $pse_msg, %esi |
jmp error_halt |
84,31 → 82,138 |
pse_supported: |
bt $(INTEL_SEP), %edx |
jc sep_supported |
#ifdef CONFIG_FB |
mov $vesa_init, %esi |
mov $VESA_INIT_SEGMENT << 4, %edi |
mov $e_vesa_init - vesa_init, %ecx |
rep movsb |
mov $VESA_INIT_SEGMENT << 4, %edi |
jmpl *%edi |
movl $sep_msg, %esi |
jmp error_halt |
vesa_meeting_point: |
sep_supported: |
#include "vesa_prot.inc" |
# map kernel and turn paging on |
call map_kernel |
mov %esi, KA2PA(vesa_ph_addr) |
mov %di, KA2PA(vesa_height) |
shr $16, %edi |
mov %di, KA2PA(vesa_width) |
mov %bx, KA2PA(vesa_scanline) |
shr $16, %ebx |
mov %bx, KA2PA(vesa_bpp) |
#endif |
# call arch_pre_main(grub_eax, grub_ebx) |
pushl grub_ebx |
pushl grub_eax |
call arch_pre_main |
call map_kernel # map kernel and turn paging on |
call main_bsp |
movl grub_eax, %eax |
movl grub_ebx, %ebx |
cmpl $MULTIBOOT_LOADER_MAGIC, %eax # compare GRUB signature |
je valid_boot |
xorl %ecx, %ecx # no memory map available |
movl %ecx, e820counter |
jmp invalid_boot |
valid_boot: |
movl (%ebx), %eax # ebx = physical address of struct multiboot_info |
bt $3, %eax # mbi->flags[3] (mods_count, mods_addr valid) |
jc mods_valid |
xorl %ecx, %ecx |
movl %ecx, init |
jmp mods_end |
mods_valid: |
movl 20(%ebx), %ecx # mbi->mods_count |
movl %ecx, init |
cmpl $0, %ecx |
je mods_end |
movl 24(%ebx), %esi # mbi->mods_addr |
movl $init, %edi |
mods_loop: |
movl 0(%esi), %edx # mods->mod_start |
addl $0x80000000, %edx |
movl %edx, 4(%edi) |
movl 4(%esi), %edx |
subl 0(%esi), %edx # mods->mod_end - mods->mod_start |
movl %edx, 8(%edi) |
addl $16, %esi |
addl $8 , %edi |
loop mods_loop |
mods_end: |
bt $6, %eax # mbi->flags[6] (mmap_length, mmap_addr valid) |
jc mmap_valid |
xorl %edx, %edx |
jmp mmap_invalid |
mmap_valid: |
movl 44(%ebx), %ecx # mbi->mmap_length |
movl 48(%ebx), %esi # mbi->mmap_addr |
movl $e820table, %edi |
xorl %edx, %edx |
mmap_loop: |
cmpl $0, %ecx |
jle mmap_end |
movl 4(%esi), %eax # mmap->base_addr_low |
movl %eax, (%edi) |
movl 8(%esi), %eax # mmap->base_addr_high |
movl %eax, 4(%edi) |
movl 12(%esi), %eax # mmap->length_low |
movl %eax, 8(%edi) |
movl 16(%esi), %eax # mmap->length_high |
movl %eax, 12(%edi) |
movl 20(%esi), %eax # mmap->type |
movl %eax, 16(%edi) |
movl (%esi), %eax # mmap->size |
addl $0x4, %eax |
addl %eax, %esi |
subl %eax, %ecx |
addl $MEMMAP_E820_RECORD_SIZE, %edi |
incl %edx |
jmp mmap_loop |
mmap_end: |
mmap_invalid: |
movl %edx, e820counter |
invalid_boot: |
# not reached |
#ifdef CONFIG_SMP |
# copy AP bootstrap routines below 1 MB |
movl $BOOT_OFFSET, %esi |
movl $AP_BOOT_OFFSET, %edi |
movl $_hardcoded_unmapped_size, %ecx |
rep movsb |
#endif |
call main_bsp # never returns |
cli |
hlt0: |
hlt |
jmp hlt0 |
hlt |
.global map_kernel |
map_kernel: |
117,8 → 222,8 |
# For simplicity, we map the entire 4G space. |
# |
movl %cr4, %ecx |
orl $(1 << 4), %ecx # turn PSE on |
andl $(~(1 << 5)), %ecx # turn PAE off |
orl $(1 << 4), %ecx # turn PSE on |
andl $(~(1 << 5)), %ecx # turn PAE off |
movl %ecx, %cr4 |
movl $(page_directory + 0), %esi |
125,31 → 230,30 |
movl $(page_directory + 2048), %edi |
xorl %ecx, %ecx |
xorl %ebx, %ebx |
floop: |
movl $((1 << 7) | (1 << 1) | (1 << 0)), %eax |
orl %ebx, %eax |
movl %eax, (%esi, %ecx, 4) # mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M |
movl %eax, (%edi, %ecx, 4) # mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M |
addl $(4 * 1024 * 1024), %ebx |
incl %ecx |
cmpl $512, %ecx |
jl floop |
0: |
movl $((1 << 7) | (1 << 1) | (1 << 0)), %eax |
orl %ebx, %eax |
movl %eax, (%esi, %ecx, 4) # mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M |
movl %eax, (%edi, %ecx, 4) # mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M |
addl $(4 * 1024 * 1024), %ebx |
incl %ecx |
cmpl $512, %ecx |
jl 0b |
movl %esi, %cr3 |
movl %cr0, %ebx |
orl $(1 << 31), %ebx # turn paging on |
orl $(1 << 31), %ebx # turn paging on |
movl %ebx, %cr0 |
ret |
# Print string from %esi to EGA display (in red) and halt |
error_halt: |
movl $0xb8000, %edi # base of EGA text mode memory |
movl $0xb8000, %edi # base of EGA text mode memory |
xorl %eax, %eax |
movw $0x3d4, %dx # read bits 8 - 15 of the cursor address |
movw $0x3d4, %dx # read bits 8 - 15 of the cursor address |
movb $0xe, %al |
outb %al, %dx |
157,7 → 261,7 |
inb %dx, %al |
shl $8, %ax |
movw $0x3d4, %dx # read bits 0 - 7 of the cursor address |
movw $0x3d4, %dx # read bits 0 - 7 of the cursor address |
movb $0xf, %al |
outb %al, %dx |
166,9 → 270,7 |
cmp $1920, %ax |
jbe cursor_ok |
movw $1920, %ax # sanity check for the cursor on the last line |
movw $1920, %ax # sanity check for the cursor on the last line |
cursor_ok: |
movw %ax, %bx |
175,7 → 277,7 |
shl $1, %eax |
addl %eax, %edi |
movw $0x0c00, %ax # black background, light red foreground |
movw $0x0c00, %ax # black background, light red foreground |
ploop: |
lodsb |
182,11 → 284,11 |
cmp $0, %al |
je ploop_end |
stosw |
inc %bx |
inc %bx |
jmp ploop |
ploop_end: |
movw $0x3d4, %dx # write bits 8 - 15 of the cursor address |
movw $0x3d4, %dx # write bits 8 - 15 of the cursor address |
movb $0xe, %al |
outb %al, %dx |
194,7 → 296,7 |
movb %bh, %al |
outb %al, %dx |
movw $0x3d4, %dx # write bits 0 - 7 of the cursor address |
movw $0x3d4, %dx # write bits 0 - 7 of the cursor address |
movb $0xf, %al |
outb %al, %dx |
201,14 → 303,240 |
movw $0x3d5, %dx |
movb %bl, %al |
outb %al, %dx |
cli |
hlt1: |
hlt |
jmp hlt1 |
hlt |
#include "vesa_real.inc" |
#ifdef CONFIG_FB |
vesa_init: |
jmp $selector(VESA_INIT_DES), $vesa_init_real - vesa_init |
.code16 |
vesa_init_real: |
mov %cr0, %eax |
and $~1, %eax |
mov %eax, %cr0 |
jmp $VESA_INIT_SEGMENT, $vesa_init_real2 - vesa_init |
vesa_init_real2: |
mov $VESA_INIT_SEGMENT, %bx |
mov %bx, %es |
mov %bx, %fs |
mov %bx, %gs |
mov %bx, %ds |
mov %bx, %ss |
movl %esp, %eax |
movl $0x0000fffc, %esp |
movl $0x0000fffc, %ebp |
pushl %eax |
#define VESA_INFO_SIZE 1024 |
#define VESA_MODE_ATTRIBUTES_OFFSET 0 |
#define VESA_MODE_LIST_PTR_OFFSET 14 |
#define VESA_MODE_SCANLINE_OFFSET 16 |
#define VESA_MODE_WIDTH_OFFSET 18 |
#define VESA_MODE_HEIGHT_OFFSET 20 |
#define VESA_MODE_BPP_OFFSET 25 |
#define VESA_MODE_PHADDR_OFFSET 40 |
#define VESA_END_OF_MODES 0xffff |
#define VESA_OK 0x4f |
#define VESA_GET_INFO 0x4f00 |
#define VESA_GET_MODE_INFO 0x4f01 |
#define VESA_SET_MODE 0x4f02 |
#define VESA_SET_PALETTE 0x4f09 |
#if CONFIG_VESA_BPP == 24 |
#define CONFIG_VESA_BPP_VARIANT 32 |
#endif |
mov $VESA_GET_INFO, %ax |
mov $e_vesa_init - vesa_init, %di |
push %di |
int $0x10 |
pop %di |
cmp $VESA_OK, %al |
jnz 0f |
mov 2 + VESA_MODE_LIST_PTR_OFFSET(%di), %si |
mov %si, %gs |
mov VESA_MODE_LIST_PTR_OFFSET(%di), %si |
add $VESA_INFO_SIZE, %di |
1:# Try next mode |
mov %gs:(%si), %cx |
cmp $VESA_END_OF_MODES, %cx |
jz 0f |
inc %si |
inc %si |
push %cx |
push %di |
push %si |
mov $VESA_GET_MODE_INFO, %ax |
int $0x10 |
pop %si |
pop %di |
pop %cx |
cmp $VESA_OK, %al |
jnz 0f |
mov $CONFIG_VESA_WIDTH, %ax |
cmp VESA_MODE_WIDTH_OFFSET(%di), %ax |
jnz 1b |
mov $CONFIG_VESA_HEIGHT, %ax |
cmp VESA_MODE_HEIGHT_OFFSET(%di), %ax |
jnz 1b |
mov $CONFIG_VESA_BPP, %al |
cmp VESA_MODE_BPP_OFFSET(%di), %al |
#ifdef CONFIG_VESA_BPP_VARIANT |
jz 2f |
mov $CONFIG_VESA_BPP_VARIANT, %al |
cmp VESA_MODE_BPP_OFFSET(%di), %al |
#endif |
jnz 1b |
2: |
mov %cx, %bx |
or $0xc000, %bx |
push %di |
mov $VESA_SET_MODE, %ax |
int $0x10 |
pop %di |
cmp $VESA_OK, %al |
jnz 0f |
#if CONFIG_VESA_BPP == 8 |
# Set 3:2:3 VGA palette |
mov VESA_MODE_ATTRIBUTES_OFFSET(%di), %ax |
push %di |
mov $vga323 - vesa_init, %di |
mov $0x100, %ecx |
bt $5, %ax # Test if VGA compatible registers are present |
jnc vga_compat |
# Try VESA routine to set palette |
mov $VESA_SET_PALETTE, %ax |
xor %bl, %bl |
xor %dx, %dx |
int $0x10 |
jmp vga_not_compat |
vga_compat: |
# Try VGA registers to set palette |
movw $0x3c6, %dx # Set palette mask |
movb $0xff, %al |
outb %al, %dx |
movw $0x3c8, %dx # First index to set |
xor %al, %al |
outb %al, %dx |
movw $0x3c9, %dx # Data port |
vga_loop: |
movb %es:2(%di), %al |
outb %al, %dx |
movb %es:1(%di), %al |
outb %al, %dx |
movb %es:(%di), %al |
outb %al, %dx |
addw $4, %di |
loop vga_loop |
vga_not_compat: |
pop %di |
#endif |
mov VESA_MODE_PHADDR_OFFSET(%di), %esi |
mov VESA_MODE_WIDTH_OFFSET(%di), %ax |
shl $16, %eax |
mov VESA_MODE_HEIGHT_OFFSET(%di), %ax |
mov VESA_MODE_BPP_OFFSET(%di), %bl |
xor %bh, %bh |
shl $16, %ebx |
mov VESA_MODE_SCANLINE_OFFSET(%di), %bx |
mov %eax, %edi |
8: |
mov %cr0, %eax |
or $1, %eax |
mov %eax, %cr0 |
jmp 9f |
9: |
ljmpl $selector(KTEXT_DES), $(vesa_init_protect - vesa_init + VESA_INIT_SEGMENT << 4) |
0:# No prefered mode found |
mov $0x111, %cx |
push %di |
push %cx |
mov $VESA_GET_MODE_INFO, %ax |
int $0x10 |
pop %cx |
pop %di |
cmp $VESA_OK, %al |
jnz 1f |
jz 2b # Force relative jump |
1: |
mov $0x0003, %ax |
int $0x10 |
mov $0xffffffff, %edi # EGA text mode used, because of problems with VESA |
xor %ax, %ax |
jz 8b # Force relative jump |
vga323: |
#include "vga323.pal" |
.code32 |
vesa_init_protect: |
movw $selector(KDATA_DES), %cx |
movw %cx, %es |
movw %cx, %fs |
movw %cx, %gs |
movw %cx, %ds # kernel data + stack |
movw %cx, %ss |
movl $START_STACK, %esp # initialize stack pointer |
jmpl $selector(KTEXT_DES), $vesa_meeting_point |
.align 4 |
e_vesa_init: |
#endif |
.section K_DATA_START, "aw", @progbits |
.align 4096 |
223,6 → 551,3 |
pse_msg: |
.asciz "Page Size Extension not supported. System halted." |
sep_msg: |
.asciz "SYSENTER/SYSEXIT not supported. System halted." |
/branches/arm/kernel/arch/ia32/src/boot/vga323.pal |
---|
1,256 → 1,256 |
.byte 0x00, 0x00, 0x00, 0x00 |
.byte 0x09, 0x00, 0x00, 0x00 |
.byte 0x12, 0x00, 0x00, 0x00 |
.byte 0x1b, 0x00, 0x00, 0x00 |
.byte 0x24, 0x00, 0x00, 0x00 |
.byte 0x2d, 0x00, 0x00, 0x00 |
.byte 0x36, 0x00, 0x00, 0x00 |
.byte 0x3f, 0x00, 0x00, 0x00 |
.byte 0x00, 0x15, 0x00, 0x00 |
.byte 0x09, 0x15, 0x00, 0x00 |
.byte 0x12, 0x15, 0x00, 0x00 |
.byte 0x1b, 0x15, 0x00, 0x00 |
.byte 0x24, 0x15, 0x00, 0x00 |
.byte 0x2d, 0x15, 0x00, 0x00 |
.byte 0x36, 0x15, 0x00, 0x00 |
.byte 0x3f, 0x15, 0x00, 0x00 |
.byte 0x00, 0x2a, 0x00, 0x00 |
.byte 0x09, 0x2a, 0x00, 0x00 |
.byte 0x12, 0x2a, 0x00, 0x00 |
.byte 0x1b, 0x2a, 0x00, 0x00 |
.byte 0x24, 0x2a, 0x00, 0x00 |
.byte 0x2d, 0x2a, 0x00, 0x00 |
.byte 0x36, 0x2a, 0x00, 0x00 |
.byte 0x3f, 0x2a, 0x00, 0x00 |
.byte 0x00, 0x3f, 0x00, 0x00 |
.byte 0x09, 0x3f, 0x00, 0x00 |
.byte 0x12, 0x3f, 0x00, 0x00 |
.byte 0x1b, 0x3f, 0x00, 0x00 |
.byte 0x24, 0x3f, 0x00, 0x00 |
.byte 0x2d, 0x3f, 0x00, 0x00 |
.byte 0x36, 0x3f, 0x00, 0x00 |
.byte 0x3f, 0x3f, 0x00, 0x00 |
.byte 0x00, 0x00, 0x09, 0x00 |
.byte 0x09, 0x00, 0x09, 0x00 |
.byte 0x12, 0x00, 0x09, 0x00 |
.byte 0x1b, 0x00, 0x09, 0x00 |
.byte 0x24, 0x00, 0x09, 0x00 |
.byte 0x2d, 0x00, 0x09, 0x00 |
.byte 0x36, 0x00, 0x09, 0x00 |
.byte 0x3f, 0x00, 0x09, 0x00 |
.byte 0x00, 0x15, 0x09, 0x00 |
.byte 0x09, 0x15, 0x09, 0x00 |
.byte 0x12, 0x15, 0x09, 0x00 |
.byte 0x1b, 0x15, 0x09, 0x00 |
.byte 0x24, 0x15, 0x09, 0x00 |
.byte 0x2d, 0x15, 0x09, 0x00 |
.byte 0x36, 0x15, 0x09, 0x00 |
.byte 0x3f, 0x15, 0x09, 0x00 |
.byte 0x00, 0x2a, 0x09, 0x00 |
.byte 0x09, 0x2a, 0x09, 0x00 |
.byte 0x12, 0x2a, 0x09, 0x00 |
.byte 0x1b, 0x2a, 0x09, 0x00 |
.byte 0x24, 0x2a, 0x09, 0x00 |
.byte 0x2d, 0x2a, 0x09, 0x00 |
.byte 0x36, 0x2a, 0x09, 0x00 |
.byte 0x3f, 0x2a, 0x09, 0x00 |
.byte 0x00, 0x3f, 0x09, 0x00 |
.byte 0x09, 0x3f, 0x09, 0x00 |
.byte 0x12, 0x3f, 0x09, 0x00 |
.byte 0x1b, 0x3f, 0x09, 0x00 |
.byte 0x24, 0x3f, 0x09, 0x00 |
.byte 0x2d, 0x3f, 0x09, 0x00 |
.byte 0x36, 0x3f, 0x09, 0x00 |
.byte 0x3f, 0x3f, 0x09, 0x00 |
.byte 0x00, 0x00, 0x12, 0x00 |
.byte 0x09, 0x00, 0x12, 0x00 |
.byte 0x12, 0x00, 0x12, 0x00 |
.byte 0x1b, 0x00, 0x12, 0x00 |
.byte 0x24, 0x00, 0x12, 0x00 |
.byte 0x2d, 0x00, 0x12, 0x00 |
.byte 0x36, 0x00, 0x12, 0x00 |
.byte 0x3f, 0x00, 0x12, 0x00 |
.byte 0x00, 0x15, 0x12, 0x00 |
.byte 0x09, 0x15, 0x12, 0x00 |
.byte 0x12, 0x15, 0x12, 0x00 |
.byte 0x1b, 0x15, 0x12, 0x00 |
.byte 0x24, 0x15, 0x12, 0x00 |
.byte 0x2d, 0x15, 0x12, 0x00 |
.byte 0x36, 0x15, 0x12, 0x00 |
.byte 0x3f, 0x15, 0x12, 0x00 |
.byte 0x00, 0x2a, 0x12, 0x00 |
.byte 0x09, 0x2a, 0x12, 0x00 |
.byte 0x12, 0x2a, 0x12, 0x00 |
.byte 0x1b, 0x2a, 0x12, 0x00 |
.byte 0x24, 0x2a, 0x12, 0x00 |
.byte 0x2d, 0x2a, 0x12, 0x00 |
.byte 0x36, 0x2a, 0x12, 0x00 |
.byte 0x3f, 0x2a, 0x12, 0x00 |
.byte 0x00, 0x3f, 0x12, 0x00 |
.byte 0x09, 0x3f, 0x12, 0x00 |
.byte 0x12, 0x3f, 0x12, 0x00 |
.byte 0x1b, 0x3f, 0x12, 0x00 |
.byte 0x24, 0x3f, 0x12, 0x00 |
.byte 0x2d, 0x3f, 0x12, 0x00 |
.byte 0x36, 0x3f, 0x12, 0x00 |
.byte 0x3f, 0x3f, 0x12, 0x00 |
.byte 0x00, 0x00, 0x1b, 0x00 |
.byte 0x09, 0x00, 0x1b, 0x00 |
.byte 0x12, 0x00, 0x1b, 0x00 |
.byte 0x1b, 0x00, 0x1b, 0x00 |
.byte 0x24, 0x00, 0x1b, 0x00 |
.byte 0x2d, 0x00, 0x1b, 0x00 |
.byte 0x36, 0x00, 0x1b, 0x00 |
.byte 0x3f, 0x00, 0x1b, 0x00 |
.byte 0x00, 0x15, 0x1b, 0x00 |
.byte 0x09, 0x15, 0x1b, 0x00 |
.byte 0x12, 0x15, 0x1b, 0x00 |
.byte 0x1b, 0x15, 0x1b, 0x00 |
.byte 0x24, 0x15, 0x1b, 0x00 |
.byte 0x2d, 0x15, 0x1b, 0x00 |
.byte 0x36, 0x15, 0x1b, 0x00 |
.byte 0x3f, 0x15, 0x1b, 0x00 |
.byte 0x00, 0x2a, 0x1b, 0x00 |
.byte 0x09, 0x2a, 0x1b, 0x00 |
.byte 0x12, 0x2a, 0x1b, 0x00 |
.byte 0x1b, 0x2a, 0x1b, 0x00 |
.byte 0x24, 0x2a, 0x1b, 0x00 |
.byte 0x2d, 0x2a, 0x1b, 0x00 |
.byte 0x36, 0x2a, 0x1b, 0x00 |
.byte 0x3f, 0x2a, 0x1b, 0x00 |
.byte 0x00, 0x3f, 0x1b, 0x00 |
.byte 0x09, 0x3f, 0x1b, 0x00 |
.byte 0x12, 0x3f, 0x1b, 0x00 |
.byte 0x1b, 0x3f, 0x1b, 0x00 |
.byte 0x24, 0x3f, 0x1b, 0x00 |
.byte 0x2d, 0x3f, 0x1b, 0x00 |
.byte 0x36, 0x3f, 0x1b, 0x00 |
.byte 0x3f, 0x3f, 0x1b, 0x00 |
.byte 0x00, 0x00, 0x24, 0x00 |
.byte 0x09, 0x00, 0x24, 0x00 |
.byte 0x12, 0x00, 0x24, 0x00 |
.byte 0x1b, 0x00, 0x24, 0x00 |
.byte 0x24, 0x00, 0x24, 0x00 |
.byte 0x2d, 0x00, 0x24, 0x00 |
.byte 0x36, 0x00, 0x24, 0x00 |
.byte 0x3f, 0x00, 0x24, 0x00 |
.byte 0x00, 0x15, 0x24, 0x00 |
.byte 0x09, 0x15, 0x24, 0x00 |
.byte 0x12, 0x15, 0x24, 0x00 |
.byte 0x1b, 0x15, 0x24, 0x00 |
.byte 0x24, 0x15, 0x24, 0x00 |
.byte 0x2d, 0x15, 0x24, 0x00 |
.byte 0x36, 0x15, 0x24, 0x00 |
.byte 0x3f, 0x15, 0x24, 0x00 |
.byte 0x00, 0x2a, 0x24, 0x00 |
.byte 0x09, 0x2a, 0x24, 0x00 |
.byte 0x12, 0x2a, 0x24, 0x00 |
.byte 0x1b, 0x2a, 0x24, 0x00 |
.byte 0x24, 0x2a, 0x24, 0x00 |
.byte 0x2d, 0x2a, 0x24, 0x00 |
.byte 0x36, 0x2a, 0x24, 0x00 |
.byte 0x3f, 0x2a, 0x24, 0x00 |
.byte 0x00, 0x3f, 0x24, 0x00 |
.byte 0x09, 0x3f, 0x24, 0x00 |
.byte 0x12, 0x3f, 0x24, 0x00 |
.byte 0x1b, 0x3f, 0x24, 0x00 |
.byte 0x24, 0x3f, 0x24, 0x00 |
.byte 0x2d, 0x3f, 0x24, 0x00 |
.byte 0x36, 0x3f, 0x24, 0x00 |
.byte 0x3f, 0x3f, 0x24, 0x00 |
.byte 0x00, 0x00, 0x2d, 0x00 |
.byte 0x09, 0x00, 0x2d, 0x00 |
.byte 0x12, 0x00, 0x2d, 0x00 |
.byte 0x1b, 0x00, 0x2d, 0x00 |
.byte 0x24, 0x00, 0x2d, 0x00 |
.byte 0x2d, 0x00, 0x2d, 0x00 |
.byte 0x36, 0x00, 0x2d, 0x00 |
.byte 0x3f, 0x00, 0x2d, 0x00 |
.byte 0x00, 0x15, 0x2d, 0x00 |
.byte 0x09, 0x15, 0x2d, 0x00 |
.byte 0x12, 0x15, 0x2d, 0x00 |
.byte 0x1b, 0x15, 0x2d, 0x00 |
.byte 0x24, 0x15, 0x2d, 0x00 |
.byte 0x2d, 0x15, 0x2d, 0x00 |
.byte 0x36, 0x15, 0x2d, 0x00 |
.byte 0x3f, 0x15, 0x2d, 0x00 |
.byte 0x00, 0x2a, 0x2d, 0x00 |
.byte 0x09, 0x2a, 0x2d, 0x00 |
.byte 0x12, 0x2a, 0x2d, 0x00 |
.byte 0x1b, 0x2a, 0x2d, 0x00 |
.byte 0x24, 0x2a, 0x2d, 0x00 |
.byte 0x2d, 0x2a, 0x2d, 0x00 |
.byte 0x36, 0x2a, 0x2d, 0x00 |
.byte 0x3f, 0x2a, 0x2d, 0x00 |
.byte 0x00, 0x3f, 0x2d, 0x00 |
.byte 0x09, 0x3f, 0x2d, 0x00 |
.byte 0x12, 0x3f, 0x2d, 0x00 |
.byte 0x1b, 0x3f, 0x2d, 0x00 |
.byte 0x24, 0x3f, 0x2d, 0x00 |
.byte 0x2d, 0x3f, 0x2d, 0x00 |
.byte 0x36, 0x3f, 0x2d, 0x00 |
.byte 0x3f, 0x3f, 0x2d, 0x00 |
.byte 0x00, 0x00, 0x36, 0x00 |
.byte 0x09, 0x00, 0x36, 0x00 |
.byte 0x12, 0x00, 0x36, 0x00 |
.byte 0x1b, 0x00, 0x36, 0x00 |
.byte 0x24, 0x00, 0x36, 0x00 |
.byte 0x2d, 0x00, 0x36, 0x00 |
.byte 0x36, 0x00, 0x36, 0x00 |
.byte 0x3f, 0x00, 0x36, 0x00 |
.byte 0x00, 0x15, 0x36, 0x00 |
.byte 0x09, 0x15, 0x36, 0x00 |
.byte 0x12, 0x15, 0x36, 0x00 |
.byte 0x1b, 0x15, 0x36, 0x00 |
.byte 0x24, 0x15, 0x36, 0x00 |
.byte 0x2d, 0x15, 0x36, 0x00 |
.byte 0x36, 0x15, 0x36, 0x00 |
.byte 0x3f, 0x15, 0x36, 0x00 |
.byte 0x00, 0x2a, 0x36, 0x00 |
.byte 0x09, 0x2a, 0x36, 0x00 |
.byte 0x12, 0x2a, 0x36, 0x00 |
.byte 0x1b, 0x2a, 0x36, 0x00 |
.byte 0x24, 0x2a, 0x36, 0x00 |
.byte 0x2d, 0x2a, 0x36, 0x00 |
.byte 0x36, 0x2a, 0x36, 0x00 |
.byte 0x3f, 0x2a, 0x36, 0x00 |
.byte 0x00, 0x3f, 0x36, 0x00 |
.byte 0x09, 0x3f, 0x36, 0x00 |
.byte 0x12, 0x3f, 0x36, 0x00 |
.byte 0x1b, 0x3f, 0x36, 0x00 |
.byte 0x24, 0x3f, 0x36, 0x00 |
.byte 0x2d, 0x3f, 0x36, 0x00 |
.byte 0x36, 0x3f, 0x36, 0x00 |
.byte 0x3f, 0x3f, 0x36, 0x00 |
.byte 0x00, 0x00, 0x3f, 0x00 |
.byte 0x09, 0x00, 0x3f, 0x00 |
.byte 0x12, 0x00, 0x3f, 0x00 |
.byte 0x1b, 0x00, 0x3f, 0x00 |
.byte 0x24, 0x00, 0x3f, 0x00 |
.byte 0x2d, 0x00, 0x3f, 0x00 |
.byte 0x36, 0x00, 0x3f, 0x00 |
.byte 0x3f, 0x00, 0x3f, 0x00 |
.byte 0x00, 0x15, 0x3f, 0x00 |
.byte 0x09, 0x15, 0x3f, 0x00 |
.byte 0x12, 0x15, 0x3f, 0x00 |
.byte 0x1b, 0x15, 0x3f, 0x00 |
.byte 0x24, 0x15, 0x3f, 0x00 |
.byte 0x2d, 0x15, 0x3f, 0x00 |
.byte 0x36, 0x15, 0x3f, 0x00 |
.byte 0x3f, 0x15, 0x3f, 0x00 |
.byte 0x00, 0x2a, 0x3f, 0x00 |
.byte 0x09, 0x2a, 0x3f, 0x00 |
.byte 0x12, 0x2a, 0x3f, 0x00 |
.byte 0x1b, 0x2a, 0x3f, 0x00 |
.byte 0x24, 0x2a, 0x3f, 0x00 |
.byte 0x2d, 0x2a, 0x3f, 0x00 |
.byte 0x36, 0x2a, 0x3f, 0x00 |
.byte 0x3f, 0x2a, 0x3f, 0x00 |
.byte 0x00, 0x3f, 0x3f, 0x00 |
.byte 0x09, 0x3f, 0x3f, 0x00 |
.byte 0x12, 0x3f, 0x3f, 0x00 |
.byte 0x1b, 0x3f, 0x3f, 0x00 |
.byte 0x24, 0x3f, 0x3f, 0x00 |
.byte 0x2d, 0x3f, 0x3f, 0x00 |
.byte 0x36, 0x3f, 0x3f, 0x00 |
.byte 0x3f, 0x3f, 0x3f, 0x00 |
.byte 0x36, 0x3f, 0x3f, 0x00 |
.byte 0x2d, 0x3f, 0x3f, 0x00 |
.byte 0x24, 0x3f, 0x3f, 0x00 |
.byte 0x1b, 0x3f, 0x3f, 0x00 |
.byte 0x12, 0x3f, 0x3f, 0x00 |
.byte 0x09, 0x3f, 0x3f, 0x00 |
.byte 0x00, 0x3f, 0x3f, 0x00 |
.byte 0x3f, 0x2a, 0x3f, 0x00 |
.byte 0x36, 0x2a, 0x3f, 0x00 |
.byte 0x2d, 0x2a, 0x3f, 0x00 |
.byte 0x24, 0x2a, 0x3f, 0x00 |
.byte 0x1b, 0x2a, 0x3f, 0x00 |
.byte 0x12, 0x2a, 0x3f, 0x00 |
.byte 0x09, 0x2a, 0x3f, 0x00 |
.byte 0x00, 0x2a, 0x3f, 0x00 |
.byte 0x3f, 0x15, 0x3f, 0x00 |
.byte 0x36, 0x15, 0x3f, 0x00 |
.byte 0x2d, 0x15, 0x3f, 0x00 |
.byte 0x24, 0x15, 0x3f, 0x00 |
.byte 0x1b, 0x15, 0x3f, 0x00 |
.byte 0x12, 0x15, 0x3f, 0x00 |
.byte 0x09, 0x15, 0x3f, 0x00 |
.byte 0x00, 0x15, 0x3f, 0x00 |
.byte 0x3f, 0x00, 0x3f, 0x00 |
.byte 0x36, 0x00, 0x3f, 0x00 |
.byte 0x2d, 0x00, 0x3f, 0x00 |
.byte 0x24, 0x00, 0x3f, 0x00 |
.byte 0x1b, 0x00, 0x3f, 0x00 |
.byte 0x12, 0x00, 0x3f, 0x00 |
.byte 0x09, 0x00, 0x3f, 0x00 |
.byte 0x00, 0x00, 0x3f, 0x00 |
.byte 0x3f, 0x3f, 0x36, 0x00 |
.byte 0x36, 0x3f, 0x36, 0x00 |
.byte 0x2d, 0x3f, 0x36, 0x00 |
.byte 0x24, 0x3f, 0x36, 0x00 |
.byte 0x1b, 0x3f, 0x36, 0x00 |
.byte 0x12, 0x3f, 0x36, 0x00 |
.byte 0x09, 0x3f, 0x36, 0x00 |
.byte 0x00, 0x3f, 0x36, 0x00 |
.byte 0x3f, 0x2a, 0x36, 0x00 |
.byte 0x36, 0x2a, 0x36, 0x00 |
.byte 0x2d, 0x2a, 0x36, 0x00 |
.byte 0x24, 0x2a, 0x36, 0x00 |
.byte 0x1b, 0x2a, 0x36, 0x00 |
.byte 0x12, 0x2a, 0x36, 0x00 |
.byte 0x09, 0x2a, 0x36, 0x00 |
.byte 0x00, 0x2a, 0x36, 0x00 |
.byte 0x3f, 0x15, 0x36, 0x00 |
.byte 0x36, 0x15, 0x36, 0x00 |
.byte 0x2d, 0x15, 0x36, 0x00 |
.byte 0x24, 0x15, 0x36, 0x00 |
.byte 0x1b, 0x15, 0x36, 0x00 |
.byte 0x12, 0x15, 0x36, 0x00 |
.byte 0x09, 0x15, 0x36, 0x00 |
.byte 0x00, 0x15, 0x36, 0x00 |
.byte 0x3f, 0x00, 0x36, 0x00 |
.byte 0x36, 0x00, 0x36, 0x00 |
.byte 0x2d, 0x00, 0x36, 0x00 |
.byte 0x24, 0x00, 0x36, 0x00 |
.byte 0x1b, 0x00, 0x36, 0x00 |
.byte 0x12, 0x00, 0x36, 0x00 |
.byte 0x09, 0x00, 0x36, 0x00 |
.byte 0x00, 0x00, 0x36, 0x00 |
.byte 0x3f, 0x3f, 0x2d, 0x00 |
.byte 0x36, 0x3f, 0x2d, 0x00 |
.byte 0x2d, 0x3f, 0x2d, 0x00 |
.byte 0x24, 0x3f, 0x2d, 0x00 |
.byte 0x1b, 0x3f, 0x2d, 0x00 |
.byte 0x12, 0x3f, 0x2d, 0x00 |
.byte 0x09, 0x3f, 0x2d, 0x00 |
.byte 0x00, 0x3f, 0x2d, 0x00 |
.byte 0x3f, 0x2a, 0x2d, 0x00 |
.byte 0x36, 0x2a, 0x2d, 0x00 |
.byte 0x2d, 0x2a, 0x2d, 0x00 |
.byte 0x24, 0x2a, 0x2d, 0x00 |
.byte 0x1b, 0x2a, 0x2d, 0x00 |
.byte 0x12, 0x2a, 0x2d, 0x00 |
.byte 0x09, 0x2a, 0x2d, 0x00 |
.byte 0x00, 0x2a, 0x2d, 0x00 |
.byte 0x3f, 0x15, 0x2d, 0x00 |
.byte 0x36, 0x15, 0x2d, 0x00 |
.byte 0x2d, 0x15, 0x2d, 0x00 |
.byte 0x24, 0x15, 0x2d, 0x00 |
.byte 0x1b, 0x15, 0x2d, 0x00 |
.byte 0x12, 0x15, 0x2d, 0x00 |
.byte 0x09, 0x15, 0x2d, 0x00 |
.byte 0x00, 0x15, 0x2d, 0x00 |
.byte 0x3f, 0x00, 0x2d, 0x00 |
.byte 0x36, 0x00, 0x2d, 0x00 |
.byte 0x2d, 0x00, 0x2d, 0x00 |
.byte 0x24, 0x00, 0x2d, 0x00 |
.byte 0x1b, 0x00, 0x2d, 0x00 |
.byte 0x12, 0x00, 0x2d, 0x00 |
.byte 0x09, 0x00, 0x2d, 0x00 |
.byte 0x00, 0x00, 0x2d, 0x00 |
.byte 0x3f, 0x3f, 0x24, 0x00 |
.byte 0x36, 0x3f, 0x24, 0x00 |
.byte 0x2d, 0x3f, 0x24, 0x00 |
.byte 0x24, 0x3f, 0x24, 0x00 |
.byte 0x1b, 0x3f, 0x24, 0x00 |
.byte 0x12, 0x3f, 0x24, 0x00 |
.byte 0x09, 0x3f, 0x24, 0x00 |
.byte 0x00, 0x3f, 0x24, 0x00 |
.byte 0x3f, 0x2a, 0x24, 0x00 |
.byte 0x36, 0x2a, 0x24, 0x00 |
.byte 0x2d, 0x2a, 0x24, 0x00 |
.byte 0x24, 0x2a, 0x24, 0x00 |
.byte 0x1b, 0x2a, 0x24, 0x00 |
.byte 0x12, 0x2a, 0x24, 0x00 |
.byte 0x09, 0x2a, 0x24, 0x00 |
.byte 0x00, 0x2a, 0x24, 0x00 |
.byte 0x3f, 0x15, 0x24, 0x00 |
.byte 0x36, 0x15, 0x24, 0x00 |
.byte 0x2d, 0x15, 0x24, 0x00 |
.byte 0x24, 0x15, 0x24, 0x00 |
.byte 0x1b, 0x15, 0x24, 0x00 |
.byte 0x12, 0x15, 0x24, 0x00 |
.byte 0x09, 0x15, 0x24, 0x00 |
.byte 0x00, 0x15, 0x24, 0x00 |
.byte 0x3f, 0x00, 0x24, 0x00 |
.byte 0x36, 0x00, 0x24, 0x00 |
.byte 0x2d, 0x00, 0x24, 0x00 |
.byte 0x24, 0x00, 0x24, 0x00 |
.byte 0x1b, 0x00, 0x24, 0x00 |
.byte 0x12, 0x00, 0x24, 0x00 |
.byte 0x09, 0x00, 0x24, 0x00 |
.byte 0x00, 0x00, 0x24, 0x00 |
.byte 0x3f, 0x3f, 0x1b, 0x00 |
.byte 0x36, 0x3f, 0x1b, 0x00 |
.byte 0x2d, 0x3f, 0x1b, 0x00 |
.byte 0x24, 0x3f, 0x1b, 0x00 |
.byte 0x1b, 0x3f, 0x1b, 0x00 |
.byte 0x12, 0x3f, 0x1b, 0x00 |
.byte 0x09, 0x3f, 0x1b, 0x00 |
.byte 0x00, 0x3f, 0x1b, 0x00 |
.byte 0x3f, 0x2a, 0x1b, 0x00 |
.byte 0x36, 0x2a, 0x1b, 0x00 |
.byte 0x2d, 0x2a, 0x1b, 0x00 |
.byte 0x24, 0x2a, 0x1b, 0x00 |
.byte 0x1b, 0x2a, 0x1b, 0x00 |
.byte 0x12, 0x2a, 0x1b, 0x00 |
.byte 0x09, 0x2a, 0x1b, 0x00 |
.byte 0x00, 0x2a, 0x1b, 0x00 |
.byte 0x3f, 0x15, 0x1b, 0x00 |
.byte 0x36, 0x15, 0x1b, 0x00 |
.byte 0x2d, 0x15, 0x1b, 0x00 |
.byte 0x24, 0x15, 0x1b, 0x00 |
.byte 0x1b, 0x15, 0x1b, 0x00 |
.byte 0x12, 0x15, 0x1b, 0x00 |
.byte 0x09, 0x15, 0x1b, 0x00 |
.byte 0x00, 0x15, 0x1b, 0x00 |
.byte 0x3f, 0x00, 0x1b, 0x00 |
.byte 0x36, 0x00, 0x1b, 0x00 |
.byte 0x2d, 0x00, 0x1b, 0x00 |
.byte 0x24, 0x00, 0x1b, 0x00 |
.byte 0x1b, 0x00, 0x1b, 0x00 |
.byte 0x12, 0x00, 0x1b, 0x00 |
.byte 0x09, 0x00, 0x1b, 0x00 |
.byte 0x00, 0x00, 0x1b, 0x00 |
.byte 0x3f, 0x3f, 0x12, 0x00 |
.byte 0x36, 0x3f, 0x12, 0x00 |
.byte 0x2d, 0x3f, 0x12, 0x00 |
.byte 0x24, 0x3f, 0x12, 0x00 |
.byte 0x1b, 0x3f, 0x12, 0x00 |
.byte 0x12, 0x3f, 0x12, 0x00 |
.byte 0x09, 0x3f, 0x12, 0x00 |
.byte 0x00, 0x3f, 0x12, 0x00 |
.byte 0x3f, 0x2a, 0x12, 0x00 |
.byte 0x36, 0x2a, 0x12, 0x00 |
.byte 0x2d, 0x2a, 0x12, 0x00 |
.byte 0x24, 0x2a, 0x12, 0x00 |
.byte 0x1b, 0x2a, 0x12, 0x00 |
.byte 0x12, 0x2a, 0x12, 0x00 |
.byte 0x09, 0x2a, 0x12, 0x00 |
.byte 0x00, 0x2a, 0x12, 0x00 |
.byte 0x3f, 0x15, 0x12, 0x00 |
.byte 0x36, 0x15, 0x12, 0x00 |
.byte 0x2d, 0x15, 0x12, 0x00 |
.byte 0x24, 0x15, 0x12, 0x00 |
.byte 0x1b, 0x15, 0x12, 0x00 |
.byte 0x12, 0x15, 0x12, 0x00 |
.byte 0x09, 0x15, 0x12, 0x00 |
.byte 0x00, 0x15, 0x12, 0x00 |
.byte 0x3f, 0x00, 0x12, 0x00 |
.byte 0x36, 0x00, 0x12, 0x00 |
.byte 0x2d, 0x00, 0x12, 0x00 |
.byte 0x24, 0x00, 0x12, 0x00 |
.byte 0x1b, 0x00, 0x12, 0x00 |
.byte 0x12, 0x00, 0x12, 0x00 |
.byte 0x09, 0x00, 0x12, 0x00 |
.byte 0x00, 0x00, 0x12, 0x00 |
.byte 0x3f, 0x3f, 0x09, 0x00 |
.byte 0x36, 0x3f, 0x09, 0x00 |
.byte 0x2d, 0x3f, 0x09, 0x00 |
.byte 0x24, 0x3f, 0x09, 0x00 |
.byte 0x1b, 0x3f, 0x09, 0x00 |
.byte 0x12, 0x3f, 0x09, 0x00 |
.byte 0x09, 0x3f, 0x09, 0x00 |
.byte 0x00, 0x3f, 0x09, 0x00 |
.byte 0x3f, 0x2a, 0x09, 0x00 |
.byte 0x36, 0x2a, 0x09, 0x00 |
.byte 0x2d, 0x2a, 0x09, 0x00 |
.byte 0x24, 0x2a, 0x09, 0x00 |
.byte 0x1b, 0x2a, 0x09, 0x00 |
.byte 0x12, 0x2a, 0x09, 0x00 |
.byte 0x09, 0x2a, 0x09, 0x00 |
.byte 0x00, 0x2a, 0x09, 0x00 |
.byte 0x3f, 0x15, 0x09, 0x00 |
.byte 0x36, 0x15, 0x09, 0x00 |
.byte 0x2d, 0x15, 0x09, 0x00 |
.byte 0x24, 0x15, 0x09, 0x00 |
.byte 0x1b, 0x15, 0x09, 0x00 |
.byte 0x12, 0x15, 0x09, 0x00 |
.byte 0x09, 0x15, 0x09, 0x00 |
.byte 0x00, 0x15, 0x09, 0x00 |
.byte 0x3f, 0x00, 0x09, 0x00 |
.byte 0x36, 0x00, 0x09, 0x00 |
.byte 0x2d, 0x00, 0x09, 0x00 |
.byte 0x24, 0x00, 0x09, 0x00 |
.byte 0x1b, 0x00, 0x09, 0x00 |
.byte 0x12, 0x00, 0x09, 0x00 |
.byte 0x09, 0x00, 0x09, 0x00 |
.byte 0x00, 0x00, 0x09, 0x00 |
.byte 0x3f, 0x3f, 0x00, 0x00 |
.byte 0x36, 0x3f, 0x00, 0x00 |
.byte 0x2d, 0x3f, 0x00, 0x00 |
.byte 0x24, 0x3f, 0x00, 0x00 |
.byte 0x1b, 0x3f, 0x00, 0x00 |
.byte 0x12, 0x3f, 0x00, 0x00 |
.byte 0x09, 0x3f, 0x00, 0x00 |
.byte 0x00, 0x3f, 0x00, 0x00 |
.byte 0x3f, 0x2a, 0x00, 0x00 |
.byte 0x36, 0x2a, 0x00, 0x00 |
.byte 0x2d, 0x2a, 0x00, 0x00 |
.byte 0x24, 0x2a, 0x00, 0x00 |
.byte 0x1b, 0x2a, 0x00, 0x00 |
.byte 0x12, 0x2a, 0x00, 0x00 |
.byte 0x09, 0x2a, 0x00, 0x00 |
.byte 0x00, 0x2a, 0x00, 0x00 |
.byte 0x3f, 0x15, 0x00, 0x00 |
.byte 0x36, 0x15, 0x00, 0x00 |
.byte 0x2d, 0x15, 0x00, 0x00 |
.byte 0x24, 0x15, 0x00, 0x00 |
.byte 0x1b, 0x15, 0x00, 0x00 |
.byte 0x12, 0x15, 0x00, 0x00 |
.byte 0x09, 0x15, 0x00, 0x00 |
.byte 0x00, 0x15, 0x00, 0x00 |
.byte 0x3f, 0x00, 0x00, 0x00 |
.byte 0x36, 0x00, 0x00, 0x00 |
.byte 0x2d, 0x00, 0x00, 0x00 |
.byte 0x24, 0x00, 0x00, 0x00 |
.byte 0x1b, 0x00, 0x00, 0x00 |
.byte 0x12, 0x00, 0x00, 0x00 |
.byte 0x09, 0x00, 0x00, 0x00 |
.byte 0x00, 0x00, 0x00, 0x00 |
/branches/arm/kernel/arch/ia32/src/ia32.c |
---|
1,7 → 1,5 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* Copyright (c) 2009 Jiri Svoboda |
* Copyright (c) 2009 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
40,12 → 38,9 |
#include <arch/pm.h> |
#include <genarch/multiboot/multiboot.h> |
#include <genarch/drivers/legacy/ia32/io.h> |
#include <genarch/drivers/ega/ega.h> |
#include <arch/drivers/ega.h> |
#include <arch/drivers/vesa.h> |
#include <genarch/drivers/i8042/i8042.h> |
#include <genarch/kbrd/kbrd.h> |
#include <genarch/kbd/i8042.h> |
#include <arch/drivers/i8254.h> |
#include <arch/drivers/i8259.h> |
65,30 → 60,12 |
#include <proc/thread.h> |
#include <syscall/syscall.h> |
#include <console/console.h> |
#include <sysinfo/sysinfo.h> |
#include <arch/boot/boot.h> |
#include <ddi/device.h> |
#ifdef CONFIG_SMP |
#include <arch/smp/apic.h> |
#endif |
/** Perform ia32-specific initialization before main_bsp() is called. |
* |
* @param signature Should contain the multiboot signature. |
* @param mi Pointer to the multiboot information structure. |
*/ |
void arch_pre_main(uint32_t signature, const multiboot_info_t *mi) |
{ |
/* Parse multiboot information obtained from the bootloader. */ |
multiboot_info_parse(signature, mi); |
#ifdef CONFIG_SMP |
/* Copy AP bootstrap routines below 1 MB. */ |
memcpy((void *) AP_BOOT_OFFSET, (void *) BOOT_OFFSET, |
(size_t) &_hardcoded_unmapped_size); |
#endif |
} |
void arch_pre_mm_init(void) |
{ |
pm_init(); |
110,17 → 87,13 |
/* hard clock */ |
i8254_init(); |
#ifdef CONFIG_FB |
if (vesa_present()) |
if (vesa_present()) |
vesa_init(); |
else |
#endif |
#ifdef CONFIG_EGA |
ega_init(EGA_BASE, EGA_VIDEORAM); /* video */ |
#else |
{} |
#endif |
ega_init(); /* video */ |
/* Enable debugger */ |
debugger_init(); |
150,33 → 123,10 |
void arch_post_smp_init(void) |
{ |
#ifdef CONFIG_PC_KBD |
/* |
* Initialize the i8042 controller. Then initialize the keyboard |
* module and connect it to i8042. Enable keyboard interrupts. |
*/ |
i8042_instance_t *i8042_instance = i8042_init((i8042_t *) I8042_BASE, IRQ_KBD); |
if (i8042_instance) { |
kbrd_instance_t *kbrd_instance = kbrd_init(); |
if (kbrd_instance) { |
indev_t *sink = stdin_wire(); |
indev_t *kbrd = kbrd_wire(kbrd_instance, sink); |
i8042_wire(i8042_instance, kbrd); |
trap_virtual_enable_irqs(1 << IRQ_KBD); |
} |
} |
/* |
* This is the necessary evil until the userspace driver is entirely |
* self-sufficient. |
*/ |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.inr", NULL, IRQ_KBD); |
sysinfo_set_item_val("kbd.address.physical", NULL, |
(uintptr_t) I8042_BASE); |
sysinfo_set_item_val("kbd.address.kernel", NULL, |
(uintptr_t) I8042_BASE); |
#endif |
devno_t kbd = device_assign_devno(); |
devno_t mouse = device_assign_devno(); |
/* keyboard controller */ |
i8042_init(kbd, IRQ_KBD, mouse, IRQ_MOUSE); |
} |
void calibrate_delay_loop(void) |
209,45 → 159,15 |
*/ |
void arch_grab_console(void) |
{ |
#ifdef CONFIG_FB |
if (vesa_present()) |
vesa_redraw(); |
else |
#endif |
#ifdef CONFIG_EGA |
ega_redraw(); |
#else |
{} |
#endif |
i8042_grab(); |
} |
/** Return console to userspace |
* |
*/ |
void arch_release_console(void) |
{ |
i8042_release(); |
} |
/** Construct function pointer |
* |
* @param fptr function pointer structure |
* @param addr function address |
* @param caller calling function address |
* |
* @return address of the function pointer |
* |
*/ |
void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller) |
{ |
return addr; |
} |
void arch_reboot(void) |
{ |
#ifdef CONFIG_PC_KBD |
i8042_cpu_reset((i8042_t *) I8042_BASE); |
#endif |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32/src/ddi/ddi.c |
---|
57,7 → 57,7 |
*/ |
int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size) |
{ |
size_t bits; |
count_t bits; |
bits = ioaddr + size; |
if (bits > IO_PORTS) |
99,7 → 99,7 |
/* |
* Enable the range and we are done. |
*/ |
bitmap_clear_range(&task->arch.iomap, (size_t) ioaddr, (size_t) size); |
bitmap_clear_range(&task->arch.iomap, (index_t) ioaddr, (count_t) size); |
/* |
* Increment I/O Permission bitmap generation counter. |
118,10 → 118,10 |
*/ |
void io_perm_bitmap_install(void) |
{ |
size_t bits; |
count_t bits; |
ptr_16_32_t cpugdtr; |
descriptor_t *gdt_p; |
size_t ver; |
count_t ver; |
/* First, copy the I/O Permission Bitmap. */ |
spinlock_lock(&TASK->lock); |
156,7 → 156,7 |
* type must be changed to describe inactive TSS. |
*/ |
gdt_p[TSS_DES].access = AR_PRESENT | AR_TSS | DPL_KERNEL; |
tr_load(gdtselector(TSS_DES)); |
tr_load(selector(TSS_DES)); |
/* |
* Update the generation count so that faults caused by |
/branches/arm/kernel/arch/ia32/src/proc/scheduler.c |
---|
38,6 → 38,7 |
#include <proc/thread.h> |
#include <arch.h> |
#include <arch/context.h> /* SP_DELTA */ |
#include <arch/debugger.h> |
#include <arch/pm.h> |
#include <arch/asm.h> |
#include <arch/ddi/ddi.h> |
57,18 → 58,21 |
*/ |
void before_thread_runs_arch(void) |
{ |
uintptr_t kstk = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE - |
CPU->arch.tss->esp0 = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE - |
SP_DELTA]; |
/* Set kernel stack for CP3 -> CPL0 switch via SYSENTER */ |
write_msr(IA32_MSR_SYSENTER_ESP, kstk); |
/* Set kernel stack for CPL3 -> CPL0 switch via interrupt */ |
CPU->arch.tss->esp0 = kstk; |
CPU->arch.tss->ss0 = gdtselector(KDATA_DES); |
CPU->arch.tss->ss0 = selector(KDATA_DES); |
/* Set up TLS in GS register */ |
set_tls_desc(THREAD->arch.tls); |
#ifdef CONFIG_DEBUG_AS_WATCHPOINT |
/* Set watchpoint on AS to ensure that nobody sets it to zero */ |
if (CPU->id < BKPOINTS_MAX) { |
the_t *the = THE; |
breakpoint_add(&((the_t *) the->thread->kstack)->as, |
BKPOINT_WRITE | BKPOINT_CHECK_ZERO, the->cpu->id); |
} |
#endif |
} |
void after_thread_ran_arch(void) |
/branches/arm/kernel/arch/ia32/src/interrupt.c |
---|
44,6 → 44,7 |
#include <mm/tlb.h> |
#include <mm/as.h> |
#include <arch.h> |
#include <symtab.h> |
#include <proc/thread.h> |
#include <proc/task.h> |
#include <synch/spinlock.h> |
51,7 → 52,6 |
#include <ipc/sysipc.h> |
#include <interrupt.h> |
#include <ddi/irq.h> |
#include <symtab.h> |
/* |
* Interrupt and exception dispatching. |
63,9 → 63,10 |
void decode_istate(istate_t *istate) |
{ |
char *symbol; |
char *symbol = get_symtab_entry(istate->eip); |
symbol = symtab_fmt_name_lookup(istate->eip); |
if (!symbol) |
symbol = ""; |
if (CPU) |
printf("----------------EXCEPTION OCCURED (cpu%u)----------------\n", CPU->id); |
76,6 → 77,9 |
printf("ERROR_WORD=%#lx\n", istate->error_word); |
printf("%%cs=%#lx,flags=%#lx\n", istate->cs, istate->eflags); |
printf("%%eax=%#lx, %%ecx=%#lx, %%edx=%#lx, %%esp=%p\n", istate->eax, istate->ecx, istate->edx, &istate->stack[0]); |
#ifdef CONFIG_DEBUG_ALLREGS |
printf("%%esi=%#lx, %%edi=%#lx, %%ebp=%#lx, %%ebx=%#lx\n", istate->esi, istate->edi, istate->ebp, istate->ebx); |
#endif |
printf("stack: %#lx, %#lx, %#lx, %#lx\n", istate->stack[0], istate->stack[1], istate->stack[2], istate->stack[3]); |
printf(" %#lx, %#lx, %#lx, %#lx\n", istate->stack[4], istate->stack[5], istate->stack[6], istate->stack[7]); |
} |
85,16 → 89,16 |
if (eoi_function) |
eoi_function(); |
else |
panic("No eoi_function."); |
panic("no eoi_function\n"); |
} |
static void null_interrupt(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "Unserviced interrupt: %d.", n); |
fault_if_from_uspace(istate, "unserviced interrupt: %d", n); |
decode_istate(istate); |
panic("Unserviced interrupt: %d.", n); |
panic("unserviced interrupt: %d\n", n); |
} |
/** General Protection Fault. */ |
101,7 → 105,7 |
static void gp_fault(int n __attribute__((unused)), istate_t *istate) |
{ |
if (TASK) { |
size_t ver; |
count_t ver; |
spinlock_lock(&TASK->lock); |
ver = TASK->arch.iomapver; |
118,19 → 122,19 |
io_perm_bitmap_install(); |
return; |
} |
fault_if_from_uspace(istate, "General protection fault."); |
fault_if_from_uspace(istate, "general protection fault"); |
} |
decode_istate(istate); |
panic("General protection fault."); |
panic("general protection fault\n"); |
} |
static void ss_fault(int n __attribute__((unused)), istate_t *istate) |
{ |
fault_if_from_uspace(istate, "Stack fault."); |
fault_if_from_uspace(istate, "stack fault"); |
decode_istate(istate); |
panic("Stack fault."); |
panic("stack fault\n"); |
} |
static void simd_fp_exception(int n __attribute__((unused)), istate_t *istate) |
137,15 → 141,15 |
{ |
uint32_t mxcsr; |
asm ( |
"stmxcsr %[mxcsr]\n" |
: [mxcsr] "=m" (mxcsr) |
"stmxcsr %0;\n" |
: "=m" (mxcsr) |
); |
fault_if_from_uspace(istate, "SIMD FP exception(19), MXCSR: %#zx.", |
fault_if_from_uspace(istate, "SIMD FP exception(19), MXCSR: %#zx", |
(unative_t) mxcsr); |
decode_istate(istate); |
printf("MXCSR: %#lx\n", mxcsr); |
panic("SIMD FP exception(19)."); |
panic("SIMD FP exception(19)\n"); |
} |
static void nm_fault(int n __attribute__((unused)), istate_t *istate __attribute__((unused))) |
153,8 → 157,8 |
#ifdef CONFIG_FPU_LAZY |
scheduler_fpu_lazy_request(); |
#else |
fault_if_from_uspace(istate, "FPU fault."); |
panic("FPU fault."); |
fault_if_from_uspace(istate, "fpu fault"); |
panic("fpu fault"); |
#endif |
} |
187,7 → 191,7 |
trap_virtual_eoi(); |
ack = true; |
} |
irq->handler(irq); |
irq->handler(irq, irq->arg); |
spinlock_unlock(&irq->lock); |
} else { |
/* |
229,7 → 233,7 |
if (enable_irqs_function) |
enable_irqs_function(irqmask); |
else |
panic("No enable_irqs_function."); |
panic("no enable_irqs_function\n"); |
} |
void trap_virtual_disable_irqs(uint16_t irqmask) |
237,7 → 241,7 |
if (disable_irqs_function) |
disable_irqs_function(irqmask); |
else |
panic("No disable_irqs_function."); |
panic("no disable_irqs_function\n"); |
} |
/** @} |
/branches/arm/kernel/arch/ia32/src/cpu/cpu.c |
---|
42,23 → 42,22 |
#include <fpu_context.h> |
#include <arch/smp/apic.h> |
#include <arch/syscall.h> |
/* |
* Identification of CPUs. |
* Contains only non-MP-Specification specific SMP code. |
*/ |
#define AMD_CPUID_EBX 0x68747541 |
#define AMD_CPUID_ECX 0x444d4163 |
#define AMD_CPUID_EDX 0x69746e65 |
#define AMD_CPUID_EBX 0x68747541 |
#define AMD_CPUID_ECX 0x444d4163 |
#define AMD_CPUID_EDX 0x69746e65 |
#define INTEL_CPUID_EBX 0x756e6547 |
#define INTEL_CPUID_ECX 0x6c65746e |
#define INTEL_CPUID_EDX 0x49656e69 |
#define INTEL_CPUID_EBX 0x756e6547 |
#define INTEL_CPUID_ECX 0x6c65746e |
#define INTEL_CPUID_EDX 0x49656e69 |
enum vendor { |
VendorUnknown = 0, |
VendorUnknown=0, |
VendorAMD, |
VendorIntel |
}; |
65,17 → 64,19 |
static char *vendor_str[] = { |
"Unknown Vendor", |
"AMD", |
"Intel" |
"AuthenticAMD", |
"GenuineIntel" |
}; |
void fpu_disable(void) |
{ |
asm volatile ( |
"mov %%cr0, %%eax\n" |
"or $8, %%eax\n" |
"mov %%eax, %%cr0\n" |
::: "%eax" |
"mov %%cr0,%%eax;" |
"or $8,%%eax;" |
"mov %%eax,%%cr0;" |
: |
: |
:"%eax" |
); |
} |
82,11 → 83,13 |
void fpu_enable(void) |
{ |
asm volatile ( |
"mov %%cr0, %%eax\n" |
"and $0xffFFffF7, %%eax\n" |
"mov %%eax,%%cr0\n" |
::: "%eax" |
); |
"mov %%cr0,%%eax;" |
"and $0xffFFffF7,%%eax;" |
"mov %%eax,%%cr0;" |
: |
: |
:"%eax" |
); |
} |
void cpu_arch_init(void) |
98,11 → 101,11 |
CPU->arch.tss = tss_p; |
CPU->arch.tss->iomap_base = &CPU->arch.tss->iomap[0] - ((uint8_t *) CPU->arch.tss); |
CPU->fpu_owner = NULL; |
cpuid(1, &info); |
fi.word = info.cpuid_edx; |
efi.word = info.cpuid_ecx; |
109,20 → 112,17 |
if (fi.bits.fxsr) |
fpu_fxsr(); |
else |
fpu_fsr(); |
fpu_fsr(); |
if (fi.bits.sse) { |
asm volatile ( |
"mov %%cr4, %[help]\n" |
"or %[mask], %[help]\n" |
"mov %[help], %%cr4\n" |
: [help] "+r" (help) |
: [mask] "i" (CR4_OSFXSR_MASK | (1 << 10)) |
"mov %%cr4,%0\n" |
"or %1,%0\n" |
"mov %0,%%cr4\n" |
: "+r" (help) |
: "i" (CR4_OSFXSR_MASK|(1<<10)) |
); |
} |
/* Setup fast SYSENTER/SYSEXIT syscalls */ |
syscall_setup_cpu(); |
} |
void cpu_identify(void) |
136,31 → 136,29 |
/* |
* Check for AMD processor. |
*/ |
if ((info.cpuid_ebx == AMD_CPUID_EBX) |
&& (info.cpuid_ecx == AMD_CPUID_ECX) |
&& (info.cpuid_edx == AMD_CPUID_EDX)) |
if (info.cpuid_ebx==AMD_CPUID_EBX && info.cpuid_ecx==AMD_CPUID_ECX && info.cpuid_edx==AMD_CPUID_EDX) { |
CPU->arch.vendor = VendorAMD; |
} |
/* |
* Check for Intel processor. |
*/ |
if ((info.cpuid_ebx == INTEL_CPUID_EBX) |
&& (info.cpuid_ecx == INTEL_CPUID_ECX) |
&& (info.cpuid_edx == INTEL_CPUID_EDX)) |
if (info.cpuid_ebx==INTEL_CPUID_EBX && info.cpuid_ecx==INTEL_CPUID_ECX && info.cpuid_edx==INTEL_CPUID_EDX) { |
CPU->arch.vendor = VendorIntel; |
} |
cpuid(1, &info); |
CPU->arch.family = (info.cpuid_eax >> 8) & 0x0f; |
CPU->arch.model = (info.cpuid_eax >> 4) & 0x0f; |
CPU->arch.stepping = (info.cpuid_eax >> 0) & 0x0f; |
CPU->arch.family = (info.cpuid_eax>>8)&0xf; |
CPU->arch.model = (info.cpuid_eax>>4)&0xf; |
CPU->arch.stepping = (info.cpuid_eax>>0)&0xf; |
} |
} |
void cpu_print_report(cpu_t* cpu) |
void cpu_print_report(cpu_t* m) |
{ |
printf("cpu%u: (%s family=%u model=%u stepping=%u) %" PRIu16 " MHz\n", |
cpu->id, vendor_str[cpu->arch.vendor], cpu->arch.family, |
cpu->arch.model, cpu->arch.stepping, cpu->frequency_mhz); |
printf("cpu%d: (%s family=%d model=%d stepping=%d) %dMHz\n", |
m->id, vendor_str[m->arch.vendor], m->arch.family, m->arch.model, m->arch.stepping, |
m->frequency_mhz); |
} |
/** @} |
/branches/arm/kernel/arch/ia32/src/fpu_context.c |
---|
44,43 → 44,46 |
static void fpu_context_f_save(fpu_context_t *fctx) |
{ |
asm volatile ( |
"fnsave %[fctx]" |
: [fctx] "=m" (*fctx) |
); |
"fnsave %0" |
: "=m"(*fctx) |
); |
} |
static void fpu_context_f_restore(fpu_context_t *fctx) |
{ |
asm volatile ( |
"frstor %[fctx]" |
: [fctx] "=m" (*fctx) |
); |
"frstor %0" |
: "=m"(*fctx) |
); |
} |
static void fpu_context_fx_save(fpu_context_t *fctx) |
{ |
asm volatile ( |
"fxsave %[fctx]" |
: [fctx] "=m" (*fctx) |
); |
"fxsave %0" |
: "=m"(*fctx) |
); |
} |
static void fpu_context_fx_restore(fpu_context_t *fctx) |
{ |
asm volatile ( |
"fxrstor %[fctx]" |
: [fctx] "=m" (*fctx) |
); |
"fxrstor %0" |
: "=m"(*fctx) |
); |
} |
/* Setup using fxsr instruction */ |
/* |
Setup using fxsr instruction |
*/ |
void fpu_fxsr(void) |
{ |
fpu_save=fpu_context_fx_save; |
fpu_restore=fpu_context_fx_restore; |
} |
/* Setup using not fxsr instruction */ |
/* |
Setup using not fxsr instruction |
*/ |
void fpu_fsr(void) |
{ |
fpu_save = fpu_context_f_save; |
99,18 → 102,16 |
void fpu_init() |
{ |
uint32_t help0 = 0; |
uint32_t help1 = 0; |
uint32_t help0 = 0, help1 = 0; |
asm volatile ( |
"fninit\n" |
"stmxcsr %[help0]\n" |
"mov %[help0], %[help1]\n" |
"or %[magic], %[help1]\n" |
"mov %[help1], %[help0]\n" |
"ldmxcsr %[help0]\n" |
: [help0] "+m" (help0), [help1] "+r" (help1) |
: [magic] "i" (0x1f80) |
"fninit;\n" |
"stmxcsr %0\n" |
"mov %0,%1;\n" |
"or %2,%1;\n" |
"mov %1,%0;\n" |
"ldmxcsr %0;\n" |
: "+m" (help0), "+r" (help1) |
: "i" (0x1f80) |
); |
} |
/branches/arm/kernel/arch/ia32/src/atomic.S |
---|
42,7 → 42,9 |
movl 12(%esp),%ebx |
0: |
#ifdef CONFIG_HT |
pause # Pentium 4's with HT love this instruction |
#endif |
movl (%ebx),%eax |
testl %eax,%eax |
jnz 0b # lightweight looping while it is locked |
/branches/arm/kernel/arch/ia32/_link.ld.in |
---|
1,11 → 1,11 |
/** IA-32 linker script |
* |
* |
* umapped section: |
* kernel text |
* kernel data |
* kernel text |
* kernel data |
* mapped section: |
* kernel text |
* kernel data |
* kernel text |
* kernel data |
*/ |
#include <arch/boot/boot.h> |
28,9 → 28,9 |
ktext_end = .; |
kdata_start = .; |
*(.data); /* initialized data */ |
*(.rodata*); /* string literals */ |
*(COMMON); /* global variables */ |
*(.data); /* initialized data */ |
*(.rodata*); /* string literals */ |
*(COMMON); /* global variables */ |
hardcoded_load_address = .; |
LONG(PA2KA(BOOT_OFFSET)); |
hardcoded_ktext_size = .; |
42,23 → 42,23 |
hardcoded_unmapped_kdata_size = .; |
LONG(unmapped_kdata_end - unmapped_kdata_start); |
symbol_table = .; |
*(symtab.*); /* Symbol table, must be LAST symbol! */ |
*(.bss); /* uninitialized static variables */ |
*(symtab.*); /* Symbol table, must be LAST symbol! */ |
*(.bss); /* uninitialized static variables */ |
kdata_end = .; |
} |
/DISCARD/ : { |
*(.note.GNU-stack); |
*(.note.GNU-stack); |
*(.comment); |
} |
#ifdef CONFIG_SMP |
#ifdef CONFIG_SMP |
_hardcoded_unmapped_size = (unmapped_ktext_end - unmapped_ktext_start) + (unmapped_kdata_end - unmapped_kdata_start); |
ap_boot = unmapped_ap_boot - BOOT_OFFSET + AP_BOOT_OFFSET; |
ap_gdtr = unmapped_ap_gdtr - BOOT_OFFSET + AP_BOOT_OFFSET; |
protected_ap_gdtr = PA2KA(ap_gdtr); |
#endif /* CONFIG_SMP */ |
} |
/branches/arm/kernel/arch/amd64/include/atomic.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup amd64 |
/** @addtogroup amd64 |
* @{ |
*/ |
/** @file |
41,29 → 41,17 |
static inline void atomic_inc(atomic_t *val) { |
#ifdef CONFIG_SMP |
asm volatile ( |
"lock incq %[count]\n" |
: [count] "+m" (val->count) |
); |
asm volatile ("lock incq %0\n" : "+m" (val->count)); |
#else |
asm volatile ( |
"incq %[count]\n" |
: [count] "+m" (val->count) |
); |
asm volatile ("incq %0\n" : "+m" (val->count)); |
#endif /* CONFIG_SMP */ |
} |
static inline void atomic_dec(atomic_t *val) { |
#ifdef CONFIG_SMP |
asm volatile ( |
"lock decq %[count]\n" |
: [count] "+m" (val->count) |
); |
asm volatile ("lock decq %0\n" : "+m" (val->count)); |
#else |
asm volatile ( |
"decq %[count]\n" |
: [count] "+m" (val->count) |
); |
asm volatile ("decq %0\n" : "+m" (val->count)); |
#endif /* CONFIG_SMP */ |
} |
70,12 → 58,12 |
static inline long atomic_postinc(atomic_t *val) |
{ |
long r = 1; |
asm volatile ( |
"lock xaddq %[r], %[count]\n" |
: [count] "+m" (val->count), [r] "+r" (r) |
"lock xaddq %1, %0\n" |
: "+m" (val->count), "+r" (r) |
); |
return r; |
} |
84,23 → 72,23 |
long r = -1; |
asm volatile ( |
"lock xaddq %[r], %[count]\n" |
: [count] "+m" (val->count), [r] "+r" (r) |
"lock xaddq %1, %0\n" |
: "+m" (val->count), "+r" (r) |
); |
return r; |
} |
#define atomic_preinc(val) (atomic_postinc(val) + 1) |
#define atomic_predec(val) (atomic_postdec(val) - 1) |
#define atomic_preinc(val) (atomic_postinc(val) + 1) |
#define atomic_predec(val) (atomic_postdec(val) - 1) |
static inline uint64_t test_and_set(atomic_t *val) { |
uint64_t v; |
asm volatile ( |
"movq $1, %[v]\n" |
"xchgq %[v], %[count]\n" |
: [v] "=r" (v), [count] "+m" (val->count) |
"movq $1, %0\n" |
"xchgq %0, %1\n" |
: "=r" (v), "+m" (val->count) |
); |
return v; |
111,20 → 99,22 |
static inline void atomic_lock_arch(atomic_t *val) |
{ |
uint64_t tmp; |
preemption_disable(); |
asm volatile ( |
"0:\n" |
#ifdef CONFIG_HT |
"pause\n" |
"mov %[count], %[tmp]\n" |
"testq %[tmp], %[tmp]\n" |
#endif |
"mov %0, %1\n" |
"testq %1, %1\n" |
"jnz 0b\n" /* lightweight looping on locked spinlock */ |
"incq %[tmp]\n" /* now use the atomic operation */ |
"xchgq %[count], %[tmp]\n" |
"testq %[tmp], %[tmp]\n" |
"incq %1\n" /* now use the atomic operation */ |
"xchgq %0, %1\n" |
"testq %1, %1\n" |
"jnz 0b\n" |
: [count] "+m" (val->count), [tmp] "=&r" (tmp) |
: "+m" (val->count), "=&r" (tmp) |
); |
/* |
* Prevent critical section code from bleeding out this way up. |
/branches/arm/kernel/arch/amd64/include/mm/page.h |
---|
112,33 → 112,33 |
#define SET_PTL0_ADDRESS_ARCH(ptl0) \ |
(write_cr3((uintptr_t) (ptl0))) |
#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) \ |
set_pt_addr((pte_t *) (ptl0), (size_t) (i), a) |
set_pt_addr((pte_t *) (ptl0), (index_t) (i), a) |
#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a) \ |
set_pt_addr((pte_t *) (ptl1), (size_t) (i), a) |
set_pt_addr((pte_t *) (ptl1), (index_t) (i), a) |
#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a) \ |
set_pt_addr((pte_t *) (ptl2), (size_t) (i), a) |
set_pt_addr((pte_t *) (ptl2), (index_t) (i), a) |
#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) \ |
set_pt_addr((pte_t *) (ptl3), (size_t) (i), a) |
set_pt_addr((pte_t *) (ptl3), (index_t) (i), a) |
/* Get PTE flags accessors for each level. */ |
#define GET_PTL1_FLAGS_ARCH(ptl0, i) \ |
get_pt_flags((pte_t *) (ptl0), (size_t) (i)) |
get_pt_flags((pte_t *) (ptl0), (index_t) (i)) |
#define GET_PTL2_FLAGS_ARCH(ptl1, i) \ |
get_pt_flags((pte_t *) (ptl1), (size_t) (i)) |
get_pt_flags((pte_t *) (ptl1), (index_t) (i)) |
#define GET_PTL3_FLAGS_ARCH(ptl2, i) \ |
get_pt_flags((pte_t *) (ptl2), (size_t) (i)) |
get_pt_flags((pte_t *) (ptl2), (index_t) (i)) |
#define GET_FRAME_FLAGS_ARCH(ptl3, i) \ |
get_pt_flags((pte_t *) (ptl3), (size_t) (i)) |
get_pt_flags((pte_t *) (ptl3), (index_t) (i)) |
/* Set PTE flags accessors for each level. */ |
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \ |
set_pt_flags((pte_t *) (ptl0), (size_t) (i), (x)) |
set_pt_flags((pte_t *) (ptl0), (index_t) (i), (x)) |
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x) \ |
set_pt_flags((pte_t *) (ptl1), (size_t) (i), (x)) |
set_pt_flags((pte_t *) (ptl1), (index_t) (i), (x)) |
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x) \ |
set_pt_flags((pte_t *) (ptl2), (size_t) (i), (x)) |
set_pt_flags((pte_t *) (ptl2), (index_t) (i), (x)) |
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \ |
set_pt_flags((pte_t *) (ptl3), (size_t) (i), (x)) |
set_pt_flags((pte_t *) (ptl3), (index_t) (i), (x)) |
/* Macros for querying the last-level PTE entries. */ |
#define PTE_VALID_ARCH(p) \ |
176,7 → 176,7 |
*/ |
#define PFERR_CODE_ID (1 << 4) |
static inline int get_pt_flags(pte_t *pt, size_t i) |
static inline int get_pt_flags(pte_t *pt, index_t i) |
{ |
pte_t *p = &pt[i]; |
189,7 → 189,7 |
p->global << PAGE_GLOBAL_SHIFT); |
} |
static inline void set_pt_addr(pte_t *pt, size_t i, uintptr_t a) |
static inline void set_pt_addr(pte_t *pt, index_t i, uintptr_t a) |
{ |
pte_t *p = &pt[i]; |
197,7 → 197,7 |
p->addr_32_51 = a >> 32; |
} |
static inline void set_pt_flags(pte_t *pt, size_t i, int flags) |
static inline void set_pt_flags(pte_t *pt, index_t i, int flags) |
{ |
pte_t *p = &pt[i]; |
/branches/arm/kernel/arch/amd64/include/mm/frame.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup amd64mm |
/** @addtogroup amd64mm |
* @{ |
*/ |
/** @file |
39,8 → 39,8 |
#include <arch/types.h> |
#endif /* __ASM__ */ |
#define FRAME_WIDTH 12 /* 4K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#define FRAME_WIDTH 12 /* 4K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#ifndef __ASM__ |
extern uintptr_t last_frame; |
/branches/arm/kernel/arch/amd64/include/mm/tlb.h |
---|
35,6 → 35,9 |
#ifndef KERN_amd64_TLB_H_ |
#define KERN_amd64_TLB_H_ |
#define tlb_arch_init() |
#define tlb_print() |
#endif |
/** @} |
/branches/arm/kernel/arch/amd64/include/types.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup amd64 |
/** @addtogroup amd64 |
* @{ |
*/ |
/** @file |
46,6 → 46,8 |
typedef unsigned long long uint64_t; |
typedef uint64_t size_t; |
typedef uint64_t count_t; |
typedef uint64_t index_t; |
typedef uint64_t uintptr_t; |
typedef uint64_t pfn_t; |
55,12 → 57,11 |
typedef uint64_t unative_t; |
typedef int64_t native_t; |
typedef struct { |
} fncptr_t; |
/**< Formats for uintptr_t, size_t */ |
/**< Formats for uintptr_t, size_t, count_t and index_t */ |
#define PRIp "llx" |
#define PRIs "llu" |
#define PRIc "llu" |
#define PRIi "llu" |
/**< Formats for (u)int8_t, (u)int16_t, (u)int32_t, (u)int64_t and (u)native_t */ |
#define PRId8 "d" |
/branches/arm/kernel/arch/amd64/include/byteorder.h |
---|
0,0 → 1,44 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup amd64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_amd64_BYTEORDER_H_ |
#define KERN_amd64_BYTEORDER_H_ |
/* AMD64 is little-endian */ |
#define ARCH_IS_LITTLE_ENDIAN |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/amd64/include/cpu.h |
---|
35,9 → 35,9 |
#ifndef KERN_amd64_CPU_H_ |
#define KERN_amd64_CPU_H_ |
#define RFLAGS_IF (1 << 9) |
#define RFLAGS_DF (1 << 10) |
#define RFLAGS_RF (1 << 16) |
#define RFLAGS_IF (1 << 9) |
#define RFLAGS_DF (1 << 10) |
#define RFLAGS_RF (1 << 16) |
#define EFER_MSR_NUM 0xc0000080 |
#define AMD_SCE_FLAG 0 |
62,15 → 62,17 |
int family; |
int model; |
int stepping; |
tss_t *tss; |
struct tss *tss; |
size_t iomapver_copy; /** Copy of TASK's I/O Permission bitmap generation count. */ |
count_t iomapver_copy; /** Copy of TASK's I/O Permission bitmap generation count. */ |
} cpu_arch_t; |
struct star_msr { |
}; |
struct lstar_msr { |
}; |
extern void set_efer_flag(int flag); |
/branches/arm/kernel/arch/amd64/include/cpuid.h |
---|
35,15 → 35,14 |
#ifndef KERN_amd64_CPUID_H_ |
#define KERN_amd64_CPUID_H_ |
#define AMD_CPUID_EXTENDED 0x80000001 |
#define AMD_EXT_NOEXECUTE 20 |
#define AMD_EXT_LONG_MODE 29 |
#define AMD_CPUID_EXTENDED 0x80000001 |
#define AMD_EXT_NOEXECUTE 20 |
#define AMD_EXT_LONG_MODE 29 |
#define INTEL_CPUID_LEVEL 0x00000000 |
#define INTEL_CPUID_STANDARD 0x00000001 |
#define INTEL_CPUID_EXTENDED 0x80000000 |
#define INTEL_SSE2 26 |
#define INTEL_FXSAVE 24 |
#define INTEL_CPUID_STANDARD 0x00000001 |
#define INTEL_CPUID_EXTENDED 0x80000000 |
#define INTEL_SSE2 26 |
#define INTEL_FXSAVE 24 |
#ifndef __ASM__ |
/branches/arm/kernel/arch/amd64/include/proc/task.h |
---|
40,7 → 40,7 |
typedef struct { |
/** I/O Permission bitmap Generation counter. */ |
size_t iomapver; |
count_t iomapver; |
/** I/O Permission bitmap. */ |
bitmap_t iomap; |
} task_arch_t; |
/branches/arm/kernel/arch/amd64/include/interrupt.h |
---|
71,6 → 71,7 |
/** This is passed to interrupt handlers */ |
typedef struct { |
uint64_t rax; |
uint64_t rbx; |
uint64_t rcx; |
uint64_t rdx; |
uint64_t rsi; |
79,6 → 80,11 |
uint64_t r9; |
uint64_t r10; |
uint64_t r11; |
uint64_t r12; |
uint64_t r13; |
uint64_t r14; |
uint64_t r15; |
uint64_t rbp; |
uint64_t error_word; |
uint64_t rip; |
uint64_t cs; |
/branches/arm/kernel/arch/amd64/include/asm.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup amd64 |
/** @addtogroup amd64 |
* @{ |
*/ |
/** @file |
36,8 → 36,6 |
#define KERN_amd64_ASM_H_ |
#include <config.h> |
#include <arch/types.h> |
#include <typedefs.h> |
extern void asm_delay_loop(uint32_t t); |
extern void asm_fake_loop(uint32_t t); |
47,17 → 45,12 |
* Return the base address of the current stack. |
* The stack is assumed to be STACK_SIZE bytes long. |
* The stack must start on page boundary. |
* |
*/ |
static inline uintptr_t get_stack_base(void) |
{ |
uintptr_t v; |
asm volatile ( |
"andq %%rsp, %[v]\n" |
: [v] "=r" (v) |
: "0" (~((uint64_t) STACK_SIZE-1)) |
); |
asm volatile ("andq %%rsp, %0\n" : "=r" (v) : "0" (~((uint64_t)STACK_SIZE-1))); |
return v; |
} |
69,11 → 62,7 |
static inline void cpu_halt(void) |
{ |
asm volatile ( |
"0:\n" |
" hlt\n" |
" jmp 0b\n" |
); |
asm volatile ("hlt\n"); |
} |
83,63 → 72,15 |
* |
* @param port Port to read from |
* @return Value read |
* |
*/ |
static inline uint8_t pio_read_8(ioport8_t *port) |
static inline uint8_t inb(uint16_t port) |
{ |
uint8_t val; |
asm volatile ( |
"inb %w[port], %b[val]\n" |
: [val] "=a" (val) |
: [port] "d" (port) |
); |
return val; |
} |
/** Word from port |
* |
* Get word from port |
* |
* @param port Port to read from |
* @return Value read |
* |
*/ |
static inline uint16_t pio_read_16(ioport16_t *port) |
{ |
uint16_t val; |
asm volatile ( |
"inw %w[port], %w[val]\n" |
: [val] "=a" (val) |
: [port] "d" (port) |
); |
asm volatile ("inb %w1, %b0 \n" : "=a" (val) : "d" (port)); |
return val; |
} |
/** Double word from port |
* |
* Get double word from port |
* |
* @param port Port to read from |
* @return Value read |
* |
*/ |
static inline uint32_t pio_read_32(ioport32_t *port) |
{ |
uint32_t val; |
asm volatile ( |
"inl %w[port], %[val]\n" |
: [val] "=a" (val) |
: [port] "d" (port) |
); |
return val; |
} |
/** Byte to port |
* |
* Output byte to port |
146,48 → 87,12 |
* |
* @param port Port to write to |
* @param val Value to write |
* |
*/ |
static inline void pio_write_8(ioport8_t *port, uint8_t val) |
static inline void outb(uint16_t port, uint8_t val) |
{ |
asm volatile ( |
"outb %b[val], %w[port]\n" |
:: [val] "a" (val), [port] "d" (port) |
); |
asm volatile ("outb %b0, %w1\n" : : "a" (val), "d" (port)); |
} |
/** Word to port |
* |
* Output word to port |
* |
* @param port Port to write to |
* @param val Value to write |
* |
*/ |
static inline void pio_write_16(ioport16_t *port, uint16_t val) |
{ |
asm volatile ( |
"outw %w[val], %w[port]\n" |
:: [val] "a" (val), [port] "d" (port) |
); |
} |
/** Double word to port |
* |
* Output double word to port |
* |
* @param port Port to write to |
* @param val Value to write |
* |
*/ |
static inline void pio_write_32(ioport32_t *port, uint32_t val) |
{ |
asm volatile ( |
"outl %[val], %w[port]\n" |
:: [val] "a" (val), [port] "d" (port) |
); |
} |
/** Swap Hidden part of GS register with visible one */ |
static inline void swapgs(void) |
{ |
200,18 → 105,15 |
* value of EFLAGS. |
* |
* @return Old interrupt priority level. |
* |
*/ |
static inline ipl_t interrupts_enable(void) { |
ipl_t v; |
asm volatile ( |
__asm__ volatile ( |
"pushfq\n" |
"popq %[v]\n" |
"popq %0\n" |
"sti\n" |
: [v] "=r" (v) |
: "=r" (v) |
); |
return v; |
} |
221,18 → 123,15 |
* value of EFLAGS. |
* |
* @return Old interrupt priority level. |
* |
*/ |
static inline ipl_t interrupts_disable(void) { |
ipl_t v; |
asm volatile ( |
__asm__ volatile ( |
"pushfq\n" |
"popq %[v]\n" |
"popq %0\n" |
"cli\n" |
: [v] "=r" (v) |
); |
: "=r" (v) |
); |
return v; |
} |
241,14 → 140,13 |
* Restore EFLAGS. |
* |
* @param ipl Saved interrupt priority level. |
* |
*/ |
static inline void interrupts_restore(ipl_t ipl) { |
asm volatile ( |
"pushq %[ipl]\n" |
__asm__ volatile ( |
"pushq %0\n" |
"popfq\n" |
:: [ipl] "r" (ipl) |
); |
: : "r" (ipl) |
); |
} |
/** Return interrupt priority level. |
256,17 → 154,14 |
* Return EFLAFS. |
* |
* @return Current interrupt priority level. |
* |
*/ |
static inline ipl_t interrupts_read(void) { |
ipl_t v; |
asm volatile ( |
__asm__ volatile ( |
"pushfq\n" |
"popq %[v]\n" |
: [v] "=r" (v) |
"popq %0\n" |
: "=r" (v) |
); |
return v; |
} |
273,25 → 168,21 |
/** Write to MSR */ |
static inline void write_msr(uint32_t msr, uint64_t value) |
{ |
asm volatile ( |
"wrmsr\n" |
:: "c" (msr), |
"a" ((uint32_t) (value)), |
"d" ((uint32_t) (value >> 32)) |
); |
__asm__ volatile ( |
"wrmsr;" : : "c" (msr), |
"a" ((uint32_t)(value)), |
"d" ((uint32_t)(value >> 32)) |
); |
} |
static inline unative_t read_msr(uint32_t msr) |
{ |
uint32_t ax, dx; |
asm volatile ( |
"rdmsr\n" |
: "=a" (ax), "=d" (dx) |
: "c" (msr) |
); |
return ((uint64_t) dx << 32) | ax; |
__asm__ volatile ( |
"rdmsr;" : "=a"(ax), "=d"(dx) : "c" (msr) |
); |
return ((uint64_t)dx << 32) | ax; |
} |
298,29 → 189,29 |
/** Enable local APIC |
* |
* Enable local APIC in MSR. |
* |
*/ |
static inline void enable_l_apic_in_msr() |
{ |
asm volatile ( |
__asm__ volatile ( |
"movl $0x1b, %%ecx\n" |
"rdmsr\n" |
"orl $(1 << 11),%%eax\n" |
"orl $(1<<11),%%eax\n" |
"orl $(0xfee00000),%%eax\n" |
"wrmsr\n" |
::: "%eax","%ecx","%edx" |
); |
: |
: |
:"%eax","%ecx","%edx" |
); |
} |
static inline uintptr_t * get_ip() |
{ |
uintptr_t *ip; |
asm volatile ( |
"mov %%rip, %[ip]" |
: [ip] "=r" (ip) |
); |
__asm__ volatile ( |
"mov %%rip, %0" |
: "=r" (ip) |
); |
return ip; |
} |
327,84 → 218,59 |
/** Invalidate TLB Entry. |
* |
* @param addr Address on a page whose TLB entry is to be invalidated. |
* |
*/ |
static inline void invlpg(uintptr_t addr) |
{ |
asm volatile ( |
"invlpg %[addr]\n" |
:: [addr] "m" (*((unative_t *) addr)) |
); |
__asm__ volatile ("invlpg %0\n" :: "m" (*((unative_t *)addr))); |
} |
/** Load GDTR register from memory. |
* |
* @param gdtr_reg Address of memory from where to load GDTR. |
* |
*/ |
static inline void gdtr_load(ptr_16_64_t *gdtr_reg) |
static inline void gdtr_load(struct ptr_16_64 *gdtr_reg) |
{ |
asm volatile ( |
"lgdtq %[gdtr_reg]\n" |
:: [gdtr_reg] "m" (*gdtr_reg) |
); |
__asm__ volatile ("lgdtq %0\n" : : "m" (*gdtr_reg)); |
} |
/** Store GDTR register to memory. |
* |
* @param gdtr_reg Address of memory to where to load GDTR. |
* |
*/ |
static inline void gdtr_store(ptr_16_64_t *gdtr_reg) |
static inline void gdtr_store(struct ptr_16_64 *gdtr_reg) |
{ |
asm volatile ( |
"sgdtq %[gdtr_reg]\n" |
:: [gdtr_reg] "m" (*gdtr_reg) |
); |
__asm__ volatile ("sgdtq %0\n" : : "m" (*gdtr_reg)); |
} |
/** Load IDTR register from memory. |
* |
* @param idtr_reg Address of memory from where to load IDTR. |
* |
*/ |
static inline void idtr_load(ptr_16_64_t *idtr_reg) |
static inline void idtr_load(struct ptr_16_64 *idtr_reg) |
{ |
asm volatile ( |
"lidtq %[idtr_reg]\n" |
:: [idtr_reg] "m" (*idtr_reg)); |
__asm__ volatile ("lidtq %0\n" : : "m" (*idtr_reg)); |
} |
/** Load TR from descriptor table. |
* |
* @param sel Selector specifying descriptor of TSS segment. |
* |
*/ |
static inline void tr_load(uint16_t sel) |
{ |
asm volatile ( |
"ltr %[sel]" |
:: [sel] "r" (sel) |
); |
__asm__ volatile ("ltr %0" : : "r" (sel)); |
} |
#define GEN_READ_REG(reg) static inline unative_t read_ ##reg (void) \ |
{ \ |
unative_t res; \ |
asm volatile ( \ |
"movq %%" #reg ", %[res]" \ |
: [res] "=r" (res) \ |
); \ |
return res; \ |
} |
{ \ |
unative_t res; \ |
__asm__ volatile ("movq %%" #reg ", %0" : "=r" (res) ); \ |
return res; \ |
} |
#define GEN_WRITE_REG(reg) static inline void write_ ##reg (unative_t regn) \ |
{ \ |
asm volatile ( \ |
"movq %[regn], %%" #reg \ |
:: [regn] "r" (regn) \ |
); \ |
} |
{ \ |
__asm__ volatile ("movq %0, %%" #reg : : "r" (regn)); \ |
} |
GEN_READ_REG(cr0) |
GEN_READ_REG(cr2) |
/branches/arm/kernel/arch/amd64/include/pm.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup amd64 |
/** @addtogroup amd64 |
* @{ |
*/ |
/** @file |
36,60 → 36,63 |
#define KERN_amd64_PM_H_ |
#ifndef __ASM__ |
#include <arch/types.h> |
#include <arch/context.h> |
# include <arch/types.h> |
# include <arch/context.h> |
#endif |
#define IDT_ITEMS 64 |
#define GDT_ITEMS 8 |
#define IDT_ITEMS 64 |
#define GDT_ITEMS 8 |
#define NULL_DES 0 |
/* Warning: Do not reorder the following items, unless you look into syscall.c! */ |
#define KTEXT_DES 1 |
#define KDATA_DES 2 |
#define UDATA_DES 3 |
#define UTEXT_DES 4 |
#define KTEXT32_DES 5 |
/* End of warning */ |
#define TSS_DES 6 |
#define NULL_DES 0 |
/* Warning: Do not reorder next items, unless you look into syscall.c!!! */ |
#define KTEXT_DES 1 |
#define KDATA_DES 2 |
#define UDATA_DES 3 |
#define UTEXT_DES 4 |
#define KTEXT32_DES 5 |
/* EndOfWarning */ |
#define TSS_DES 6 |
#ifdef CONFIG_FB |
#define VESA_INIT_DES 8 |
#define VESA_INIT_SEGMENT 0x8000 |
#define VESA_INIT_DES 8 |
#define VESA_INIT_SEGMENT 0x8000 |
#undef GDT_ITEMS |
#define GDT_ITEMS 9 |
#undef GDT_ITEMS |
#define GDT_ITEMS 9 |
#endif /*CONFIG_FB*/ |
#endif /* CONFIG_FB */ |
#define gdtselector(des) ((des) << 3) |
#define idtselector(des) ((des) << 4) |
#define PL_KERNEL 0 |
#define PL_USER 3 |
#define gdtselector(des) ((des) << 3) |
#define idtselector(des) ((des) << 4) |
#define AR_PRESENT ( 1 << 7) |
#define AR_DATA (2 << 3) |
#define AR_CODE (3 << 3) |
#define AR_WRITABLE (1 << 1) |
#define AR_READABLE (1 << 1) |
#define AR_TSS (0x09) |
#define AR_INTERRUPT (0x0e) |
#define AR_TRAP (0x0f) |
#define PL_KERNEL 0 |
#define PL_USER 3 |
#define DPL_KERNEL (PL_KERNEL << 5) |
#define DPL_USER (PL_USER << 5) |
#define AR_PRESENT (1<<7) |
#define AR_DATA (2<<3) |
#define AR_CODE (3<<3) |
#define AR_WRITABLE (1<<1) |
#define AR_READABLE (1<<1) |
#define AR_TSS (0x9) |
#define AR_INTERRUPT (0xe) |
#define AR_TRAP (0xf) |
#define TSS_BASIC_SIZE 104 |
#define TSS_IOMAP_SIZE (16 * 1024 + 1) /* 16K for bitmap + 1 terminating byte for convenience */ |
#define DPL_KERNEL (PL_KERNEL<<5) |
#define DPL_USER (PL_USER<<5) |
#define IO_PORTS (64 * 1024) |
#define TSS_BASIC_SIZE 104 |
#define TSS_IOMAP_SIZE (16*1024+1) /* 16K for bitmap + 1 terminating byte for convenience */ |
#define IO_PORTS (64*1024) |
#ifndef __ASM__ |
typedef struct { |
struct descriptor { |
unsigned limit_0_15: 16; |
unsigned base_0_15: 16; |
unsigned base_16_23: 8; |
100,9 → 103,10 |
unsigned special: 1; |
unsigned granularity : 1; |
unsigned base_24_31: 8; |
} __attribute__ ((packed)) descriptor_t; |
} __attribute__ ((packed)); |
typedef struct descriptor descriptor_t; |
typedef struct { |
struct tss_descriptor { |
unsigned limit_0_15: 16; |
unsigned base_0_15: 16; |
unsigned base_16_23: 8; |
117,9 → 121,10 |
unsigned base_24_31: 8; |
unsigned base_32_63 : 32; |
unsigned : 32; |
} __attribute__ ((packed)) tss_descriptor_t; |
} __attribute__ ((packed)); |
typedef struct tss_descriptor tss_descriptor_t; |
typedef struct { |
struct idescriptor { |
unsigned offset_0_15: 16; |
unsigned selector: 16; |
unsigned ist:3; |
130,19 → 135,22 |
unsigned offset_16_31: 16; |
unsigned offset_32_63: 32; |
unsigned : 32; |
} __attribute__ ((packed)) idescriptor_t; |
} __attribute__ ((packed)); |
typedef struct idescriptor idescriptor_t; |
typedef struct { |
struct ptr_16_64 { |
uint16_t limit; |
uint64_t base; |
} __attribute__ ((packed)) ptr_16_64_t; |
} __attribute__ ((packed)); |
typedef struct ptr_16_64 ptr_16_64_t; |
typedef struct { |
struct ptr_16_32 { |
uint16_t limit; |
uint32_t base; |
} __attribute__ ((packed)) ptr_16_32_t; |
} __attribute__ ((packed)); |
typedef struct ptr_16_32 ptr_16_32_t; |
typedef struct { |
struct tss { |
uint32_t reserve1; |
uint64_t rsp0; |
uint64_t rsp1; |
159,7 → 167,8 |
uint16_t reserve4; |
uint16_t iomap_base; |
uint8_t iomap[TSS_IOMAP_SIZE]; |
} __attribute__ ((packed)) tss_t; |
} __attribute__ ((packed)); |
typedef struct tss tss_t; |
extern tss_t *tss_p; |
/branches/arm/kernel/arch/amd64/include/syscall.h |
---|
35,6 → 35,8 |
#ifndef KERN_amd64_SYSCALL_H_ |
#define KERN_amd64_SYSCALL_H_ |
#include <arch/types.h> |
extern void syscall_setup_cpu(void); |
#endif |
/branches/arm/kernel/arch/amd64/include/boot/boot.h |
---|
42,17 → 42,8 |
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 |
#define MULTIBOOT_HEADER_FLAGS 0x00010003 |
#ifndef __ASM__ |
#define MULTIBOOT_LOADER_MAGIC 0x2BADB002 |
#ifdef CONFIG_SMP |
/* This is only a symbol so the type is dummy. Obtain the value using &. */ |
extern int _hardcoded_unmapped_size; |
#endif /* CONFIG_SMP */ |
#endif /* __ASM__ */ |
#endif |
/** @} |
/branches/arm/kernel/arch/amd64/include/arch.h |
---|
35,10 → 35,6 |
#ifndef KERN_amd64_ARCH_H_ |
#define KERN_amd64_ARCH_H_ |
#include <genarch/multiboot/multiboot.h> |
extern void arch_pre_main(uint32_t, const multiboot_info_t *); |
#endif |
/** @} |
/branches/arm/kernel/arch/amd64/include/drivers |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/branches/arm/kernel/arch/amd64/include/drivers/vesa.h |
---|
0,0 → 1,44 |
/* |
* Copyright (c) 2006-2006 Jakub Vana |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup amd64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_amd64_VESA_H_ |
#define KERN_amd64_VESA_H_ |
int vesa_present(void); |
void vesa_init(void); |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/amd64/include/drivers/i8254.h |
---|
0,0 → 1,0 |
link ../../../ia32/include/drivers/i8254.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/amd64/include/drivers/i8259.h |
---|
0,0 → 1,0 |
link ../../../ia32/include/drivers/i8259.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/amd64/include/drivers/ega.h |
---|
0,0 → 1,0 |
link ../../../ia32/include/drivers/ega.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/amd64/include/drivers/i8042.h |
---|
0,0 → 1,0 |
link ../../../ia32/include/drivers/i8042.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/amd64/Makefile.inc |
---|
29,6 → 29,10 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf64-x86-64 |
BFD_ARCH = i386:x86-64 |
BFD = binary |
41,51 → 45,83 |
ICC_CFLAGS += $(CMN1) |
SUNCC_CFLAGS += -m64 -xmodel=kernel |
BITS = 64 |
ENDIANESS = LE |
DEFS += -DMACHINE=$(MACHINE) -D__64_BITS__ |
## Accepted CPUs |
# |
ifeq ($(PROCESSOR),opteron) |
ifeq ($(MACHINE),opteron) |
CMN2 := -march=opteron |
GCC_CFLAGS += $(CMN2) |
ICC_CFLAGS += $(CMN2) |
SUNCC_CFLAGS += -xtarget=opteron |
DEFS += -DFENCES=p4 |
endif |
## Own configuration directives |
# |
CONFIG_ACPI = y |
## Compile with hierarchical page tables support. |
# |
CONFIG_PAGE_PT = y |
DEFS += -DCONFIG_PAGE_PT |
## Compile with i8042 support. |
# |
CONFIG_I8042 = y |
DEFS += -DCONFIG_I8042 |
## Accepted configuration directives |
# |
ifeq ($(CONFIG_SMP),y) |
DEFS += -DCONFIG_SMP |
endif |
ifeq ($(CONFIG_HT),y) |
DEFS += -DCONFIG_HT |
endif |
ifeq ($(CONFIG_SIMICS_FIX),y) |
DEFS += -DCONFIG_SIMICS_FIX |
endif |
ARCH_SOURCES = \ |
arch/$(KARCH)/src/fpu_context.c \ |
arch/$(KARCH)/src/boot/boot.S \ |
arch/$(KARCH)/src/boot/memmap.c \ |
arch/$(KARCH)/src/pm.c \ |
arch/$(KARCH)/src/context.S \ |
arch/$(KARCH)/src/ddi/ddi.c \ |
arch/$(KARCH)/src/drivers/vesa.c \ |
arch/$(KARCH)/src/drivers/i8254.c \ |
arch/$(KARCH)/src/drivers/i8259.c \ |
arch/$(KARCH)/src/delay.S \ |
arch/$(KARCH)/src/amd64.c \ |
arch/$(KARCH)/src/bios/bios.c \ |
arch/$(KARCH)/src/interrupt.c \ |
arch/$(KARCH)/src/mm/as.c \ |
arch/$(KARCH)/src/mm/frame.c \ |
arch/$(KARCH)/src/mm/page.c \ |
arch/$(KARCH)/src/mm/tlb.c \ |
arch/$(KARCH)/src/asm_utils.S \ |
arch/$(KARCH)/src/cpu/cpu.c \ |
arch/$(KARCH)/src/proc/scheduler.c \ |
arch/$(KARCH)/src/proc/task.c \ |
arch/$(KARCH)/src/proc/thread.c \ |
arch/$(KARCH)/src/userspace.c \ |
arch/$(KARCH)/src/syscall.c \ |
arch/$(KARCH)/src/debugger.c |
arch/$(ARCH)/src/fpu_context.c \ |
arch/$(ARCH)/src/boot/boot.S \ |
arch/$(ARCH)/src/boot/memmap.c \ |
arch/$(ARCH)/src/pm.c \ |
arch/$(ARCH)/src/context.S \ |
arch/$(ARCH)/src/ddi/ddi.c \ |
arch/$(ARCH)/src/drivers/ega.c \ |
arch/$(ARCH)/src/drivers/vesa.c \ |
arch/$(ARCH)/src/drivers/i8254.c \ |
arch/$(ARCH)/src/drivers/i8259.c \ |
arch/$(ARCH)/src/delay.S \ |
arch/$(ARCH)/src/amd64.c \ |
arch/$(ARCH)/src/bios/bios.c \ |
arch/$(ARCH)/src/interrupt.c \ |
arch/$(ARCH)/src/mm/as.c \ |
arch/$(ARCH)/src/mm/frame.c \ |
arch/$(ARCH)/src/mm/page.c \ |
arch/$(ARCH)/src/mm/tlb.c \ |
arch/$(ARCH)/src/asm_utils.S \ |
arch/$(ARCH)/src/cpu/cpu.c \ |
arch/$(ARCH)/src/proc/scheduler.c \ |
arch/$(ARCH)/src/proc/task.c \ |
arch/$(ARCH)/src/proc/thread.c \ |
arch/$(ARCH)/src/userspace.c \ |
arch/$(ARCH)/src/syscall.c \ |
arch/$(ARCH)/src/debugger.c |
ifeq ($(CONFIG_SMP),y) |
ARCH_SOURCES += \ |
arch/$(KARCH)/src/smp/ap.S \ |
arch/$(KARCH)/src/smp/apic.c \ |
arch/$(KARCH)/src/smp/ipi.c \ |
arch/$(KARCH)/src/smp/mps.c \ |
arch/$(KARCH)/src/smp/smp.c |
arch/$(ARCH)/src/smp/ap.S \ |
arch/$(ARCH)/src/smp/apic.c \ |
arch/$(ARCH)/src/smp/ipi.c \ |
arch/$(ARCH)/src/smp/mps.c \ |
arch/$(ARCH)/src/smp/smp.c |
endif |
/branches/arm/kernel/arch/amd64/src/asm_utils.S |
---|
26,17 → 26,23 |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
#define IREGISTER_SPACE 72 |
#define IREGISTER_SPACE 120 |
#define IOFFSET_RAX 0x0 |
#define IOFFSET_RCX 0x8 |
#define IOFFSET_RDX 0x10 |
#define IOFFSET_RSI 0x18 |
#define IOFFSET_RDI 0x20 |
#define IOFFSET_R8 0x28 |
#define IOFFSET_R9 0x30 |
#define IOFFSET_R10 0x38 |
#define IOFFSET_R11 0x40 |
#define IOFFSET_RAX 0x0 |
#define IOFFSET_RBX 0x8 |
#define IOFFSET_RCX 0x10 |
#define IOFFSET_RDX 0x18 |
#define IOFFSET_RSI 0x20 |
#define IOFFSET_RDI 0x28 |
#define IOFFSET_R8 0x30 |
#define IOFFSET_R9 0x38 |
#define IOFFSET_R10 0x40 |
#define IOFFSET_R11 0x48 |
#define IOFFSET_R12 0x50 |
#define IOFFSET_R13 0x58 |
#define IOFFSET_R14 0x60 |
#define IOFFSET_R15 0x68 |
#define IOFFSET_RBP 0x70 |
# Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int has no error word |
# and 1 means interrupt with error word |
167,7 → 173,7 |
rdmsr |
ret |
# Push all volatile general purpose registers on stack |
# Push all general purpose registers on stack except %rbp, %rsp |
.macro save_all_gpr |
movq %rax, IOFFSET_RAX(%rsp) |
movq %rcx, IOFFSET_RCX(%rsp) |
178,6 → 184,14 |
movq %r9, IOFFSET_R9(%rsp) |
movq %r10, IOFFSET_R10(%rsp) |
movq %r11, IOFFSET_R11(%rsp) |
#ifdef CONFIG_DEBUG_ALLREGS |
movq %rbx, IOFFSET_RBX(%rsp) |
movq %rbp, IOFFSET_RBP(%rsp) |
movq %r12, IOFFSET_R12(%rsp) |
movq %r13, IOFFSET_R13(%rsp) |
movq %r14, IOFFSET_R14(%rsp) |
movq %r15, IOFFSET_R15(%rsp) |
#endif |
.endm |
.macro restore_all_gpr |
190,9 → 204,21 |
movq IOFFSET_R9(%rsp), %r9 |
movq IOFFSET_R10(%rsp), %r10 |
movq IOFFSET_R11(%rsp), %r11 |
#ifdef CONFIG_DEBUG_ALLREGS |
movq IOFFSET_RBX(%rsp), %rbx |
movq IOFFSET_RBP(%rsp), %rbp |
movq IOFFSET_R12(%rsp), %r12 |
movq IOFFSET_R13(%rsp), %r13 |
movq IOFFSET_R14(%rsp), %r14 |
movq IOFFSET_R15(%rsp), %r15 |
#endif |
.endm |
#define INTERRUPT_ALIGN 128 |
#ifdef CONFIG_DEBUG_ALLREGS |
# define INTERRUPT_ALIGN 256 |
#else |
# define INTERRUPT_ALIGN 128 |
#endif |
## Declare interrupt handlers |
# |
/branches/arm/kernel/arch/amd64/src/userspace.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup amd64 |
/** @addtogroup amd64 |
* @{ |
*/ |
/** @file |
47,33 → 47,36 |
*/ |
void userspace(uspace_arg_t *kernel_uarg) |
{ |
ipl_t ipl = interrupts_disable(); |
ipl_t ipl; |
/* Clear CF, PF, AF, ZF, SF, DF, OF */ |
ipl = interrupts_disable(); |
/* Clear CF,PF,AF,ZF,SF,DF,OF */ |
ipl &= ~(0xcd4); |
asm volatile ("" |
"pushq %0\n" |
"pushq %1\n" |
"pushq %2\n" |
"pushq %3\n" |
"pushq %4\n" |
"movq %5, %%rax\n" |
/* %rdi is defined to hold pcb_ptr - set it to 0 */ |
"xorq %%rdi, %%rdi\n" |
"iretq\n" |
: : |
"i" (gdtselector(UDATA_DES) | PL_USER), |
"r" (kernel_uarg->uspace_stack+THREAD_STACK_SIZE), |
"r" (ipl), |
"i" (gdtselector(UTEXT_DES) | PL_USER), |
"r" (kernel_uarg->uspace_entry), |
"r" (kernel_uarg->uspace_uarg) |
: "rax" |
); |
asm volatile ( |
"pushq %[udata_des]\n" |
"pushq %[stack_size]\n" |
"pushq %[ipl]\n" |
"pushq %[utext_des]\n" |
"pushq %[entry]\n" |
"movq %[uarg], %%rax\n" |
/* %rdi is defined to hold pcb_ptr - set it to 0 */ |
"xorq %%rdi, %%rdi\n" |
"iretq\n" |
:: [udata_des] "i" (gdtselector(UDATA_DES) | PL_USER), |
[stack_size] "r" (kernel_uarg->uspace_stack + THREAD_STACK_SIZE), |
[ipl] "r" (ipl), |
[utext_des] "i" (gdtselector(UTEXT_DES) | PL_USER), |
[entry] "r" (kernel_uarg->uspace_entry), |
[uarg] "r" (kernel_uarg->uspace_uarg) |
: "rax" |
); |
/* Unreachable */ |
while (1); |
for(;;) |
; |
} |
/** @} |
/branches/arm/kernel/arch/amd64/src/debugger.c |
---|
35,6 → 35,7 |
#include <arch/debugger.h> |
#include <console/kconsole.h> |
#include <console/cmd.h> |
#include <symtab.h> |
#include <print.h> |
#include <panic.h> |
#include <interrupt.h> |
43,7 → 44,6 |
#include <debug.h> |
#include <func.h> |
#include <smp/ipi.h> |
#include <symtab.h> |
typedef struct { |
uintptr_t address; /**< Breakpoint address */ |
54,8 → 54,6 |
static bpinfo_t breakpoints[BKPOINTS_MAX]; |
SPINLOCK_INITIALIZE(bkpoint_lock); |
#ifdef CONFIG_KCONSOLE |
static int cmd_print_breakpoints(cmd_arg_t *argv); |
static cmd_info_t bkpts_info = { |
.name = "bkpts", |
64,6 → 62,8 |
.argc = 0, |
}; |
#ifndef CONFIG_DEBUG_AS_WATCHPOINT |
static int cmd_del_breakpoint(cmd_arg_t *argv); |
static cmd_arg_t del_argv = { |
.type = ARG_TYPE_INT |
99,8 → 99,44 |
.argv = &addw_argv |
}; |
#endif /* CONFIG_KCONSOLE */ |
#endif |
/** Print table of active breakpoints */ |
int cmd_print_breakpoints(cmd_arg_t *argv __attribute__((unused))) |
{ |
unsigned int i; |
char *symbol; |
#ifdef __32_BITS__ |
printf("# Count Address In symbol\n"); |
printf("-- ----- ---------- ---------\n"); |
#endif |
#ifdef __64_BITS__ |
printf("# Count Address In symbol\n"); |
printf("-- ----- ------------------ ---------\n"); |
#endif |
for (i = 0; i < BKPOINTS_MAX; i++) |
if (breakpoints[i].address) { |
symbol = get_symtab_entry(breakpoints[i].address); |
#ifdef __32_BITS__ |
printf("%-2u %-5d %#10zx %s\n", i, |
breakpoints[i].counter, breakpoints[i].address, |
symbol); |
#endif |
#ifdef __64_BITS__ |
printf("%-2u %-5d %#18zx %s\n", i, |
breakpoints[i].counter, breakpoints[i].address, |
symbol); |
#endif |
} |
return 1; |
} |
/* Setup DR register according to table */ |
static void setup_dr(int curidx) |
{ |
201,16 → 237,16 |
/* Send IPI */ |
#ifdef CONFIG_SMP |
// ipi_broadcast(VECTOR_DEBUG_IPI); |
// ipi_broadcast(VECTOR_DEBUG_IPI); |
#endif |
return curidx; |
} |
#ifdef __64_BITS__ |
#define getip(x) ((x)->rip) |
#ifdef amd64 |
# define getip(x) ((x)->rip) |
#else |
#define getip(x) ((x)->eip) |
# define getip(x) ((x)->eip) |
#endif |
static void handle_exception(int slot, istate_t *istate) |
229,15 → 265,12 |
*((unative_t *) breakpoints[slot].address)); |
} |
} |
printf("Reached breakpoint %d:%lx (%s)\n", slot, getip(istate), |
symtab_fmt_name_lookup(getip(istate))); |
#ifdef CONFIG_KCONSOLE |
atomic_set(&haltstate, 1); |
kconsole("debug", "Debug console ready.\n", false); |
atomic_set(&haltstate, 0); |
#endif |
printf("Reached breakpoint %d:%lx(%s)\n", slot, getip(istate), |
get_symtab_entry(getip(istate))); |
printf("***Type 'exit' to exit kconsole.\n"); |
atomic_set(&haltstate,1); |
kconsole((void *) "debug"); |
atomic_set(&haltstate,0); |
} |
void breakpoint_del(int slot) |
266,8 → 299,42 |
#endif |
} |
#ifndef CONFIG_DEBUG_AS_WATCHPOINT |
/** Remove breakpoint from table */ |
int cmd_del_breakpoint(cmd_arg_t *argv) |
{ |
unative_t bpno = argv->intval; |
if (bpno > BKPOINTS_MAX) { |
printf("Invalid breakpoint number.\n"); |
return 0; |
} |
breakpoint_del(argv->intval); |
return 1; |
} |
/** Add new breakpoint to table */ |
static int cmd_add_breakpoint(cmd_arg_t *argv) |
{ |
int flags; |
int id; |
if (argv == &add_argv) { |
flags = BKPOINT_INSTR; |
} else { /* addwatchp */ |
flags = BKPOINT_WRITE; |
} |
printf("Adding breakpoint on address: %p\n", argv->intval); |
id = breakpoint_add((void *)argv->intval, flags, -1); |
if (id < 0) |
printf("Add breakpoint failed.\n"); |
else |
printf("Added breakpoint %d.\n", id); |
return 1; |
} |
#endif |
static void debug_exception(int n __attribute__((unused)), istate_t *istate) |
{ |
unative_t dr6; |
274,7 → 341,7 |
int i; |
/* Set RF to restart the instruction */ |
#ifdef __64_BITS__ |
#ifdef amd64 |
istate->rflags |= RFLAGS_RF; |
#else |
istate->eflags |= EFLAGS_RF; |
312,24 → 379,24 |
for (i = 0; i < BKPOINTS_MAX; i++) |
breakpoints[i].address = NULL; |
#ifdef CONFIG_KCONSOLE |
cmd_initialize(&bkpts_info); |
if (!cmd_register(&bkpts_info)) |
printf("Cannot register command %s\n", bkpts_info.name); |
panic("could not register command %s\n", bkpts_info.name); |
#ifndef CONFIG_DEBUG_AS_WATCHPOINT |
cmd_initialize(&delbkpt_info); |
if (!cmd_register(&delbkpt_info)) |
printf("Cannot register command %s\n", delbkpt_info.name); |
panic("could not register command %s\n", delbkpt_info.name); |
cmd_initialize(&addbkpt_info); |
if (!cmd_register(&addbkpt_info)) |
printf("Cannot register command %s\n", addbkpt_info.name); |
panic("could not register command %s\n", addbkpt_info.name); |
cmd_initialize(&addwatchp_info); |
if (!cmd_register(&addwatchp_info)) |
printf("Cannot register command %s\n", addwatchp_info.name); |
#endif /* CONFIG_KCONSOLE */ |
panic("could not register command %s\n", addwatchp_info.name); |
#endif |
exc_register(VECTOR_DEBUG, "debugger", debug_exception); |
#ifdef CONFIG_SMP |
337,77 → 404,5 |
#endif |
} |
#ifdef CONFIG_KCONSOLE |
/** Print table of active breakpoints */ |
int cmd_print_breakpoints(cmd_arg_t *argv __attribute__((unused))) |
{ |
unsigned int i; |
char *symbol; |
#ifdef __32_BITS__ |
printf("# Count Address In symbol\n"); |
printf("-- ----- ---------- ---------\n"); |
#endif |
#ifdef __64_BITS__ |
printf("# Count Address In symbol\n"); |
printf("-- ----- ------------------ ---------\n"); |
#endif |
for (i = 0; i < BKPOINTS_MAX; i++) |
if (breakpoints[i].address) { |
symbol = symtab_fmt_name_lookup( |
breakpoints[i].address); |
#ifdef __32_BITS__ |
printf("%-2u %-5d %#10zx %s\n", i, |
breakpoints[i].counter, breakpoints[i].address, |
symbol); |
#endif |
#ifdef __64_BITS__ |
printf("%-2u %-5d %#18zx %s\n", i, |
breakpoints[i].counter, breakpoints[i].address, |
symbol); |
#endif |
} |
return 1; |
} |
/** Remove breakpoint from table */ |
int cmd_del_breakpoint(cmd_arg_t *argv) |
{ |
unative_t bpno = argv->intval; |
if (bpno > BKPOINTS_MAX) { |
printf("Invalid breakpoint number.\n"); |
return 0; |
} |
breakpoint_del(argv->intval); |
return 1; |
} |
/** Add new breakpoint to table */ |
static int cmd_add_breakpoint(cmd_arg_t *argv) |
{ |
int flags; |
int id; |
if (argv == &add_argv) { |
flags = BKPOINT_INSTR; |
} else { /* addwatchp */ |
flags = BKPOINT_WRITE; |
} |
printf("Adding breakpoint on address: %p\n", argv->intval); |
id = breakpoint_add((void *)argv->intval, flags, -1); |
if (id < 0) |
printf("Add breakpoint failed.\n"); |
else |
printf("Added breakpoint %d.\n", id); |
return 1; |
} |
#endif /* CONFIG_KCONSOLE */ |
/** @} |
*/ |
/branches/arm/kernel/arch/amd64/src/pm.c |
---|
137,8 → 137,8 |
void gdt_tss_setlimit(descriptor_t *d, uint32_t limit) |
{ |
tss_descriptor_t *td = (tss_descriptor_t *) d; |
struct tss_descriptor *td = (tss_descriptor_t *) d; |
td->limit_0_15 = limit & 0xffff; |
td->limit_16_19 = (limit >> 16) & 0xf; |
} |
185,14 → 185,14 |
*/ |
void pm_init(void) |
{ |
descriptor_t *gdt_p = (descriptor_t *) gdtr.base; |
descriptor_t *gdt_p = (struct descriptor *) gdtr.base; |
tss_descriptor_t *tss_desc; |
/* |
* Each CPU has its private GDT and TSS. |
* All CPUs share one IDT. |
*/ |
if (config.cpu_active == 1) { |
idt_init(); |
/* |
200,19 → 200,20 |
* the heap hasn't been initialized so far. |
*/ |
tss_p = &tss; |
} else { |
} |
else { |
/* We are going to use malloc, which may return |
* non boot-mapped pointer, initialize the CR3 register |
* ahead of page_init */ |
write_cr3((uintptr_t) AS_KERNEL->genarch.page_table); |
tss_p = (tss_t *) malloc(sizeof(tss_t), FRAME_ATOMIC); |
tss_p = (struct tss *) malloc(sizeof(tss_t), FRAME_ATOMIC); |
if (!tss_p) |
panic("Cannot allocate TSS."); |
panic("could not allocate TSS\n"); |
} |
tss_initialize(tss_p); |
tss_desc = (tss_descriptor_t *) (&gdt_p[TSS_DES]); |
tss_desc->present = 1; |
tss_desc->type = AR_TSS; |
220,7 → 221,7 |
gdt_tss_setbase(&gdt_p[TSS_DES], (uintptr_t) tss_p); |
gdt_tss_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE - 1); |
gdtr_load(&gdtr); |
idtr_load(&idtr); |
/* |
230,5 → 231,24 |
tr_load(gdtselector(TSS_DES)); |
} |
/* Reboot the machine by initiating |
* a triple fault |
*/ |
void arch_reboot(void) |
{ |
preemption_disable(); |
ipl_t ipl = interrupts_disable(); |
memsetb(idt, sizeof(idt), 0); |
idtr_load(&idtr); |
interrupts_restore(ipl); |
asm volatile ( |
"int $0x03\n" |
"cli\n" |
"hlt\n" |
); |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/amd64/src/proc/scheduler.c |
---|
39,6 → 39,7 |
#include <arch.h> |
#include <arch/context.h> /* SP_DELTA */ |
#include <arch/asm.h> |
#include <arch/debugger.h> |
#include <print.h> |
#include <arch/pm.h> |
#include <arch/ddi/ddi.h> |
67,6 → 68,13 |
/* TLS support - set FS to thread local storage */ |
write_msr(AMD_MSR_FS, THREAD->arch.tls); |
#ifdef CONFIG_DEBUG_AS_WATCHPOINT |
/* Set watchpoint on AS to ensure that nobody sets it to zero */ |
if (CPU->id < BKPOINTS_MAX) |
breakpoint_add(&((the_t *) THREAD->kstack)->as, |
BKPOINT_WRITE | BKPOINT_CHECK_ZERO, CPU->id); |
#endif |
} |
void after_thread_ran_arch(void) |
/branches/arm/kernel/arch/amd64/src/boot/vesa_prot.inc |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/branches/arm/kernel/arch/amd64/src/boot/vesa_real.inc |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/branches/arm/kernel/arch/amd64/src/boot/vesa_ret.inc |
---|
File deleted |
/branches/arm/kernel/arch/amd64/src/boot/boot.S |
---|
1,4 → 1,4 |
# |
# Copyright (c) 2005 Ondrej Palkovsky |
# Copyright (c) 2006 Martin Decky |
# Copyright (c) 2008 Jakub Jermar |
37,7 → 37,7 |
#include <arch/cpuid.h> |
#define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE) |
.section K_TEXT_START, "ax" |
.code32 |
46,7 → 46,7 |
multiboot_header: |
.long MULTIBOOT_HEADER_MAGIC |
.long MULTIBOOT_HEADER_FLAGS |
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) # checksum |
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) # checksum |
.long multiboot_header |
.long unmapped_ktext_start |
.long 0 |
55,19 → 55,15 |
multiboot_image_start: |
cld |
movl $START_STACK, %esp # initialize stack pointer |
lgdtl bootstrap_gdtr # initialize Global Descriptor Table register |
movl $START_STACK, %esp # initialize stack pointer |
lgdtl bootstrap_gdtr # initialize Global Descriptor Table register |
movw $gdtselector(KDATA_DES), %cx |
movw %cx, %es |
movw %cx, %ds # kernel data + stack |
movw %cx, %ds # kernel data + stack |
movw %cx, %ss |
# |
# Simics seems to remove hidden part of GS on entering user mode |
# when _visible_ part of GS does not point to user-mode segment. |
# |
# when _visible_ part of GS does not point to user-mode segment |
movw $gdtselector(UDATA_DES), %cx |
movw %cx, %fs |
movw %cx, %gs |
75,19 → 71,17 |
jmpl $gdtselector(KTEXT32_DES), $multiboot_meeting_point |
multiboot_meeting_point: |
movl %eax, grub_eax # save parameters from GRUB |
movl %eax, grub_eax # save parameters from GRUB |
movl %ebx, grub_ebx |
# |
# Protected 32-bit. We want to reuse the code-seg descriptor, |
# the Default operand size must not be 1 when entering long mode. |
# |
# the Default operand size must not be 1 when entering long mode |
movl $(INTEL_CPUID_EXTENDED), %eax |
cpuid |
cmp $(INTEL_CPUID_EXTENDED), %eax |
movl $(INTEL_CPUID_EXTENDED), %eax |
cpuid |
cmp $(INTEL_CPUID_EXTENDED), %eax |
ja extended_cpuid_supported |
movl $extended_cpuid_msg, %esi |
jmp error_halt |
96,11 → 90,11 |
movl $(AMD_CPUID_EXTENDED), %eax |
cpuid |
bt $(AMD_EXT_LONG_MODE), %edx |
jc long_mode_supported |
jc long_mode_supported |
movl $long_mode_msg, %esi |
jmp error_halt |
long_mode_supported: |
bt $(AMD_EXT_NOEXECUTE), %edx |
114,7 → 108,7 |
movl $(INTEL_CPUID_STANDARD), %eax |
cpuid |
bt $(INTEL_FXSAVE), %edx |
jc fx_supported |
jc fx_supported |
movl $fx_msg, %esi |
jmp error_halt |
122,43 → 116,59 |
fx_supported: |
bt $(INTEL_SSE2), %edx |
jc sse2_supported |
jc sse2_supported |
movl $sse2_msg, %esi |
jmp error_halt |
sse2_supported: |
#ifdef CONFIG_FB |
mov $vesa_init, %esi |
mov $VESA_INIT_SEGMENT << 4, %edi |
mov $e_vesa_init - vesa_init, %ecx |
rep movsb |
#include "vesa_prot.inc" |
# |
mov $VESA_INIT_SEGMENT << 4, %edi |
jmpl *%edi |
vesa_meeting_point: |
mov %esi, KA2PA(vesa_ph_addr) |
mov %di, KA2PA(vesa_height) |
shr $16, %edi |
mov %di, KA2PA(vesa_width) |
mov %bx, KA2PA(vesa_scanline) |
shr $16, %ebx |
mov %bx, KA2PA(vesa_bpp) |
#endif |
# Enable 64-bit page translation entries - CR4.PAE = 1. |
# Paging is not enabled until after long mode is enabled. |
# |
# Paging is not enabled until after long mode is enabled |
movl %cr4, %eax |
btsl $5, %eax |
movl %eax, %cr4 |
# Set up paging tables |
# set up paging tables |
leal ptl_0, %eax |
movl %eax, %cr3 |
# enable long mode |
# Enable long mode |
movl $EFER_MSR_NUM, %ecx # EFER MSR number |
rdmsr # read EFER |
btsl $AMD_LME_FLAG, %eax # set LME = 1 |
wrmsr # write EFER |
movl $EFER_MSR_NUM, %ecx # EFER MSR number |
rdmsr # Read EFER |
btsl $AMD_LME_FLAG, %eax # Set LME = 1 |
wrmsr # Write EFER |
# enable paging to activate long mode (set CR0.PG = 1) |
# Enable paging to activate long mode (set CR0.PG = 1) |
movl %cr0, %eax |
btsl $31, %eax |
movl %eax, %cr0 |
# at this point we are in compatibility mode |
# At this point we are in compatibility mode |
jmpl $gdtselector(KTEXT_DES), $start64 |
165,29 → 175,362 |
.code64 |
start64: |
movq $(PA2KA(START_STACK)), %rsp |
movl grub_eax, %eax |
movl grub_ebx, %ebx |
# call arch_pre_main(grub_eax, grub_ebx) |
xorq %rdi, %rdi |
movl grub_eax, %edi |
xorq %rsi, %rsi |
movl grub_ebx, %esi |
call arch_pre_main |
cmpl $MULTIBOOT_LOADER_MAGIC, %eax # compare GRUB signature |
je valid_boot |
xorl %ecx, %ecx # no memory size or map available |
movl %ecx, e820counter |
jmp invalid_boot |
valid_boot: |
movl (%ebx), %eax # ebx = physical address of struct multiboot_info |
bt $3, %eax # mbi->flags[3] (mods_count, mods_addr valid) |
jc mods_valid |
xorq %rcx, %rcx |
movq %rcx, init |
jmp mods_end |
mods_valid: |
xorq %rcx, %rcx |
movl 20(%ebx), %ecx # mbi->mods_count |
movq %rcx, init |
cmpl $0, %ecx |
je mods_end |
movl 24(%ebx), %esi # mbi->mods_addr |
movq $init, %rdi |
mods_loop: |
xorq %rdx, %rdx |
movl 0(%esi), %edx # mods->mod_start |
movq $0xffff800000000000, %r10 |
addq %r10, %rdx |
movq %rdx, 8(%rdi) |
xorq %rdx, %rdx |
movl 4(%esi), %edx |
subl 0(%esi), %edx # mods->mod_end - mods->mod_start |
movq %rdx, 16(%rdi) |
addl $16, %esi |
addq $16, %rdi |
loop mods_loop |
mods_end: |
bt $6, %eax # mbi->flags[6] (mmap_length, mmap_addr valid) |
jc mmap_valid |
xorl %edx, %edx |
jmp mmap_invalid |
mmap_valid: |
movl 44(%ebx), %ecx # mbi->mmap_length |
movl 48(%ebx), %esi # mbi->mmap_addr |
movq $e820table, %rdi |
xorl %edx, %edx |
mmap_loop: |
cmpl $0, %ecx |
jle mmap_end |
movl 4(%esi), %eax # mmap->base_addr_low |
movl %eax, (%rdi) |
movl 8(%esi), %eax # mmap->base_addr_high |
movl %eax, 4(%rdi) |
movl 12(%esi), %eax # mmap->length_low |
movl %eax, 8(%rdi) |
movl 16(%esi), %eax # mmap->length_high |
movl %eax, 12(%rdi) |
movl 20(%esi), %eax # mmap->type |
movl %eax, 16(%rdi) |
movl (%esi), %eax # mmap->size |
addl $0x4, %eax |
addl %eax, %esi |
subl %eax, %ecx |
addq $MEMMAP_E820_RECORD_SIZE, %rdi |
incl %edx |
jmp mmap_loop |
mmap_end: |
mmap_invalid: |
movl %edx, e820counter |
invalid_boot: |
call main_bsp |
#ifdef CONFIG_SMP |
# not reached |
# copy AP bootstrap routines below 1 MB |
movq $BOOT_OFFSET, %rsi |
movq $AP_BOOT_OFFSET, %rdi |
movq $_hardcoded_unmapped_size, %rcx |
rep movsb |
#endif |
call main_bsp # never returns |
cli |
hlt0: |
hlt |
jmp hlt0 |
hlt |
#ifdef CONFIG_FB |
.code32 |
vesa_init: |
jmp $gdtselector(VESA_INIT_DES), $vesa_init_real - vesa_init |
.code16 |
vesa_init_real: |
mov %cr0, %eax |
and $~1, %eax |
mov %eax, %cr0 |
jmp $VESA_INIT_SEGMENT, $vesa_init_real2 - vesa_init |
vesa_init_real2: |
mov $VESA_INIT_SEGMENT, %bx |
mov %bx, %es |
mov %bx, %fs |
mov %bx, %gs |
mov %bx, %ds |
mov %bx, %ss |
movl $0x0000fffc, %esp |
movl $0x0000fffc, %ebp |
#define VESA_INFO_SIZE 1024 |
#define VESA_MODE_ATTRIBUTES_OFFSET 0 |
#define VESA_MODE_LIST_PTR_OFFSET 14 |
#define VESA_MODE_SCANLINE_OFFSET 16 |
#define VESA_MODE_WIDTH_OFFSET 18 |
#define VESA_MODE_HEIGHT_OFFSET 20 |
#define VESA_MODE_BPP_OFFSET 25 |
#define VESA_MODE_PHADDR_OFFSET 40 |
#define VESA_END_OF_MODES 0xffff |
#define VESA_OK 0x4f |
#define VESA_GET_INFO 0x4f00 |
#define VESA_GET_MODE_INFO 0x4f01 |
#define VESA_SET_MODE 0x4f02 |
#define VESA_SET_PALETTE 0x4f09 |
#define CONFIG_VESA_BPP_a 255 |
#if CONFIG_VESA_BPP == 24 |
#define CONFIG_VESA_BPP_VARIANT 32 |
#endif |
mov $VESA_GET_INFO, %ax |
mov $e_vesa_init - vesa_init, %di |
push %di |
int $0x10 |
pop %di |
cmp $VESA_OK, %al |
jnz 0f |
mov 2 + VESA_MODE_LIST_PTR_OFFSET(%di), %si |
mov %si, %gs |
mov VESA_MODE_LIST_PTR_OFFSET(%di), %si |
add $VESA_INFO_SIZE, %di |
1:# Try next mode |
mov %gs:(%si), %cx |
cmp $VESA_END_OF_MODES, %cx |
jz 0f |
inc %si |
inc %si |
push %cx |
push %di |
push %si |
mov $VESA_GET_MODE_INFO, %ax |
int $0x10 |
pop %si |
pop %di |
pop %cx |
cmp $VESA_OK, %al |
jnz 0f |
mov $CONFIG_VESA_WIDTH, %ax |
cmp VESA_MODE_WIDTH_OFFSET(%di), %ax |
jnz 1b |
mov $CONFIG_VESA_HEIGHT, %ax |
cmp VESA_MODE_HEIGHT_OFFSET(%di), %ax |
jnz 1b |
mov $CONFIG_VESA_BPP, %al |
cmp VESA_MODE_BPP_OFFSET(%di), %al |
#ifdef CONFIG_VESA_BPP_VARIANT |
jz 2f |
mov $CONFIG_VESA_BPP_VARIANT, %al |
cmp VESA_MODE_BPP_OFFSET(%di), %al |
#endif |
jnz 1b |
2: |
mov %cx, %bx |
or $0xc000, %bx |
push %di |
mov $VESA_SET_MODE, %ax |
int $0x10 |
pop %di |
cmp $VESA_OK, %al |
jnz 0f |
#if CONFIG_VESA_BPP == 8 |
# Set 3:2:3 VGA palette |
mov VESA_MODE_ATTRIBUTES_OFFSET(%di), %ax |
push %di |
mov $vga323 - vesa_init, %di |
mov $0x100, %ecx |
bt $5, %ax # Test if VGA compatible registers are present |
jnc vga_compat |
# Try VESA routine to set palette |
mov $VESA_SET_PALETTE, %ax |
xor %bl, %bl |
xor %dx, %dx |
int $0x10 |
jmp vga_not_compat |
vga_compat: |
# Try VGA registers to set palette |
movw $0x3c6, %dx # Set palette mask |
movb $0xff, %al |
outb %al, %dx |
movw $0x3c8, %dx # First index to set |
xor %al, %al |
outb %al, %dx |
movw $0x3c9, %dx # Data port |
vga_loop: |
movb %es:2(%di), %al |
outb %al, %dx |
movb %es:1(%di), %al |
outb %al, %dx |
movb %es:(%di), %al |
outb %al, %dx |
addw $4, %di |
loop vga_loop |
vga_not_compat: |
pop %di |
#endif |
mov VESA_MODE_PHADDR_OFFSET(%di), %esi |
mov VESA_MODE_WIDTH_OFFSET(%di), %ax |
shl $16, %eax |
mov VESA_MODE_HEIGHT_OFFSET(%di), %ax |
mov VESA_MODE_BPP_OFFSET(%di), %bl |
xor %bh, %bh |
shl $16, %ebx |
mov VESA_MODE_SCANLINE_OFFSET(%di), %bx |
mov %eax, %edi |
8: |
mov %cr0, %eax |
or $1, %eax |
mov %eax, %cr0 |
jmp 9f |
9: |
ljmpl $gdtselector(KTEXT32_DES), $(vesa_init_protect - vesa_init + VESA_INIT_SEGMENT << 4) |
0:# No prefered mode found |
mov $0x111, %cx |
push %di |
push %cx |
mov $VESA_GET_MODE_INFO, %ax |
int $0x10 |
pop %cx |
pop %di |
cmp $VESA_OK, %al |
jnz 1f |
jz 2b # Force relative jump |
1: |
mov $0x0003, %ax |
int $0x10 |
mov $0xffffffff, %edi # EGA text mode used, because of problems with VESA |
xor %ax, %ax |
jz 8b # Force relative jump |
vga323: |
#include "vga323.pal" |
.code32 |
vesa_init_protect: |
movw $gdtselector(KDATA_DES), %cx |
movw %cx, %es |
movw %cx, %ds # kernel data + stack |
movw %cx, %ss |
# Simics seems to remove hidden part of GS on entering user mode |
# when _visible_ part of GS does not point to user-mode segment |
movw $gdtselector(UDATA_DES), %cx |
movw %cx, %fs |
movw %cx, %gs |
movl $START_STACK, %esp # initialize stack pointer |
jmpl $gdtselector(KTEXT32_DES), $vesa_meeting_point |
.align 4 |
e_vesa_init: |
#endif |
# Print string from %esi to EGA display (in red) and halt |
error_halt: |
movl $0xb8000, %edi # base of EGA text mode memory |
movl $0xb8000, %edi # base of EGA text mode memory |
xorl %eax, %eax |
movw $0x3d4, %dx # read bits 8 - 15 of the cursor address |
movw $0x3d4, %dx # read bits 8 - 15 of the cursor address |
movb $0xe, %al |
outb %al, %dx |
195,7 → 538,7 |
inb %dx, %al |
shl $8, %ax |
movw $0x3d4, %dx # read bits 0 - 7 of the cursor address |
movw $0x3d4, %dx # read bits 0 - 7 of the cursor address |
movb $0xf, %al |
outb %al, %dx |
204,9 → 547,7 |
cmp $1920, %ax |
jbe cursor_ok |
movw $1920, %ax # sanity check for the cursor on the last line |
movw $1920, %ax # sanity check for the cursor on the last line |
cursor_ok: |
movw %ax, %bx |
213,7 → 554,7 |
shl $1, %eax |
addl %eax, %edi |
movw $0x0c00, %ax # black background, light red foreground |
movw $0x0c00, %ax # black background, light red foreground |
ploop: |
lodsb |
220,11 → 561,11 |
cmp $0, %al |
je ploop_end |
stosw |
inc %bx |
inc %bx |
jmp ploop |
ploop_end: |
movw $0x3d4, %dx # write bits 8 - 15 of the cursor address |
movw $0x3d4, %dx # write bits 8 - 15 of the cursor address |
movb $0xe, %al |
outb %al, %dx |
232,7 → 573,7 |
movb %bh, %al |
outb %al, %dx |
movw $0x3d4, %dx # write bits 0 - 7 of the cursor address |
movw $0x3d4, %dx # write bits 0 - 7 of the cursor address |
movb $0xf, %al |
outb %al, %dx |
239,20 → 580,17 |
movw $0x3d5, %dx |
movb %bl, %al |
outb %al, %dx |
cli |
hlt1: |
hlt |
jmp hlt1 |
hlt |
#include "vesa_real.inc" |
.section K_INI_PTLS, "aw", @progbits |
# |
# Macro for generating initial page table contents. |
# @param cnt Number of entries to generat. Must be multiple of 8. |
# @param g Number of GB that will be added to the mapping. |
# @param cnt Number of entries to generat. Must be multiple of 8. |
# @param g Number of GB that will be added to the mapping. |
# |
.macro ptl2gen cnt g |
.if \cnt |
304,7 → 642,7 |
# Mapping of [0; 1G) at -2G |
.quad ptl_2_0g + (PTL_WRITABLE | PTL_PRESENT) |
.fill 1, 8, 0 |
.align 4096 |
.global ptl_0 |
ptl_0: |
/branches/arm/kernel/arch/amd64/src/boot/memmap.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup amd64mm |
/** @addtogroup amd64mm |
* @{ |
*/ |
/** @file |
/branches/arm/kernel/arch/amd64/src/cpu/cpu.c |
---|
77,19 → 77,21 |
void cpu_setup_fpu(void) |
{ |
asm volatile ( |
"movq %%cr0, %%rax\n" |
"btsq $1, %%rax\n" /* cr0.mp */ |
"btrq $2, %%rax\n" /* cr0.em */ |
"movq %%rax, %%cr0\n" |
"movq %%cr4, %%rax\n" |
"bts $9, %%rax\n" /* cr4.osfxsr */ |
"movq %%rax, %%cr4\n" |
::: "%rax" |
); |
"movq %%cr0, %%rax;" |
"btsq $1, %%rax;" /* cr0.mp */ |
"btrq $2, %%rax;" /* cr0.em */ |
"movq %%rax, %%cr0;" |
"movq %%cr4, %%rax;" |
"bts $9, %%rax;" /* cr4.osfxsr */ |
"movq %%rax, %%cr4;" |
: |
: |
:"%rax" |
); |
} |
/** Set the TS flag to 1. |
/** Set the TS flag to 1. |
* |
* If a thread accesses coprocessor, exception is run, which |
* does a lazy fpu context switch. |
97,22 → 99,26 |
*/ |
void fpu_disable(void) |
{ |
asm volatile ( |
"mov %%cr0, %%rax\n" |
"bts $3, %%rax\n" |
"mov %%rax, %%cr0\n" |
::: "%rax" |
); |
asm volatile ( |
"mov %%cr0,%%rax;" |
"bts $3,%%rax;" |
"mov %%rax,%%cr0;" |
: |
: |
:"%rax" |
); |
} |
void fpu_enable(void) |
{ |
asm volatile ( |
"mov %%cr0, %%rax\n" |
"btr $3, %%rax\n" |
"mov %%rax, %%cr0\n" |
::: "%rax" |
); |
asm volatile ( |
"mov %%cr0,%%rax;" |
"btr $3,%%rax;" |
"mov %%rax,%%cr0;" |
: |
: |
:"%rax" |
); |
} |
void cpu_arch_init(void) |
/branches/arm/kernel/arch/amd64/src/mm/page.c |
---|
180,7 → 180,7 |
page = read_cr2(); |
if (istate->error_word & PFERR_CODE_RSVD) |
panic("Reserved bit set in page table entry."); |
panic("Reserved bit set in page table entry.\n"); |
if (istate->error_word & PFERR_CODE_RW) |
access = PF_ACCESS_WRITE; |
190,11 → 190,11 |
access = PF_ACCESS_READ; |
if (as_page_fault(page, access, istate) == AS_PF_FAULT) { |
fault_if_from_uspace(istate, "Page fault: %#x.", page); |
fault_if_from_uspace(istate, "Page fault: %#x", page); |
decode_istate(n, istate); |
printf("Page fault address: %llx.\n", page); |
panic("Page fault."); |
printf("Page fault address: %llx\n", page); |
panic("page fault\n"); |
} |
} |
202,7 → 202,7 |
uintptr_t hw_map(uintptr_t physaddr, size_t size) |
{ |
if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) |
panic("Unable to map physical memory %p (%d bytes).", physaddr, size) |
panic("Unable to map physical memory %p (%d bytes)", physaddr, size) |
uintptr_t virtaddr = PA2KA(last_frame); |
pfn_t i; |
/branches/arm/kernel/arch/amd64/src/amd64.c |
---|
39,15 → 39,11 |
#include <config.h> |
#include <proc/thread.h> |
#include <genarch/multiboot/multiboot.h> |
#include <genarch/drivers/legacy/ia32/io.h> |
#include <genarch/drivers/ega/ega.h> |
#include <arch/drivers/ega.h> |
#include <arch/drivers/vesa.h> |
#include <genarch/drivers/i8042/i8042.h> |
#include <genarch/kbrd/kbrd.h> |
#include <genarch/kbd/i8042.h> |
#include <arch/drivers/i8254.h> |
#include <arch/drivers/i8259.h> |
#include <arch/boot/boot.h> |
#ifdef CONFIG_SMP |
#include <arch/smp/apic.h> |
65,8 → 61,9 |
#include <syscall/syscall.h> |
#include <console/console.h> |
#include <ddi/irq.h> |
#include <sysinfo/sysinfo.h> |
#include <ddi/device.h> |
/** Disable I/O on non-privileged levels |
* |
* Clean IOPL(12,13) and NT(14) flags in EFLAGS register |
73,13 → 70,15 |
*/ |
static void clean_IOPL_NT_flags(void) |
{ |
asm volatile ( |
asm ( |
"pushfq\n" |
"pop %%rax\n" |
"and $~(0x7000), %%rax\n" |
"pushq %%rax\n" |
"popfq\n" |
::: "%rax" |
: |
: |
: "%rax" |
); |
} |
89,31 → 88,16 |
*/ |
static void clean_AM_flag(void) |
{ |
asm volatile ( |
asm ( |
"mov %%cr0, %%rax\n" |
"and $~(0x40000), %%rax\n" |
"mov %%rax, %%cr0\n" |
::: "%rax" |
: |
: |
: "%rax" |
); |
} |
/** Perform amd64-specific initialization before main_bsp() is called. |
* |
* @param signature Should contain the multiboot signature. |
* @param mi Pointer to the multiboot information structure. |
*/ |
void arch_pre_main(uint32_t signature, const multiboot_info_t *mi) |
{ |
/* Parse multiboot information obtained from the bootloader. */ |
multiboot_info_parse(signature, mi); |
#ifdef CONFIG_SMP |
/* Copy AP bootstrap routines below 1 MB. */ |
memcpy((void *) AP_BOOT_OFFSET, (void *) BOOT_OFFSET, |
(size_t) &_hardcoded_unmapped_size); |
#endif |
} |
void arch_pre_mm_init(void) |
{ |
/* Enable no-execute pages */ |
149,17 → 133,13 |
/* hard clock */ |
i8254_init(); |
#ifdef CONFIG_FB |
if (vesa_present()) |
vesa_init(); |
else |
#endif |
#ifdef CONFIG_EGA |
ega_init(EGA_BASE, EGA_VIDEORAM); /* video */ |
#else |
{} |
#endif |
ega_init(); /* video */ |
/* Enable debugger */ |
debugger_init(); |
192,33 → 172,8 |
void arch_post_smp_init(void) |
{ |
#ifdef CONFIG_PC_KBD |
/* |
* Initialize the i8042 controller. Then initialize the keyboard |
* module and connect it to i8042. Enable keyboard interrupts. |
*/ |
i8042_instance_t *i8042_instance = i8042_init((i8042_t *) I8042_BASE, IRQ_KBD); |
if (i8042_instance) { |
kbrd_instance_t *kbrd_instance = kbrd_init(); |
if (kbrd_instance) { |
indev_t *sink = stdin_wire(); |
indev_t *kbrd = kbrd_wire(kbrd_instance, sink); |
i8042_wire(i8042_instance, kbrd); |
trap_virtual_enable_irqs(1 << IRQ_KBD); |
} |
} |
/* |
* This is the necessary evil until the userspace driver is entirely |
* self-sufficient. |
*/ |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.inr", NULL, IRQ_KBD); |
sysinfo_set_item_val("kbd.address.physical", NULL, |
(uintptr_t) I8042_BASE); |
sysinfo_set_item_val("kbd.address.kernel", NULL, |
(uintptr_t) I8042_BASE); |
#endif |
/* keyboard controller */ |
i8042_init(device_assign_devno(), IRQ_KBD, device_assign_devno(), IRQ_MOUSE); |
} |
void calibrate_delay_loop(void) |
253,45 → 208,15 |
*/ |
void arch_grab_console(void) |
{ |
#ifdef CONFIG_FB |
if (vesa_present()) |
vesa_redraw(); |
else |
#endif |
#ifdef CONFIG_EGA |
ega_redraw(); |
#else |
{} |
#endif |
i8042_grab(); |
} |
/** Return console to userspace |
* |
*/ |
void arch_release_console(void) |
{ |
i8042_release(); |
} |
/** Construct function pointer |
* |
* @param fptr function pointer structure |
* @param addr function address |
* @param caller calling function address |
* |
* @return address of the function pointer |
* |
*/ |
void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller) |
{ |
return addr; |
} |
void arch_reboot(void) |
{ |
#ifdef CONFIG_PC_KBD |
i8042_cpu_reset((i8042_t *) I8042_BASE); |
#endif |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/amd64/src/ddi/ddi.c |
---|
56,16 → 56,16 |
*/ |
int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size) |
{ |
size_t bits; |
count_t bits; |
bits = ioaddr + size; |
if (bits > IO_PORTS) |
return ENOENT; |
if (task->arch.iomap.bits < bits) { |
bitmap_t oldiomap; |
uint8_t *newmap; |
/* |
* The I/O permission bitmap is too small and needs to be grown. |
*/ |
77,17 → 77,17 |
bitmap_initialize(&oldiomap, task->arch.iomap.map, |
task->arch.iomap.bits); |
bitmap_initialize(&task->arch.iomap, newmap, bits); |
/* |
* Mark the new range inaccessible. |
*/ |
bitmap_set_range(&task->arch.iomap, oldiomap.bits, |
bits - oldiomap.bits); |
/* |
* In case there really existed smaller iomap, |
* copy its contents and deallocate it. |
*/ |
*/ |
if (oldiomap.bits) { |
bitmap_copy(&task->arch.iomap, &oldiomap, |
oldiomap.bits); |
94,17 → 94,17 |
free(oldiomap.map); |
} |
} |
/* |
* Enable the range and we are done. |
*/ |
bitmap_clear_range(&task->arch.iomap, (size_t) ioaddr, (size_t) size); |
bitmap_clear_range(&task->arch.iomap, (index_t) ioaddr, (count_t) size); |
/* |
* Increment I/O Permission bitmap generation counter. |
*/ |
task->arch.iomapver++; |
return 0; |
} |
117,12 → 117,12 |
*/ |
void io_perm_bitmap_install(void) |
{ |
size_t bits; |
count_t bits; |
ptr_16_64_t cpugdtr; |
descriptor_t *gdt_p; |
tss_descriptor_t *tss_desc; |
size_t ver; |
count_t ver; |
/* First, copy the I/O Permission Bitmap. */ |
spinlock_lock(&TASK->lock); |
ver = TASK->arch.iomapver; |
140,7 → 140,7 |
bitmap_set_range(&iomap, ALIGN_UP(TASK->arch.iomap.bits, 8), 8); |
} |
spinlock_unlock(&TASK->lock); |
/* |
* Second, adjust TSS segment limit. |
* Take the extra ending byte will all bits set into account. |
151,10 → 151,10 |
gdtr_load(&cpugdtr); |
/* |
* Before we load new TSS limit, the current TSS descriptor |
* type must be changed to describe inactive TSS. |
*/ |
tss_desc = (tss_descriptor_t *) &gdt_p[TSS_DES]; |
* Before we load new TSS limit, the current TSS descriptor |
* type must be changed to describe inactive TSS. |
*/ |
tss_desc = (tss_descriptor_t *) &gdt_p[TSS_DES]; |
tss_desc->type = AR_TSS; |
tr_load(gdtselector(TSS_DES)); |
/branches/arm/kernel/arch/amd64/src/interrupt.c |
---|
43,6 → 43,7 |
#include <mm/tlb.h> |
#include <mm/as.h> |
#include <arch.h> |
#include <symtab.h> |
#include <arch/asm.h> |
#include <proc/scheduler.h> |
#include <proc/thread.h> |
51,7 → 52,6 |
#include <arch/ddi/ddi.h> |
#include <interrupt.h> |
#include <ddi/irq.h> |
#include <symtab.h> |
/* |
* Interrupt and exception dispatching. |
64,8 → 64,10 |
void decode_istate(int n, istate_t *istate) |
{ |
char *symbol; |
/* uint64_t *x = &istate->stack[0]; */ |
symbol = symtab_fmt_name_lookup(istate->rip); |
if (!(symbol = get_symtab_entry(istate->rip))) |
symbol = ""; |
printf("-----EXCEPTION(%d) OCCURED----- ( %s )\n", n, __func__); |
printf("%%rip: %#llx (%s)\n", istate->rip, symbol); |
78,6 → 80,12 |
istate->rdi, istate->r8); |
printf("%%r9=%#llx, %%r10=%#llx, %%r11=%#llx\n", istate->r9, |
istate->r10, istate->r11); |
#ifdef CONFIG_DEBUG_ALLREGS |
printf("%%r12=%#llx, %%r13=%#llx, %%r14=%#llx\n", istate->r12, |
istate->r13, istate->r14); |
printf("%%r15=%#llx, %%rbx=%#llx, %%rbp=%#llx\n", istate->r15, |
istate->rbx, &istate->rbp); |
#endif |
printf("%%rsp=%#llx\n", &istate->stack[0]); |
} |
86,15 → 94,15 |
if (eoi_function) |
eoi_function(); |
else |
panic("No eoi_function."); |
panic("no eoi_function\n"); |
} |
static void null_interrupt(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "Unserviced interrupt: %d.", n); |
fault_if_from_uspace(istate, "unserviced interrupt: %d", n); |
decode_istate(n, istate); |
panic("Unserviced interrupt."); |
panic("unserviced interrupt\n"); |
} |
/** General Protection Fault. */ |
101,7 → 109,7 |
static void gp_fault(int n, istate_t *istate) |
{ |
if (TASK) { |
size_t ver; |
count_t ver; |
spinlock_lock(&TASK->lock); |
ver = TASK->arch.iomapver; |
118,37 → 126,35 |
io_perm_bitmap_install(); |
return; |
} |
fault_if_from_uspace(istate, "General protection fault."); |
fault_if_from_uspace(istate, "general protection fault"); |
} |
decode_istate(n, istate); |
panic("General protection fault."); |
panic("general protection fault\n"); |
} |
static void ss_fault(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "Stack fault."); |
fault_if_from_uspace(istate, "stack fault"); |
decode_istate(n, istate); |
panic("Stack fault."); |
panic("stack fault\n"); |
} |
static void nm_fault(int n, istate_t *istate) |
{ |
#ifdef CONFIG_FPU_LAZY |
#ifdef CONFIG_FPU_LAZY |
scheduler_fpu_lazy_request(); |
#else |
fault_if_from_uspace(istate, "FPU fault."); |
panic("FPU fault."); |
fault_if_from_uspace(istate, "fpu fault"); |
panic("fpu fault"); |
#endif |
} |
#ifdef CONFIG_SMP |
static void tlb_shootdown_ipi(int n, istate_t *istate) |
{ |
trap_virtual_eoi(); |
tlb_shootdown_ipi_recv(); |
} |
#endif |
/** Handler of IRQ exceptions */ |
static void irq_interrupt(int n, istate_t *istate) |
171,7 → 177,7 |
trap_virtual_eoi(); |
ack = true; |
} |
irq->handler(irq); |
irq->handler(irq, irq->arg); |
spinlock_unlock(&irq->lock); |
} else { |
/* |
215,7 → 221,7 |
if (enable_irqs_function) |
enable_irqs_function(irqmask); |
else |
panic("No enable_irqs_function."); |
panic("no enable_irqs_function\n"); |
} |
void trap_virtual_disable_irqs(uint16_t irqmask) |
223,7 → 229,7 |
if (disable_irqs_function) |
disable_irqs_function(irqmask); |
else |
panic("No disable_irqs_function."); |
panic("no disable_irqs_function\n"); |
} |
/** @} |
/branches/arm/kernel/arch/amd64/src/fpu_context.c |
---|
39,9 → 39,9 |
void fpu_context_save(fpu_context_t *fctx) |
{ |
asm volatile ( |
"fxsave %[fctx]\n" |
: [fctx] "=m" (*fctx) |
); |
"fxsave %0" |
: "=m"(*fctx) |
); |
} |
/** Restore FPU (mmx,sse) context using fxrstor instruction */ |
48,9 → 48,9 |
void fpu_context_restore(fpu_context_t *fctx) |
{ |
asm volatile ( |
"fxrstor %[fctx]\n" |
: [fctx] "=m" (*fctx) |
); |
"fxrstor %0" |
: "=m"(*fctx) |
); |
} |
void fpu_init() |
57,7 → 57,7 |
{ |
/* TODO: Zero all SSE, MMX etc. registers */ |
asm volatile ( |
"fninit\n" |
"fninit;" |
); |
} |
/branches/arm/kernel/arch/amd64/_link.ld.in |
---|
43,6 → 43,8 |
QUAD(unmapped_kdata_end - unmapped_kdata_start); |
*(COMMON); /* global variables */ |
*(.eh_frame); |
symbol_table = .; |
*(symtab.*); /* Symbol table, must be LAST symbol!*/ |
50,10 → 52,6 |
kdata_end = .; |
} |
/DISCARD/ : { |
*(*); |
} |
#ifdef CONFIG_SMP |
_hardcoded_unmapped_size = (unmapped_ktext_end - unmapped_ktext_start) + (unmapped_kdata_end - unmapped_kdata_start); |
/branches/arm/kernel/arch/ia32xen/Makefile.inc |
---|
0,0 → 1,144 |
# |
# Copyright (c) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf32-i386 |
BFD_ARCH = i386 |
BFD = elf32-i386 |
TARGET = i686-pc-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/i686 |
DEFS += -DMACHINE=$(MACHINE) -D__32_BITS__ |
CMN1 = -m32 |
GCC_CFLAGS += $(CMN1) |
ICC_CFLAGS += $(CMN1) |
SUNCC_CFLAGS += $(CMN1) |
## Accepted CPUs |
# |
ifeq ($(MACHINE),athlon-xp) |
CMN2 = -march=athlon-xp -mmmx -msse -m3dnow |
GCC_CFLAGS += $(CMN2) |
ICC_CFLAGS += $(CMN2) |
SUNCC_CFLAGS += -xarch=ssea |
DEFS += -DCONFIG_FENCES_P3 |
CONFIG_SMP = n |
CONFIG_HT = n |
endif |
ifeq ($(MACHINE),athlon-mp) |
CMN2 = -march=athlon-mp -mmmx -msse -m3dnow |
GCC_CFLAGS += $(CMN2) |
ICC_CFLAGS += $(CMN2) |
SUNCC_CFLAGS += -xarch=ssea |
DEFS += -DCONFIG_FENCES_P3 |
CONFIG_HT = n |
endif |
ifeq ($(MACHINE),pentium3) |
CMN2 = -march=pentium3 -mmmx -msse |
GCC_CFLAGS += $(CMN2) |
ICC_CFLAGS += $(CMN2) |
SUNCC_CFLAGS += -xarch=sse |
DEFS += -DCONFIG_FENCES_P3 |
CONFIG_HT = n |
endif |
ifeq ($(MACHINE),core) |
CMN2 = -march=prescott -mfpmath=sse -mmmx -msse -msse2 -msse3 |
GCC_CFLAGS += $(CMN2) |
ICC_CFLAGS += $(CMN2) |
SUNCC_CFLAGS += -xarch=sse3 |
DEFS += -DCONFIG_FENCES_P4 |
endif |
ifeq ($(MACHINE),pentium4) |
GCC_CFLAGS += -march=pentium4 -mfpmath=sse -mmmx -msse -msse2 |
ICC_CFLAGS += -march=pentium4 |
SUNCC_CFLAGS += -xarch=sse2 |
DEFS += -DCONFIG_FENCES_P4 |
endif |
## Own configuration directives |
# |
CONFIG_ACPI = y |
## Compile with hierarchical page tables support. |
# |
CONFIG_PAGE_PT = y |
DEFS += -DCONFIG_PAGE_PT |
## Accepted configuration directives |
# |
ifeq ($(CONFIG_SMP),y) |
DEFS += -DCONFIG_SMP |
endif |
ifeq ($(CONFIG_HT),y) |
DEFS += -DCONFIG_HT |
endif |
## Compile with support for software integer division. |
# |
CONFIG_SOFTINT = y |
ARCH_SOURCES = \ |
arch/$(ARCH)/src/context.S \ |
arch/$(ARCH)/src/debug/panic.s \ |
arch/$(ARCH)/src/delay.s \ |
arch/$(ARCH)/src/asm.S \ |
arch/$(ARCH)/src/proc/scheduler.c \ |
arch/$(ARCH)/src/proc/task.c \ |
arch/$(ARCH)/src/proc/thread.c \ |
arch/$(ARCH)/src/bios/bios.c \ |
arch/$(ARCH)/src/smp/apic.c \ |
arch/$(ARCH)/src/smp/mps.c \ |
arch/$(ARCH)/src/smp/smp.c \ |
arch/$(ARCH)/src/atomic.S \ |
arch/$(ARCH)/src/smp/ipi.c \ |
arch/$(ARCH)/src/ia32xen.c \ |
arch/$(ARCH)/src/interrupt.c \ |
arch/$(ARCH)/src/pm.c \ |
arch/$(ARCH)/src/userspace.c \ |
arch/$(ARCH)/src/cpu/cpu.c \ |
arch/$(ARCH)/src/mm/as.c \ |
arch/$(ARCH)/src/mm/frame.c \ |
arch/$(ARCH)/src/mm/page.c \ |
arch/$(ARCH)/src/mm/tlb.c \ |
arch/$(ARCH)/src/ddi/ddi.c \ |
arch/$(ARCH)/src/drivers/xconsole.c \ |
arch/$(ARCH)/src/boot/boot.S \ |
arch/$(ARCH)/src/fpu_context.c \ |
arch/$(ARCH)/src/debugger.c |
/branches/arm/kernel/arch/ia32xen/src/asm.S |
---|
0,0 → 1,124 |
# |
# Copyright (c) 2001-2004 Jakub Jermar |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
## very low and hardware-level functions |
# Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int has no error word |
# and 1 means interrupt with error word |
#define ERROR_WORD_INTERRUPT_LIST 0x00027D00 |
.text |
.global xen_callback |
.global xen_failsafe_callback |
.global enable_l_apic_in_msr |
.global memcpy |
.global memcpy_from_uspace |
.global memcpy_from_uspace_failover_address |
.global memcpy_to_uspace |
.global memcpy_to_uspace_failover_address |
xen_callback: |
iret |
xen_failsafe_callback: |
iret |
#define MEMCPY_DST 4 |
#define MEMCPY_SRC 8 |
#define MEMCPY_SIZE 12 |
/** Copy memory to/from userspace. |
* |
* This is almost conventional memcpy(). |
* The difference is that there is a failover part |
* to where control is returned from a page fault |
* if the page fault occurs during copy_from_uspace() |
* or copy_to_uspace(). |
* |
* @param MEMCPY_DST(%esp) Destination address. |
* @param MEMCPY_SRC(%esp) Source address. |
* @param MEMCPY_SIZE(%esp) Size. |
* |
* @return MEMCPY_DST(%esp) on success and 0 on failure. |
*/ |
memcpy: |
memcpy_from_uspace: |
memcpy_to_uspace: |
movl %edi, %edx /* save %edi */ |
movl %esi, %eax /* save %esi */ |
movl MEMCPY_SIZE(%esp), %ecx |
shrl $2, %ecx /* size / 4 */ |
movl MEMCPY_DST(%esp), %edi |
movl MEMCPY_SRC(%esp), %esi |
rep movsl /* copy as much as possible word by word */ |
movl MEMCPY_SIZE(%esp), %ecx |
andl $3, %ecx /* size % 4 */ |
jz 0f |
rep movsb /* copy the rest byte by byte */ |
0: |
movl %edx, %edi |
movl %eax, %esi |
movl MEMCPY_DST(%esp), %eax /* MEMCPY_DST(%esp), success */ |
ret |
/* |
* We got here from as_page_fault() after the memory operations |
* above had caused a page fault. |
*/ |
memcpy_from_uspace_failover_address: |
memcpy_to_uspace_failover_address: |
movl %edx, %edi |
movl %eax, %esi |
xorl %eax, %eax /* return 0, failure */ |
ret |
## Enable local APIC |
# |
# Enable local APIC in MSR. |
# |
enable_l_apic_in_msr: |
push %eax |
movl $0x1b, %ecx |
rdmsr |
orl $(1<<11),%eax |
orl $(0xfee00000),%eax |
wrmsr |
pop %eax |
ret |
/branches/arm/kernel/arch/ia32xen/src/userspace.c |
---|
0,0 → 1,93 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#include <userspace.h> |
#include <arch/pm.h> |
#include <arch/types.h> |
#include <arch.h> |
#include <proc/uarg.h> |
#include <mm/as.h> |
/** Enter userspace |
* |
* Change CPU protection level to 3, enter userspace. |
* |
*/ |
void userspace(uspace_arg_t *kernel_uarg) |
{ |
uint32_t ipl = interrupts_disable(); |
asm volatile ( |
/* |
* Clear nested task flag. |
*/ |
"pushfl\n" |
"pop %%eax\n" |
"and $0xffffbfff, %%eax\n" |
"push %%eax\n" |
"popfl\n" |
/* Set up GS register (TLS) */ |
"movl %6, %%gs\n" |
"pushl %0\n" |
"pushl %1\n" |
"pushl %2\n" |
"pushl %3\n" |
"pushl %4\n" |
"movl %5, %%eax\n" |
/* %ebx is defined to hold pcb_ptr - set it to 0 */ |
"xorl %%ebx, %%ebx\n" |
"iret\n" |
: |
: "i" (selector(UDATA_DES) | PL_USER), |
"r" (kernel_uarg->uspace_stack + THREAD_STACK_SIZE), |
"r" (ipl), |
"i" (selector(UTEXT_DES) | PL_USER), |
"r" (kernel_uarg->uspace_entry), |
"r" (kernel_uarg->uspace_uarg), |
"r" (selector(TLS_DES)) |
: "eax" |
); |
/* Unreachable */ |
for(;;) |
; |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32xen/src/ia32xen.c |
---|
0,0 → 1,218 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#include <arch.h> |
#include <main/main.h> |
#include <arch/types.h> |
#include <align.h> |
#include <arch/pm.h> |
#include <arch/drivers/xconsole.h> |
#include <arch/mm/page.h> |
#include <arch/context.h> |
#include <config.h> |
#include <arch/interrupt.h> |
#include <arch/asm.h> |
#include <genarch/acpi/acpi.h> |
#include <arch/bios/bios.h> |
#include <interrupt.h> |
#include <arch/debugger.h> |
#include <proc/thread.h> |
#include <syscall/syscall.h> |
#include <console/console.h> |
#include <ddi/irq.h> |
start_info_t start_info; |
memzone_t meminfo; |
extern void xen_callback(void); |
extern void xen_failsafe_callback(void); |
void arch_pre_main(void) |
{ |
pte_t pte; |
memsetb(&pte, sizeof(pte), 0); |
pte.present = 1; |
pte.writeable = 1; |
pte.frame_address = ADDR2PFN((uintptr_t) start_info.shared_info); |
ASSERT(xen_update_va_mapping(&shared_info, pte, UVMF_INVLPG) == 0); |
if (!(start_info.flags & SIF_INITDOMAIN)) { |
/* Map console frame */ |
pte.present = 1; |
pte.writeable = 1; |
pte.frame_address = start_info.console.domU.mfn; |
ASSERT(xen_update_va_mapping(&console_page, pte, UVMF_INVLPG) == 0); |
} else |
start_info.console.domU.evtchn = 0; |
ASSERT(xen_set_callbacks(XEN_CS, xen_callback, XEN_CS, xen_failsafe_callback) == 0); |
/* Create identity mapping */ |
meminfo.start = ADDR2PFN(ALIGN_UP(KA2PA(start_info.ptl0), PAGE_SIZE)) + start_info.pt_frames; |
meminfo.size = start_info.frames - meminfo.start; |
meminfo.reserved = 0; |
uintptr_t pa; |
index_t last_ptl0 = 0; |
for (pa = PFN2ADDR(meminfo.start); pa < PFN2ADDR(meminfo.start + meminfo.size); pa += FRAME_SIZE) { |
uintptr_t va = PA2KA(pa); |
if ((PTL0_INDEX(va) != last_ptl0) && (GET_PTL1_FLAGS(start_info.ptl0, PTL0_INDEX(va)) & PAGE_NOT_PRESENT)) { |
/* New page directory entry needed */ |
uintptr_t tpa = PFN2ADDR(meminfo.start + meminfo.reserved); |
uintptr_t tva = PA2KA(tpa); |
memsetb((void *) tva, PAGE_SIZE, 0); |
pte_t *tptl3 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(start_info.ptl0, PTL0_INDEX(tva))); |
SET_FRAME_ADDRESS(tptl3, PTL3_INDEX(tva), 0); |
SET_PTL1_ADDRESS(start_info.ptl0, PTL0_INDEX(va), tpa); |
SET_FRAME_ADDRESS(tptl3, PTL3_INDEX(tva), tpa); |
last_ptl0 = PTL0_INDEX(va); |
meminfo.reserved++; |
} |
pte_t *ptl3 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(start_info.ptl0, PTL0_INDEX(va))); |
SET_FRAME_ADDRESS(ptl3, PTL3_INDEX(va), pa); |
SET_FRAME_FLAGS(ptl3, PTL3_INDEX(va), PAGE_PRESENT | PAGE_WRITE); |
} |
/* Put initial stack safely in the mapped area */ |
stack_safe = PA2KA(PFN2ADDR(meminfo.start + meminfo.reserved)); |
} |
void arch_pre_mm_init(void) |
{ |
pm_init(); |
if (config.cpu_active == 1) { |
interrupt_init(); |
// bios_init(); |
} |
} |
void arch_post_mm_init(void) |
{ |
if (config.cpu_active == 1) { |
/* Initialize IRQ routing */ |
irq_init(IRQ_COUNT, IRQ_COUNT); |
/* Video */ |
xen_console_init(); |
/* Enable debugger */ |
debugger_init(); |
/* Merge all memory zones to 1 big zone */ |
zone_merge_all(); |
} |
} |
void arch_post_cpu_init(void) |
{ |
} |
void arch_pre_smp_init(void) |
{ |
if (config.cpu_active == 1) { |
#ifdef CONFIG_SMP |
acpi_init(); |
#endif /* CONFIG_SMP */ |
} |
} |
void arch_post_smp_init(void) |
{ |
} |
void calibrate_delay_loop(void) |
{ |
// i8254_calibrate_delay_loop(); |
if (config.cpu_active == 1) { |
/* |
* This has to be done only on UP. |
* On SMP, i8254 is not used for time keeping and its interrupt pin remains masked. |
*/ |
// i8254_normal_operation(); |
} |
} |
/** Set thread-local-storage pointer |
* |
* TLS pointer is set in GS register. That means, the GS contains |
* selector, and the descriptor->base is the correct address. |
*/ |
unative_t sys_tls_set(unative_t addr) |
{ |
THREAD->arch.tls = addr; |
set_tls_desc(addr); |
return 0; |
} |
/** Acquire console back for kernel |
* |
*/ |
void arch_grab_console(void) |
{ |
} |
/** Return console to userspace |
* |
*/ |
void arch_release_console(void) |
{ |
} |
void arch_reboot(void) |
{ |
// TODO |
while (1); |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32xen/src/pm.c |
---|
0,0 → 1,206 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/pm.h> |
#include <config.h> |
#include <arch/types.h> |
#include <arch/interrupt.h> |
#include <arch/asm.h> |
#include <arch/context.h> |
#include <panic.h> |
#include <arch/mm/page.h> |
#include <mm/slab.h> |
#include <memstr.h> |
#include <interrupt.h> |
/* |
* Early ia32xen configuration functions and data structures. |
*/ |
/* |
* We have no use for segmentation so we set up flat mode. In this |
* mode, we use, for each privilege level, two segments spanning the |
* whole memory. One is for code and one is for data. |
* |
* One is for GS register which holds pointer to the TLS thread |
* structure in it's base. |
*/ |
descriptor_t gdt[GDT_ITEMS] = { |
/* NULL descriptor */ |
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
/* KTEXT descriptor */ |
{ 0xffff, 0, 0, AR_PRESENT | AR_CODE | DPL_KERNEL, 0xf, 0, 0, 1, 1, 0 }, |
/* KDATA descriptor */ |
{ 0xffff, 0, 0, AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_KERNEL, 0xf, 0, 0, 1, 1, 0 }, |
/* UTEXT descriptor */ |
{ 0xffff, 0, 0, AR_PRESENT | AR_CODE | DPL_USER, 0xf, 0, 0, 1, 1, 0 }, |
/* UDATA descriptor */ |
{ 0xffff, 0, 0, AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_USER, 0xf, 0, 0, 1, 1, 0 }, |
/* TSS descriptor - set up will be completed later */ |
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
/* TLS descriptor */ |
{ 0xffff, 0, 0, AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_USER, 0xf, 0, 0, 1, 1, 0 }, |
}; |
static trap_info_t traps[IDT_ITEMS + 1]; |
static tss_t tss; |
tss_t *tss_p = NULL; |
/* gdtr is changed by kmp before next CPU is initialized */ |
ptr_16_32_t bootstrap_gdtr = { .limit = sizeof(gdt), .base = KA2PA((uintptr_t) gdt) }; |
ptr_16_32_t gdtr = { .limit = sizeof(gdt), .base = (uintptr_t) gdt }; |
void gdt_setbase(descriptor_t *d, uintptr_t base) |
{ |
d->base_0_15 = base & 0xffff; |
d->base_16_23 = ((base) >> 16) & 0xff; |
d->base_24_31 = ((base) >> 24) & 0xff; |
} |
void gdt_setlimit(descriptor_t *d, uint32_t limit) |
{ |
d->limit_0_15 = limit & 0xffff; |
d->limit_16_19 = (limit >> 16) & 0xf; |
} |
void tss_initialize(tss_t *t) |
{ |
memsetb(t, sizeof(struct tss), 0); |
} |
static void trap(void) |
{ |
} |
void traps_init(void) |
{ |
index_t i; |
for (i = 0; i < IDT_ITEMS; i++) { |
traps[i].vector = i; |
if (i == VECTOR_SYSCALL) |
traps[i].flags = 3; |
else |
traps[i].flags = 0; |
traps[i].cs = XEN_CS; |
traps[i].address = trap; |
} |
traps[IDT_ITEMS].vector = 0; |
traps[IDT_ITEMS].flags = 0; |
traps[IDT_ITEMS].cs = 0; |
traps[IDT_ITEMS].address = NULL; |
} |
/* Clean IOPL(12,13) and NT(14) flags in EFLAGS register */ |
static void clean_IOPL_NT_flags(void) |
{ |
// asm volatile ( |
// "pushfl\n" |
// "pop %%eax\n" |
// "and $0xffff8fff, %%eax\n" |
// "push %%eax\n" |
// "popfl\n" |
// : : : "eax" |
// ); |
} |
/* Clean AM(18) flag in CR0 register */ |
static void clean_AM_flag(void) |
{ |
// asm volatile ( |
// "mov %%cr0, %%eax\n" |
// "and $0xfffbffff, %%eax\n" |
// "mov %%eax, %%cr0\n" |
// : : : "eax" |
// ); |
} |
void pm_init(void) |
{ |
descriptor_t *gdt_p = (descriptor_t *) gdtr.base; |
// gdtr_load(&gdtr); |
if (config.cpu_active == 1) { |
traps_init(); |
xen_set_trap_table(traps); |
/* |
* NOTE: bootstrap CPU has statically allocated TSS, because |
* the heap hasn't been initialized so far. |
*/ |
tss_p = &tss; |
} else { |
tss_p = (tss_t *) malloc(sizeof(tss_t), FRAME_ATOMIC); |
if (!tss_p) |
panic("could not allocate TSS\n"); |
} |
// tss_initialize(tss_p); |
gdt_p[TSS_DES].access = AR_PRESENT | AR_TSS | DPL_KERNEL; |
gdt_p[TSS_DES].special = 1; |
gdt_p[TSS_DES].granularity = 0; |
gdt_setbase(&gdt_p[TSS_DES], (uintptr_t) tss_p); |
gdt_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE - 1); |
/* |
* As of this moment, the current CPU has its own GDT pointing |
* to its own TSS. We just need to load the TR register. |
*/ |
// tr_load(selector(TSS_DES)); |
clean_IOPL_NT_flags(); /* Disable I/O on nonprivileged levels and clear NT flag. */ |
clean_AM_flag(); /* Disable alignment check */ |
} |
void set_tls_desc(uintptr_t tls) |
{ |
ptr_16_32_t cpugdtr; |
descriptor_t *gdt_p; |
gdtr_store(&cpugdtr); |
gdt_p = (descriptor_t *) cpugdtr.base; |
gdt_setbase(&gdt_p[TLS_DES], tls); |
/* Reload gdt register to update GS in CPU */ |
gdtr_load(&cpugdtr); |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32xen/src/smp/smp.c |
---|
0,0 → 1,174 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#include <smp/smp.h> |
#include <arch/smp/smp.h> |
#include <arch/smp/mps.h> |
#include <arch/smp/ap.h> |
#include <genarch/acpi/acpi.h> |
#include <genarch/acpi/madt.h> |
#include <config.h> |
#include <synch/waitq.h> |
#include <synch/synch.h> |
#include <arch/pm.h> |
#include <func.h> |
#include <panic.h> |
#include <debug.h> |
#include <arch/asm.h> |
#include <mm/frame.h> |
#include <mm/page.h> |
#include <mm/slab.h> |
#include <mm/as.h> |
#include <print.h> |
#include <memstr.h> |
#ifdef CONFIG_SMP |
static struct smp_config_operations *ops = NULL; |
void smp_init(void) |
{ |
uintptr_t l_apic_address, io_apic_address; |
if (acpi_madt) { |
acpi_madt_parse(); |
ops = &madt_config_operations; |
} |
if (config.cpu_count == 1) { |
mps_init(); |
ops = &mps_config_operations; |
} |
l_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, FRAME_ATOMIC | FRAME_KA); |
if (!l_apic_address) |
panic("cannot allocate address for l_apic\n"); |
io_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, FRAME_ATOMIC | FRAME_KA); |
if (!io_apic_address) |
panic("cannot allocate address for io_apic\n"); |
if (config.cpu_count > 1) { |
page_mapping_insert(AS_KERNEL, l_apic_address, (uintptr_t) l_apic, |
PAGE_NOT_CACHEABLE | PAGE_WRITE); |
page_mapping_insert(AS_KERNEL, io_apic_address, (uintptr_t) io_apic, |
PAGE_NOT_CACHEABLE | PAGE_WRITE); |
l_apic = (uint32_t *) l_apic_address; |
io_apic = (uint32_t *) io_apic_address; |
} |
} |
/* |
* Kernel thread for bringing up application processors. It becomes clear |
* that we need an arrangement like this (AP's being initialized by a kernel |
* thread), for a thread has its dedicated stack. (The stack used during the |
* BSP initialization (prior the very first call to scheduler()) will be used |
* as an initialization stack for each AP.) |
*/ |
void kmp(void *arg) |
{ |
unsigned int i; |
ASSERT(ops != NULL); |
waitq_initialize(&ap_completion_wq); |
/* |
* We need to access data in frame 0. |
* We boldly make use of kernel address space mapping. |
*/ |
/* |
* Save 0xa to address 0xf of the CMOS RAM. |
* BIOS will not do the POST after the INIT signal. |
*/ |
outb(0x70,0xf); |
outb(0x71,0xa); |
// pic_disable_irqs(0xffff); |
apic_init(); |
for (i = 0; i < ops->cpu_count(); i++) { |
struct descriptor *gdt_new; |
/* |
* Skip processors marked unusable. |
*/ |
if (!ops->cpu_enabled(i)) |
continue; |
/* |
* The bootstrap processor is already up. |
*/ |
if (ops->cpu_bootstrap(i)) |
continue; |
if (ops->cpu_apic_id(i) == l_apic_id()) { |
printf("%s: bad processor entry #%d, will not send IPI to myself\n", __FUNCTION__, i); |
continue; |
} |
/* |
* Prepare new GDT for CPU in question. |
*/ |
if (!(gdt_new = (struct descriptor *) malloc(GDT_ITEMS * sizeof(struct descriptor), FRAME_ATOMIC))) |
panic("couldn't allocate memory for GDT\n"); |
memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(struct descriptor)); |
memsetb(&gdt_new[TSS_DES], sizeof(struct descriptor), 0); |
gdtr.base = (uintptr_t) gdt_new; |
if (l_apic_send_init_ipi(ops->cpu_apic_id(i))) { |
/* |
* There may be just one AP being initialized at |
* the time. After it comes completely up, it is |
* supposed to wake us up. |
*/ |
if (waitq_sleep_timeout(&ap_completion_wq, 1000000, SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT) |
printf("%s: waiting for cpu%d (APIC ID = %d) timed out\n", __FUNCTION__, config.cpu_active > i ? config.cpu_active : i, ops->cpu_apic_id(i)); |
} else |
printf("INIT IPI for l_apic%d failed\n", ops->cpu_apic_id(i)); |
} |
} |
int smp_irq_to_pin(unsigned int irq) |
{ |
ASSERT(ops != NULL); |
return ops->irq_to_pin(irq); |
} |
#endif /* CONFIG_SMP */ |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32xen/src/smp/mps.c |
---|
0,0 → 1,433 |
/* |
* Copyright (c) 2001-2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#ifdef CONFIG_SMP |
#include <config.h> |
#include <print.h> |
#include <debug.h> |
#include <arch/smp/mps.h> |
#include <arch/smp/apic.h> |
#include <arch/smp/smp.h> |
#include <func.h> |
#include <arch/types.h> |
#include <cpu.h> |
#include <arch/asm.h> |
#include <arch/bios/bios.h> |
#include <mm/frame.h> |
/* |
* MultiProcessor Specification detection code. |
*/ |
#define FS_SIGNATURE 0x5f504d5f |
#define CT_SIGNATURE 0x504d4350 |
int mps_fs_check(uint8_t *base); |
int mps_ct_check(void); |
int configure_via_ct(void); |
int configure_via_default(uint8_t n); |
int ct_processor_entry(struct __processor_entry *pr); |
void ct_bus_entry(struct __bus_entry *bus); |
void ct_io_apic_entry(struct __io_apic_entry *ioa); |
void ct_io_intr_entry(struct __io_intr_entry *iointr); |
void ct_l_intr_entry(struct __l_intr_entry *lintr); |
void ct_extended_entries(void); |
static struct mps_fs *fs; |
static struct mps_ct *ct; |
struct __processor_entry *processor_entries = NULL; |
struct __bus_entry *bus_entries = NULL; |
struct __io_apic_entry *io_apic_entries = NULL; |
struct __io_intr_entry *io_intr_entries = NULL; |
struct __l_intr_entry *l_intr_entries = NULL; |
unsigned int processor_entry_cnt = 0; |
unsigned int bus_entry_cnt = 0; |
unsigned int io_apic_entry_cnt = 0; |
unsigned int io_intr_entry_cnt = 0; |
unsigned int l_intr_entry_cnt = 0; |
waitq_t ap_completion_wq; |
/* |
* Implementation of IA-32 SMP configuration interface. |
*/ |
static count_t get_cpu_count(void); |
static bool is_cpu_enabled(index_t i); |
static bool is_bsp(index_t i); |
static uint8_t get_cpu_apic_id(index_t i); |
static int mps_irq_to_pin(unsigned int irq); |
struct smp_config_operations mps_config_operations = { |
.cpu_count = get_cpu_count, |
.cpu_enabled = is_cpu_enabled, |
.cpu_bootstrap = is_bsp, |
.cpu_apic_id = get_cpu_apic_id, |
.irq_to_pin = mps_irq_to_pin |
}; |
count_t get_cpu_count(void) |
{ |
return processor_entry_cnt; |
} |
bool is_cpu_enabled(index_t i) |
{ |
ASSERT(i < processor_entry_cnt); |
return processor_entries[i].cpu_flags & 0x1; |
} |
bool is_bsp(index_t i) |
{ |
ASSERT(i < processor_entry_cnt); |
return processor_entries[i].cpu_flags & 0x2; |
} |
uint8_t get_cpu_apic_id(index_t i) |
{ |
ASSERT(i < processor_entry_cnt); |
return processor_entries[i].l_apic_id; |
} |
/* |
* Used to check the integrity of the MP Floating Structure. |
*/ |
int mps_fs_check(uint8_t *base) |
{ |
int i; |
uint8_t sum; |
for (i = 0, sum = 0; i < 16; i++) |
sum += base[i]; |
return !sum; |
} |
/* |
* Used to check the integrity of the MP Configuration Table. |
*/ |
int mps_ct_check(void) |
{ |
uint8_t *base = (uint8_t *) ct; |
uint8_t *ext = base + ct->base_table_length; |
uint8_t sum; |
int i; |
/* count the checksum for the base table */ |
for (i=0,sum=0; i < ct->base_table_length; i++) |
sum += base[i]; |
if (sum) |
return 0; |
/* count the checksum for the extended table */ |
for (i=0,sum=0; i < ct->ext_table_length; i++) |
sum += ext[i]; |
return sum == ct->ext_table_checksum; |
} |
void mps_init(void) |
{ |
uint8_t *addr[2] = { NULL, (uint8_t *) PA2KA(0xf0000) }; |
int i, j, length[2] = { 1024, 64*1024 }; |
/* |
* Find MP Floating Pointer Structure |
* 1a. search first 1K of EBDA |
* 1b. if EBDA is undefined, search last 1K of base memory |
* 2. search 64K starting at 0xf0000 |
*/ |
addr[0] = (uint8_t *) PA2KA(ebda ? ebda : 639 * 1024); |
for (i = 0; i < 2; i++) { |
for (j = 0; j < length[i]; j += 16) { |
if (*((uint32_t *) &addr[i][j]) == FS_SIGNATURE && mps_fs_check(&addr[i][j])) { |
fs = (struct mps_fs *) &addr[i][j]; |
goto fs_found; |
} |
} |
} |
return; |
fs_found: |
printf("%p: MPS Floating Pointer Structure\n", fs); |
if (fs->config_type == 0 && fs->configuration_table) { |
if (fs->mpfib2 >> 7) { |
printf("%s: PIC mode not supported\n", __func__); |
return; |
} |
ct = (struct mps_ct *)PA2KA((uintptr_t)fs->configuration_table); |
config.cpu_count = configure_via_ct(); |
} |
else |
config.cpu_count = configure_via_default(fs->config_type); |
return; |
} |
int configure_via_ct(void) |
{ |
uint8_t *cur; |
int i, cnt; |
if (ct->signature != CT_SIGNATURE) { |
printf("%s: bad ct->signature\n", __func__); |
return 1; |
} |
if (!mps_ct_check()) { |
printf("%s: bad ct checksum\n", __func__); |
return 1; |
} |
if (ct->oem_table) { |
printf("%s: ct->oem_table not supported\n", __func__); |
return 1; |
} |
l_apic = (uint32_t *)(uintptr_t)ct->l_apic; |
cnt = 0; |
cur = &ct->base_table[0]; |
for (i=0; i < ct->entry_count; i++) { |
switch (*cur) { |
/* Processor entry */ |
case 0: |
processor_entries = processor_entries ? processor_entries : (struct __processor_entry *) cur; |
processor_entry_cnt++; |
cnt += ct_processor_entry((struct __processor_entry *) cur); |
cur += 20; |
break; |
/* Bus entry */ |
case 1: |
bus_entries = bus_entries ? bus_entries : (struct __bus_entry *) cur; |
bus_entry_cnt++; |
ct_bus_entry((struct __bus_entry *) cur); |
cur += 8; |
break; |
/* I/O Apic */ |
case 2: |
io_apic_entries = io_apic_entries ? io_apic_entries : (struct __io_apic_entry *) cur; |
io_apic_entry_cnt++; |
ct_io_apic_entry((struct __io_apic_entry *) cur); |
cur += 8; |
break; |
/* I/O Interrupt Assignment */ |
case 3: |
io_intr_entries = io_intr_entries ? io_intr_entries : (struct __io_intr_entry *) cur; |
io_intr_entry_cnt++; |
ct_io_intr_entry((struct __io_intr_entry *) cur); |
cur += 8; |
break; |
/* Local Interrupt Assignment */ |
case 4: |
l_intr_entries = l_intr_entries ? l_intr_entries : (struct __l_intr_entry *) cur; |
l_intr_entry_cnt++; |
ct_l_intr_entry((struct __l_intr_entry *) cur); |
cur += 8; |
break; |
default: |
/* |
* Something is wrong. Fallback to UP mode. |
*/ |
printf("%s: ct badness\n", __func__); |
return 1; |
} |
} |
/* |
* Process extended entries. |
*/ |
ct_extended_entries(); |
return cnt; |
} |
int configure_via_default(uint8_t n) |
{ |
/* |
* Not yet implemented. |
*/ |
printf("%s: not supported\n", __func__); |
return 1; |
} |
int ct_processor_entry(struct __processor_entry *pr) |
{ |
/* |
* Ignore processors which are not marked enabled. |
*/ |
if ((pr->cpu_flags & (1<<0)) == 0) |
return 0; |
apic_id_mask |= (1<<pr->l_apic_id); |
return 1; |
} |
void ct_bus_entry(struct __bus_entry *bus) |
{ |
#ifdef MPSCT_VERBOSE |
char buf[7]; |
memcpy((void *) buf, (void *) bus->bus_type, 6); |
buf[6] = 0; |
printf("bus%d: %s\n", bus->bus_id, buf); |
#endif |
} |
void ct_io_apic_entry(struct __io_apic_entry *ioa) |
{ |
static int io_apic_count = 0; |
/* this ioapic is marked unusable */ |
if ((ioa->io_apic_flags & 1) == 0) |
return; |
if (io_apic_count++ > 0) { |
/* |
* Multiple IO APIC's are currently not supported. |
*/ |
return; |
} |
io_apic = (uint32_t *)(uintptr_t)ioa->io_apic; |
} |
//#define MPSCT_VERBOSE |
void ct_io_intr_entry(struct __io_intr_entry *iointr) |
{ |
#ifdef MPSCT_VERBOSE |
switch (iointr->intr_type) { |
case 0: printf("INT"); break; |
case 1: printf("NMI"); break; |
case 2: printf("SMI"); break; |
case 3: printf("ExtINT"); break; |
} |
putchar(','); |
switch (iointr->poel&3) { |
case 0: printf("bus-like"); break; |
case 1: printf("active high"); break; |
case 2: printf("reserved"); break; |
case 3: printf("active low"); break; |
} |
putchar(','); |
switch ((iointr->poel>>2)&3) { |
case 0: printf("bus-like"); break; |
case 1: printf("edge-triggered"); break; |
case 2: printf("reserved"); break; |
case 3: printf("level-triggered"); break; |
} |
putchar(','); |
printf("bus%d,irq%d", iointr->src_bus_id, iointr->src_bus_irq); |
putchar(','); |
printf("io_apic%d,pin%d", iointr->dst_io_apic_id, iointr->dst_io_apic_pin); |
putchar('\n'); |
#endif |
} |
void ct_l_intr_entry(struct __l_intr_entry *lintr) |
{ |
#ifdef MPSCT_VERBOSE |
switch (lintr->intr_type) { |
case 0: printf("INT"); break; |
case 1: printf("NMI"); break; |
case 2: printf("SMI"); break; |
case 3: printf("ExtINT"); break; |
} |
putchar(','); |
switch (lintr->poel&3) { |
case 0: printf("bus-like"); break; |
case 1: printf("active high"); break; |
case 2: printf("reserved"); break; |
case 3: printf("active low"); break; |
} |
putchar(','); |
switch ((lintr->poel>>2)&3) { |
case 0: printf("bus-like"); break; |
case 1: printf("edge-triggered"); break; |
case 2: printf("reserved"); break; |
case 3: printf("level-triggered"); break; |
} |
putchar(','); |
printf("bus%d,irq%d", lintr->src_bus_id, lintr->src_bus_irq); |
putchar(','); |
printf("l_apic%d,pin%d", lintr->dst_l_apic_id, lintr->dst_l_apic_pin); |
putchar('\n'); |
#endif |
} |
void ct_extended_entries(void) |
{ |
uint8_t *ext = (uint8_t *) ct + ct->base_table_length; |
uint8_t *cur; |
for (cur = ext; cur < ext + ct->ext_table_length; cur += cur[CT_EXT_ENTRY_LEN]) { |
switch (cur[CT_EXT_ENTRY_TYPE]) { |
default: |
printf("%p: skipping MP Configuration Table extended entry type %d\n", cur, cur[CT_EXT_ENTRY_TYPE]); |
break; |
} |
} |
} |
int mps_irq_to_pin(unsigned int irq) |
{ |
unsigned int i; |
for (i = 0; i < io_intr_entry_cnt; i++) { |
if (io_intr_entries[i].src_bus_irq == irq && io_intr_entries[i].intr_type == 0) |
return io_intr_entries[i].dst_io_apic_pin; |
} |
return -1; |
} |
#endif /* CONFIG_SMP */ |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32xen/src/smp/apic.c |
---|
0,0 → 1,581 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/types.h> |
#include <arch/smp/apic.h> |
#include <arch/smp/ap.h> |
#include <arch/smp/mps.h> |
#include <mm/page.h> |
#include <time/delay.h> |
#include <interrupt.h> |
#include <arch/interrupt.h> |
#include <print.h> |
#include <arch/asm.h> |
#include <arch.h> |
#ifdef CONFIG_SMP |
/* |
* Advanced Programmable Interrupt Controller for SMP systems. |
* Tested on: |
* Bochs 2.0.2 - Bochs 2.2.6 with 2-8 CPUs |
* Simics 2.0.28 - Simics 2.2.19 2-15 CPUs |
* VMware Workstation 5.5 with 2 CPUs |
* QEMU 0.8.0 with 2-15 CPUs |
* ASUS P/I-P65UP5 + ASUS C-P55T2D REV. 1.41 with 2x 200Mhz Pentium CPUs |
* ASUS PCH-DL with 2x 3000Mhz Pentium 4 Xeon (HT) CPUs |
* MSI K7D Master-L with 2x 2100MHz Athlon MP CPUs |
*/ |
/* |
* These variables either stay configured as initilalized, or are changed by |
* the MP configuration code. |
* |
* Pay special attention to the volatile keyword. Without it, gcc -O2 would |
* optimize the code too much and accesses to l_apic and io_apic, that must |
* always be 32-bit, would use byte oriented instructions. |
*/ |
volatile uint32_t *l_apic = (uint32_t *) 0xfee00000; |
volatile uint32_t *io_apic = (uint32_t *) 0xfec00000; |
uint32_t apic_id_mask = 0; |
static int apic_poll_errors(void); |
#ifdef LAPIC_VERBOSE |
static char *delmod_str[] = { |
"Fixed", |
"Lowest Priority", |
"SMI", |
"Reserved", |
"NMI", |
"INIT", |
"STARTUP", |
"ExtInt" |
}; |
static char *destmod_str[] = { |
"Physical", |
"Logical" |
}; |
static char *trigmod_str[] = { |
"Edge", |
"Level" |
}; |
static char *mask_str[] = { |
"Unmasked", |
"Masked" |
}; |
static char *delivs_str[] = { |
"Idle", |
"Send Pending" |
}; |
static char *tm_mode_str[] = { |
"One-shot", |
"Periodic" |
}; |
static char *intpol_str[] = { |
"Polarity High", |
"Polarity Low" |
}; |
#endif /* LAPIC_VERBOSE */ |
static void apic_spurious(int n, istate_t *istate); |
static void l_apic_timer_interrupt(int n, istate_t *istate); |
/** Initialize APIC on BSP. */ |
void apic_init(void) |
{ |
io_apic_id_t idreg; |
unsigned int i; |
exc_register(VECTOR_APIC_SPUR, "apic_spurious", (iroutine) apic_spurious); |
enable_irqs_function = io_apic_enable_irqs; |
disable_irqs_function = io_apic_disable_irqs; |
eoi_function = l_apic_eoi; |
/* |
* Configure interrupt routing. |
* IRQ 0 remains masked as the time signal is generated by l_apic's themselves. |
* Other interrupts will be forwarded to the lowest priority CPU. |
*/ |
io_apic_disable_irqs(0xffff); |
exc_register(VECTOR_CLK, "l_apic_timer", (iroutine) l_apic_timer_interrupt); |
for (i = 0; i < IRQ_COUNT; i++) { |
int pin; |
if ((pin = smp_irq_to_pin(i)) != -1) { |
io_apic_change_ioredtbl(pin, DEST_ALL, IVT_IRQBASE+i, LOPRI); |
} |
} |
/* |
* Ensure that io_apic has unique ID. |
*/ |
idreg.value = io_apic_read(IOAPICID); |
if ((1 << idreg.apic_id) & apic_id_mask) { /* see if IO APIC ID is used already */ |
for (i = 0; i < APIC_ID_COUNT; i++) { |
if (!((1<<i) & apic_id_mask)) { |
idreg.apic_id = i; |
io_apic_write(IOAPICID, idreg.value); |
break; |
} |
} |
} |
/* |
* Configure the BSP's lapic. |
*/ |
l_apic_init(); |
l_apic_debug(); |
} |
/** APIC spurious interrupt handler. |
* |
* @param n Interrupt vector. |
* @param istate Interrupted state. |
*/ |
void apic_spurious(int n, istate_t *istate) |
{ |
#ifdef CONFIG_DEBUG |
printf("cpu%d: APIC spurious interrupt\n", CPU->id); |
#endif |
} |
/** Poll for APIC errors. |
* |
* Examine Error Status Register and report all errors found. |
* |
* @return 0 on error, 1 on success. |
*/ |
int apic_poll_errors(void) |
{ |
esr_t esr; |
esr.value = l_apic[ESR]; |
if (esr.send_checksum_error) |
printf("Send Checksum Error\n"); |
if (esr.receive_checksum_error) |
printf("Receive Checksum Error\n"); |
if (esr.send_accept_error) |
printf("Send Accept Error\n"); |
if (esr.receive_accept_error) |
printf("Receive Accept Error\n"); |
if (esr.send_illegal_vector) |
printf("Send Illegal Vector\n"); |
if (esr.received_illegal_vector) |
printf("Received Illegal Vector\n"); |
if (esr.illegal_register_address) |
printf("Illegal Register Address\n"); |
return !esr.err_bitmap; |
} |
/** Send all CPUs excluding CPU IPI vector. |
* |
* @param vector Interrupt vector to be sent. |
* |
* @return 0 on failure, 1 on success. |
*/ |
int l_apic_broadcast_custom_ipi(uint8_t vector) |
{ |
icr_t icr; |
icr.lo = l_apic[ICRlo]; |
icr.delmod = DELMOD_FIXED; |
icr.destmod = DESTMOD_LOGIC; |
icr.level = LEVEL_ASSERT; |
icr.shorthand = SHORTHAND_ALL_EXCL; |
icr.trigger_mode = TRIGMOD_LEVEL; |
icr.vector = vector; |
l_apic[ICRlo] = icr.lo; |
icr.lo = l_apic[ICRlo]; |
if (icr.delivs == DELIVS_PENDING) { |
#ifdef CONFIG_DEBUG |
printf("IPI is pending.\n"); |
#endif |
} |
return apic_poll_errors(); |
} |
/** Universal Start-up Algorithm for bringing up the AP processors. |
* |
* @param apicid APIC ID of the processor to be brought up. |
* |
* @return 0 on failure, 1 on success. |
*/ |
int l_apic_send_init_ipi(uint8_t apicid) |
{ |
icr_t icr; |
int i; |
/* |
* Read the ICR register in and zero all non-reserved fields. |
*/ |
icr.lo = l_apic[ICRlo]; |
icr.hi = l_apic[ICRhi]; |
icr.delmod = DELMOD_INIT; |
icr.destmod = DESTMOD_PHYS; |
icr.level = LEVEL_ASSERT; |
icr.trigger_mode = TRIGMOD_LEVEL; |
icr.shorthand = SHORTHAND_NONE; |
icr.vector = 0; |
icr.dest = apicid; |
l_apic[ICRhi] = icr.hi; |
l_apic[ICRlo] = icr.lo; |
/* |
* According to MP Specification, 20us should be enough to |
* deliver the IPI. |
*/ |
delay(20); |
if (!apic_poll_errors()) |
return 0; |
icr.lo = l_apic[ICRlo]; |
if (icr.delivs == DELIVS_PENDING) { |
#ifdef CONFIG_DEBUG |
printf("IPI is pending.\n"); |
#endif |
} |
icr.delmod = DELMOD_INIT; |
icr.destmod = DESTMOD_PHYS; |
icr.level = LEVEL_DEASSERT; |
icr.shorthand = SHORTHAND_NONE; |
icr.trigger_mode = TRIGMOD_LEVEL; |
icr.vector = 0; |
l_apic[ICRlo] = icr.lo; |
/* |
* Wait 10ms as MP Specification specifies. |
*/ |
delay(10000); |
if (!is_82489DX_apic(l_apic[LAVR])) { |
/* |
* If this is not 82489DX-based l_apic we must send two STARTUP IPI's. |
*/ |
for (i = 0; i < 2; i++) { |
icr.lo = l_apic[ICRlo]; |
icr.delmod = DELMOD_STARTUP; |
icr.destmod = DESTMOD_PHYS; |
icr.level = LEVEL_ASSERT; |
icr.shorthand = SHORTHAND_NONE; |
icr.trigger_mode = TRIGMOD_LEVEL; |
l_apic[ICRlo] = icr.lo; |
delay(200); |
} |
} |
return apic_poll_errors(); |
} |
/** Initialize Local APIC. */ |
void l_apic_init(void) |
{ |
lvt_error_t error; |
lvt_lint_t lint; |
tpr_t tpr; |
svr_t svr; |
icr_t icr; |
tdcr_t tdcr; |
lvt_tm_t tm; |
ldr_t ldr; |
dfr_t dfr; |
uint32_t t1, t2; |
/* Initialize LVT Error register. */ |
error.value = l_apic[LVT_Err]; |
error.masked = true; |
l_apic[LVT_Err] = error.value; |
/* Initialize LVT LINT0 register. */ |
lint.value = l_apic[LVT_LINT0]; |
lint.masked = true; |
l_apic[LVT_LINT0] = lint.value; |
/* Initialize LVT LINT1 register. */ |
lint.value = l_apic[LVT_LINT1]; |
lint.masked = true; |
l_apic[LVT_LINT1] = lint.value; |
/* Task Priority Register initialization. */ |
tpr.value = l_apic[TPR]; |
tpr.pri_sc = 0; |
tpr.pri = 0; |
l_apic[TPR] = tpr.value; |
/* Spurious-Interrupt Vector Register initialization. */ |
svr.value = l_apic[SVR]; |
svr.vector = VECTOR_APIC_SPUR; |
svr.lapic_enabled = true; |
svr.focus_checking = true; |
l_apic[SVR] = svr.value; |
if (CPU->arch.family >= 6) |
enable_l_apic_in_msr(); |
/* Interrupt Command Register initialization. */ |
icr.lo = l_apic[ICRlo]; |
icr.delmod = DELMOD_INIT; |
icr.destmod = DESTMOD_PHYS; |
icr.level = LEVEL_DEASSERT; |
icr.shorthand = SHORTHAND_ALL_INCL; |
icr.trigger_mode = TRIGMOD_LEVEL; |
l_apic[ICRlo] = icr.lo; |
/* Timer Divide Configuration Register initialization. */ |
tdcr.value = l_apic[TDCR]; |
tdcr.div_value = DIVIDE_1; |
l_apic[TDCR] = tdcr.value; |
/* Program local timer. */ |
tm.value = l_apic[LVT_Tm]; |
tm.vector = VECTOR_CLK; |
tm.mode = TIMER_PERIODIC; |
tm.masked = false; |
l_apic[LVT_Tm] = tm.value; |
/* |
* Measure and configure the timer to generate timer |
* interrupt with period 1s/HZ seconds. |
*/ |
t1 = l_apic[CCRT]; |
l_apic[ICRT] = 0xffffffff; |
while (l_apic[CCRT] == t1) |
; |
t1 = l_apic[CCRT]; |
delay(1000000/HZ); |
t2 = l_apic[CCRT]; |
l_apic[ICRT] = t1-t2; |
/* Program Logical Destination Register. */ |
ldr.value = l_apic[LDR]; |
if (CPU->id < sizeof(CPU->id) * 8) /* size in bits */ |
ldr.id = (1 << CPU->id); |
l_apic[LDR] = ldr.value; |
/* Program Destination Format Register for Flat mode. */ |
dfr.value = l_apic[DFR]; |
dfr.model = MODEL_FLAT; |
l_apic[DFR] = dfr.value; |
} |
/** Local APIC End of Interrupt. */ |
void l_apic_eoi(void) |
{ |
l_apic[EOI] = 0; |
} |
/** Dump content of Local APIC registers. */ |
void l_apic_debug(void) |
{ |
#ifdef LAPIC_VERBOSE |
lvt_tm_t tm; |
lvt_lint_t lint; |
lvt_error_t error; |
printf("LVT on cpu%d, LAPIC ID: %d\n", CPU->id, l_apic_id()); |
tm.value = l_apic[LVT_Tm]; |
printf("LVT Tm: vector=%hhd, %s, %s, %s\n", tm.vector, delivs_str[tm.delivs], mask_str[tm.masked], tm_mode_str[tm.mode]); |
lint.value = l_apic[LVT_LINT0]; |
printf("LVT LINT0: vector=%hhd, %s, %s, %s, irr=%d, %s, %s\n", tm.vector, delmod_str[lint.delmod], delivs_str[lint.delivs], intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode], mask_str[lint.masked]); |
lint.value = l_apic[LVT_LINT1]; |
printf("LVT LINT1: vector=%hhd, %s, %s, %s, irr=%d, %s, %s\n", tm.vector, delmod_str[lint.delmod], delivs_str[lint.delivs], intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode], mask_str[lint.masked]); |
error.value = l_apic[LVT_Err]; |
printf("LVT Err: vector=%hhd, %s, %s\n", error.vector, delivs_str[error.delivs], mask_str[error.masked]); |
#endif |
} |
/** Local APIC Timer Interrupt. |
* |
* @param n Interrupt vector number. |
* @param istate Interrupted state. |
*/ |
void l_apic_timer_interrupt(int n, istate_t *istate) |
{ |
l_apic_eoi(); |
clock(); |
} |
/** Get Local APIC ID. |
* |
* @return Local APIC ID. |
*/ |
uint8_t l_apic_id(void) |
{ |
l_apic_id_t idreg; |
idreg.value = l_apic[L_APIC_ID]; |
return idreg.apic_id; |
} |
/** Read from IO APIC register. |
* |
* @param address IO APIC register address. |
* |
* @return Content of the addressed IO APIC register. |
*/ |
uint32_t io_apic_read(uint8_t address) |
{ |
io_regsel_t regsel; |
regsel.value = io_apic[IOREGSEL]; |
regsel.reg_addr = address; |
io_apic[IOREGSEL] = regsel.value; |
return io_apic[IOWIN]; |
} |
/** Write to IO APIC register. |
* |
* @param address IO APIC register address. |
* @param x Content to be written to the addressed IO APIC register. |
*/ |
void io_apic_write(uint8_t address, uint32_t x) |
{ |
io_regsel_t regsel; |
regsel.value = io_apic[IOREGSEL]; |
regsel.reg_addr = address; |
io_apic[IOREGSEL] = regsel.value; |
io_apic[IOWIN] = x; |
} |
/** Change some attributes of one item in I/O Redirection Table. |
* |
* @param pin IO APIC pin number. |
* @param dest Interrupt destination address. |
* @param v Interrupt vector to trigger. |
* @param flags Flags. |
*/ |
void io_apic_change_ioredtbl(uint8_t pin, uint8_t dest, uint8_t v, int flags) |
{ |
io_redirection_reg_t reg; |
int dlvr = DELMOD_FIXED; |
if (flags & LOPRI) |
dlvr = DELMOD_LOWPRI; |
reg.lo = io_apic_read(IOREDTBL + pin * 2); |
reg.hi = io_apic_read(IOREDTBL + pin * 2 + 1); |
reg.dest = dest; |
reg.destmod = DESTMOD_LOGIC; |
reg.trigger_mode = TRIGMOD_EDGE; |
reg.intpol = POLARITY_HIGH; |
reg.delmod = dlvr; |
reg.intvec = v; |
io_apic_write(IOREDTBL + pin * 2, reg.lo); |
io_apic_write(IOREDTBL + pin * 2 + 1, reg.hi); |
} |
/** Mask IRQs in IO APIC. |
* |
* @param irqmask Bitmask of IRQs to be masked (0 = do not mask, 1 = mask). |
*/ |
void io_apic_disable_irqs(uint16_t irqmask) |
{ |
io_redirection_reg_t reg; |
unsigned int i; |
int pin; |
for (i = 0; i < 16; i++) { |
if (irqmask & (1 << i)) { |
/* |
* Mask the signal input in IO APIC if there is a |
* mapping for the respective IRQ number. |
*/ |
pin = smp_irq_to_pin(i); |
if (pin != -1) { |
reg.lo = io_apic_read(IOREDTBL + pin * 2); |
reg.masked = true; |
io_apic_write(IOREDTBL + pin*2, reg.lo); |
} |
} |
} |
} |
/** Unmask IRQs in IO APIC. |
* |
* @param irqmask Bitmask of IRQs to be unmasked (0 = do not unmask, 1 = unmask). |
*/ |
void io_apic_enable_irqs(uint16_t irqmask) |
{ |
unsigned int i; |
int pin; |
io_redirection_reg_t reg; |
for (i = 0; i < 16; i++) { |
if (irqmask & (1 << i)) { |
/* |
* Unmask the signal input in IO APIC if there is a |
* mapping for the respective IRQ number. |
*/ |
pin = smp_irq_to_pin(i); |
if (pin != -1) { |
reg.lo = io_apic_read(IOREDTBL + pin * 2); |
reg.masked = false; |
io_apic_write(IOREDTBL + pin*2, reg.lo); |
} |
} |
} |
} |
#endif /* CONFIG_SMP */ |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32xen/src/smp/ipi.c |
---|
0,0 → 1,48 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#ifdef CONFIG_SMP |
#include <smp/ipi.h> |
#include <arch/smp/apic.h> |
void ipi_broadcast_arch(int ipi) |
{ |
(void) l_apic_broadcast_custom_ipi((uint8_t) ipi); |
} |
#endif /* CONFIG_SMP */ |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32xen/src/context.S |
---|
0,0 → 1,0 |
link ../../ia32/src/context.S |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/ia32xen/src/mm/tlb.c |
---|
0,0 → 1,75 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_mm |
* @{ |
*/ |
/** @file |
* @ingroup ia32xen_mm |
*/ |
#include <mm/tlb.h> |
#include <arch/mm/asid.h> |
#include <arch/asm.h> |
#include <arch/types.h> |
#include <arch/hypercall.h> |
/** Invalidate all entries in TLB. */ |
void tlb_invalidate_all(void) |
{ |
mmuext_op_t mmu_ext; |
mmu_ext.cmd = MMUEXT_TLB_FLUSH_LOCAL; |
xen_mmuext_op(&mmu_ext, 1, NULL, DOMID_SELF); |
} |
/** Invalidate all entries in TLB that belong to specified address space. |
* |
* @param asid This parameter is ignored as the architecture doesn't support it. |
*/ |
void tlb_invalidate_asid(asid_t asid) |
{ |
tlb_invalidate_all(); |
} |
/** Invalidate TLB entries for specified page range belonging to specified address space. |
* |
* @param asid This parameter is ignored as the architecture doesn't support it. |
* @param page Address of the first page whose entry is to be invalidated. |
* @param cnt Number of entries to invalidate. |
*/ |
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt) |
{ |
unsigned int i; |
for (i = 0; i < cnt; i++) |
invlpg(page + i * PAGE_SIZE); |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32xen/src/mm/frame.c |
---|
0,0 → 1,57 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_mm |
* @{ |
*/ |
/** @file |
* @ingroup ia32xen_mm |
*/ |
#include <mm/frame.h> |
#include <config.h> |
void physmem_print(void) |
{ |
printf("Base Size Reserved\n"); |
printf("---------- ---------- ---------\n"); |
printf("%#10x %#10x %#10x\n", PFN2ADDR(meminfo.start), |
PFN2ADDR(meminfo.size), PFN2ADDR(meminfo.reserved)); |
} |
void frame_arch_init(void) |
{ |
if (config.cpu_active == 1) { |
/* The only memory zone */ |
zone_create(meminfo.start, meminfo.size, meminfo.start + meminfo.reserved, 0); |
frame_mark_unavailable(meminfo.start, meminfo.reserved); |
} |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32xen/src/mm/page.c |
---|
0,0 → 1,86 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_mm |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/mm/page.h> |
#include <genarch/mm/page_pt.h> |
#include <arch/mm/frame.h> |
#include <mm/frame.h> |
#include <mm/page.h> |
#include <mm/as.h> |
#include <arch/types.h> |
#include <align.h> |
#include <config.h> |
#include <func.h> |
#include <arch/interrupt.h> |
#include <arch/asm.h> |
#include <debug.h> |
#include <memstr.h> |
#include <print.h> |
#include <interrupt.h> |
void page_arch_init(void) |
{ |
if (config.cpu_active == 1) { |
page_mapping_operations = &pt_mapping_operations; |
AS_KERNEL->genarch.page_table = (pte_t *) KA2PA(start_info.ptl0); |
} else |
SET_PTL0_ADDRESS_ARCH(AS_KERNEL->genarch.page_table); |
} |
void page_fault(int n, istate_t *istate) |
{ |
uintptr_t page; |
pf_access_t access; |
page = read_cr2(); |
if (istate->error_word & PFERR_CODE_RSVD) |
panic("Reserved bit set in page directory.\n"); |
if (istate->error_word & PFERR_CODE_RW) |
access = PF_ACCESS_WRITE; |
else |
access = PF_ACCESS_READ; |
if (as_page_fault(page, access, istate) == AS_PF_FAULT) { |
fault_if_from_uspace(istate, "Page fault: %#x", page); |
decode_istate(istate); |
printf("page fault address: %#x\n", page); |
panic("page fault\n"); |
} |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32xen/src/mm/as.c |
---|
0,0 → 1,46 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_mm |
* @{ |
*/ |
/** @file |
* @ingroup ia32xen_mm |
*/ |
#include <arch/mm/as.h> |
#include <genarch/mm/page_pt.h> |
/** Architecture dependent address space init. */ |
void as_arch_init(void) |
{ |
as_operations = &as_pt_operations; |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32xen/src/interrupt.c |
---|
0,0 → 1,248 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_interrupt |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/interrupt.h> |
#include <syscall/syscall.h> |
#include <print.h> |
#include <debug.h> |
#include <panic.h> |
#include <func.h> |
#include <cpu.h> |
#include <arch/asm.h> |
#include <mm/tlb.h> |
#include <mm/as.h> |
#include <arch.h> |
#include <symtab.h> |
#include <proc/thread.h> |
#include <proc/task.h> |
#include <synch/spinlock.h> |
#include <arch/ddi/ddi.h> |
#include <ipc/sysipc.h> |
#include <interrupt.h> |
#include <ddi/irq.h> |
/* |
* Interrupt and exception dispatching. |
*/ |
void (* disable_irqs_function)(uint16_t irqmask) = NULL; |
void (* enable_irqs_function)(uint16_t irqmask) = NULL; |
void (* eoi_function)(void) = NULL; |
void decode_istate(istate_t *istate) |
{ |
char *symbol = get_symtab_entry(istate->eip); |
if (!symbol) |
symbol = ""; |
if (CPU) |
printf("----------------EXCEPTION OCCURED (cpu%d)----------------\n", CPU->id); |
else |
printf("----------------EXCEPTION OCCURED----------------\n"); |
printf("%%eip: %#x (%s)\n",istate->eip,symbol); |
printf("ERROR_WORD=%#x\n", istate->error_word); |
printf("%%cs=%#x,flags=%#x\n", istate->cs, istate->eflags); |
printf("%%eax=%#x, %%ecx=%#x, %%edx=%#x, %%esp=%#x\n", istate->eax,istate->ecx,istate->edx,&istate->stack[0]); |
#ifdef CONFIG_DEBUG_ALLREGS |
printf("%%esi=%#x, %%edi=%#x, %%ebp=%#x, %%ebx=%#x\n", istate->esi,istate->edi,istate->ebp,istate->ebx); |
#endif |
printf("stack: %#x, %#x, %#x, %#x\n", istate->stack[0], istate->stack[1], istate->stack[2], istate->stack[3]); |
printf(" %#x, %#x, %#x, %#x\n", istate->stack[4], istate->stack[5], istate->stack[6], istate->stack[7]); |
} |
static void trap_virtual_eoi(void) |
{ |
if (eoi_function) |
eoi_function(); |
else |
panic("no eoi_function\n"); |
} |
static void null_interrupt(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "unserviced interrupt: %d", n); |
decode_istate(istate); |
panic("unserviced interrupt: %d\n", n); |
} |
/** General Protection Fault. */ |
static void gp_fault(int n, istate_t *istate) |
{ |
if (TASK) { |
count_t ver; |
spinlock_lock(&TASK->lock); |
ver = TASK->arch.iomapver; |
spinlock_unlock(&TASK->lock); |
if (CPU->arch.iomapver_copy != ver) { |
/* |
* This fault can be caused by an early access |
* to I/O port because of an out-dated |
* I/O Permission bitmap installed on CPU. |
* Install the fresh copy and restart |
* the instruction. |
*/ |
io_perm_bitmap_install(); |
return; |
} |
fault_if_from_uspace(istate, "general protection fault"); |
} |
decode_istate(istate); |
panic("general protection fault\n"); |
} |
static void ss_fault(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "stack fault"); |
decode_istate(istate); |
panic("stack fault\n"); |
} |
static void simd_fp_exception(int n, istate_t *istate) |
{ |
uint32_t mxcsr; |
asm |
( |
"stmxcsr %0;\n" |
:"=m"(mxcsr) |
); |
fault_if_from_uspace(istate, "SIMD FP exception(19), MXCSR: %#zx", |
(unative_t)mxcsr); |
decode_istate(istate); |
printf("MXCSR: %#zx\n",(unative_t)(mxcsr)); |
panic("SIMD FP exception(19)\n"); |
} |
static void nm_fault(int n, istate_t *istate) |
{ |
#ifdef CONFIG_FPU_LAZY |
scheduler_fpu_lazy_request(); |
#else |
fault_if_from_uspace(istate, "fpu fault"); |
panic("fpu fault"); |
#endif |
} |
#ifdef CONFIG_SMP |
static void tlb_shootdown_ipi(int n, istate_t *istate) |
{ |
trap_virtual_eoi(); |
tlb_shootdown_ipi_recv(); |
} |
#endif |
/** Handler of IRQ exceptions */ |
static void irq_interrupt(int n, istate_t *istate) |
{ |
ASSERT(n >= IVT_IRQBASE); |
int inum = n - IVT_IRQBASE; |
bool ack = false; |
ASSERT(inum < IRQ_COUNT); |
ASSERT((inum != IRQ_PIC_SPUR) && (inum != IRQ_PIC1)); |
irq_t *irq = irq_dispatch_and_lock(inum); |
if (irq) { |
/* |
* The IRQ handler was found. |
*/ |
if (irq->preack) { |
/* Send EOI before processing the interrupt */ |
trap_virtual_eoi(); |
ack = true; |
} |
irq->handler(irq, irq->arg); |
spinlock_unlock(&irq->lock); |
} else { |
/* |
* Spurious interrupt. |
*/ |
#ifdef CONFIG_DEBUG |
printf("cpu%d: spurious interrupt (inum=%d)\n", CPU->id, inum); |
#endif |
} |
if (!ack) |
trap_virtual_eoi(); |
} |
void interrupt_init(void) |
{ |
int i; |
for (i = 0; i < IVT_ITEMS; i++) |
exc_register(i, "null", (iroutine) null_interrupt); |
for (i = 0; i < IRQ_COUNT; i++) { |
if ((i != IRQ_PIC_SPUR) && (i != IRQ_PIC1)) |
exc_register(IVT_IRQBASE + i, "irq", (iroutine) irq_interrupt); |
} |
exc_register(7, "nm_fault", (iroutine) nm_fault); |
exc_register(12, "ss_fault", (iroutine) ss_fault); |
exc_register(13, "gp_fault", (iroutine) gp_fault); |
exc_register(19, "simd_fp", (iroutine) simd_fp_exception); |
#ifdef CONFIG_SMP |
exc_register(VECTOR_TLB_SHOOTDOWN_IPI, "tlb_shootdown", (iroutine) tlb_shootdown_ipi); |
#endif |
} |
void trap_virtual_enable_irqs(uint16_t irqmask) |
{ |
if (enable_irqs_function) |
enable_irqs_function(irqmask); |
else |
panic("no enable_irqs_function\n"); |
} |
void trap_virtual_disable_irqs(uint16_t irqmask) |
{ |
if (disable_irqs_function) |
disable_irqs_function(irqmask); |
else |
panic("no disable_irqs_function\n"); |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32xen/src/boot/boot.S |
---|
0,0 → 1,102 |
# |
# Copyright (c) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
#include <arch/mm/page.h> |
#include <arch/hypercall.h> |
#define ELFNOTE(name, type, desctype, descval) \ |
.section .note.name; \ |
.align 4; \ |
.long 2f - 1f; \ |
.long 4f - 3f; \ |
.long type; \ |
1:.asciz #name; \ |
2:.align 4; \ |
3:desctype descval; \ |
4:.align 4 |
ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz, "HelenOS") |
ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz, RELEASE) |
ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz, "xen-3.0") |
ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE, .long, PA2KA(BOOT_OFFSET)) |
ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET, .long, 0) |
ELFNOTE(Xen, XEN_ELFNOTE_ENTRY, .long, kernel_image_start) |
ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .long, hypercall_page) |
ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .asciz, "auto_translated_physmap|supervisor_mode_kernel") |
ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz, "no") |
ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz, "generic") |
.text |
.code32 |
.align 4 |
.global kernel_image_start |
kernel_image_start: |
# copy start_info (esi initialized by Xen) |
movl $start_info, %edi |
movl $START_INFO_SIZE >> 2, %ecx |
cld |
rep movsb |
# switch to temporal kernel stack |
movl $kernel_stack, %esp |
call arch_pre_main |
call main_bsp # never returns |
cli |
hlt |
kernel_stack_bottom: |
.space TEMP_STACK_SIZE |
kernel_stack: |
.section K_TEXT_START, "aw", @progbits |
.global hypercall_page |
.org 0 |
hypercall_page: |
.space PAGE_SIZE |
.global shared_info |
.org 0x1000 |
shared_info: |
.space PAGE_SIZE |
.global console_page |
.org 0x2000 |
console_page: |
.space PAGE_SIZE |
# Xen 3.0.3 ELF loader is somehow buggy |
# thus this workaround |
.global dummy_fill |
dummy_fill: |
.space (1024 * 1024) |
/branches/arm/kernel/arch/ia32xen/src/proc/scheduler.c |
---|
0,0 → 1,81 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_proc |
* @{ |
*/ |
/** @file |
*/ |
#include <proc/scheduler.h> |
#include <cpu.h> |
#include <proc/task.h> |
#include <proc/thread.h> |
#include <arch.h> |
#include <arch/context.h> /* SP_DELTA */ |
#include <arch/debugger.h> |
#include <arch/pm.h> |
#include <arch/asm.h> |
#include <arch/ddi/ddi.h> |
/** Perform ia32 specific tasks needed before the new task is run. |
* |
* Interrupts are disabled. |
*/ |
void before_task_runs_arch(void) |
{ |
// io_perm_bitmap_install(); |
} |
/** Perform ia32 specific tasks needed before the new thread is scheduled. |
* |
* THREAD is locked and interrupts are disabled. |
*/ |
void before_thread_runs_arch(void) |
{ |
CPU->arch.tss->esp0 = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE-SP_DELTA]; |
CPU->arch.tss->ss0 = selector(KDATA_DES); |
/* Set up TLS in GS register */ |
// set_tls_desc(THREAD->arch.tls); |
#ifdef CONFIG_DEBUG_AS_WATCHPOINT |
/* Set watchpoint on AS to ensure that nobody sets it to zero */ |
if (CPU->id < BKPOINTS_MAX) |
breakpoint_add(&((the_t *) THREAD->kstack)->as, |
BKPOINT_WRITE | BKPOINT_CHECK_ZERO, |
CPU->id); |
#endif |
} |
void after_thread_ran_arch(void) |
{ |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32xen/src/proc/task.c |
---|
0,0 → 1,61 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_proc |
* @{ |
*/ |
/** @file |
*/ |
#include <proc/task.h> |
#include <arch/types.h> |
#include <adt/bitmap.h> |
#include <mm/slab.h> |
/** Perform ia32 specific task initialization. |
* |
* @param t Task to be initialized. |
*/ |
void task_create_arch(task_t *t) |
{ |
t->arch.iomapver = 0; |
bitmap_initialize(&t->arch.iomap, NULL, 0); |
} |
/** Perform ia32 specific task destruction. |
* |
* @param t Task to be initialized. |
*/ |
void task_destroy_arch(task_t *t) |
{ |
if (t->arch.iomap.map) |
free(t->arch.iomap.map); |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32xen/src/proc/thread.c |
---|
0,0 → 1,47 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_proc |
* @{ |
*/ |
/** @file |
*/ |
#include <proc/thread.h> |
/** Perform ia32xen specific thread initialization. |
* |
* @param t Thread to be initialized. |
*/ |
void thread_create_arch(thread_t *t) |
{ |
t->arch.tls = 0; |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32xen/src/drivers/xconsole.c |
---|
0,0 → 1,83 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** |
* @file |
* @brief ia32xen console driver. |
*/ |
#include <arch/drivers/xconsole.h> |
#include <putchar.h> |
#include <console/chardev.h> |
#include <console/console.h> |
#include <arch/hypercall.h> |
#define MASK_INDEX(index, ring) ((index) & (sizeof(ring) - 1)) |
static void xen_putchar(chardev_t *d, const char ch); |
chardev_t xen_console; |
static chardev_operations_t xen_ops = { |
.write = xen_putchar |
}; |
void xen_console_init(void) |
{ |
chardev_initialize("xen_out", &xen_console, &xen_ops); |
stdout = &xen_console; |
} |
void xen_putchar(chardev_t *d, const char ch) |
{ |
if (start_info.console.domU.evtchn != 0) { |
uint32_t cons = console_page.out_cons; |
uint32_t prod = console_page.out_prod; |
memory_barrier(); |
if ((prod - cons) > sizeof(console_page.out)) |
return; |
if (ch == '\n') |
console_page.out[MASK_INDEX(prod++, console_page.out)] = '\r'; |
console_page.out[MASK_INDEX(prod++, console_page.out)] = ch; |
write_barrier(); |
console_page.out_prod = prod; |
xen_notify_remote(start_info.console.domU.evtchn); |
} else |
xen_console_io(CONSOLE_IO_WRITE, 1, &ch); |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32xen/src/fpu_context.c |
---|
0,0 → 1,0 |
link ../../ia32/src/fpu_context.c |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/ia32xen/src/debug |
---|
0,0 → 1,0 |
link ../../ia32/src/debug |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/ia32xen/src/cpu |
---|
0,0 → 1,0 |
link ../../ia32/src/cpu |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/ia32xen/src/bios |
---|
0,0 → 1,0 |
link ../../ia32/src/bios |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/ia32xen/src/delay.s |
---|
0,0 → 1,0 |
link ../../ia32/src/delay.s |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/ia32xen/src/ddi |
---|
0,0 → 1,0 |
link ../../ia32/src/ddi |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/ia32xen/src/debugger.c |
---|
0,0 → 1,0 |
link ../../ia32/src/debugger.c |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/ia32xen/src/atomic.S |
---|
0,0 → 1,0 |
link ../../ia32/src/atomic.S |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/ia32xen/include/mm/page.h |
---|
0,0 → 1,257 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_mm |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia32xen_PAGE_H_ |
#define KERN_ia32xen_PAGE_H_ |
#include <arch/mm/frame.h> |
#define PAGE_WIDTH FRAME_WIDTH |
#define PAGE_SIZE FRAME_SIZE |
#ifdef KERNEL |
#ifndef __ASM__ |
# define KA2PA(x) (((uintptr_t) (x)) - 0x80000000) |
# define PA2KA(x) (((uintptr_t) (x)) + 0x80000000) |
#else |
# define KA2PA(x) ((x) - 0x80000000) |
# define PA2KA(x) ((x) + 0x80000000) |
#endif |
/* |
* Implementation of generic 4-level page table interface. |
* IA-32 has 2-level page tables, so PTL1 and PTL2 are left out. |
*/ |
/* Number of entries in each level. */ |
#define PTL0_ENTRIES_ARCH 1024 |
#define PTL1_ENTRIES_ARCH 0 |
#define PTL2_ENTRIES_ARCH 0 |
#define PTL3_ENTRIES_ARCH 1024 |
/* Page table size for each level. */ |
#define PTL0_SIZE_ARCH ONE_FRAME |
#define PTL1_SIZE_ARCH 0 |
#define PTL2_SIZE_ARCH 0 |
#define PTL3_SIZE_ARCH ONE_FRAME |
/* Macros calculating indices into page tables in each level. */ |
#define PTL0_INDEX_ARCH(vaddr) (((vaddr) >> 22) & 0x3ff) |
#define PTL1_INDEX_ARCH(vaddr) 0 |
#define PTL2_INDEX_ARCH(vaddr) 0 |
#define PTL3_INDEX_ARCH(vaddr) (((vaddr) >> 12) & 0x3ff) |
/* Get PTE address accessors for each level. */ |
#define GET_PTL1_ADDRESS_ARCH(ptl0, i) \ |
((pte_t *) MA2PA((((pte_t *) (ptl0))[(i)].frame_address) << 12)) |
#define GET_PTL2_ADDRESS_ARCH(ptl1, i) \ |
(ptl1) |
#define GET_PTL3_ADDRESS_ARCH(ptl2, i) \ |
(ptl2) |
#define GET_FRAME_ADDRESS_ARCH(ptl3, i) \ |
((uintptr_t) MA2PA((((pte_t *) (ptl3))[(i)].frame_address) << 12)) |
/* Set PTE address accessors for each level. */ |
#define SET_PTL0_ADDRESS_ARCH(ptl0) \ |
{ \ |
mmuext_op_t mmu_ext; \ |
\ |
mmu_ext.cmd = MMUEXT_NEW_BASEPTR; \ |
mmu_ext.mfn = ADDR2PFN(PA2MA(ptl0)); \ |
ASSERT(xen_mmuext_op(&mmu_ext, 1, NULL, DOMID_SELF) == 0); \ |
} |
#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) \ |
{ \ |
mmuext_op_t mmu_ext; \ |
\ |
mmu_ext.cmd = MMUEXT_PIN_L1_TABLE; \ |
mmu_ext.mfn = ADDR2PFN(PA2MA(a)); \ |
ASSERT(xen_mmuext_op(&mmu_ext, 1, NULL, DOMID_SELF) == 0); \ |
\ |
mmu_update_t update; \ |
\ |
update.ptr = PA2MA(KA2PA(&((pte_t *) (ptl0))[(i)])); \ |
update.val = PA2MA(a); \ |
ASSERT(xen_mmu_update(&update, 1, NULL, DOMID_SELF) == 0); \ |
} |
#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a) |
#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a) |
#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) \ |
{ \ |
mmu_update_t update; \ |
\ |
update.ptr = PA2MA(KA2PA(&((pte_t *) (ptl3))[(i)])); \ |
update.val = PA2MA(a); \ |
ASSERT(xen_mmu_update(&update, 1, NULL, DOMID_SELF) == 0); \ |
} |
/* Get PTE flags accessors for each level. */ |
#define GET_PTL1_FLAGS_ARCH(ptl0, i) \ |
get_pt_flags((pte_t *) (ptl0), (index_t) (i)) |
#define GET_PTL2_FLAGS_ARCH(ptl1, i) \ |
PAGE_PRESENT |
#define GET_PTL3_FLAGS_ARCH(ptl2, i) \ |
PAGE_PRESENT |
#define GET_FRAME_FLAGS_ARCH(ptl3, i) \ |
get_pt_flags((pte_t *) (ptl3), (index_t) (i)) |
/* Set PTE flags accessors for each level. */ |
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \ |
set_pt_flags((pte_t *) (ptl0), (index_t) (i), (x)) |
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x) |
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x) |
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \ |
set_pt_flags((pte_t *) (ptl3), (index_t) (i), (x)) |
/* Query macros for the last level. */ |
#define PTE_VALID_ARCH(p) \ |
(*((uint32_t *) (p)) != 0) |
#define PTE_PRESENT_ARCH(p) \ |
((p)->present != 0) |
#define PTE_GET_FRAME_ARCH(p) \ |
((p)->frame_address << FRAME_WIDTH) |
#define PTE_WRITABLE_ARCH(p) \ |
((p)->writeable != 0) |
#define PTE_EXECUTABLE_ARCH(p) \ |
1 |
#ifndef __ASM__ |
#include <mm/mm.h> |
#include <arch/hypercall.h> |
#include <arch/interrupt.h> |
/* Page fault error codes. */ |
/** When bit on this position is 0, the page fault was caused by a not-present |
* page. |
*/ |
#define PFERR_CODE_P (1 << 0) |
/** When bit on this position is 1, the page fault was caused by a write. */ |
#define PFERR_CODE_RW (1 << 1) |
/** When bit on this position is 1, the page fault was caused in user mode. */ |
#define PFERR_CODE_US (1 << 2) |
/** When bit on this position is 1, a reserved bit was set in page directory. */ |
#define PFERR_CODE_RSVD (1 << 3) |
typedef struct { |
uint64_t ptr; /**< Machine address of PTE */ |
union { /**< New contents of PTE */ |
uint64_t val; |
pte_t pte; |
}; |
} mmu_update_t; |
typedef struct { |
unsigned int cmd; |
union { |
unsigned long mfn; |
unsigned long linear_addr; |
}; |
union { |
unsigned int nr_ents; |
void *vcpumask; |
}; |
} mmuext_op_t; |
static inline int xen_update_va_mapping(const void *va, const pte_t pte, |
const unsigned int flags) |
{ |
return hypercall4(XEN_UPDATE_VA_MAPPING, va, pte, 0, flags); |
} |
static inline int xen_mmu_update(const mmu_update_t *req, |
const unsigned int count, unsigned int *success_count, domid_t domid) |
{ |
return hypercall4(XEN_MMU_UPDATE, req, count, success_count, domid); |
} |
static inline int xen_mmuext_op(const mmuext_op_t *op, const unsigned int count, |
unsigned int *success_count, domid_t domid) |
{ |
return hypercall4(XEN_MMUEXT_OP, op, count, success_count, domid); |
} |
static inline int get_pt_flags(pte_t *pt, index_t i) |
{ |
pte_t *p = &pt[i]; |
return ((!p->page_cache_disable) << PAGE_CACHEABLE_SHIFT | |
(!p->present) << PAGE_PRESENT_SHIFT | |
p->uaccessible << PAGE_USER_SHIFT | |
1 << PAGE_READ_SHIFT | |
p->writeable << PAGE_WRITE_SHIFT | |
1 << PAGE_EXEC_SHIFT | |
p->global << PAGE_GLOBAL_SHIFT); |
} |
static inline void set_pt_flags(pte_t *pt, index_t i, int flags) |
{ |
pte_t p = pt[i]; |
p.page_cache_disable = !(flags & PAGE_CACHEABLE); |
p.present = !(flags & PAGE_NOT_PRESENT); |
p.uaccessible = (flags & PAGE_USER) != 0; |
p.writeable = (flags & PAGE_WRITE) != 0; |
p.global = (flags & PAGE_GLOBAL) != 0; |
/* |
* Ensure that there is at least one bit set even if the present bit is cleared. |
*/ |
p.soft_valid = true; |
mmu_update_t update; |
update.ptr = PA2MA(KA2PA(&(pt[i]))); |
update.pte = p; |
xen_mmu_update(&update, 1, NULL, DOMID_SELF); |
} |
extern void page_arch_init(void); |
extern void page_fault(int n, istate_t *istate); |
#endif /* __ASM__ */ |
#endif /* KERNEL */ |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32xen/include/mm/frame.h |
---|
0,0 → 1,57 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_mm |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia32xen_FRAME_H_ |
#define KERN_ia32xen_FRAME_H_ |
#define FRAME_WIDTH 12 /* 4K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#ifdef KERNEL |
#ifndef __ASM__ |
#define PA2MA(x) ((start_info.pm_map[((uintptr_t) (x)) >> 12] << 12) + (((uintptr_t) (x)) & 0xfff)) |
#define MA2PA(x) ((mp_map[((uintptr_t) (x)) >> 12] << 12) + (((uintptr_t) (x)) & 0xfff)) |
extern void frame_arch_init(void); |
extern void physmem_print(void); |
#endif /* __ASM__ */ |
#endif /* KERNEL */ |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32xen/include/mm/as.h |
---|
0,0 → 1,64 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_mm |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia32xen_AS_H_ |
#define KERN_ia32xen_AS_H_ |
#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH 0 |
#define KERNEL_ADDRESS_SPACE_START_ARCH ((unsigned long) 0x80000000) |
#define KERNEL_ADDRESS_SPACE_END_ARCH ((unsigned long) 0xffffffff) |
#define USER_ADDRESS_SPACE_START_ARCH ((unsigned long) 0x00000000) |
#define USER_ADDRESS_SPACE_END_ARCH ((unsigned long) 0x7fffffff) |
#define USTACK_ADDRESS_ARCH (USER_ADDRESS_SPACE_END_ARCH-(PAGE_SIZE-1)) |
typedef struct { |
} as_arch_t; |
#include <genarch/mm/as_pt.h> |
#define as_constructor_arch(as, flags) (as != as) |
#define as_destructor_arch(as) (as != as) |
#define as_create_arch(as, flags) (as != as) |
#define as_install_arch(as) |
#define as_deinstall_arch(as) |
#define as_invalidate_translation_cache(as, page, cnt) |
extern void as_arch_init(void); |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32xen/include/mm/asid.h |
---|
0,0 → 1,55 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_mm |
* @{ |
*/ |
/** @file |
* @ingroup ia32xen_mm |
*/ |
/* |
* ia32xen has no hardware support for address space identifiers. |
* This file is provided to do nop-implementation of mm/asid.h |
* interface. |
*/ |
#ifndef KERN_ia32xen_ASID_H_ |
#define KERN_ia32xen_ASID_H_ |
typedef int asid_t; |
#define ASID_MAX_ARCH 3 |
#define asid_get() (ASID_START+1) |
#define asid_put(asid) |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32xen/include/mm/tlb.h |
---|
0,0 → 1,44 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_mm |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia32xen_TLB_H_ |
#define KERN_ia32xen_TLB_H_ |
#define tlb_arch_init() |
#define tlb_print() |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32xen/include/types.h |
---|
0,0 → 1,83 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia32xen_TYPES_H_ |
#define KERN_ia32xen_TYPES_H_ |
#define NULL 0 |
#define false 0 |
#define true 1 |
typedef signed char int8_t; |
typedef signed short int16_t; |
typedef signed long int32_t; |
typedef signed long long int64_t; |
typedef unsigned char uint8_t; |
typedef unsigned short uint16_t; |
typedef unsigned long uint32_t; |
typedef unsigned long long uint64_t; |
typedef uint32_t size_t; |
typedef uint32_t count_t; |
typedef uint32_t index_t; |
typedef uint32_t uintptr_t; |
typedef uint32_t pfn_t; |
typedef uint8_t ipl_t; |
typedef uint32_t unative_t; |
typedef int32_t native_t; |
/** Page Table Entry. */ |
typedef struct { |
unsigned present : 1; |
unsigned writeable : 1; |
unsigned uaccessible : 1; |
unsigned page_write_through : 1; |
unsigned page_cache_disable : 1; |
unsigned accessed : 1; |
unsigned dirty : 1; |
unsigned pat : 1; |
unsigned global : 1; |
unsigned soft_valid : 1; /**< Valid content even if the present bit is not set. */ |
unsigned avl : 2; |
unsigned frame_address : 20; |
} __attribute__ ((packed)) pte_t; |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32xen/include/context_offset.h |
---|
0,0 → 1,0 |
link ../../ia32/include/context_offset.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/ia32xen/include/pm.h |
---|
0,0 → 1,159 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia32xen_PM_H_ |
#define KERN_ia32xen_PM_H_ |
#define IDT_ITEMS 64 |
#define GDT_ITEMS 7 |
#define NULL_DES 0 |
#define KTEXT_DES 1 |
#define KDATA_DES 2 |
#define UTEXT_DES 3 |
#define UDATA_DES 4 |
#define TSS_DES 5 |
#define TLS_DES 6 /* Pointer to Thread-Local-Storage data */ |
#define selector(des) ((des) << 3) |
#define PL_KERNEL 1 |
#define PL_USER 3 |
#define AR_PRESENT (1<<7) |
#define AR_DATA (2<<3) |
#define AR_CODE (3<<3) |
#define AR_WRITABLE (1<<1) |
#define AR_INTERRUPT (0xe) |
#define AR_TSS (0x9) |
#define DPL_KERNEL (PL_KERNEL<<5) |
#define DPL_USER (PL_USER<<5) |
#define TSS_BASIC_SIZE 104 |
#define TSS_IOMAP_SIZE (16*1024+1) /* 16K for bitmap + 1 terminating byte for convenience */ |
#define IO_PORTS (64*1024) |
#ifndef __ASM__ |
#include <arch/types.h> |
#include <arch/context.h> |
struct ptr_16_32 { |
uint16_t limit; |
uint32_t base; |
} __attribute__ ((packed)); |
typedef struct ptr_16_32 ptr_16_32_t; |
struct descriptor { |
unsigned limit_0_15: 16; |
unsigned base_0_15: 16; |
unsigned base_16_23: 8; |
unsigned access: 8; |
unsigned limit_16_19: 4; |
unsigned available: 1; |
unsigned unused: 1; |
unsigned special: 1; |
unsigned granularity : 1; |
unsigned base_24_31: 8; |
} __attribute__ ((packed)); |
typedef struct descriptor descriptor_t; |
struct tss { |
uint16_t link; |
unsigned : 16; |
uint32_t esp0; |
uint16_t ss0; |
unsigned : 16; |
uint32_t esp1; |
uint16_t ss1; |
unsigned : 16; |
uint32_t esp2; |
uint16_t ss2; |
unsigned : 16; |
uint32_t cr3; |
uint32_t eip; |
uint32_t eflags; |
uint32_t eax; |
uint32_t ecx; |
uint32_t edx; |
uint32_t ebx; |
uint32_t esp; |
uint32_t ebp; |
uint32_t esi; |
uint32_t edi; |
uint16_t es; |
unsigned : 16; |
uint16_t cs; |
unsigned : 16; |
uint16_t ss; |
unsigned : 16; |
uint16_t ds; |
unsigned : 16; |
uint16_t fs; |
unsigned : 16; |
uint16_t gs; |
unsigned : 16; |
uint16_t ldtr; |
unsigned : 16; |
unsigned : 16; |
uint16_t iomap_base; |
uint8_t iomap[TSS_IOMAP_SIZE]; |
} __attribute__ ((packed)); |
typedef struct tss tss_t; |
extern ptr_16_32_t gdtr; |
extern ptr_16_32_t bootstrap_gdtr; |
extern ptr_16_32_t protected_ap_gdtr; |
extern struct tss *tss_p; |
extern descriptor_t gdt[]; |
extern void pm_init(void); |
extern void gdt_setbase(descriptor_t *d, uintptr_t base); |
extern void gdt_setlimit(descriptor_t *d, uint32_t limit); |
extern void traps_init(void); |
extern void tss_initialize(tss_t *t); |
extern void set_tls_desc(uintptr_t tls); |
#endif /* __ASM__ */ |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32xen/include/hypercall.h |
---|
0,0 → 1,381 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#ifndef KERN_ia32xen_HYPERCALL_H_ |
#define KERN_ia32xen_HYPERCALL_H_ |
#ifndef __ASM__ |
# include <arch/types.h> |
# include <macros.h> |
#endif |
#define GUEST_CMDLINE 1024 |
#define VIRT_CPUS 32 |
#define START_INFO_SIZE 1104 |
#define BOOT_OFFSET 0x0000 |
#define TEMP_STACK_SIZE 0x1000 |
#define XEN_VIRT_START 0xFC000000 |
#define XEN_CS 0xe019 |
#define XEN_ELFNOTE_INFO 0 |
#define XEN_ELFNOTE_ENTRY 1 |
#define XEN_ELFNOTE_HYPERCALL_PAGE 2 |
#define XEN_ELFNOTE_VIRT_BASE 3 |
#define XEN_ELFNOTE_PADDR_OFFSET 4 |
#define XEN_ELFNOTE_XEN_VERSION 5 |
#define XEN_ELFNOTE_GUEST_OS 6 |
#define XEN_ELFNOTE_GUEST_VERSION 7 |
#define XEN_ELFNOTE_LOADER 8 |
#define XEN_ELFNOTE_PAE_MODE 9 |
#define XEN_ELFNOTE_FEATURES 10 |
#define XEN_ELFNOTE_BSD_SYMTAB 11 |
#define mp_map ((pfn_t *) XEN_VIRT_START) |
#define SIF_PRIVILEGED (1 << 0) /**< Privileged domain */ |
#define SIF_INITDOMAIN (1 << 1) /**< Iinitial control domain */ |
#define XEN_CONSOLE_VGA 0x03 |
#define XEN_CONSOLE_VESA 0x23 |
#define XEN_SET_TRAP_TABLE 0 |
#define XEN_MMU_UPDATE 1 |
#define XEN_SET_CALLBACKS 4 |
#define XEN_UPDATE_VA_MAPPING 14 |
#define XEN_EVENT_CHANNEL_OP 16 |
#define XEN_VERSION 17 |
#define XEN_CONSOLE_IO 18 |
#define XEN_MMUEXT_OP 26 |
/* |
* Commands for XEN_CONSOLE_IO |
*/ |
#define CONSOLE_IO_WRITE 0 |
#define CONSOLE_IO_READ 1 |
#define MMUEXT_PIN_L1_TABLE 0 |
#define MMUEXT_PIN_L2_TABLE 1 |
#define MMUEXT_PIN_L3_TABLE 2 |
#define MMUEXT_PIN_L4_TABLE 3 |
#define MMUEXT_UNPIN_TABLE 4 |
#define MMUEXT_NEW_BASEPTR 5 |
#define MMUEXT_TLB_FLUSH_LOCAL 6 |
#define MMUEXT_INVLPG_LOCAL 7 |
#define MMUEXT_TLB_FLUSH_MULTI 8 |
#define MMUEXT_INVLPG_MULTI 9 |
#define MMUEXT_TLB_FLUSH_ALL 10 |
#define MMUEXT_INVLPG_ALL 11 |
#define MMUEXT_FLUSH_CACHE 12 |
#define MMUEXT_SET_LDT 13 |
#define MMUEXT_NEW_USER_BASEPTR 15 |
#define EVTCHNOP_SEND 4 |
#define UVMF_NONE 0 /**< No flushing at all */ |
#define UVMF_TLB_FLUSH 1 /**< Flush entire TLB(s) */ |
#define UVMF_INVLPG 2 /**< Flush only one entry */ |
#define UVMF_FLUSHTYPE_MASK 3 |
#define UVMF_MULTI 0 /**< Flush subset of TLBs */ |
#define UVMF_LOCAL 0 /**< Flush local TLB */ |
#define UVMF_ALL (1 << 2) /**< Flush all TLBs */ |
#define DOMID_SELF (0x7FF0U) |
#define DOMID_IO (0x7FF1U) |
#ifndef __ASM__ |
typedef uint16_t domid_t; |
typedef uint32_t evtchn_t; |
typedef struct { |
uint32_t version; |
uint32_t pad0; |
uint64_t tsc_timestamp; /**< TSC at last update of time vals */ |
uint64_t system_time; /**< Time, in nanosecs, since boot */ |
uint32_t tsc_to_system_mul; |
int8_t tsc_shift; |
int8_t pad1[3]; |
} vcpu_time_info_t; |
typedef struct { |
uint32_t cr2; |
uint32_t pad[5]; |
} arch_vcpu_info_t; |
typedef struct arch_shared_info { |
pfn_t max_pfn; /**< max pfn that appears in table */ |
uint32_t pfn_to_mfn_frame_list_list; |
uint32_t nmi_reason; |
} arch_shared_info_t; |
typedef struct { |
uint8_t evtchn_upcall_pending; |
ipl_t evtchn_upcall_mask; |
evtchn_t evtchn_pending_sel; |
arch_vcpu_info_t arch; |
vcpu_time_info_t time; |
} vcpu_info_t; |
typedef struct { |
vcpu_info_t vcpu_info[VIRT_CPUS]; |
evtchn_t evtchn_pending[32]; |
evtchn_t evtchn_mask[32]; |
uint32_t wc_version; /**< Version counter */ |
uint32_t wc_sec; /**< Secs 00:00:00 UTC, Jan 1, 1970 */ |
uint32_t wc_nsec; /**< Nsecs 00:00:00 UTC, Jan 1, 1970 */ |
arch_shared_info_t arch; |
} shared_info_t; |
typedef struct { |
int8_t magic[32]; /**< "xen-<version>-<platform>" */ |
uint32_t frames; /**< Available frames */ |
shared_info_t *shared_info; /**< Shared info structure (machine address) */ |
uint32_t flags; /**< SIF_xxx flags */ |
pfn_t store_mfn; /**< Shared page (machine page) */ |
evtchn_t store_evtchn; /**< Event channel for store communication */ |
union { |
struct { |
pfn_t mfn; /**< Console page (machine page) */ |
evtchn_t evtchn; /**< Event channel for console messages */ |
} domU; |
struct { |
uint32_t info_off; /**< Offset of console_info struct */ |
uint32_t info_size; /**< Size of console_info struct from start */ |
} dom0; |
} console; |
pte_t *ptl0; /**< Boot PTL0 (kernel address) */ |
uint32_t pt_frames; /**< Number of bootstrap page table frames */ |
pfn_t *pm_map; /**< Physical->machine frame map (kernel address) */ |
void *mod_start; /**< Modules start (kernel address) */ |
uint32_t mod_len; /**< Modules size (bytes) */ |
int8_t cmd_line[GUEST_CMDLINE]; |
} start_info_t; |
typedef struct { |
uint8_t video_type; |
union { |
struct { |
uint16_t font_height; |
uint16_t cursor_x; |
uint16_t cursor_y; |
uint16_t rows; |
uint16_t columns; |
} vga; |
struct { |
uint16_t width; |
uint16_t height; |
uint16_t bytes_per_line; |
uint16_t bits_per_pixel; |
uint32_t lfb_base; |
uint32_t lfb_size; |
uint8_t red_pos; |
uint8_t red_size; |
uint8_t green_pos; |
uint8_t green_size; |
uint8_t blue_pos; |
uint8_t blue_size; |
uint8_t rsvd_pos; |
uint8_t rsvd_size; |
} vesa_lfb; |
} info; |
} console_info_t; |
typedef struct { |
pfn_t start; |
pfn_t size; |
pfn_t reserved; |
} memzone_t; |
extern start_info_t start_info; |
extern shared_info_t shared_info; |
extern memzone_t meminfo; |
typedef struct { |
uint8_t vector; /**< Exception vector */ |
uint8_t flags; /**< 0-3: privilege level; 4: clear event enable */ |
uint16_t cs; /**< Code selector */ |
void *address; /**< Code offset */ |
} trap_info_t; |
typedef struct { |
evtchn_t port; |
} evtchn_send_t; |
typedef struct { |
uint32_t cmd; |
union { |
evtchn_send_t send; |
}; |
} evtchn_op_t; |
#define force_evtchn_callback() ((void) xen_version(0, 0)) |
#define hypercall0(id) \ |
({ \ |
unative_t ret; \ |
asm volatile ( \ |
"call hypercall_page + (" STRING(id) " * 32)\n" \ |
: "=a" (ret) \ |
: \ |
: "memory" \ |
); \ |
ret; \ |
}) |
#define hypercall1(id, p1) \ |
({ \ |
unative_t ret, __ign1; \ |
asm volatile ( \ |
"call hypercall_page + (" STRING(id) " * 32)\n" \ |
: "=a" (ret), \ |
"=b" (__ign1) \ |
: "1" (p1) \ |
: "memory" \ |
); \ |
ret; \ |
}) |
#define hypercall2(id, p1, p2) \ |
({ \ |
unative_t ret, __ign1, __ign2; \ |
asm volatile ( \ |
"call hypercall_page + (" STRING(id) " * 32)\n" \ |
: "=a" (ret), \ |
"=b" (__ign1), \ |
"=c" (__ign2) \ |
: "1" (p1), \ |
"2" (p2) \ |
: "memory" \ |
); \ |
ret; \ |
}) |
#define hypercall3(id, p1, p2, p3) \ |
({ \ |
unative_t ret, __ign1, __ign2, __ign3; \ |
asm volatile ( \ |
"call hypercall_page + (" STRING(id) " * 32)\n" \ |
: "=a" (ret), \ |
"=b" (__ign1), \ |
"=c" (__ign2), \ |
"=d" (__ign3) \ |
: "1" (p1), \ |
"2" (p2), \ |
"3" (p3) \ |
: "memory" \ |
); \ |
ret; \ |
}) |
#define hypercall4(id, p1, p2, p3, p4) \ |
({ \ |
unative_t ret, __ign1, __ign2, __ign3, __ign4; \ |
asm volatile ( \ |
"call hypercall_page + (" STRING(id) " * 32)\n" \ |
: "=a" (ret), \ |
"=b" (__ign1), \ |
"=c" (__ign2), \ |
"=d" (__ign3), \ |
"=S" (__ign4) \ |
: "1" (p1), \ |
"2" (p2), \ |
"3" (p3), \ |
"4" (p4) \ |
: "memory" \ |
); \ |
ret; \ |
}) |
#define hypercall5(id, p1, p2, p3, p4, p5) \ |
({ \ |
unative_t ret, __ign1, __ign2, __ign3, __ign4, __ign5; \ |
asm volatile ( \ |
"call hypercall_page + (" STRING(id) " * 32)\n" \ |
: "=a" (ret), \ |
"=b" (__ign1), \ |
"=c" (__ign2), \ |
"=d" (__ign3), \ |
"=S" (__ign4), \ |
"=D" (__ign5) \ |
: "1" (p1), \ |
"2" (p2), \ |
"3" (p3), \ |
"4" (p4), \ |
"5" (p5) \ |
: "memory" \ |
); \ |
ret; \ |
}) |
static inline int xen_console_io(const unsigned int cmd, const unsigned int count, const char *str) |
{ |
return hypercall3(XEN_CONSOLE_IO, cmd, count, str); |
} |
static inline int xen_set_callbacks(const unsigned int event_selector, const void *event_address, const unsigned int failsafe_selector, void *failsafe_address) |
{ |
return hypercall4(XEN_SET_CALLBACKS, event_selector, event_address, failsafe_selector, failsafe_address); |
} |
static inline int xen_set_trap_table(const trap_info_t *table) |
{ |
return hypercall1(XEN_SET_TRAP_TABLE, table); |
} |
static inline int xen_version(const unsigned int cmd, const void *arg) |
{ |
return hypercall2(XEN_VERSION, cmd, arg); |
} |
static inline int xen_notify_remote(evtchn_t channel) |
{ |
evtchn_op_t op; |
op.cmd = EVTCHNOP_SEND; |
op.send.port = channel; |
return hypercall1(XEN_EVENT_CHANNEL_OP, &op); |
} |
#endif |
#endif |
/branches/arm/kernel/arch/ia32xen/include/asm.h |
---|
0,0 → 1,272 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* Copyright (c) 2005 Sergey Bondari |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia32xen_ASM_H_ |
#define KERN_ia32xen_ASM_H_ |
#include <arch/pm.h> |
#include <arch/types.h> |
#include <arch/barrier.h> |
#include <config.h> |
extern void enable_l_apic_in_msr(void); |
extern void asm_delay_loop(uint32_t t); |
extern void asm_fake_loop(uint32_t t); |
/** Halt CPU |
* |
* Halt the current CPU until interrupt event. |
*/ |
#define cpu_halt() ((void) 0) |
#define cpu_sleep() ((void) 0) |
#define GEN_READ_REG(reg) static inline unative_t read_ ##reg (void) \ |
{ \ |
unative_t res; \ |
asm volatile ("movl %%" #reg ", %0" : "=r" (res) ); \ |
return res; \ |
} |
#define GEN_WRITE_REG(reg) static inline void write_ ##reg (unative_t regn) \ |
{ \ |
asm volatile ("movl %0, %%" #reg : : "r" (regn)); \ |
} |
GEN_READ_REG(cr0); |
GEN_READ_REG(cr2); |
GEN_READ_REG(dr0); |
GEN_READ_REG(dr1); |
GEN_READ_REG(dr2); |
GEN_READ_REG(dr3); |
GEN_READ_REG(dr6); |
GEN_READ_REG(dr7); |
GEN_WRITE_REG(dr0); |
GEN_WRITE_REG(dr1); |
GEN_WRITE_REG(dr2); |
GEN_WRITE_REG(dr3); |
GEN_WRITE_REG(dr6); |
GEN_WRITE_REG(dr7); |
/** Byte to port |
* |
* Output byte to port |
* |
* @param port Port to write to |
* @param val Value to write |
*/ |
static inline void outb(uint16_t port, uint8_t val) { asm volatile ("outb %b0, %w1\n" : : "a" (val), "d" (port) ); } |
/** Word to port |
* |
* Output word to port |
* |
* @param port Port to write to |
* @param val Value to write |
*/ |
static inline void outw(uint16_t port, uint16_t val) { asm volatile ("outw %w0, %w1\n" : : "a" (val), "d" (port) ); } |
/** Double word to port |
* |
* Output double word to port |
* |
* @param port Port to write to |
* @param val Value to write |
*/ |
static inline void outl(uint16_t port, uint32_t val) { asm volatile ("outl %l0, %w1\n" : : "a" (val), "d" (port) ); } |
/** Byte from port |
* |
* Get byte from port |
* |
* @param port Port to read from |
* @return Value read |
*/ |
static inline uint8_t inb(uint16_t port) { uint8_t val; asm volatile ("inb %w1, %b0 \n" : "=a" (val) : "d" (port) ); return val; } |
/** Word from port |
* |
* Get word from port |
* |
* @param port Port to read from |
* @return Value read |
*/ |
static inline uint16_t inw(uint16_t port) { uint16_t val; asm volatile ("inw %w1, %w0 \n" : "=a" (val) : "d" (port) ); return val; } |
/** Double word from port |
* |
* Get double word from port |
* |
* @param port Port to read from |
* @return Value read |
*/ |
static inline uint32_t inl(uint16_t port) { uint32_t val; asm volatile ("inl %w1, %l0 \n" : "=a" (val) : "d" (port) ); return val; } |
/** Enable interrupts. |
* |
* Enable interrupts and return previous |
* value of EFLAGS. |
* |
* @return Old interrupt priority level. |
*/ |
static inline ipl_t interrupts_enable(void) |
{ |
// FIXME SMP |
ipl_t v = shared_info.vcpu_info[0].evtchn_upcall_mask; |
write_barrier(); |
shared_info.vcpu_info[0].evtchn_upcall_mask = 0; |
write_barrier(); |
if (shared_info.vcpu_info[0].evtchn_upcall_pending) |
force_evtchn_callback(); |
return v; |
} |
/** Disable interrupts. |
* |
* Disable interrupts and return previous |
* value of EFLAGS. |
* |
* @return Old interrupt priority level. |
*/ |
static inline ipl_t interrupts_disable(void) |
{ |
// FIXME SMP |
ipl_t v = shared_info.vcpu_info[0].evtchn_upcall_mask; |
shared_info.vcpu_info[0].evtchn_upcall_mask = 1; |
write_barrier(); |
return v; |
} |
/** Restore interrupt priority level. |
* |
* Restore EFLAGS. |
* |
* @param ipl Saved interrupt priority level. |
*/ |
static inline void interrupts_restore(ipl_t ipl) |
{ |
if (ipl == 0) |
interrupts_enable(); |
else |
interrupts_disable(); |
} |
/** Return interrupt priority level. |
* |
* @return EFLAFS. |
*/ |
static inline ipl_t interrupts_read(void) |
{ |
// FIXME SMP |
return shared_info.vcpu_info[0].evtchn_upcall_mask; |
} |
/** Return base address of current stack |
* |
* Return the base address of the current stack. |
* The stack is assumed to be STACK_SIZE bytes long. |
* The stack must start on page boundary. |
*/ |
static inline uintptr_t get_stack_base(void) |
{ |
uintptr_t v; |
asm volatile ("andl %%esp, %0\n" : "=r" (v) : "0" (~(STACK_SIZE-1))); |
return v; |
} |
/** Return current IP address */ |
static inline uintptr_t * get_ip() |
{ |
uintptr_t *ip; |
asm volatile ( |
"mov %%eip, %0" |
: "=r" (ip) |
); |
return ip; |
} |
/** Invalidate TLB Entry. |
* |
* @param addr Address on a page whose TLB entry is to be invalidated. |
*/ |
static inline void invlpg(uintptr_t addr) |
{ |
asm volatile ("invlpg %0\n" :: "m" (*(unative_t *)addr)); |
} |
/** Load GDTR register from memory. |
* |
* @param gdtr_reg Address of memory from where to load GDTR. |
*/ |
static inline void gdtr_load(ptr_16_32_t *gdtr_reg) |
{ |
asm volatile ("lgdtl %0\n" : : "m" (*gdtr_reg)); |
} |
/** Store GDTR register to memory. |
* |
* @param gdtr_reg Address of memory to where to load GDTR. |
*/ |
static inline void gdtr_store(ptr_16_32_t *gdtr_reg) |
{ |
asm volatile ("sgdtl %0\n" : : "m" (*gdtr_reg)); |
} |
/** Load TR from descriptor table. |
* |
* @param sel Selector specifying descriptor of TSS segment. |
*/ |
static inline void tr_load(uint16_t sel) |
{ |
asm volatile ("ltr %0" : : "r" (sel)); |
} |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32xen/include/drivers/xconsole.h |
---|
0,0 → 1,56 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia32xen_XCONSOLE_H_ |
#define KERN_ia32xen_XCONSOLE_H_ |
#include <arch/types.h> |
typedef struct { |
char in[1024]; |
char out[2048]; |
uint32_t in_cons; |
uint32_t in_prod; |
uint32_t out_cons; |
uint32_t out_prod; |
} xencons_t; |
extern xencons_t console_page; |
extern void xen_console_init(void); |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ia32xen/include/cycle.h |
---|
0,0 → 1,0 |
link ../../ia32/include/cycle.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/ia32xen/include/interrupt.h |
---|
0,0 → 1,0 |
link ../../ia32/include/interrupt.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/ia32xen/include/fpu_context.h |
---|
0,0 → 1,0 |
link ../../ia32/include/fpu_context.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/ia32xen/include/byteorder.h |
---|
0,0 → 1,0 |
link ../../ia32/include/byteorder.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/ia32xen/include/cpuid.h |
---|
0,0 → 1,0 |
link ../../ia32/include/cpuid.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/ia32xen/include/elf.h |
---|
0,0 → 1,0 |
link ../../ia32/include/elf.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/ia32xen/include/bios |
---|
0,0 → 1,0 |
link ../../ia32/include/bios |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/ia32xen/include/memstr.h |
---|
0,0 → 1,0 |
link ../../ia32/include/memstr.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/ia32xen/include/arg.h |
---|
0,0 → 1,0 |
link ../../ia32/include/arg.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/ia32xen/include/smp |
---|
0,0 → 1,0 |
link ../../ia32/include/smp |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/ia32xen/include/ddi |
---|
0,0 → 1,0 |
link ../../ia32/include/ddi |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/ia32xen/include/atomic.h |
---|
0,0 → 1,0 |
link ../../ia32/include/atomic.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/ia32xen/include/arch.h |
---|
0,0 → 1,0 |
link ../../ia32/include/arch.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/ia32xen/include/proc |
---|
0,0 → 1,0 |
link ../../ia32/include/proc |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/ia32xen/include/faddr.h |
---|
0,0 → 1,0 |
link ../../ia32/include/faddr.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/ia32xen/include/debugger.h |
---|
0,0 → 1,0 |
link ../../ia32/include/debugger.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/ia32xen/include/context.h |
---|
0,0 → 1,0 |
link ../../ia32/include/context.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/ia32xen/include/debug.h |
---|
0,0 → 1,0 |
link ../../ia32/include/debug.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/ia32xen/include/barrier.h |
---|
0,0 → 1,0 |
link ../../ia32/include/barrier.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/ia32xen/include/cpu.h |
---|
0,0 → 1,0 |
link ../../ia32/include/cpu.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/arm/kernel/arch/ia32xen/_link.ld.in |
---|
0,0 → 1,45 |
/** ia32xen linker script |
*/ |
#include <arch/hypercall.h> |
#include <arch/mm/page.h> |
ENTRY(kernel_image_start) |
PHDRS { |
image PT_LOAD FLAGS(7); /* RWE */ |
note PT_NOTE FLAGS(4); /* R__ */ |
} |
SECTIONS { |
.image PA2KA(BOOT_OFFSET): AT (BOOT_OFFSET) { |
ktext_start = .; |
*(K_TEXT_START); |
*(.text); |
ktext_end = .; |
kdata_start = .; |
*(.data); /* initialized data */ |
*(.rodata*); /* string literals */ |
*(COMMON); /* global variables */ |
hardcoded_load_address = .; |
LONG(PA2KA(0)); |
hardcoded_ktext_size = .; |
LONG(ktext_end - ktext_start); |
hardcoded_kdata_size = .; |
LONG(kdata_end - kdata_start); |
symbol_table = .; |
*(symtab.*); /* Symbol table, must be LAST symbol! */ |
*(.bss); /* uninitialized static variables */ |
kdata_end = .; |
} :image |
.notes : { |
*(.note.Xen); |
} :note |
/DISCARD/ : { |
*(.note.GNU-stack); |
*(.comment); |
} |
} |
/branches/arm/kernel/arch/ppc64/Makefile.inc |
---|
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. |
# |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf64-powerpc |
BFD_ARCH = powerpc:common64 |
BFD = binary |
TARGET = ppc64-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/ppc64 |
GCC_CFLAGS += -mcpu=powerpc64 -msoft-float -m64 |
AFLAGS += -a64 |
LFLAGS += -no-check-sections -N |
DEFS += -D__64_BITS__ |
## Own configuration directives |
# |
CONFIG_FB = y |
## Compile with hierarchical page tables support. |
# |
CONFIG_PAGE_PT = y |
DEFS += -DCONFIG_PAGE_PT |
ARCH_SOURCES = \ |
arch/$(ARCH)/src/context.S \ |
arch/$(ARCH)/src/debug/panic.s \ |
arch/$(ARCH)/src/fpu_context.S \ |
arch/$(ARCH)/src/boot/boot.S \ |
arch/$(ARCH)/src/ppc64.c \ |
arch/$(ARCH)/src/dummy.s \ |
arch/$(ARCH)/src/exception.S \ |
arch/$(ARCH)/src/interrupt.c \ |
arch/$(ARCH)/src/asm.S \ |
arch/$(ARCH)/src/cpu/cpu.c \ |
arch/$(ARCH)/src/proc/scheduler.c \ |
arch/$(ARCH)/src/ddi/ddi.c \ |
arch/$(ARCH)/src/mm/as.c \ |
arch/$(ARCH)/src/mm/frame.c \ |
arch/$(ARCH)/src/mm/page.c \ |
arch/$(ARCH)/src/mm/tlb.c \ |
arch/$(ARCH)/src/drivers/pic.c |
/branches/arm/kernel/arch/ppc64/include/mm/page.h |
---|
0,0 → 1,184 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64mm |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_PAGE_H_ |
#define KERN_ppc64_PAGE_H_ |
#include <arch/mm/frame.h> |
#define PAGE_WIDTH FRAME_WIDTH |
#define PAGE_SIZE FRAME_SIZE |
#ifdef KERNEL |
#ifndef __ASM__ |
# define KA2PA(x) (((uintptr_t) (x)) - 0x80000000) |
# define PA2KA(x) (((uintptr_t) (x)) + 0x80000000) |
#else |
# define KA2PA(x) ((x) - 0x80000000) |
# define PA2KA(x) ((x) + 0x80000000) |
#endif |
/* |
* Implementation of generic 4-level page table interface, |
* the hardware Page Hash Table is used as cache. |
* |
* Page table layout: |
* - 32-bit virtual addressess |
* - Offset is 12 bits => pages are 4K long |
* - PTL0 has 1024 entries (10 bits) |
* - PTL1 is not used |
* - PTL2 is not used |
* - PLT3 has 1024 entries (10 bits) |
*/ |
/* Number of entries in each level. */ |
#define PTL0_ENTRIES_ARCH 1024 |
#define PTL1_ENTRIES_ARCH 0 |
#define PTL2_ENTRIES_ARCH 0 |
#define PTL3_ENTRIES_ARCH 1024 |
/* Sizes of page tables in each level. */ |
#define PTL0_SIZE_ARCH ONE_FRAME |
#define PTL1_SIZE_ARCH 0 |
#define PTL2_SIZE_ARCH 0 |
#define PTL3_SIZE_ARCH ONE_FRAME |
/* Macros calculating indices into page tables in each level. */ |
#define PTL0_INDEX_ARCH(vaddr) (((vaddr) >> 22) & 0x3ff) |
#define PTL1_INDEX_ARCH(vaddr) 0 |
#define PTL2_INDEX_ARCH(vaddr) 0 |
#define PTL3_INDEX_ARCH(vaddr) (((vaddr) >> 12) & 0x3ff) |
/* Get PTE address accessors for each level. */ |
#define GET_PTL1_ADDRESS_ARCH(ptl0, i) \ |
(((pte_t *) (ptl0))[(i)].pfn << 12) |
#define GET_PTL2_ADDRESS_ARCH(ptl1, i) \ |
(ptl1) |
#define GET_PTL3_ADDRESS_ARCH(ptl2, i) \ |
(ptl2) |
#define GET_FRAME_ADDRESS_ARCH(ptl3, i) \ |
(((pte_t *) (ptl3))[(i)].pfn << 12) |
/* Set PTE address accessors for each level. */ |
#define SET_PTL0_ADDRESS_ARCH(ptl0) |
#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) \ |
(((pte_t *) (ptl0))[(i)].pfn = (a) >> 12) |
#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a) |
#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a) |
#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) \ |
(((pte_t *) (ptl3))[(i)].pfn = (a) >> 12) |
/* Get PTE flags accessors for each level. */ |
#define GET_PTL1_FLAGS_ARCH(ptl0, i) \ |
get_pt_flags((pte_t *) (ptl0), (index_t) (i)) |
#define GET_PTL2_FLAGS_ARCH(ptl1, i) \ |
PAGE_PRESENT |
#define GET_PTL3_FLAGS_ARCH(ptl2, i) \ |
PAGE_PRESENT |
#define GET_FRAME_FLAGS_ARCH(ptl3, i) \ |
get_pt_flags((pte_t *) (ptl3), (index_t) (i)) |
/* Set PTE flags accessors for each level. */ |
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \ |
set_pt_flags((pte_t *) (ptl0), (index_t) (i), (x)) |
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x) |
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x) |
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \ |
set_pt_flags((pte_t *) (ptl3), (index_t) (i), (x)) |
/* Macros for querying the last-level PTEs. */ |
#define PTE_VALID_ARCH(pte) (*((uint32_t *) (pte)) != 0) |
#define PTE_PRESENT_ARCH(pte) ((pte)->p != 0) |
#define PTE_GET_FRAME_ARCH(pte) ((uintptr_t) ((pte)->pfn << 12)) |
#define PTE_WRITABLE_ARCH(pte) 1 |
#define PTE_EXECUTABLE_ARCH(pte) 1 |
#ifndef __ASM__ |
#include <mm/mm.h> |
#include <arch/interrupt.h> |
static inline int get_pt_flags(pte_t *pt, index_t i) |
{ |
pte_t *p = &pt[i]; |
return ((1 << PAGE_CACHEABLE_SHIFT) | |
((!p->p) << PAGE_PRESENT_SHIFT) | |
(1 << PAGE_USER_SHIFT) | |
(1 << PAGE_READ_SHIFT) | |
(1 << PAGE_WRITE_SHIFT) | |
(1 << PAGE_EXEC_SHIFT) | |
(p->g << PAGE_GLOBAL_SHIFT)); |
} |
static inline void set_pt_flags(pte_t *pt, index_t i, int flags) |
{ |
pte_t *p = &pt[i]; |
p->p = !(flags & PAGE_NOT_PRESENT); |
p->g = (flags & PAGE_GLOBAL) != 0; |
p->valid = 1; |
} |
extern void page_arch_init(void); |
#define PHT_BITS 16 |
#define PHT_ORDER 4 |
typedef struct { |
unsigned v : 1; /**< Valid */ |
unsigned vsid : 24; /**< Virtual Segment ID */ |
unsigned h : 1; /**< Primary/secondary hash */ |
unsigned api : 6; /**< Abbreviated Page Index */ |
unsigned rpn : 20; /**< Real Page Number */ |
unsigned reserved0 : 3; |
unsigned r : 1; /**< Reference */ |
unsigned c : 1; /**< Change */ |
unsigned wimg : 4; /**< Access control */ |
unsigned reserved1 : 1; |
unsigned pp : 2; /**< Page protection */ |
} phte_t; |
extern void pht_refill(bool data, istate_t *istate); |
extern void pht_init(void); |
#endif /* __ASM__ */ |
#endif /* KERNEL */ |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/include/mm/frame.h |
---|
0,0 → 1,57 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64mm |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_FRAME_H_ |
#define KERN_ppc64_FRAME_H_ |
#define FRAME_WIDTH 12 /* 4K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#ifdef KERNEL |
#ifndef __ASM__ |
#include <arch/types.h> |
extern uintptr_t last_frame; |
extern void frame_arch_init(void); |
extern void physmem_print(void); |
#endif /* __ASM__ */ |
#endif /* KERNEL */ |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/include/mm/as.h |
---|
0,0 → 1,64 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64mm |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_AS_H_ |
#define KERN_ppc64_AS_H_ |
#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH 0 |
#define KERNEL_ADDRESS_SPACE_START_ARCH ((unsigned long) 0x80000000) |
#define KERNEL_ADDRESS_SPACE_END_ARCH ((unsigned long) 0xffffffff) |
#define USER_ADDRESS_SPACE_START_ARCH ((unsigned long) 0x00000000) |
#define USER_ADDRESS_SPACE_END_ARCH ((unsigned long) 0x7fffffff) |
#define USTACK_ADDRESS_ARCH (0x7fffffff - (PAGE_SIZE - 1)) |
typedef struct { |
} as_arch_t; |
#include <genarch/mm/as_pt.h> |
#define as_constructor_arch(as, flags) (as != as) |
#define as_destructor_arch(as) (as != as) |
#define as_create_arch(as, flags) (as != as) |
#define as_install_arch(as) |
#define as_deinstall_arch(as) |
#define as_invalidate_translation_cache(as, page, cnt) |
extern void as_arch_init(void); |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/include/mm/asid.h |
---|
0,0 → 1,48 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64mm |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_ASID_H_ |
#define KERN_ppc64_ASID_H_ |
typedef int asid_t; |
#define ASID_MAX_ARCH 3 |
#define asid_get() (ASID_START+1) |
#define asid_put(asid) |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/include/mm/tlb.h |
---|
0,0 → 1,41 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64mm |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_TLB_H_ |
#define KERN_ppc64_TLB_H_ |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/include/barrier.h |
---|
0,0 → 1,51 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_BARRIER_H_ |
#define KERN_ppc64_BARRIER_H_ |
#define CS_ENTER_BARRIER() asm volatile ("" ::: "memory") |
#define CS_LEAVE_BARRIER() asm volatile ("" ::: "memory") |
#define memory_barrier() asm volatile ("sync" ::: "memory") |
#define read_barrier() asm volatile ("sync" ::: "memory") |
#define write_barrier() asm volatile ("eieio" ::: "memory") |
#define smc_coherence(a) |
#define smc_coherence_block(a, l) |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/include/memstr.h |
---|
0,0 → 1,48 |
/* |
* Copyright (c) 2005 Sergey Bondari |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_MEMSTR_H_ |
#define KERN_ppc64_MEMSTR_H_ |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
extern void memsetw(void *dst, size_t cnt, uint16_t x); |
extern void memsetb(void *dst, size_t cnt, uint8_t x); |
extern int memcmp(const void *a, const void *b, size_t cnt); |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/include/exception.h |
---|
0,0 → 1,102 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_EXCEPTION_H_ |
#define KERN_ppc64_EXCEPTION_H_ |
#include <arch/types.h> |
typedef struct { |
uint64_t r0; |
uint64_t r2; |
uint64_t r3; |
uint64_t r4; |
uint64_t r5; |
uint64_t r6; |
uint64_t r7; |
uint64_t r8; |
uint64_t r9; |
uint64_t r10; |
uint64_t r11; |
uint64_t r13; |
uint64_t r14; |
uint64_t r15; |
uint64_t r16; |
uint64_t r17; |
uint64_t r18; |
uint64_t r19; |
uint64_t r20; |
uint64_t r21; |
uint64_t r22; |
uint64_t r23; |
uint64_t r24; |
uint64_t r25; |
uint64_t r26; |
uint64_t r27; |
uint64_t r28; |
uint64_t r29; |
uint64_t r30; |
uint64_t r31; |
uint64_t cr; |
uint64_t pc; |
uint64_t srr1; |
uint64_t lr; |
uint64_t ctr; |
uint64_t xer; |
uint64_t r12; |
uint64_t sp; |
} istate_t; |
static inline void istate_set_retaddr(istate_t *istate, uintptr_t retaddr) |
{ |
istate->pc = retaddr; |
} |
/** Return true if exception happened while in userspace */ |
#include <panic.h> |
static inline int istate_from_uspace(istate_t *istate) |
{ |
panic("istate_from_uspace not yet implemented"); |
return 0; |
} |
static inline unative_t istate_get_pc(istate_t *istate) |
{ |
return istate->pc; |
} |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/include/types.h |
---|
0,0 → 1,72 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_TYPES_H_ |
#define KERN_ppc64_TYPES_H_ |
typedef signed char int8_t; |
typedef signed short int16_t; |
typedef signed int int32_t; |
typedef signed long int64_t; |
typedef unsigned char uint8_t; |
typedef unsigned short uint16_t; |
typedef unsigned int uint32_t; |
typedef unsigned long uint64_t; |
typedef uint64_t size_t; |
typedef uint64_t count_t; |
typedef uint64_t index_t; |
typedef uint64_t uintptr_t; |
typedef uint64_t pfn_t; |
typedef uint64_t ipl_t; |
typedef uint64_t unative_t; |
typedef int64_t native_t; |
/** Page Table Entry. */ |
typedef struct { |
unsigned p : 1; /**< Present bit. */ |
unsigned a : 1; /**< Accessed bit. */ |
unsigned g : 1; /**< Global bit. */ |
unsigned valid : 1; /**< Valid content even if not present. */ |
unsigned pfn : 20; /**< Physical frame number. */ |
} pte_t; |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/include/context_offset.h |
---|
0,0 → 1,132 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#ifndef KERN_ppc64_CONTEXT_OFFSET_H_ |
#define KERN_ppc64_CONTEXT_OFFSET_H_ |
#define OFFSET_SP 0x0 |
#define OFFSET_PC 0x8 |
#define OFFSET_R2 0x10 |
#define OFFSET_R13 0x18 |
#define OFFSET_R14 0x20 |
#define OFFSET_R15 0x28 |
#define OFFSET_R16 0x30 |
#define OFFSET_R17 0x38 |
#define OFFSET_R18 0x40 |
#define OFFSET_R19 0x48 |
#define OFFSET_R20 0x50 |
#define OFFSET_R21 0x58 |
#define OFFSET_R22 0x60 |
#define OFFSET_R23 0x68 |
#define OFFSET_R24 0x70 |
#define OFFSET_R25 0x78 |
#define OFFSET_R26 0x80 |
#define OFFSET_R27 0x88 |
#define OFFSET_R28 0x90 |
#define OFFSET_R29 0x98 |
#define OFFSET_R30 0xa0 |
#define OFFSET_R31 0xa8 |
#define OFFSET_CR 0xb0 |
#define OFFSET_FR14 0x0 |
#define OFFSET_FR15 0x8 |
#define OFFSET_FR16 0x10 |
#define OFFSET_FR17 0x18 |
#define OFFSET_FR18 0x20 |
#define OFFSET_FR19 0x28 |
#define OFFSET_FR20 0x30 |
#define OFFSET_FR21 0x38 |
#define OFFSET_FR22 0x40 |
#define OFFSET_FR23 0x48 |
#define OFFSET_FR24 0x50 |
#define OFFSET_FR25 0x58 |
#define OFFSET_FR26 0x60 |
#define OFFSET_FR27 0x68 |
#define OFFSET_FR28 0x70 |
#define OFFSET_FR29 0x78 |
#define OFFSET_FR30 0x80 |
#define OFFSET_FR31 0x88 |
#define OFFSET_FPSCR 0x90 |
#ifdef __ASM__ |
# include <arch/asm/regname.h> |
# ctx: address of the structure with saved context |
.macro CONTEXT_SAVE_ARCH_CORE ctx:req |
stw sp, OFFSET_SP(\ctx) |
stw r2, OFFSET_R2(\ctx) |
stw r13, OFFSET_R13(\ctx) |
stw r14, OFFSET_R14(\ctx) |
stw r15, OFFSET_R15(\ctx) |
stw r16, OFFSET_R16(\ctx) |
stw r17, OFFSET_R17(\ctx) |
stw r18, OFFSET_R18(\ctx) |
stw r19, OFFSET_R19(\ctx) |
stw r20, OFFSET_R20(\ctx) |
stw r21, OFFSET_R21(\ctx) |
stw r22, OFFSET_R22(\ctx) |
stw r23, OFFSET_R23(\ctx) |
stw r24, OFFSET_R24(\ctx) |
stw r25, OFFSET_R25(\ctx) |
stw r26, OFFSET_R26(\ctx) |
stw r27, OFFSET_R27(\ctx) |
stw r28, OFFSET_R28(\ctx) |
stw r29, OFFSET_R29(\ctx) |
stw r30, OFFSET_R30(\ctx) |
stw r31, OFFSET_R31(\ctx) |
.endm |
# ctx: address of the structure with saved context |
.macro CONTEXT_RESTORE_ARCH_CORE ctx:req |
lwz sp, OFFSET_SP(\ctx) |
lwz r2, OFFSET_R2(\ctx) |
lwz r13, OFFSET_R13(\ctx) |
lwz r14, OFFSET_R14(\ctx) |
lwz r15, OFFSET_R15(\ctx) |
lwz r16, OFFSET_R16(\ctx) |
lwz r17, OFFSET_R17(\ctx) |
lwz r18, OFFSET_R18(\ctx) |
lwz r19, OFFSET_R19(\ctx) |
lwz r20, OFFSET_R20(\ctx) |
lwz r21, OFFSET_R21(\ctx) |
lwz r22, OFFSET_R22(\ctx) |
lwz r23, OFFSET_R23(\ctx) |
lwz r24, OFFSET_R24(\ctx) |
lwz r25, OFFSET_R25(\ctx) |
lwz r26, OFFSET_R26(\ctx) |
lwz r27, OFFSET_R27(\ctx) |
lwz r28, OFFSET_R28(\ctx) |
lwz r29, OFFSET_R29(\ctx) |
lwz r30, OFFSET_R30(\ctx) |
lwz r31, OFFSET_R31(\ctx) |
.endm |
#endif /* __ASM__ */ |
#endif |
/branches/arm/kernel/arch/ppc64/include/byteorder.h |
---|
0,0 → 1,43 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_BYTEORDER_H_ |
#define KERN_ppc64_BYTEORDER_H_ |
#define ARCH_IS_BIG_ENDIAN |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/include/cpu.h |
---|
0,0 → 1,48 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_CPU_H_ |
#define KERN_ppc64_CPU_H_ |
#include <arch/asm.h> |
typedef struct { |
int version; |
int revision; |
} cpu_arch_t; |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/include/drivers/pic.h |
---|
0,0 → 1,56 |
/* |
* Copyright (c) 2006 Ondrej Palkovsky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_PIC_H_ |
#define KERN_ppc64_PIC_H_ |
#include <arch/types.h> |
#define PIC_PENDING_LOW 8 |
#define PIC_PENDING_HIGH 4 |
#define PIC_MASK_LOW 9 |
#define PIC_MASK_HIGH 5 |
#define PIC_ACK_LOW 10 |
#define PIC_ACK_HIGH 6 |
void pic_init(uintptr_t base, size_t size); |
void pic_enable_interrupt(int intnum); |
void pic_disable_interrupt(int intnum); |
void pic_ack_interrupt(int intnum); |
int pic_get_pending(void); |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/include/fpu_context.h |
---|
0,0 → 1,67 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_FPU_CONTEXT_H_ |
#define KERN_ppc64_FPU_CONTEXT_H_ |
#ifndef KERN_ppc64_TYPES_H_ |
# include <arch/types.h> |
#endif |
typedef struct { |
uint64_t fr14; |
uint64_t fr15; |
uint64_t fr16; |
uint64_t fr17; |
uint64_t fr18; |
uint64_t fr19; |
uint64_t fr20; |
uint64_t fr21; |
uint64_t fr22; |
uint64_t fr23; |
uint64_t fr24; |
uint64_t fr25; |
uint64_t fr26; |
uint64_t fr27; |
uint64_t fr28; |
uint64_t fr29; |
uint64_t fr30; |
uint64_t fr31; |
uint32_t fpscr; |
} __attribute__ ((packed)) fpu_context_t; |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/include/context.h |
---|
0,0 → 1,75 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_CONTEXT_H_ |
#define KERN_ppc64_CONTEXT_H_ |
#include <arch/types.h> |
#define SP_DELTA 16 |
typedef struct { |
uintptr_t sp; |
uintptr_t pc; |
uint64_t r2; |
uint64_t r13; |
uint64_t r14; |
uint64_t r15; |
uint64_t r16; |
uint64_t r17; |
uint64_t r18; |
uint64_t r19; |
uint64_t r20; |
uint64_t r21; |
uint64_t r22; |
uint64_t r23; |
uint64_t r24; |
uint64_t r25; |
uint64_t r26; |
uint64_t r27; |
uint64_t r28; |
uint64_t r29; |
uint64_t r30; |
uint64_t r31; |
uint64_t cr; |
ipl_t ipl; |
} __attribute__ ((packed)) context_t; |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/include/cpuid.h |
---|
0,0 → 1,56 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_CPUID_H_ |
#define KERN_ppc64_CPUID_H_ |
#include <arch/types.h> |
typedef struct { |
uint16_t version; |
uint16_t revision; |
} __attribute__ ((packed)) cpu_info_t; |
static inline void cpu_version(cpu_info_t *info) |
{ |
asm volatile ( |
"mfpvr %0\n" |
: "=r" (*info) |
); |
} |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/include/asm/regname.h |
---|
0,0 → 1,215 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_REGNAME_H_ |
#define KERN_ppc64_REGNAME_H_ |
/* Condition Register Bit Fields */ |
#define cr0 0 |
#define cr1 1 |
#define cr2 2 |
#define cr3 3 |
#define cr4 4 |
#define cr5 5 |
#define cr6 6 |
#define cr7 7 |
/* General Purpose Registers (GPRs) */ |
#define r0 0 |
#define r1 1 |
#define r2 2 |
#define r3 3 |
#define r4 4 |
#define r5 5 |
#define r6 6 |
#define r7 7 |
#define r8 8 |
#define r9 9 |
#define r10 10 |
#define r11 11 |
#define r12 12 |
#define r13 13 |
#define r14 14 |
#define r15 15 |
#define r16 16 |
#define r17 17 |
#define r18 18 |
#define r19 19 |
#define r20 20 |
#define r21 21 |
#define r22 22 |
#define r23 23 |
#define r24 24 |
#define r25 25 |
#define r26 26 |
#define r27 27 |
#define r28 28 |
#define r29 29 |
#define r30 30 |
#define r31 31 |
/* GPR Aliases */ |
#define sp 1 |
/* Floating Point Registers (FPRs) */ |
#define fr0 0 |
#define fr1 1 |
#define fr2 2 |
#define fr3 3 |
#define fr4 4 |
#define fr5 5 |
#define fr6 6 |
#define fr7 7 |
#define fr8 8 |
#define fr9 9 |
#define fr10 10 |
#define fr11 11 |
#define fr12 12 |
#define fr13 13 |
#define fr14 14 |
#define fr15 15 |
#define fr16 16 |
#define fr17 17 |
#define fr18 18 |
#define fr19 19 |
#define fr20 20 |
#define fr21 21 |
#define fr22 22 |
#define fr23 23 |
#define fr24 24 |
#define fr25 25 |
#define fr26 26 |
#define fr27 27 |
#define fr28 28 |
#define fr29 29 |
#define fr30 30 |
#define fr31 31 |
#define vr0 0 |
#define vr1 1 |
#define vr2 2 |
#define vr3 3 |
#define vr4 4 |
#define vr5 5 |
#define vr6 6 |
#define vr7 7 |
#define vr8 8 |
#define vr9 9 |
#define vr10 10 |
#define vr11 11 |
#define vr12 12 |
#define vr13 13 |
#define vr14 14 |
#define vr15 15 |
#define vr16 16 |
#define vr17 17 |
#define vr18 18 |
#define vr19 19 |
#define vr20 20 |
#define vr21 21 |
#define vr22 22 |
#define vr23 23 |
#define vr24 24 |
#define vr25 25 |
#define vr26 26 |
#define vr27 27 |
#define vr28 28 |
#define vr29 29 |
#define vr30 30 |
#define vr31 31 |
#define evr0 0 |
#define evr1 1 |
#define evr2 2 |
#define evr3 3 |
#define evr4 4 |
#define evr5 5 |
#define evr6 6 |
#define evr7 7 |
#define evr8 8 |
#define evr9 9 |
#define evr10 10 |
#define evr11 11 |
#define evr12 12 |
#define evr13 13 |
#define evr14 14 |
#define evr15 15 |
#define evr16 16 |
#define evr17 17 |
#define evr18 18 |
#define evr19 19 |
#define evr20 20 |
#define evr21 21 |
#define evr22 22 |
#define evr23 23 |
#define evr24 24 |
#define evr25 25 |
#define evr26 26 |
#define evr27 27 |
#define evr28 28 |
#define evr29 29 |
#define evr30 30 |
#define evr31 31 |
/* Special Purpose Registers (SPRs) */ |
#define xer 1 |
#define lr 8 |
#define ctr 9 |
#define dec 22 |
#define sdr1 25 |
#define srr0 26 |
#define srr1 27 |
#define sprg0 272 |
#define sprg1 273 |
#define sprg2 274 |
#define sprg3 275 |
#define prv 287 |
#define hid0 1008 |
/* MSR bits */ |
#define msr_ir (1 << 4) |
#define msr_dr (1 << 5) |
#define msr_pr (1 << 14) |
#define msr_ee (1 << 15) |
/* HID0 bits */ |
#define hid0_ice (1 << 15) |
#define hid0_dce (1 << 14) |
#define hid0_icfi (1 << 11) |
#define hid0_dci (1 << 10) |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/include/interrupt.h |
---|
0,0 → 1,55 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64interrupt |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_INTERRUPT_H_ |
#define KERN_ppc64_INTERRUPT_H_ |
#include <arch/exception.h> |
#define IVT_ITEMS 16 |
#define IVT_FIRST 0 |
#define VECTOR_DATA_STORAGE 2 |
#define VECTOR_INSTRUCTION_STORAGE 3 |
#define VECTOR_EXTERNAL 4 |
#define VECTOR_DECREMENTER 8 |
extern void start_decrementer(void); |
extern void interrupt_init(void); |
extern void extint_handler(int n, istate_t *istate); |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/include/cycle.h |
---|
0,0 → 1,46 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_CYCLE_H_ |
#define KERN_ppc64_CYCLE_H_ |
static inline uint64_t get_cycle(void) |
{ |
return 0; |
} |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/include/elf.h |
---|
0,0 → 1,45 |
/* |
* Copyright (c) 2006 Sergey Bondari |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_ELF_H_ |
#define KERN_ppc64_ELF_H_ |
#define ELF_MACHINE EM_PPC64 |
#define ELF_DATA_ENCODING ELFDATA2MSB |
#define ELF_CLASS ELFCLASS32 |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/include/arg.h |
---|
0,0 → 1,43 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_ARG_H_ |
#define KERN_ppc64_ARG_H_ |
#include <stdarg.h> |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/include/atomic.h |
---|
0,0 → 1,97 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_ATOMIC_H_ |
#define KERN_ppc64_ATOMIC_H_ |
static inline void atomic_inc(atomic_t *val) |
{ |
long tmp; |
asm volatile ( |
"1:\n" |
"lwarx %0, 0, %2\n" |
"addic %0, %0, 1\n" |
"stwcx. %0, 0, %2\n" |
"bne- 1b" |
: "=&r" (tmp), "=m" (val->count) |
: "r" (&val->count), "m" (val->count) |
: "cc" |
); |
} |
static inline void atomic_dec(atomic_t *val) |
{ |
long tmp; |
asm volatile ( |
"1:\n" |
"lwarx %0, 0, %2\n" |
"addic %0, %0, -1\n" |
"stwcx. %0, 0, %2\n" |
"bne- 1b" |
: "=&r" (tmp), "=m" (val->count) |
: "r" (&val->count), "m" (val->count) |
: "cc" |
); |
} |
static inline long atomic_postinc(atomic_t *val) |
{ |
atomic_inc(val); |
return val->count - 1; |
} |
static inline long atomic_postdec(atomic_t *val) |
{ |
atomic_dec(val); |
return val->count + 1; |
} |
static inline long atomic_preinc(atomic_t *val) |
{ |
atomic_inc(val); |
return val->count; |
} |
static inline long atomic_predec(atomic_t *val) |
{ |
atomic_dec(val); |
return val->count; |
} |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/include/boot/boot.h |
---|
0,0 → 1,92 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_BOOT_H_ |
#define KERN_ppc64_BOOT_H_ |
#define BOOT_OFFSET 0x4000 |
/* Temporary stack size for boot process */ |
#define TEMP_STACK_SIZE 0x100 |
#define TASKMAP_MAX_RECORDS 32 |
#define MEMMAP_MAX_RECORDS 32 |
#ifndef __ASM__ |
#include <arch/types.h> |
typedef struct { |
uintptr_t addr; |
uint64_t size; |
} utask_t; |
typedef struct { |
uint32_t count; |
utask_t tasks[TASKMAP_MAX_RECORDS]; |
} taskmap_t; |
typedef struct { |
uintptr_t start; |
uint64_t size; |
} memzone_t; |
typedef struct { |
uint64_t total; |
uint32_t count; |
memzone_t zones[MEMMAP_MAX_RECORDS]; |
} memmap_t; |
typedef struct { |
uintptr_t addr; |
unsigned int width; |
unsigned int height; |
unsigned int bpp; |
unsigned int scanline; |
} screen_t; |
typedef struct { |
taskmap_t taskmap; |
memmap_t memmap; |
screen_t screen; |
} bootinfo_t; |
extern bootinfo_t bootinfo; |
#endif |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/include/arch.h |
---|
0,0 → 1,41 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_ARCH_H_ |
#define KERN_ppc64_ARCH_H_ |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/include/proc/task.h |
---|
0,0 → 1,47 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64proc |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_TASK_H_ |
#define KERN_ppc64_TASK_H_ |
typedef struct { |
} task_arch_t; |
#define task_create_arch(t) |
#define task_destroy_arch(t) |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/include/proc/thread.h |
---|
0,0 → 1,48 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64proc |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_THREAD_H_ |
#define KERN_ppc64_THREAD_H_ |
typedef struct { |
} thread_arch_t; |
#define thr_constructor_arch(t) |
#define thr_destructor_arch(t) |
#define thread_create_arch(t) |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/include/asm.h |
---|
0,0 → 1,161 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_ASM_H_ |
#define KERN_ppc64_ASM_H_ |
#include <arch/types.h> |
#include <config.h> |
/** Enable interrupts. |
* |
* Enable interrupts and return previous |
* value of EE. |
* |
* @return Old interrupt priority level. |
*/ |
static inline ipl_t interrupts_enable(void) |
{ |
ipl_t v; |
ipl_t tmp; |
asm volatile ( |
"mfmsr %0\n" |
"mfmsr %1\n" |
"ori %1, %1, 1 << 15\n" |
"mtmsr %1\n" |
: "=r" (v), "=r" (tmp) |
); |
return v; |
} |
/** Disable interrupts. |
* |
* Disable interrupts and return previous |
* value of EE. |
* |
* @return Old interrupt priority level. |
*/ |
static inline ipl_t interrupts_disable(void) |
{ |
ipl_t v; |
ipl_t tmp; |
asm volatile ( |
"mfmsr %0\n" |
"mfmsr %1\n" |
"rlwinm %1, %1, 0, 17, 15\n" |
"mtmsr %1\n" |
: "=r" (v), "=r" (tmp) |
); |
return v; |
} |
/** Restore interrupt priority level. |
* |
* Restore EE. |
* |
* @param ipl Saved interrupt priority level. |
*/ |
static inline void interrupts_restore(ipl_t ipl) |
{ |
ipl_t tmp; |
asm volatile ( |
"mfmsr %1\n" |
"rlwimi %0, %1, 0, 17, 15\n" |
"cmpw 0, %0, %1\n" |
"beq 0f\n" |
"mtmsr %0\n" |
"0:\n" |
: "=r" (ipl), "=r" (tmp) |
: "0" (ipl) |
: "cr0" |
); |
} |
/** Return interrupt priority level. |
* |
* Return EE. |
* |
* @return Current interrupt priority level. |
*/ |
static inline ipl_t interrupts_read(void) |
{ |
ipl_t v; |
asm volatile ( |
"mfmsr %0\n" |
: "=r" (v) |
); |
return v; |
} |
/** Return base address of current stack. |
* |
* Return the base address of the current stack. |
* The stack is assumed to be STACK_SIZE bytes long. |
* The stack must start on page boundary. |
*/ |
static inline uintptr_t get_stack_base(void) |
{ |
uintptr_t v; |
asm volatile ( |
"and %0, %%sp, %1\n" |
: "=r" (v) |
: "r" (~(STACK_SIZE - 1)) |
); |
return v; |
} |
static inline void cpu_sleep(void) |
{ |
} |
static inline void cpu_halt(void) |
{ |
asm volatile ( |
"b 0\n" |
); |
} |
void asm_delay_loop(uint32_t t); |
extern void userspace_asm(uintptr_t uspace_uarg, uintptr_t stack, uintptr_t entry); |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/include/faddr.h |
---|
0,0 → 1,45 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_FADDR_H_ |
#define KERN_ppc64_FADDR_H_ |
#include <arch/types.h> |
#define FADDR(fptr) ((uintptr_t) (fptr)) |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/include/debug.h |
---|
0,0 → 1,41 |
/* |
* Copyright (c) 2005 |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64debug |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_DEBUG_H_ |
#define KERN_ppc64_DEBUG_H_ |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/src/asm.S |
---|
0,0 → 1,315 |
# |
# Copyright (c) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
#include <arch/asm/regname.h> |
.text |
.global userspace_asm |
.global iret |
.global iret_syscall |
.global memsetb |
.global memcpy |
.global memcpy_from_uspace |
.global memcpy_to_uspace |
.global memcpy_from_uspace_failover_address |
.global memcpy_to_uspace_failover_address |
userspace_asm: |
# r3 = uspace_uarg |
# r4 = stack |
# r5 = entry |
# disable interrupts |
mfmsr r31 |
rlwinm r31, r31, 0, 17, 15 |
mtmsr r31 |
# set entry point |
mtsrr0 r5 |
# set problem state, enable interrupts |
ori r31, r31, msr_pr |
ori r31, r31, msr_ee |
mtsrr1 r31 |
# set stack |
mr sp, r4 |
# %r3 is defined to hold pcb_ptr - set it to 0 |
xor r3, r3, r3 |
# jump to userspace |
rfi |
iret: |
# disable interrupts |
mfmsr r31 |
rlwinm r31, r31, 0, 17, 15 |
mtmsr r31 |
lwz r0, 8(sp) |
lwz r2, 12(sp) |
lwz r3, 16(sp) |
lwz r4, 20(sp) |
lwz r5, 24(sp) |
lwz r6, 28(sp) |
lwz r7, 32(sp) |
lwz r8, 36(sp) |
lwz r9, 40(sp) |
lwz r10, 44(sp) |
lwz r11, 48(sp) |
lwz r13, 52(sp) |
lwz r14, 56(sp) |
lwz r15, 60(sp) |
lwz r16, 64(sp) |
lwz r17, 68(sp) |
lwz r18, 72(sp) |
lwz r19, 76(sp) |
lwz r20, 80(sp) |
lwz r21, 84(sp) |
lwz r22, 88(sp) |
lwz r23, 92(sp) |
lwz r24, 96(sp) |
lwz r25, 100(sp) |
lwz r26, 104(sp) |
lwz r27, 108(sp) |
lwz r28, 112(sp) |
lwz r29, 116(sp) |
lwz r30, 120(sp) |
lwz r31, 124(sp) |
lwz r12, 128(sp) |
mtcr r12 |
lwz r12, 132(sp) |
mtsrr0 r12 |
lwz r12, 136(sp) |
mtsrr1 r12 |
lwz r12, 140(sp) |
mtlr r12 |
lwz r12, 144(sp) |
mtctr r12 |
lwz r12, 148(sp) |
mtxer r12 |
lwz r12, 152(sp) |
lwz sp, 156(sp) |
rfi |
iret_syscall: |
# reset decrementer |
li r31, 1000 |
mtdec r31 |
# disable interrupts |
mfmsr r31 |
rlwinm r31, r31, 0, 17, 15 |
mtmsr r31 |
lwz r0, 8(sp) |
lwz r2, 12(sp) |
lwz r4, 20(sp) |
lwz r5, 24(sp) |
lwz r6, 28(sp) |
lwz r7, 32(sp) |
lwz r8, 36(sp) |
lwz r9, 40(sp) |
lwz r10, 44(sp) |
lwz r11, 48(sp) |
lwz r13, 52(sp) |
lwz r14, 56(sp) |
lwz r15, 60(sp) |
lwz r16, 64(sp) |
lwz r17, 68(sp) |
lwz r18, 72(sp) |
lwz r19, 76(sp) |
lwz r20, 80(sp) |
lwz r21, 84(sp) |
lwz r22, 88(sp) |
lwz r23, 92(sp) |
lwz r24, 96(sp) |
lwz r25, 100(sp) |
lwz r26, 104(sp) |
lwz r27, 108(sp) |
lwz r28, 112(sp) |
lwz r29, 116(sp) |
lwz r30, 120(sp) |
lwz r31, 124(sp) |
lwz r12, 128(sp) |
mtcr r12 |
lwz r12, 132(sp) |
mtsrr0 r12 |
lwz r12, 136(sp) |
mtsrr1 r12 |
lwz r12, 140(sp) |
mtlr r12 |
lwz r12, 144(sp) |
mtctr r12 |
lwz r12, 148(sp) |
mtxer r12 |
lwz r12, 152(sp) |
lwz sp, 156(sp) |
rfi |
memsetb: |
rlwimi r5, r5, 8, 16, 23 |
rlwimi r5, r5, 16, 0, 15 |
addi r14, r3, -4 |
cmplwi 0, r4, 4 |
blt 7f |
stwu r5, 4(r14) |
beqlr |
andi. r15, r14, 3 |
add r4, r15, r4 |
subf r14, r15, r14 |
srwi r15, r4, 2 |
mtctr r15 |
bdz 6f |
1: |
stwu r5, 4(r14) |
bdnz 1b |
6: |
andi. r4, r4, 3 |
7: |
cmpwi 0, r4, 0 |
beqlr |
mtctr r4 |
addi r6, r6, 3 |
8: |
stbu r5, 1(r14) |
bdnz 8b |
blr |
memcpy: |
memcpy_from_uspace: |
memcpy_to_uspace: |
srwi. r7, r5, 3 |
addi r6, r3, -4 |
addi r4, r4, -4 |
beq 2f |
andi. r0, r6, 3 |
mtctr r7 |
bne 5f |
1: |
lwz r7, 4(r4) |
lwzu r8, 8(r4) |
stw r7, 4(r6) |
stwu r8, 8(r6) |
bdnz 1b |
andi. r5, r5, 7 |
2: |
cmplwi 0, r5, 4 |
blt 3f |
lwzu r0, 4(r4) |
addi r5, r5, -4 |
stwu r0, 4(r6) |
3: |
cmpwi 0, r5, 0 |
beqlr |
mtctr r5 |
addi r4, r4, 3 |
addi r6, r6, 3 |
4: |
lbzu r0, 1(r4) |
stbu r0, 1(r6) |
bdnz 4b |
blr |
5: |
subfic r0, r0, 4 |
mtctr r0 |
6: |
lbz r7, 4(r4) |
addi r4, r4, 1 |
stb r7, 4(r6) |
addi r6, r6, 1 |
bdnz 6b |
subf r5, r0, r5 |
rlwinm. r7, r5, 32-3, 3, 31 |
beq 2b |
mtctr r7 |
b 1b |
memcpy_from_uspace_failover_address: |
memcpy_to_uspace_failover_address: |
b memcpy_from_uspace_failover_address |
/branches/arm/kernel/arch/ppc64/src/mm/page.c |
---|
0,0 → 1,305 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64mm |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/mm/page.h> |
#include <genarch/mm/page_pt.h> |
#include <arch/mm/frame.h> |
#include <arch/asm.h> |
#include <mm/frame.h> |
#include <mm/page.h> |
#include <mm/as.h> |
#include <arch.h> |
#include <arch/types.h> |
#include <arch/exception.h> |
#include <align.h> |
#include <config.h> |
#include <print.h> |
#include <symtab.h> |
static phte_t *phte; |
/** Try to find PTE for faulting address |
* |
* Try to find PTE for faulting address. |
* The as->lock must be held on entry to this function |
* if lock is true. |
* |
* @param as Address space. |
* @param lock Lock/unlock the address space. |
* @param badvaddr Faulting virtual address. |
* @param access Access mode that caused the fault. |
* @param istate Pointer to interrupted state. |
* @param pfrc Pointer to variable where as_page_fault() return code will be stored. |
* @return PTE on success, NULL otherwise. |
* |
*/ |
static pte_t *find_mapping_and_check(as_t *as, bool lock, uintptr_t badvaddr, int access, |
istate_t *istate, int *pfrc) |
{ |
/* |
* Check if the mapping exists in page tables. |
*/ |
pte_t *pte = page_mapping_find(as, badvaddr); |
if ((pte) && (pte->p)) { |
/* |
* Mapping found in page tables. |
* Immediately succeed. |
*/ |
return pte; |
} else { |
int rc; |
/* |
* Mapping not found in page tables. |
* Resort to higher-level page fault handler. |
*/ |
page_table_unlock(as, lock); |
switch (rc = as_page_fault(badvaddr, access, istate)) { |
case AS_PF_OK: |
/* |
* The higher-level page fault handler succeeded, |
* The mapping ought to be in place. |
*/ |
page_table_lock(as, lock); |
pte = page_mapping_find(as, badvaddr); |
ASSERT((pte) && (pte->p)); |
*pfrc = 0; |
return pte; |
case AS_PF_DEFER: |
page_table_lock(as, lock); |
*pfrc = rc; |
return NULL; |
case AS_PF_FAULT: |
page_table_lock(as, lock); |
printf("Page fault.\n"); |
*pfrc = rc; |
return NULL; |
default: |
panic("unexpected rc (%d)\n", rc); |
} |
} |
} |
static void pht_refill_fail(uintptr_t badvaddr, istate_t *istate) |
{ |
char *symbol = ""; |
char *sym2 = ""; |
char *s = get_symtab_entry(istate->pc); |
if (s) |
symbol = s; |
s = get_symtab_entry(istate->lr); |
if (s) |
sym2 = s; |
panic("%p: PHT Refill Exception at %p (%s<-%s)\n", badvaddr, istate->pc, symbol, sym2); |
} |
static void pht_insert(const uintptr_t vaddr, const pfn_t pfn) |
{ |
uint32_t page = (vaddr >> 12) & 0xffff; |
uint32_t api = (vaddr >> 22) & 0x3f; |
uint32_t vsid; |
asm volatile ( |
"mfsrin %0, %1\n" |
: "=r" (vsid) |
: "r" (vaddr) |
); |
/* Primary hash (xor) */ |
uint32_t h = 0; |
uint32_t hash = vsid ^ page; |
uint32_t base = (hash & 0x3ff) << 3; |
uint32_t i; |
bool found = false; |
/* Find unused or colliding |
PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if ((!phte[base + i].v) || ((phte[base + i].vsid == vsid) && (phte[base + i].api == api))) { |
found = true; |
break; |
} |
} |
if (!found) { |
/* Secondary hash (not) */ |
uint32_t base2 = (~hash & 0x3ff) << 3; |
/* Find unused or colliding |
PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if ((!phte[base2 + i].v) || ((phte[base2 + i].vsid == vsid) && (phte[base2 + i].api == api))) { |
found = true; |
base = base2; |
h = 1; |
break; |
} |
} |
if (!found) { |
// TODO: A/C precedence groups |
i = page % 8; |
} |
} |
phte[base + i].v = 1; |
phte[base + i].vsid = vsid; |
phte[base + i].h = h; |
phte[base + i].api = api; |
phte[base + i].rpn = pfn; |
phte[base + i].r = 0; |
phte[base + i].c = 0; |
phte[base + i].pp = 2; // FIXME |
} |
/** Process Instruction/Data Storage Interrupt |
* |
* @param data True if Data Storage Interrupt. |
* @param istate Interrupted register context. |
* |
*/ |
void pht_refill(bool data, istate_t *istate) |
{ |
uintptr_t badvaddr; |
pte_t *pte; |
int pfrc; |
as_t *as; |
bool lock; |
if (AS == NULL) { |
as = AS_KERNEL; |
lock = false; |
} else { |
as = AS; |
lock = true; |
} |
if (data) { |
asm volatile ( |
"mfdar %0\n" |
: "=r" (badvaddr) |
); |
} else |
badvaddr = istate->pc; |
page_table_lock(as, lock); |
pte = find_mapping_and_check(as, lock, badvaddr, PF_ACCESS_READ /* FIXME */, istate, &pfrc); |
if (!pte) { |
switch (pfrc) { |
case AS_PF_FAULT: |
goto fail; |
break; |
case AS_PF_DEFER: |
/* |
* The page fault came during copy_from_uspace() |
* or copy_to_uspace(). |
*/ |
page_table_unlock(as, lock); |
return; |
default: |
panic("Unexpected pfrc (%d)\n", pfrc); |
} |
} |
pte->a = 1; /* Record access to PTE */ |
pht_insert(badvaddr, pte->pfn); |
page_table_unlock(as, lock); |
return; |
fail: |
page_table_unlock(as, lock); |
pht_refill_fail(badvaddr, istate); |
} |
void pht_init(void) |
{ |
memsetb(phte, 1 << PHT_BITS, 0); |
} |
void page_arch_init(void) |
{ |
if (config.cpu_active == 1) { |
page_mapping_operations = &pt_mapping_operations; |
uintptr_t cur; |
int flags; |
for (cur = 128 << 20; cur < last_frame; cur += FRAME_SIZE) { |
flags = PAGE_CACHEABLE | PAGE_WRITE; |
if ((PA2KA(cur) >= config.base) && (PA2KA(cur) < config.base + config.kernel_size)) |
flags |= PAGE_GLOBAL; |
page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags); |
} |
/* Allocate page hash table */ |
phte_t *physical_phte = (phte_t *) frame_alloc(PHT_ORDER, FRAME_KA | FRAME_ATOMIC); |
ASSERT((uintptr_t) physical_phte % (1 << PHT_BITS) == 0); |
pht_init(); |
asm volatile ( |
"mtsdr1 %0\n" |
: |
: "r" ((uintptr_t) physical_phte) |
); |
} |
} |
uintptr_t hw_map(uintptr_t physaddr, size_t size) |
{ |
if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) |
panic("Unable to map physical memory %p (%" PRIs " 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_WRITE); |
last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE); |
return virtaddr; |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/src/mm/frame.c |
---|
0,0 → 1,84 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64mm |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/boot/boot.h> |
#include <arch/mm/frame.h> |
#include <mm/frame.h> |
#include <align.h> |
#include <macros.h> |
#include <print.h> |
uintptr_t last_frame = 0; |
void physmem_print(void) |
{ |
unsigned int i; |
printf("Base Size\n"); |
printf("---------- ----------\n"); |
for (i = 0; i < bootinfo.memmap.count; i++) { |
printf("%#10x %#10x\n", bootinfo.memmap.zones[i].start, |
bootinfo.memmap.zones[i].size); |
} |
} |
void frame_arch_init(void) |
{ |
pfn_t minconf = 2; |
count_t i; |
pfn_t start, conf; |
size_t size; |
for (i = 0; i < bootinfo.memmap.count; i++) { |
start = ADDR2PFN(ALIGN_UP(bootinfo.memmap.zones[i].start, FRAME_SIZE)); |
size = SIZE2FRAMES(ALIGN_DOWN(bootinfo.memmap.zones[i].size, FRAME_SIZE)); |
if ((minconf < start) || (minconf >= start + size)) |
conf = start; |
else |
conf = minconf; |
zone_create(start, size, conf, 0); |
if (last_frame < ALIGN_UP(bootinfo.memmap.zones[i].start + bootinfo.memmap.zones[i].size, FRAME_SIZE)) |
last_frame = ALIGN_UP(bootinfo.memmap.zones[i].start + bootinfo.memmap.zones[i].size, FRAME_SIZE); |
} |
/* First is exception vector, second is 'implementation specific', third and fourth is reserved */ |
frame_mark_unavailable(0, 4); |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/src/mm/as.c |
---|
0,0 → 1,46 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64mm |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/mm/as.h> |
#include <genarch/mm/page_pt.h> |
/** Architecture dependent address space init. */ |
void as_arch_init(void) |
{ |
as_operations = &as_pt_operations; |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/src/mm/tlb.c |
---|
0,0 → 1,86 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64mm |
* @{ |
*/ |
/** @file |
*/ |
#include <mm/tlb.h> |
/** Initialize Page Hash Table. |
* |
* Setup the Page Hash Table with no entries. |
* |
*/ |
void tlb_arch_init(void) |
{ |
tlb_invalidate_all(); |
} |
void tlb_invalidate_all(void) |
{ |
asm volatile ( |
"tlbia\n" |
"tlbsync\n" |
); |
} |
/** Invalidate all entries in TLB that belong to specified address space. |
* |
* @param asid This parameter is ignored as the architecture doesn't support it. |
*/ |
void tlb_invalidate_asid(asid_t asid) |
{ |
tlb_invalidate_all(); |
} |
/** Invalidate TLB entries for specified page range belonging to specified address space. |
* |
* @param asid This parameter is ignored as the architecture doesn't support it. |
* @param page Address of the first page whose entry is to be invalidated. |
* @param cnt Number of entries to invalidate. |
*/ |
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt) |
{ |
tlb_invalidate_all(); |
} |
/** Print contents of Page Hash Table. */ |
void tlb_print(void) |
{ |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/src/cpu/cpu.c |
---|
0,0 → 1,60 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/cpu.h> |
#include <arch/cpuid.h> |
#include <cpu.h> |
#include <arch.h> |
#include <print.h> |
void cpu_arch_init(void) |
{ |
} |
void cpu_identify(void) |
{ |
cpu_info_t info; |
cpu_version(&info); |
CPU->arch.version = info.version; |
CPU->arch.revision = info.revision; |
} |
void cpu_print_report(cpu_t *m) |
{ |
printf("cpu%u: version=%d, revision=%d\n", m->id, m->arch.version, m->arch.revision); |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/src/interrupt.c |
---|
0,0 → 1,108 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64interrupt |
* @{ |
*/ |
/** @file |
*/ |
#include <ddi/irq.h> |
#include <interrupt.h> |
#include <arch/interrupt.h> |
#include <arch/types.h> |
#include <arch.h> |
#include <time/clock.h> |
#include <ipc/sysipc.h> |
#include <arch/drivers/pic.h> |
#include <arch/mm/tlb.h> |
#include <print.h> |
void start_decrementer(void) |
{ |
asm volatile ( |
"mtdec %0\n" |
: |
: "r" (1000) |
); |
} |
/** Handler of external interrupts */ |
static void exception_external(int n, istate_t *istate) |
{ |
int inum; |
while ((inum = pic_get_pending()) != -1) { |
bool ack = false; |
irq_t *irq = irq_dispatch_and_lock(inum); |
if (irq) { |
/* |
* The IRQ handler was found. |
*/ |
if (irq->preack) { |
/* Acknowledge the interrupt before processing */ |
pic_ack_interrupt(inum); |
ack = true; |
} |
irq->handler(irq, irq->arg); |
spinlock_unlock(&irq->lock); |
} else { |
/* |
* Spurious interrupt. |
*/ |
#ifdef CONFIG_DEBUG |
printf("cpu%u: spurious interrupt (inum=%d)\n", CPU->id, inum); |
#endif |
} |
if (!ack) |
pic_ack_interrupt(inum); |
} |
} |
static void exception_decrementer(int n, istate_t *istate) |
{ |
clock(); |
start_decrementer(); |
} |
/* Initialize basic tables for exception dispatching */ |
void interrupt_init(void) |
{ |
exc_register(VECTOR_EXTERNAL, "external", exception_external); |
exc_register(VECTOR_DECREMENTER, "timer", exception_decrementer); |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/src/context.S |
---|
0,0 → 1,61 |
# |
# Copyright (c) 2005 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
#include <arch/asm/regname.h> |
#include <arch/context_offset.h> |
.text |
.global context_save_arch |
.global context_restore_arch |
context_save_arch: |
CONTEXT_SAVE_ARCH_CORE r3 |
mflr r4 |
stw r4, OFFSET_PC(r3) |
mfcr r4 |
stw r4, OFFSET_CR(r3) |
# context_save returns 1 |
li r3, 1 |
blr |
context_restore_arch: |
CONTEXT_RESTORE_ARCH_CORE r3 |
lwz r4, OFFSET_CR(r3) |
mtcr r4 |
lwz r4, OFFSET_PC(r3) |
mtlr r4 |
# context_restore returns 0 |
li r3, 0 |
blr |
/branches/arm/kernel/arch/ppc64/src/ppc64.c |
---|
0,0 → 1,144 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#include <arch.h> |
#include <arch/boot/boot.h> |
#include <arch/interrupt.h> |
#include <genarch/fb/fb.h> |
#include <genarch/fb/visuals.h> |
#include <userspace.h> |
#include <proc/uarg.h> |
#include <console/console.h> |
bootinfo_t bootinfo; |
void arch_pre_main(void) |
{ |
/* Setup usermode */ |
init.cnt = bootinfo.taskmap.count; |
uint32_t i; |
for (i = 0; i < bootinfo.taskmap.count; i++) { |
init.tasks[i].addr = PA2KA(bootinfo.taskmap.tasks[i].addr); |
init.tasks[i].size = bootinfo.taskmap.tasks[i].size; |
} |
} |
void arch_pre_mm_init(void) |
{ |
/* Initialize dispatch table */ |
interrupt_init(); |
/* Start decrementer */ |
start_decrementer(); |
} |
void arch_post_mm_init(void) |
{ |
if (config.cpu_active == 1) { |
/* Initialize framebuffer */ |
unsigned int visual; |
switch (bootinfo.screen.bpp) { |
case 8: |
visual = VISUAL_INDIRECT_8; |
break; |
case 16: |
visual = VISUAL_RGB_5_5_5; |
break; |
case 24: |
visual = VISUAL_RGB_8_8_8; |
break; |
case 32: |
visual = VISUAL_RGB_0_8_8_8; |
break; |
default: |
panic("Unsupported bits per pixel"); |
} |
fb_init(bootinfo.screen.addr, bootinfo.screen.width, bootinfo.screen.height, bootinfo.screen.scanline, visual); |
/* Merge all zones to 1 big zone */ |
zone_merge_all(); |
} |
} |
void arch_post_cpu_init(void) |
{ |
} |
void arch_pre_smp_init(void) |
{ |
} |
void arch_post_smp_init(void) |
{ |
} |
void calibrate_delay_loop(void) |
{ |
} |
void userspace(uspace_arg_t *kernel_uarg) |
{ |
userspace_asm((uintptr_t) kernel_uarg->uspace_uarg, (uintptr_t) kernel_uarg->uspace_stack + THREAD_STACK_SIZE - SP_DELTA, (uintptr_t) kernel_uarg->uspace_entry); |
/* Unreachable */ |
for (;;) |
; |
} |
/** Acquire console back for kernel |
* |
*/ |
void arch_grab_console(void) |
{ |
} |
/** Return console to userspace |
* |
*/ |
void arch_release_console(void) |
{ |
} |
void arch_reboot(void) |
{ |
// TODO |
while (1); |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/src/ddi/ddi.c |
---|
0,0 → 1,55 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64ddi |
* @{ |
*/ |
/** @file |
*/ |
#include <ddi/ddi.h> |
#include <proc/task.h> |
#include <arch/types.h> |
/** Enable I/O space range for task. |
* |
* Interrupts are disabled and task is locked. |
* |
* @param task Task. |
* @param ioaddr Startign I/O space address. |
* @param size Size of the enabled I/O range. |
* |
* @return 0 on success or an error code from errno.h. |
*/ |
int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size) |
{ |
return 0; |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/src/drivers/pic.c |
---|
0,0 → 1,94 |
/* |
* Copyright (c) 2006 Ondrej Palkovsky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/drivers/pic.h> |
#include <mm/page.h> |
#include <byteorder.h> |
#include <bitops.h> |
static volatile uint32_t *pic; |
void pic_init(uintptr_t base, size_t size) |
{ |
pic = (uint32_t *) hw_map(base, size); |
} |
void pic_enable_interrupt(int intnum) |
{ |
if (intnum < 32) { |
pic[PIC_MASK_LOW] = pic[PIC_MASK_LOW] | (1 << intnum); |
} else { |
pic[PIC_MASK_HIGH] = pic[PIC_MASK_HIGH] | (1 << (intnum - 32)); |
} |
} |
void pic_disable_interrupt(int intnum) |
{ |
if (intnum < 32) { |
pic[PIC_MASK_LOW] = pic[PIC_MASK_LOW] & (~(1 << intnum)); |
} else { |
pic[PIC_MASK_HIGH] = pic[PIC_MASK_HIGH] & (~(1 << (intnum - 32))); |
} |
} |
void pic_ack_interrupt(int intnum) |
{ |
if (intnum < 32) |
pic[PIC_ACK_LOW] = 1 << intnum; |
else |
pic[PIC_ACK_HIGH] = 1 << (intnum - 32); |
} |
/** Return number of pending interrupt */ |
int pic_get_pending(void) |
{ |
int pending; |
pending = pic[PIC_PENDING_LOW]; |
if (pending) |
return fnzb32(pending); |
pending = pic[PIC_PENDING_HIGH]; |
if (pending) |
return fnzb32(pending) + 32; |
return -1; |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/src/exception.S |
---|
0,0 → 1,237 |
# |
# Copyright (c) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
#include <arch/asm/regname.h> |
#include <arch/mm/page.h> |
.section K_UNMAPPED_TEXT_START, "ax" |
.macro CONTEXT_STORE |
# save R12 in SPRG1, backup CR in R12 |
# save SP in SPRG2 |
mtsprg1 r12 |
mfcr r12 |
mtsprg2 sp |
# check whether SP is in kernel |
andis. sp, sp, 0x8000 |
bne 1f |
# stack is in user-space |
mfsprg0 sp |
b 2f |
1: |
# stack is in kernel |
mfsprg2 sp |
subis sp, sp, 0x8000 |
2: |
subi sp, sp, 160 |
stw r0, 8(sp) |
stw r2, 12(sp) |
stw r3, 16(sp) |
stw r4, 20(sp) |
stw r5, 24(sp) |
stw r6, 28(sp) |
stw r7, 32(sp) |
stw r8, 36(sp) |
stw r9, 40(sp) |
stw r10, 44(sp) |
stw r11, 48(sp) |
stw r13, 52(sp) |
stw r14, 56(sp) |
stw r15, 60(sp) |
stw r16, 64(sp) |
stw r17, 68(sp) |
stw r18, 72(sp) |
stw r19, 76(sp) |
stw r20, 80(sp) |
stw r21, 84(sp) |
stw r22, 88(sp) |
stw r23, 92(sp) |
stw r24, 96(sp) |
stw r25, 100(sp) |
stw r26, 104(sp) |
stw r27, 108(sp) |
stw r28, 112(sp) |
stw r29, 116(sp) |
stw r30, 120(sp) |
stw r31, 124(sp) |
stw r12, 128(sp) |
mfsrr0 r12 |
stw r12, 132(sp) |
mfsrr1 r12 |
stw r12, 136(sp) |
mflr r12 |
stw r12, 140(sp) |
mfctr r12 |
stw r12, 144(sp) |
mfxer r12 |
stw r12, 148(sp) |
mfsprg1 r12 |
stw r12, 152(sp) |
mfsprg2 r12 |
stw r12, 156(sp) |
.endm |
.org 0x060 |
jump_to_kernel: |
lis r12, iret@ha |
addi r12, r12, iret@l |
mtlr r12 |
mfmsr r12 |
ori r12, r12, (msr_ir | msr_dr)@l |
mtsrr1 r12 |
addis sp, sp, 0x8000 |
mr r4, sp |
addi r4, r4, 8 |
rfi |
jump_to_kernel_syscall: |
lis r12, syscall_handler@ha |
addi r12, r12, syscall_handler@l |
mtsrr0 r12 |
lis r12, iret_syscall@ha |
addi r12, r12, iret_syscall@l |
mtlr r12 |
mfmsr r12 |
ori r12, r12, (msr_ir | msr_dr)@l |
mtsrr1 r12 |
addis sp, sp, 0x8000 |
rfi |
.org 0x100 |
.global exc_system_reset |
exc_system_reset: |
b exc_system_reset |
.org 0x200 |
.global exc_machine_check |
exc_machine_check: |
b exc_machine_check |
.org 0x300 |
.global exc_data_storage |
exc_data_storage: |
CONTEXT_STORE |
lis r12, pht_refill@ha |
addi r12, r12, pht_refill@l |
mtsrr0 r12 |
li r3, 1 |
b jump_to_kernel |
.org 0x400 |
.global exc_instruction_storage |
exc_instruction_storage: |
CONTEXT_STORE |
lis r12, pht_refill@ha |
addi r12, r12, pht_refill@l |
mtsrr0 r12 |
li r3, 0 |
b jump_to_kernel |
.org 0x500 |
.global exc_external |
exc_external: |
b exc_external |
.org 0x600 |
.global exc_alignment |
exc_alignment: |
b exc_alignment |
.org 0x700 |
.global exc_program |
exc_program: |
b exc_program |
.org 0x800 |
.global exc_fp_unavailable |
exc_fp_unavailable: |
b exc_fp_unavailable |
.org 0x900 |
.global exc_decrementer |
exc_decrementer: |
CONTEXT_STORE |
lis r12, exc_dispatch@ha |
addi r12, r12, exc_dispatch@l |
mtsrr0 r12 |
li r3, 10 |
b jump_to_kernel |
.org 0xa00 |
.global exc_reserved0 |
exc_reserved0: |
b exc_reserved0 |
.org 0xb00 |
.global exc_reserved1 |
exc_reserved1: |
b exc_reserved1 |
.org 0xc00 |
.global exc_syscall |
exc_syscall: |
CONTEXT_STORE |
b jump_to_kernel_syscall |
.org 0xd00 |
.global exc_trace |
exc_trace: |
b exc_trace |
/branches/arm/kernel/arch/ppc64/src/fpu_context.S |
---|
0,0 → 1,105 |
# |
# Copyright (c) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
#include <arch/asm/regname.h> |
#include <arch/context_offset.h> |
.text |
.global fpu_context_save |
.global fpu_context_restore |
.global fpu_init |
.global fpu_enable |
.global fpu_disable |
.macro FPU_CONTEXT_STORE r |
stfd fr14, OFFSET_FR14(\r) |
stfd fr15, OFFSET_FR15(\r) |
stfd fr16, OFFSET_FR16(\r) |
stfd fr17, OFFSET_FR17(\r) |
stfd fr18, OFFSET_FR18(\r) |
stfd fr19, OFFSET_FR19(\r) |
stfd fr20, OFFSET_FR20(\r) |
stfd fr21, OFFSET_FR21(\r) |
stfd fr22, OFFSET_FR22(\r) |
stfd fr23, OFFSET_FR23(\r) |
stfd fr24, OFFSET_FR24(\r) |
stfd fr25, OFFSET_FR25(\r) |
stfd fr26, OFFSET_FR26(\r) |
stfd fr27, OFFSET_FR27(\r) |
stfd fr28, OFFSET_FR28(\r) |
stfd fr29, OFFSET_FR29(\r) |
stfd fr30, OFFSET_FR30(\r) |
stfd fr31, OFFSET_FR31(\r) |
.endm |
.macro FPU_CONTEXT_LOAD r |
lfd fr14, OFFSET_FR14(\r) |
lfd fr15, OFFSET_FR15(\r) |
lfd fr16, OFFSET_FR16(\r) |
lfd fr17, OFFSET_FR17(\r) |
lfd fr18, OFFSET_FR18(\r) |
lfd fr19, OFFSET_FR19(\r) |
lfd fr20, OFFSET_FR20(\r) |
lfd fr21, OFFSET_FR21(\r) |
lfd fr22, OFFSET_FR22(\r) |
lfd fr23, OFFSET_FR23(\r) |
lfd fr24, OFFSET_FR24(\r) |
lfd fr25, OFFSET_FR25(\r) |
lfd fr26, OFFSET_FR26(\r) |
lfd fr27, OFFSET_FR27(\r) |
lfd fr28, OFFSET_FR28(\r) |
lfd fr29, OFFSET_FR29(\r) |
lfd fr30, OFFSET_FR30(\r) |
lfd fr31, OFFSET_FR31(\r) |
.endm |
fpu_context_save: |
// FPU_CONTEXT_STORE r3 |
// |
// mffs fr0 |
// stfd fr0, OFFSET_FPSCR(r3) |
blr |
fpu_context_restore: |
// FPU_CONTEXT_LOAD r3 |
// |
// lfd fr0, OFFSET_FPSCR(r3) |
// mtfsf 7, fr0 |
blr |
fpu_init: |
blr |
fpu_enable: |
blr |
fpu_disable: |
blr |
/branches/arm/kernel/arch/ppc64/src/boot/boot.S |
---|
0,0 → 1,81 |
# |
# Copyright (c) 2005 Jakub Jermar |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
#include <arch/asm/regname.h> |
#include <arch/boot/boot.h> |
.section K_TEXT_START, "ax" |
.global kernel_image_start |
kernel_image_start: |
# load temporal kernel stack |
lis sp, kernel_stack@ha |
addi sp, sp, kernel_stack@l |
# set kernel stack for interrupt handling |
mr r31, sp |
subis r31, r31, 0x8000 |
mtsprg0 r31 |
# r3 contains physical address of bootinfo_t |
# r4 contains size of bootinfo_t |
addis r3, r3, 0x8000 |
lis r31, bootinfo@ha |
addi r31, r31, bootinfo@l # r31 = bootinfo |
cmpwi r4, 0 |
beq bootinfo_end |
bootinfo_loop: |
lwz r30, 0(r3) |
stw r30, 0(r31) |
addi r3, r3, 4 |
addi r31, r31, 4 |
subi r4, r4, 4 |
cmpwi r4, 0 |
bgt bootinfo_loop |
bootinfo_end: |
bl arch_pre_main |
b main_bsp |
.section K_DATA_START, "aw", @progbits |
.align 12 |
kernel_stack_bottom: |
.space TEMP_STACK_SIZE |
kernel_stack: |
/branches/arm/kernel/arch/ppc64/src/proc/scheduler.c |
---|
0,0 → 1,63 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64proc |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/mm/page.h> |
#include <arch/boot/boot.h> |
#include <proc/scheduler.h> |
#include <proc/thread.h> |
#include <arch.h> |
/** Perform ppc64 specific tasks needed before the new task is run. */ |
void before_task_runs_arch(void) |
{ |
} |
/** Perform ppc64 specific tasks needed before the new thread is scheduled. */ |
void before_thread_runs_arch(void) |
{ |
pht_init(); |
tlb_invalidate_all(); |
asm volatile ( |
"mtsprg0 %0\n" |
: |
: "r" (KA2PA(&THREAD->kstack[THREAD_STACK_SIZE - SP_DELTA])) |
); |
} |
void after_thread_ran_arch(void) |
{ |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/ppc64/src/debug/panic.s |
---|
0,0 → 1,38 |
# |
# Copyright (c) 2005 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
#include <arch/asm/macro.h> |
.text |
.global panic_printf |
panic_printf: |
lis %r14, halt@ha |
addi %r14, %r14, halt@l |
mtlr %r14 # fake stack to make printf return to halt |
b printf |
/branches/arm/kernel/arch/ppc64/src/dummy.s |
---|
0,0 → 1,38 |
# |
# Copyright (c) 2005 Jakub Jermar |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
.text |
.global asm_delay_loop |
.global sys_tls_set |
sys_tls_set: |
b sys_tls_set |
asm_delay_loop: |
blr |
/branches/arm/kernel/arch/ppc64/_link.ld.in |
---|
0,0 → 1,58 |
/** PPC64 linker script |
* |
* umapped section: |
* kernel text |
* kernel data |
* mapped section: |
* kernel text |
* kernel data |
* |
*/ |
#include <arch/boot/boot.h> |
#include <arch/mm/page.h> |
ENTRY(kernel_image_start) |
OUTPUT_FORMAT("elf64-powerpc") |
OUTPUT_ARCH(powerpc:common64) |
SECTIONS { |
.unmapped 0: AT (0) { |
unmapped_ktext_start = .; |
*(K_UNMAPPED_TEXT_START); |
unmapped_ktext_end = .; |
unmapped_kdata_start = .; |
*(K_UNMAPPED_DATA_START); |
unmapped_kdata_start = .; |
} |
.mapped PA2KA(BOOT_OFFSET): AT (BOOT_OFFSET) { |
ktext_start = .; |
*(K_TEXT_START); |
*(.text); |
ktext_end = .; |
kdata_start = .; |
*(K_DATA_START); |
*(.rodata); |
*(.rodata.*); |
*(.data); /* initialized data */ |
*(.sdata); |
*(.sdata2); |
*(.sbss); |
hardcoded_ktext_size = .; |
LONG(ktext_end - ktext_start); |
hardcoded_kdata_size = .; |
LONG(kdata_end - kdata_start); |
hardcoded_load_address = .; |
LONG(PA2KA(BOOT_OFFSET)); |
*(.bss); /* uninitialized static variables */ |
*(COMMON); /* global variables */ |
symbol_table = .; |
*(symtab.*); /* Symbol table, must be LAST symbol!*/ |
kdata_end = .; |
} |
} |