Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev HEAD → Rev 2242

/branches/arm/kernel/arch/mips32/include/mm/page.h
40,6 → 40,8
#define PAGE_WIDTH FRAME_WIDTH
#define PAGE_SIZE FRAME_SIZE
 
#define PAGE_COLOR_BITS 0 /* dummy */
 
#ifndef __ASM__
# define KA2PA(x) (((uintptr_t) (x)) - 0x80000000)
# define PA2KA(x) (((uintptr_t) (x)) + 0x80000000)
56,15 → 58,11
* Page table layout:
* - 32-bit virtual addresses
* - Offset is 14 bits => pages are 16K long
* - PTE's use similar format as CP0 EntryLo[01] registers => PTE is therefore
* 4 bytes long
* - PTE's use similar format as CP0 EntryLo[01] registers => PTE is therefore 4 bytes long
* - PTE's replace EntryLo v (valid) bit with p (present) bit
* - PTE's use only one bit to distinguish between cacheable and uncacheable
* mappings
* - PTE's define soft_valid field to ensure there is at least one 1 bit even if
* the p bit is cleared
* - PTE's make use of CP0 EntryLo's two-bit reserved field for bit W (writable)
* and bit A (accessed)
* - PTE's use only one bit to distinguish between cacheable and uncacheable mappings
* - PTE's define soft_valid field to ensure there is at least one 1 bit even if the p bit is cleared
* - PTE's make use of CP0 EntryLo's two-bit reserved field for bit W (writable) and bit A (accessed)
* - PTL0 has 64 entries (6 bits)
* - PTL1 is not used
* - PTL2 is not used
71,67 → 69,46
* - PTL3 has 4096 entries (12 bits)
*/
/* Macros describing number of entries in each level. */
#define PTL0_ENTRIES_ARCH 64
#define PTL1_ENTRIES_ARCH 0
#define PTL2_ENTRIES_ARCH 0
#define PTL3_ENTRIES_ARCH 4096
 
/* Macros describing size 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
#define PTL0_SIZE_ARCH ONE_FRAME
#define PTL1_SIZE_ARCH 0
#define PTL2_SIZE_ARCH 0
#define PTL3_SIZE_ARCH FOUR_FRAMES
 
/* Macros calculating entry indices for each level. */
#define PTL0_INDEX_ARCH(vaddr) ((vaddr) >> 26)
#define PTL1_INDEX_ARCH(vaddr) 0
#define PTL2_INDEX_ARCH(vaddr) 0
#define PTL3_INDEX_ARCH(vaddr) (((vaddr) >> 14) & 0xfff)
#define PTL0_INDEX_ARCH(vaddr) ((vaddr)>>26)
#define PTL1_INDEX_ARCH(vaddr) 0
#define PTL2_INDEX_ARCH(vaddr) 0
#define PTL3_INDEX_ARCH(vaddr) (((vaddr)>>14) & 0xfff)
 
/* Set accessor for PTL0 address. */
#define SET_PTL0_ADDRESS_ARCH(ptl0)
 
/* 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)
#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_PTL1_ADDRESS_ARCH(ptl0, i, a) \
(((pte_t *) (ptl0))[(i)].pfn = (a) >> 12)
#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) (((pte_t *)(ptl0))[(i)].pfn = (a)>>12)
#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) \
(((pte_t *) (ptl3))[(i)].pfn = (a) >> 12)
#define 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), (size_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))
#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), (size_t) (i), (x))
#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), (size_t) (i), (x))
#define SET_FRAME_FLAGS_ARCH(ptl3, 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)
#define PTE_PRESENT_ARCH(pte) ((pte)->p != 0)
#define PTE_GET_FRAME_ARCH(pte) ((pte)->pfn << 12)
#define PTE_GET_FRAME_ARCH(pte) ((pte)->pfn<<12)
#define PTE_WRITABLE_ARCH(pte) ((pte)->w != 0)
#define PTE_EXECUTABLE_ARCH(pte) 1
 
140,20 → 117,23
#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];
return ((p->cacheable << PAGE_CACHEABLE_SHIFT) |
((!p->p) << PAGE_PRESENT_SHIFT) |
(1 << PAGE_USER_SHIFT) |
(1 << PAGE_READ_SHIFT) |
((p->w) << PAGE_WRITE_SHIFT) |
(1 << PAGE_EXEC_SHIFT) |
(p->g << PAGE_GLOBAL_SHIFT));
return (
(p->cacheable<<PAGE_CACHEABLE_SHIFT) |
((!p->p)<<PAGE_PRESENT_SHIFT) |
(1<<PAGE_USER_SHIFT) |
(1<<PAGE_READ_SHIFT) |
((p->w)<<PAGE_WRITE_SHIFT) |
(1<<PAGE_EXEC_SHIFT) |
(p->g<<PAGE_GLOBAL_SHIFT)
);
}
 
static inline void set_pt_flags(pte_t *pt, 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
35,43 → 35,38
#ifndef KERN_mips32_TLB_H_
#define KERN_mips32_TLB_H_
 
#include <arch/types.h>
#include <typedefs.h>
#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_16K (0x3<<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,13 → 154,11
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);
extern void tlb_modified(istate_t *istate);
extern void tlb_prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, uintptr_t pfn);
extern void tlb_prepare_entry_hi(entry_hi_t *hi, asid_t asid, uintptr_t addr);
 
#endif
 
/branches/arm/kernel/arch/mips32/include/mm/as.h
38,7 → 38,7
#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH 0
 
#define KERNEL_ADDRESS_SPACE_START_ARCH (unsigned long) 0x80000000
#define KERNEL_ADDRESS_SPACE_END_ARCH (unsigned long) 0x9fffffff
#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
 
/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,16 → 35,13
#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);
 
#endif /* __ASM__ */
#endif /* KERNEL */
/branches/arm/kernel/arch/mips32/include/mm/memory_init.h
0,0 → 1,48
/*
* Copyright (c) 2005 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup mips32mm
* @{
*/
/** @file
*/
 
#ifndef KERN_mips32_MEMORY_INIT_H_
#define KERN_mips32_MEMORY_INIT_H_
 
#include <config.h>
 
/* When this function is called, we do not have ARC initiated
* - provide some reasonable minimum and update it later
*/
#define get_memory_size() CONFIG_MEMORY_SIZE
 
#endif
 
/** @}
*/
/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/context_offset.h
42,24 → 42,6
#define OFFSET_S8 0x28
#define OFFSET_GP 0x2c
 
#ifdef KERNEL
# define OFFSET_IPL 0x30
#else
# define OFFSET_TLS 0x30
 
# define OFFSET_F20 0x34
# define OFFSET_F21 0x38
# define OFFSET_F22 0x3c
# define OFFSET_F23 0x40
# define OFFSET_F24 0x44
# define OFFSET_F25 0x48
# define OFFSET_F26 0x4c
# define OFFSET_F27 0x50
# define OFFSET_F28 0x54
# define OFFSET_F29 0x58
# define OFFSET_F30 0x5c
#endif /* KERNEL */
 
/* istate_t */
#define EOFFSET_AT 0x0
#define EOFFSET_V0 0x4
76,134 → 58,25
#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__
 
#include <arch/asm/regname.h>
 
# ctx: address of the structure with saved context
.macro CONTEXT_SAVE_ARCH_CORE ctx:req
sw $s0,OFFSET_S0(\ctx)
sw $s1,OFFSET_S1(\ctx)
sw $s2,OFFSET_S2(\ctx)
sw $s3,OFFSET_S3(\ctx)
sw $s4,OFFSET_S4(\ctx)
sw $s5,OFFSET_S5(\ctx)
sw $s6,OFFSET_S6(\ctx)
sw $s7,OFFSET_S7(\ctx)
sw $s8,OFFSET_S8(\ctx)
sw $gp,OFFSET_GP(\ctx)
 
#ifndef KERNEL
sw $k1,OFFSET_TLS(\ctx)
 
#ifdef CONFIG_FPU
mfc1 $t0,$20
sw $t0, OFFSET_F20(\ctx)
 
mfc1 $t0,$21
sw $t0, OFFSET_F21(\ctx)
 
mfc1 $t0,$22
sw $t0, OFFSET_F22(\ctx)
 
mfc1 $t0,$23
sw $t0, OFFSET_F23(\ctx)
 
mfc1 $t0,$24
sw $t0, OFFSET_F24(\ctx)
 
mfc1 $t0,$25
sw $t0, OFFSET_F25(\ctx)
 
mfc1 $t0,$26
sw $t0, OFFSET_F26(\ctx)
 
mfc1 $t0,$27
sw $t0, OFFSET_F27(\ctx)
 
mfc1 $t0,$28
sw $t0, OFFSET_F28(\ctx)
 
mfc1 $t0,$29
sw $t0, OFFSET_F29(\ctx)
mfc1 $t0,$30
sw $t0, OFFSET_F30(\ctx)
#endif /* CONFIG_FPU */
#endif /* KERNEL */
 
sw $ra,OFFSET_PC(\ctx)
sw $sp,OFFSET_SP(\ctx)
.endm
 
# ctx: address of the structure with saved context
.macro CONTEXT_RESTORE_ARCH_CORE ctx:req
lw $s0,OFFSET_S0(\ctx)
lw $s1,OFFSET_S1(\ctx)
lw $s2,OFFSET_S2(\ctx)
lw $s3,OFFSET_S3(\ctx)
lw $s4,OFFSET_S4(\ctx)
lw $s5,OFFSET_S5(\ctx)
lw $s6,OFFSET_S6(\ctx)
lw $s7,OFFSET_S7(\ctx)
lw $s8,OFFSET_S8(\ctx)
lw $gp,OFFSET_GP(\ctx)
#ifndef KERNEL
lw $k1,OFFSET_TLS(\ctx)
 
#ifdef CONFIG_FPU
lw $t0, OFFSET_F20(\ctx)
mtc1 $t0,$20
 
lw $t0, OFFSET_F21(\ctx)
mtc1 $t0,$21
 
lw $t0, OFFSET_F22(\ctx)
mtc1 $t0,$22
 
lw $t0, OFFSET_F23(\ctx)
mtc1 $t0,$23
 
lw $t0, OFFSET_F24(\ctx)
mtc1 $t0,$24
 
lw $t0, OFFSET_F25(\ctx)
mtc1 $t0,$25
 
lw $t0, OFFSET_F26(\ctx)
mtc1 $t0,$26
 
lw $t0, OFFSET_F27(\ctx)
mtc1 $t0,$27
 
lw $t0, OFFSET_F28(\ctx)
mtc1 $t0,$28
 
lw $t0, OFFSET_F29(\ctx)
mtc1 $t0,$29
 
lw $t0, OFFSET_F30(\ctx)
mtc1 $t0,$30
#endif /* CONFIG_FPU */
#endif /* KERNEL */
 
lw $ra,OFFSET_PC(\ctx)
lw $sp,OFFSET_SP(\ctx)
.endm
 
#endif
 
 
#endif
/branches/arm/kernel/arch/mips32/include/interrupt.h
38,13 → 38,10
#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;
 
extern void interrupt_init(void);
 
/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/types.h
35,6 → 35,10
#ifndef KERN_mips32_TYPES_H_
#define KERN_mips32_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;
46,6 → 50,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,30 → 61,13
typedef uint32_t unative_t;
typedef int32_t native_t;
 
typedef struct {
} fncptr_t;
typedef uint8_t bool;
typedef uint64_t task_id_t;
typedef uint32_t context_id_t;
 
#define PRIp "x" /**< Format for uintptr_t. */
#define PRIs "u" /**< Format for size_t. */
typedef int32_t inr_t;
typedef int32_t devno_t;
 
#define PRId8 "d" /**< Format for int8_t. */
#define PRId16 "d" /**< Format for int16_t. */
#define PRId32 "ld" /**< Format for int32_t. */
#define PRId64 "lld" /**< Format for int64_t. */
#define PRIdn "d" /**< Format for native_t. */
 
#define PRIu8 "u" /**< Format for uint8_t. */
#define PRIu16 "u" /**< Format for uint16_t. */
#define PRIu32 "u" /**< Format for uint32_t. */
#define PRIu64 "llu" /**< Format for uint64_t. */
#define PRIun "u" /**< Format for unative_t. */
 
#define PRIx8 "x" /**< Format for hexadecimal (u)int8_t. */
#define PRIx16 "x" /**< Format for hexadecimal (u)int16_t. */
#define PRIx32 "x" /**< Format for hexadecimal (u)uint32_t. */
#define PRIx64 "llx" /**< Format for hexadecimal (u)int64_t. */
#define PRIxn "x" /**< Format for hexadecimal (u)native_t. */
 
/** Page Table Entry. */
typedef struct {
unsigned g : 1; /**< Global bit. */
/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/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"
" addiu %0, %0, %3\n" /* same as addi, but never traps on overflow */
" move %2, %0\n"
" sc %0, %1\n"
" beq %0, %4, 1b\n" /* if the atomic operation failed, try again */
" 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;
}
: "=r" (tmp), "=m" (val->count), "=r" (v)
: "i" (i), "i" (0)
);
 
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/barrier.h
45,9 → 45,6
#define read_barrier() asm volatile ("" ::: "memory")
#define write_barrier() asm volatile ("" ::: "memory")
 
#define smc_coherence(a)
#define smc_coherence_block(a, l)
 
#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/cycle.h
35,12 → 35,9
#ifndef KERN_mips32_CYCLE_H_
#define KERN_mips32_CYCLE_H_
 
#include <arch/cp0.h>
#include <arch/interrupt.h>
 
static inline uint64_t get_cycle(void)
{
return ((uint64_t) count_hi << 32) + ((uint64_t) cp0_count_read());
return 0;
}
 
#endif
/branches/arm/kernel/arch/mips32/include/byteorder.h
0,0 → 1,61
/*
* Copyright (c) 2005 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup mips32
* @{
*/
/** @file
*/
 
#ifndef KERN_mips32_BYTEORDER_H_
#define KERN_mips32_BYTEORDER_H_
 
#include <byteorder.h>
 
#ifdef BIG_ENDIAN
 
#define uint32_t_le2host(n) uint32_t_byteorder_swap(n)
#define uint64_t_le2host(n) uint64_t_byteorder_swap(n)
 
#define uint32_t_be2host(n) (n)
#define uint64_t_be2host(n) (n)
 
#else
 
#define uint32_t_le2host(n) (n)
#define uint64_t_le2host(n) (n)
 
#define uint32_t_be2host(n) uint32_t_byteorder_swap(n)
#define uint64_t_be2host(n) uint64_t_byteorder_swap(n)
 
#endif
 
#endif
 
/** @}
*/
/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/stack.h
38,14 → 38,6
#define STACK_ITEM_SIZE 4
#define STACK_ALIGNMENT 8
 
#define STACK_ARG0 0
#define STACK_ARG1 4
#define STACK_ARG2 8
#define STACK_ARG3 12
#define STACK_ARG4 16
#define STACK_ARG5 20
#define STACK_ARG6 24
 
#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/memstr.h
37,10 → 37,10
 
#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 void memsetw(uintptr_t dst, size_t cnt, uint16_t x);
extern void memsetb(uintptr_t dst, size_t cnt, uint8_t x);
 
extern int memcmp(const void *a, const void *b, size_t cnt);
extern int memcmp(uintptr_t src, uintptr_t dst, int cnt);
 
#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/include/drivers/serial.h
0,0 → 1,71
/*
* Copyright (c) 2005 Ondrej Palkovsky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup mips32
* @{
*/
/** @file
*/
 
#ifndef KERN_mips32_SERIAL_H_
#define KERN_mips32_SERIAL_H_
 
#include <console/chardev.h>
 
#define SERIAL_MAX 4
#define SERIAL_COM1 0x3f8
#define SERIAL_COM1_IRQ 4
#define SERIAL_COM2 0x2f8
#define SERIAL_COM2_IRQ 3
 
#define P_WRITEB(where,what) (*((volatile char *) (0xB8000000+where))=what)
#define P_READB(where) (*((volatile char *)(0xB8000000+where)))
 
#define SERIAL_READ(x) P_READB(x)
#define SERIAL_WRITE(x,c) P_WRITEB(x,c)
/* Interrupt enable register */
#define SERIAL_READ_IER(x) (P_READB((x) + 1))
#define SERIAL_WRITE_IER(x,c) (P_WRITEB((x)+1,c))
/* Interrupt identification register */
#define SERIAL_READ_IIR(x) (P_READB((x) + 2))
/* Line status register */
#define SERIAL_READ_LSR(x) (P_READB((x) + 5))
#define TRANSMIT_EMPTY_BIT 5
 
typedef struct {
int port;
int irq;
}serial_t;
 
extern void serial_console(devno_t devno);
extern int serial_init(void);
 
#endif
 
/** @}
*/
/branches/arm/kernel/arch/mips32/include/drivers/arc.h
0,0 → 1,267
/*
* 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_ARC_H_
#define KERN_mips32_ARC_H_
 
#include <arch/types.h>
#include <console/chardev.h>
 
#define ARC_BASE_ADDR 0x1000;
#define ARC_MAGIC 0x53435241
/* Frame size used by ARC */
#define ARC_FRAME 4096
 
typedef enum {
CmResourceTypeNull = 0,
CmResourceTypePort,
CmResourceTypeInterrupt,
CmResourceTypeMemory,
CmResourceTypeDma,
CmResourceTypeDeviceSpecific,
CmResourceTypeVendor,
CmResourceTypeProductName,
CmResourceTypeSerialNumber
} cm_resource_type;
 
typedef struct {
uint8_t type;
uint8_t sharedisposition;
uint16_t flags;
union {
struct {
long long start; /* 64-bit phys address */
unsigned long length;
}port;
struct {
unsigned long level;
unsigned long vector;
unsigned long reserved1;
}interrupt;
struct {
long long start; /* 64-bit phys address */
unsigned long length;
}memory;
}u;
} __attribute__ ((packed)) cm_resource_descriptor;
 
typedef struct {
uint16_t version;
uint16_t revision;
unsigned long count;
cm_resource_descriptor descr[1];
} __attribute__ ((packed)) cm_resource_list;
 
typedef enum {
SystemClass = 0,
ProcessorClass,
CacheClass,
AdapterClass,
ControllerClass,
PeripheralClass,
MemoryClass
} arc_component_class;
 
typedef enum {
ARC_type = 0,
CPU_type,
FPU_type,
PrimaryICache,
PrimaryDCache,
SecondaryICache,
SecondaryDCache,
SecondaryCache,
Memory, /* Not in NT PROM */
EISAAdapter,
TCAdapter,
SCSIAdapter,
DTIAdapter,
MultiFunctionAdapter,
DiskController,
TapeController,
CDROMController,
WORMController,
SerialController,
NetworkController,
DisplayController,
ParallelController,
PointerController,
KeyboardController,
AudioController,
OtherController,
DiskPeripheral,
FloppyDiskPeripheral,
TapePeripheral,
ModemPeripheral,
MonitorPeripheral,
PrinterPeripheral,
PointerPeripheral,
KeyboardPeripheral,
TerminalPeripheral,
LinePeripheral,
NetworkPeripheral,
OtherPeripheral,
XTalkAdapter,
PCIAdapter,
GIOAdapter,
TPUAdapter,
Anonymous
} arc_component_type;
 
typedef enum {
Failed = 1,
ReadOnly = 2,
Removable = 4,
ConsoleIn = 8,
ConsoleOut = 16,
Input = 32,
Output = 64
} arc_component_flags;
 
typedef struct {
arc_component_class class;
arc_component_type type;
arc_component_flags flags;
uint16_t revision;
uint16_t version;
uint32_t key;
uint32_t affinitymask;
uint32_t configdatasize;
uint32_t identifier_len;
char *identifier;
} __attribute__ ((packed)) arc_component;
 
typedef struct {
uint16_t year;
uint16_t month;
uint16_t day;
uint16_t hour;
uint16_t minutes;
uint16_t seconds;
uint16_t mseconds;
} __attribute__ ((packed)) arc_timeinfo;
 
/* This is the SGI block structure, WinNT has it different */
typedef enum {
ExceptionBlock,
SystemParameterBlock,
FreeContiguous,
FreeMemory,
BadMemory,
LoadedProgram,
FirmwareTemporary,
FirmwarePermanent
} arc_memorytype_t;
 
typedef struct {
arc_memorytype_t type;
uint32_t basepage; /* *4096 = baseaddr */
uint32_t basecount;
} arc_memdescriptor_t;
 
typedef struct {
char vendorid[8];
char prodid[8];
} arc_sysid_t;
 
typedef struct {
long (*load)(void); /* ... */
long (*invoke)(uint32_t eaddr,uint32_t saddr,uint32_t argc,char **argv,
char **envp);
long (*execute)(char *path,uint32_t argc,char **argv,char **envp);
void (*halt)(void);
void (*powerdown)(void);
void (*restart)(void);
void (*reboot)(void);
void (*enterinteractivemode)(void);
long (*reserved)(void);
/* 10 */
arc_component * (*getpeer)(arc_component *c);
arc_component * (*getchild)(arc_component *c);
arc_component * (*getparent)(arc_component *c);
long (*getconfigurationdata)(void *configdata, arc_component *c);
long (*addchild)(arc_component *c, arc_component *template,
void *configdata);
long (*deletecomponet)(arc_component *current);
long (*getcomponent)(char *path);
long (*saveconfiguration)(void);
arc_sysid_t (*getsystemid)(void);
arc_memdescriptor_t * (*getmemorydescriptor)(arc_memdescriptor_t *cur);
/* 20 */
long (*reserved2)(void);
arc_timeinfo * (*gettime)(void);
uint32_t (*getrelativetime)(void);
long (*getdirectoryentry)();
long (*open)(void); /* ... */
long (*close)(uint32_t fileid);
long (*read)(uint32_t fileid,void *buf,uint32_t n,uint32_t *cnt);
long (*getreadstatus)(uint32_t fileid);
long (*write)(uint32_t fileid, void *buf,uint32_t n,uint32_t *cnt);
long (*seek)(void); /* ... */
/* 30 */
long (*mount)(void); /* ... */
char * (*getenvironmentvariable)(char *name);
char * (*setenvironmentvariable)(char *name, char *value);
long (*getfileinformation)(void); /* ... */
long (*setfileinformation)(uint32_t fileid,uint32_t attflags,uint32_t attmask);
void (*flushallcaches)(void);
long (*testunicodecharacter)(void); /* ... */
long (*getdisplaystatus)(void); /* ... */
} arc_func_vector_t;
 
typedef struct {
uint32_t signature;
uint32_t length;
uint16_t version;
uint16_t revision;
void *restartblock;
void *debugblock;
void *gevector;
void *utlbmissvector;
uint32_t firmwarevectorlen;
arc_func_vector_t *firmwarevector;
uint32_t privvectorlen;
void *privvector;
uint32_t adaptercount;
} __attribute__ ((packed)) arc_sbp;
 
extern int arc_init(void);
extern int arc_enabled(void);
void arc_frame_init(void);
void arc_console(void);
 
#endif
 
/** @}
*/
/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
35,11 → 35,12
#ifndef KERN_mips32_MSIM_H_
#define KERN_mips32_MSIM_H_
 
/** Address of devices. */
#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/smp/dorder.h
File deleted
/branches/arm/kernel/arch/mips32/Makefile.inc
30,50 → 30,99
#
 
BFD_ARCH = mips
BFD = binary
TARGET = mipsel-linux-gnu
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mipsel
TOOLCHAIN_DIR = /usr/local/mipsel
 
GCC_CFLAGS += -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mips3
KERNEL_LOAD_ADDRESS = 0x80100000
INIT_ADDRESS = 0x81000000
INIT_SIZE = 262144
 
BITS = 32
CFLAGS += -mno-abicalls -G 0 -fno-zero-initialized-in-bss
 
DEFS += -D__32_BITS__ -DMACHINE=$(MACHINE) -DKERNEL_LOAD_ADDRESS=${KERNEL_LOAD_ADDRESS} -DINIT_ADDRESS=${INIT_ADDRESS} -DINIT_SIZE=${INIT_SIZE}
 
## Compile with hierarchical page tables support.
#
 
CONFIG_PAGE_PT = y
DEFS += -DCONFIG_PAGE_PT
 
## Compile with support for address space identifiers.
#
 
CONFIG_ASID = y
CONFIG_ASID_FIFO = y
 
## Accepted MACHINEs
#
 
ifeq ($(MACHINE),indy)
# GCC 4.0.1 compiled for mipsEL has problems compiling in
# BigEndian mode with the swl/swr/lwl/lwr instructions.
# We have to compile it with mips-sgi-irix5 to get it right.
BFD_NAME = elf32-bigmips
BFD = ecoff-bigmips --impure
TARGET = mips-sgi-irix5
TOOLCHAIN_DIR = /usr/local/mips/bin
KERNEL_LOAD_ADDRESS = 0x88002000
CFLAGS += -EB -DBIG_ENDIAN -DARCH_HAS_FPU -march=r4600
INIT_ADDRESS = 0
INIT_SIZE = 0
endif
ifeq ($(MACHINE),lgxemul)
BFD_NAME = elf32-tradlittlemips
ENDIANESS = LE
BFD = binary
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 = /usr/local/mips/bin
CFLAGS += -EB -DBIG_ENDIAN -DARCH_HAS_FPU -mips3
INIT_ADDRESS = 0x81800000
endif
ifeq ($(MACHINE),simics)
# SIMICS 4kc emulation is broken, although for instructions
# that do not bother us
BFD_NAME = elf32-tradlittlemips
BFD = elf32-tradlittlemips
CFLAGS += -mhard-float -mips3 -DTLBCNT=16
TLBCNT = 16
endif
ifeq ($(MACHINE),msim)
BFD_NAME = elf32-tradlittlemips
ENDIANESS = LE
GCC_CFLAGS += -mhard-float
BFD = binary
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/arc.c \
arch/$(ARCH)/src/drivers/msim.c \
arch/$(ARCH)/src/drivers/serial.c
/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/interrupt.c
38,12 → 38,12
#include <arch.h>
#include <arch/cp0.h>
#include <time/clock.h>
#include <arch/drivers/arc.h>
#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;
89,32 → 89,23
}
 
/* TODO: This is SMP unsafe!!! */
uint32_t count_hi = 0;
static unsigned long nextcount;
static unsigned long lastcount;
 
/** Start hardware clock */
static void timer_start(void)
{
lastcount = cp0_count_read();
nextcount = cp0_compare_value + cp0_count_read();
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;
if (cp0_count_read() < lastcount)
/* Count overflow detected */
count_hi++;
lastcount = cp0_count_read();
 
drift = cp0_count_read() - nextcount;
while (drift > cp0_compare_value) {
drift -= cp0_compare_value;
122,7 → 113,7
}
nextcount = cp0_count_read() + cp0_compare_value - drift;
cp0_compare_write(nextcount);
 
/*
* We are holding a lock which prevents preemption.
* Release the lock, call clock() and reacquire the lock again.
/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%d: 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/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/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 */
104,28 → 104,30
void cpu_print_report(cpu_t *m)
{
struct data_t *data;
unsigned int i;
int i;
 
if (m->arch.imp_num & 0x80) {
/* Count records */
for (i = 0; imp_data80[i].vendor; i++);
for (i=0;imp_data80[i].vendor;i++)
;
if ((m->arch.imp_num & 0x7f) >= i) {
printf("imp=%d\n", m->arch.imp_num);
printf("imp=%d\n",m->arch.imp_num);
return;
}
data = &imp_data80[m->arch.imp_num & 0x7f];
} else {
for (i = 0; imp_data[i].vendor; i++);
for (i=0;imp_data[i].vendor;i++)
;
if (m->arch.imp_num >= i) {
printf("imp=%d\n", m->arch.imp_num);
printf("imp=%d\n",m->arch.imp_num);
return;
}
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/mips32.c
33,68 → 33,59
*/
 
#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 <arch/drivers/arc.h>
#include <console/chardev.h>
#include <arch/barrier.h>
#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;
}
}
 
105,27 → 96,24
/* Initialize dispatch table */
exception_init();
arc_init();
 
/* Copy the exception vectors to the right places */
memcpy(TLB_EXC, (char *) tlb_refill_entry, EXCEPTION_JUMP_SIZE);
smc_coherence_block(TLB_EXC, EXCEPTION_JUMP_SIZE);
memcpy(NORM_EXC, (char *) exception_entry, EXCEPTION_JUMP_SIZE);
smc_coherence_block(NORM_EXC, EXCEPTION_JUMP_SIZE);
memcpy(CACHE_EXC, (char *) cache_error_entry, EXCEPTION_JUMP_SIZE);
smc_coherence_block(CACHE_EXC, EXCEPTION_JUMP_SIZE);
/*
* Switch to BEV normal level so that exception vectors point to the
* kernel. Clear the error level.
* Switch to BEV normal level so that exception vectors point to the kernel.
* Clear the error level.
*/
cp0_status_write(cp0_status_read() &
~(cp0_status_bev_bootstrap_bit | cp0_status_erl_error_bit));
/*
* Mask all interrupts
cp0_status_write(cp0_status_read() & ~(cp0_status_bev_bootstrap_bit|cp0_status_erl_error_bit));
 
/*
* Mask all interrupts
*/
cp0_mask_all_int();
debugger_init();
}
 
132,23 → 120,11
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); // gxemul framebuffer
#endif
sysinfo_set_item_val("machine." STRING(MACHINE), NULL, 1);
}
 
void arch_post_cpu_init(void)
161,48 → 137,20
 
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 */
/* EXL=1, UM=1, IE=1 */
cp0_status_write(cp0_status_read() | (cp0_status_exl_exception_bit |
cp0_status_um_bit | cp0_status_ie_enabled_bit));
cp0_status_um_bit |
cp0_status_ie_enabled_bit));
cp0_epc_write((uintptr_t) kernel_uarg->uspace_entry);
userspace_asm(((uintptr_t) kernel_uarg->uspace_stack + PAGE_SIZE),
(uintptr_t) kernel_uarg->uspace_uarg,
(uintptr_t) kernel_uarg->uspace_entry);
while (1);
userspace_asm(((uintptr_t) kernel_uarg->uspace_stack+PAGE_SIZE),
(uintptr_t) kernel_uarg->uspace_uarg,
(uintptr_t) kernel_uarg->uspace_entry);
while (1)
;
}
 
/** Perform mips32 specific tasks needed before the new task is run. */
213,8 → 161,7
/** Perform mips32 specific tasks needed before the new thread is scheduled. */
void before_thread_runs_arch(void)
{
supervisor_sp = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE -
SP_DELTA];
supervisor_sp = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE-SP_DELTA];
}
 
void after_thread_ran_arch(void)
231,39 → 178,5
return 0;
}
 
void arch_reboot(void)
{
___halt();
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/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/drivers/msim.c
0,0 → 1,164
/*
* 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>
 
/** Address of devices. */
#define MSIM_VIDEORAM 0xB0000000
#define MSIM_KBD_ADDRESS 0xB0000000
#define MSIM_KBD_IRQ 2
 
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);
}
 
/** @}
*/
/branches/arm/kernel/arch/mips32/src/drivers/arc.c
0,0 → 1,402
/*
* Copyright (c) 2005 Ondrej Palkovsky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup mips32
* @{
*/
/** @file
*/
 
#include <arch/drivers/arc.h>
#include <arch/mm/page.h>
#include <print.h>
#include <arch.h>
#include <arch/byteorder.h>
#include <arch/mm/frame.h>
#include <mm/frame.h>
#include <interrupt.h>
#include <align.h>
#include <console/console.h>
#include <console/kconsole.h>
#include <console/cmd.h>
#include <mm/slab.h>
 
/* This is a good joke, SGI HAS different types than NT bioses... */
/* Here is the SGI type */
static char *basetypes[] = {
"ExceptionBlock",
"SystemParameterBlock",
"FreeContiguous",
"FreeMemory",
"BadMemory",
"LoadedProgram",
"FirmwareTemporary",
"FirmwarePermanent"
};
 
static char *ctypes[] = {
"ARC_type",
"CPU_type",
"FPU_type",
"PrimaryICache",
"PrimaryDCache",
"SecondaryICache",
"SecondaryDCache",
"SecondaryCache",
"Memory",
"EISAAdapter",
"TCAdapter",
"SCSIAdapter",
"DTIAdapter",
"MultiFunctionAdapter",
"DiskController",
"TapeController",
"CDROMController",
"WORMController",
"SerialController",
"NetworkController",
"DisplayController",
"ParallelController",
"PointerController",
"KeyboardController",
"AudioController",
"OtherController",
"DiskPeripheral",
"FloppyDiskPeripheral",
"TapePeripheral",
"ModemPeripheral",
"MonitorPeripheral",
"PrinterPeripheral",
"PointerPeripheral",
"KeyboardPeripheral",
"TerminalPeripheral",
"OtherPeripheral",
"LinePeripheral",
"NetworkPeripheral"
"OtherPeripheral",
"XTalkAdapter",
"PCIAdapter",
"GIOAdapter",
"TPUAdapter",
"Anonymous"
};
 
static arc_sbp *sbp = (arc_sbp *)PA2KA(0x1000);
static arc_func_vector_t *arc_entry;
 
 
static void arc_putchar(char ch);
 
/** Return true if ARC is available */
int arc_enabled(void)
{
return sbp != NULL;
}
 
 
/** Print configuration data that ARC reports about component */
static void arc_print_confdata(arc_component *c)
{
cm_resource_list *configdata;
int i;
 
if (!c->configdatasize)
return; /* No configuration data */
 
configdata = malloc(c->configdatasize, 0);
 
if (arc_entry->getconfigurationdata(configdata, c)) {
free(configdata);
return;
}
/* Does not seem to return meaningful data, don't use now */
free(configdata);
return;
for (i=0; i < configdata->count; i++) {
switch (configdata->descr[i].type) {
case CmResourceTypePort:
printf("Port: %p-size:%d ",
(uintptr_t)configdata->descr[i].u.port.start,
configdata->descr[i].u.port.length);
break;
case CmResourceTypeInterrupt:
printf("Irq: level(%d) vector(%d) ",
configdata->descr[i].u.interrupt.level,
configdata->descr[i].u.interrupt.vector);
break;
case CmResourceTypeMemory:
printf("Memory: %p-size:%d ",
(uintptr_t)configdata->descr[i].u.port.start,
configdata->descr[i].u.port.length);
break;
default:
break;
}
}
 
free(configdata);
}
 
/** Print information about component */
static void arc_print_component(arc_component *c)
{
int i;
 
printf("%s: ",ctypes[c->type]);
for (i=0;i < c->identifier_len;i++)
printf("%c",c->identifier[i]);
 
printf(" ");
arc_print_confdata(c);
printf("\n");
}
 
/**
* Read from ARC bios configuration data and print it
*/
static int cmd_arc_print_devices(cmd_arg_t *argv)
{
arc_component *c,*next;
 
c = arc_entry->getchild(NULL);
while (c) {
arc_print_component(c);
next = arc_entry->getchild(c);
while (!next) {
next = arc_entry->getpeer(c);
if (!next)
c = arc_entry->getparent(c);
if (!c)
return 0;
}
c = next;
}
return 1;
}
static cmd_info_t devlist_info = {
.name = "arcdevlist",
.description = "Print arc device list",
.func = cmd_arc_print_devices,
.argc = 0
};
 
 
/** Read from arc bios memory map and print it
*
*/
static int cmd_arc_print_memmap(cmd_arg_t *argv)
{
arc_memdescriptor_t *desc;
 
printf("Memory map:\n");
 
desc = arc_entry->getmemorydescriptor(NULL);
while (desc) {
printf("%s: %d(%p) (size: %dKB)\n",basetypes[desc->type],
desc->basepage * ARC_FRAME,
desc->basepage * ARC_FRAME,
desc->basecount*ARC_FRAME/1024);
desc = arc_entry->getmemorydescriptor(desc);
}
return 1;
}
static cmd_info_t memmap_info = {
.name = "arcmemmap",
.description = "Print arc memory map",
.func = cmd_arc_print_memmap,
.argc = 0
};
 
/** Print charactor to console */
static void arc_putchar(char ch)
{
uint32_t cnt;
ipl_t ipl;
 
/* TODO: Should be spinlock? */
ipl = interrupts_disable();
arc_entry->write(1, &ch, 1, &cnt);
interrupts_restore(ipl);
}
 
static int cmd_reboot(cmd_arg_t *argv)
{
arc_entry->reboot();
return 0;
}
static cmd_info_t reboot_info = {
.name = "reboot",
.description = "Reboot computer",
.func = cmd_reboot,
.argc = 0
};
 
/** Initialize ARC structure
*
* @return 0 - ARC OK, -1 - ARC does not exist
*/
int arc_init(void)
{
if (sbp->signature != ARC_MAGIC) {
sbp = NULL;
return -1;
}
arc_entry = sbp->firmwarevector;
 
arc_putchar('A');
arc_putchar('R');
arc_putchar('C');
arc_putchar('\n');
 
/* Add command for resetting the computer */
cmd_initialize(&reboot_info);
cmd_register(&reboot_info);
cmd_initialize(&memmap_info);
cmd_register(&memmap_info);
cmd_initialize(&devlist_info);
cmd_register(&devlist_info);
 
return 0;
}
 
static bool kbd_polling_enabled;
static chardev_t console;
 
/** Try to get character, return character or -1 if not available */
static void arc_keyboard_poll(void)
{
char ch;
uint32_t count;
long result;
if (! kbd_polling_enabled)
return;
 
if (arc_entry->getreadstatus(0))
return;
result = arc_entry->read(0, &ch, 1, &count);
if (result || count!=1) {
return;
}
if (ch == '\r')
ch = '\n';
if (ch == 0x7f)
ch = '\b';
chardev_push_character(&console, ch);
}
 
static char arc_read(chardev_t *dev)
{
char ch;
uint32_t count;
long result;
 
result = arc_entry->read(0, &ch, 1, &count);
if (result || count!=1) {
printf("Error reading from ARC keyboard.\n");
cpu_halt();
}
if (ch == '\r')
return '\n';
if (ch == 0x7f)
return '\b';
return ch;
}
 
static void arc_write(chardev_t *dev, const char ch)
{
arc_putchar(ch);
}
 
static void arc_enable(chardev_t *dev)
{
kbd_polling_enabled = true;
}
 
static void arc_disable(chardev_t *dev)
{
kbd_polling_enabled = false;
}
 
static chardev_operations_t arc_ops = {
.resume = arc_enable,
.suspend = arc_disable,
.write = arc_write,
.read = arc_read
};
 
void arc_console(void)
{
kbd_polling_enabled = true;
chardev_initialize("arc_console", &console, &arc_ops);
virtual_timer_fnc = &arc_keyboard_poll;
stdin = &console;
stdout = &console;
}
 
/* Initialize frame zones from ARC firmware.
* In the future we may use even the FirmwareTemporary regions,
* currently we use the FreeMemory (what about the LoadedProgram?)
*/
void arc_frame_init(void)
{
arc_memdescriptor_t *desc;
int total = 0;
uintptr_t base;
size_t basesize;
 
desc = arc_entry->getmemorydescriptor(NULL);
while (desc) {
if (desc->type == FreeMemory ||
desc->type == FreeContiguous) {
base = desc->basepage*ARC_FRAME;
basesize = desc->basecount*ARC_FRAME;
 
if (base % FRAME_SIZE ) {
basesize -= FRAME_SIZE - (base % FRAME_SIZE);
base = ALIGN_UP(base, FRAME_SIZE);
}
basesize = ALIGN_DOWN(basesize, FRAME_SIZE);
 
total += basesize;
zone_create(ADDR2PFN(base), SIZE2FRAMES(basesize),
ADDR2PFN(base), 0);
}
desc = arc_entry->getmemorydescriptor(desc);
}
 
config.memory_size = total;
}
 
/** @}
*/
/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/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,234
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
 
0:
beq $a2,$zero,2f
move $a3,$zero
 
1:
addu $v0,$a1,$a3
lbu $a0,0($v0)
addu $v1,$t0,$a3
addiu $a3,$a3,1
bne $a3,$a2,1b
sb $a0,0($v1)
 
2:
jr $ra
move $v0,$a1
 
3:
addiu $v0,$a0,3
and $v0,$v0,$v1
bne $a0,$v0,0b
srl $t1,$a2,2
 
beq $t1,$zero,5f
move $a3,$zero
 
move $a3,$zero
move $a0,$zero
4:
addu $v0,$a1,$a0
lw $v1,0($v0)
addiu $a3,$a3,1
addu $v0,$t0,$a0
sw $v1,0($v0)
bne $a3,$t1,4b
addiu $a0,$a0,4
 
5:
andi $a2,$a2,0x3
beq $a2,$zero,2b
nop
 
sll $v0,$a3,2
addu $t1,$v0,$t0
move $a3,$zero
addu $t0,$v0,$a1
6:
addu $v0,$t0,$a3
lbu $a0,0($v0)
addu $v1,$t1,$a3
addiu $a3,$a3,1
bne $a3,$a2,6b
sb $a0,0($v1)
 
jr $ra
move $v0,$a1
 
memcpy_from_uspace_failover_address:
memcpy_to_uspace_failover_address:
jr $ra
move $v0, $zero
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/console.c
0,0 → 1,69
/*
* Copyright (c) 2005 Ondrej Palkovsky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup mips32
* @{
*/
/** @file
*/
 
#include <console/console.h>
#include <arch/console.h>
#include <arch/drivers/arc.h>
#include <arch/drivers/serial.h>
#include <arch/drivers/msim.h>
 
void console_init(devno_t devno)
{
if (arc_enabled()) {
arc_console();
} else 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/context.S
26,6 → 26,7
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
#include <arch/asm/regname.h>
#include <arch/context_offset.h>
.text
37,9 → 38,41
.global context_save_arch
.global context_restore_arch
 
.macro CONTEXT_STORE r
sw $s0,OFFSET_S0(\r)
sw $s1,OFFSET_S1(\r)
sw $s2,OFFSET_S2(\r)
sw $s3,OFFSET_S3(\r)
sw $s4,OFFSET_S4(\r)
sw $s5,OFFSET_S5(\r)
sw $s6,OFFSET_S6(\r)
sw $s7,OFFSET_S7(\r)
sw $s8,OFFSET_S8(\r)
sw $gp,OFFSET_GP(\r)
sw $ra,OFFSET_PC(\r)
sw $sp,OFFSET_SP(\r)
.endm
 
.macro CONTEXT_LOAD r
lw $s0,OFFSET_S0(\r)
lw $s1,OFFSET_S1(\r)
lw $s2,OFFSET_S2(\r)
lw $s3,OFFSET_S3(\r)
lw $s4,OFFSET_S4(\r)
lw $s5,OFFSET_S5(\r)
lw $s6,OFFSET_S6(\r)
lw $s7,OFFSET_S7(\r)
lw $s8,OFFSET_S8(\r)
lw $gp,OFFSET_GP(\r)
lw $ra,OFFSET_PC(\r)
lw $sp,OFFSET_SP(\r)
.endm
 
context_save_arch:
CONTEXT_SAVE_ARCH_CORE $a0
CONTEXT_STORE $a0
 
# context_save returns 1
j $31
46,7 → 79,7
li $2, 1
context_restore_arch:
CONTEXT_RESTORE_ARCH_CORE $a0
CONTEXT_LOAD $a0
 
# context_restore returns 0
j $31
/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/src/start.S
30,8 → 30,7
#include <arch/mm/page.h>
#include <arch/asm/boot.h>
#include <arch/context_offset.h>
#include <arch/stack.h>
 
.text
 
.set noat
52,23 → 51,23
# These changes will be automatically reversed in REGISTER_LOAD
# SP is NOT saved as part of these registers
.macro REGISTERS_STORE_AND_EXC_RESET r
sw $at, EOFFSET_AT(\r)
sw $v0, EOFFSET_V0(\r)
sw $v1, EOFFSET_V1(\r)
sw $a0, EOFFSET_A0(\r)
sw $a1, EOFFSET_A1(\r)
sw $a2, EOFFSET_A2(\r)
sw $a3, EOFFSET_A3(\r)
sw $t0, EOFFSET_T0(\r)
sw $t1, EOFFSET_T1(\r)
sw $t2, EOFFSET_T2(\r)
sw $t3, EOFFSET_T3(\r)
sw $t4, EOFFSET_T4(\r)
sw $t5, EOFFSET_T5(\r)
sw $t6, EOFFSET_T6(\r)
sw $t7, EOFFSET_T7(\r)
sw $t8, EOFFSET_T8(\r)
sw $t9, EOFFSET_T9(\r)
sw $at,EOFFSET_AT(\r)
sw $v0,EOFFSET_V0(\r)
sw $v1,EOFFSET_V1(\r)
sw $a0,EOFFSET_A0(\r)
sw $a1,EOFFSET_A1(\r)
sw $a2,EOFFSET_A2(\r)
sw $a3,EOFFSET_A3(\r)
sw $t0,EOFFSET_T0(\r)
sw $t1,EOFFSET_T1(\r)
sw $t2,EOFFSET_T2(\r)
sw $t3,EOFFSET_T3(\r)
sw $t4,EOFFSET_T4(\r)
sw $t5,EOFFSET_T5(\r)
sw $t6,EOFFSET_T6(\r)
sw $t7,EOFFSET_T7(\r)
sw $t8,EOFFSET_T8(\r)
sw $t9,EOFFSET_T9(\r)
 
mflo $at
sw $at, EOFFSET_LO(\r)
75,16 → 74,28
mfhi $at
sw $at, EOFFSET_HI(\r)
sw $gp, EOFFSET_GP(\r)
sw $ra, EOFFSET_RA(\r)
sw $k1, EOFFSET_K1(\r)
#ifdef CONFIG_DEBUG_ALLREGS
sw $s0,EOFFSET_S0(\r)
sw $s1,EOFFSET_S1(\r)
sw $s2,EOFFSET_S2(\r)
sw $s3,EOFFSET_S3(\r)
sw $s4,EOFFSET_S4(\r)
sw $s5,EOFFSET_S5(\r)
sw $s6,EOFFSET_S6(\r)
sw $s7,EOFFSET_S7(\r)
sw $s8,EOFFSET_S8(\r)
#endif
sw $gp,EOFFSET_GP(\r)
sw $ra,EOFFSET_RA(\r)
sw $k1,EOFFSET_K1(\r)
 
mfc0 $t0, $status
mfc0 $t1, $epc
and $t2, $t0, REG_SAVE_MASK # Save only KSU,EXL,ERL,IE
and $t2, $t0, REG_SAVE_MASK # Save only KSU,EXL,ERL,IE
li $t3, ~(0x1f)
and $t0, $t0, $t3 # Clear KSU,EXL,ERL,IE
and $t0, $t0, $t3 # Clear KSU,EXL,ERL,IE
sw $t2,EOFFSET_STATUS(\r)
sw $t1,EOFFSET_EPC(\r)
97,43 → 108,54
mfc0 $t0, $status
lw $t1,EOFFSET_STATUS(\r)
 
li $t2, ~REG_SAVE_MASK # Mask UM,EXL,ERL,IE
li $t2, ~REG_SAVE_MASK # Mask UM,EXL,ERL,IE
and $t0, $t0, $t2
or $t0, $t0, $t1 # Copy UM,EXL, ERL, IE from saved status
or $t0, $t0, $t1 # Copy UM,EXL,ERL,IE from saved status
mtc0 $t0, $status
lw $v0, EOFFSET_V0(\r)
lw $v1, EOFFSET_V1(\r)
lw $a0, EOFFSET_A0(\r)
lw $a1, EOFFSET_A1(\r)
lw $a2, EOFFSET_A2(\r)
lw $a3, EOFFSET_A3(\r)
lw $t0, EOFFSET_T0(\r)
lw $t1, EOFFSET_T1(\r)
lw $t2, EOFFSET_T2(\r)
lw $t3, EOFFSET_T3(\r)
lw $t4, EOFFSET_T4(\r)
lw $t5, EOFFSET_T5(\r)
lw $t6, EOFFSET_T6(\r)
lw $t7, EOFFSET_T7(\r)
lw $t8, EOFFSET_T8(\r)
lw $t9, EOFFSET_T9(\r)
lw $v0,EOFFSET_V0(\r)
lw $v1,EOFFSET_V1(\r)
lw $a0,EOFFSET_A0(\r)
lw $a1,EOFFSET_A1(\r)
lw $a2,EOFFSET_A2(\r)
lw $a3,EOFFSET_A3(\r)
lw $t0,EOFFSET_T0(\r)
lw $t1,EOFFSET_T1(\r)
lw $t2,EOFFSET_T2(\r)
lw $t3,EOFFSET_T3(\r)
lw $t4,EOFFSET_T4(\r)
lw $t5,EOFFSET_T5(\r)
lw $t6,EOFFSET_T6(\r)
lw $t7,EOFFSET_T7(\r)
lw $t8,EOFFSET_T8(\r)
lw $t9,EOFFSET_T9(\r)
lw $gp, EOFFSET_GP(\r)
lw $ra, EOFFSET_RA(\r)
lw $k1, EOFFSET_K1(\r)
#ifdef CONFIG_DEBUG_ALLREGS
lw $s0,EOFFSET_S0(\r)
lw $s1,EOFFSET_S1(\r)
lw $s2,EOFFSET_S2(\r)
lw $s3,EOFFSET_S3(\r)
lw $s4,EOFFSET_S4(\r)
lw $s5,EOFFSET_S5(\r)
lw $s6,EOFFSET_S6(\r)
lw $s7,EOFFSET_S7(\r)
lw $s8,EOFFSET_S8(\r)
#endif
lw $gp,EOFFSET_GP(\r)
lw $ra,EOFFSET_RA(\r)
lw $k1,EOFFSET_K1(\r)
lw $at, EOFFSET_LO(\r)
lw $at,EOFFSET_LO(\r)
mtlo $at
lw $at, EOFFSET_HI(\r)
lw $at,EOFFSET_HI(\r)
mthi $at
 
lw $at, EOFFSET_EPC(\r)
lw $at,EOFFSET_EPC(\r)
mtc0 $at, $epc
lw $at, EOFFSET_AT(\r)
lw $sp, EOFFSET_SP(\r)
lw $at,EOFFSET_AT(\r)
lw $sp,EOFFSET_SP(\r)
.endm
 
# Move kernel stack pointer address to register K0
152,9 → 174,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 → 183,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,27 → 227,29
 
exception_entry:
j exception_handler
nop
nop
 
exception_handler:
KERNEL_STACK_TO_K0
sub $k0, REGISTER_SPACE
sw $sp, EOFFSET_SP($k0)
sw $sp,EOFFSET_SP($k0)
move $sp, $k0
mfc0 $k0, $cause
sra $k0, $k0, 0x2 # cp0_exc_cause() part 1
andi $k0, $k0, 0x1f # cp0_exc_cause() part 2
sub $k0, 8 # 8 = SYSCALL
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
213,66 → 256,49
# The $sp is automatically restored to former value
eret
 
## Syscall entry
#
# Registers:
#
# @param v0 Syscall number.
# @param a0 1st argument.
# @param a1 2nd argument.
# @param a2 3rd argument.
# @param a3 4th argument.
# @param t0 5th argument.
# @param t1 6th argument.
#
# @return The return value will be stored in v0.
#
#define SS_SP EOFFSET_SP
#define SS_STATUS EOFFSET_STATUS
#define SS_EPC EOFFSET_EPC
#define SS_K1 EOFFSET_K1
# it seems that mips reserves some space on stack for varfuncs???
#define SS_ARG4 16
#define SS_SP EOFFSET_SP
#define SS_STATUS EOFFSET_STATUS
#define SS_EPC EOFFSET_EPC
#define SS_K1 EOFFSET_K1
syscall_shortcut:
# We have a lot of space on the stack, with free use
mfc0 $t3, $epc
mfc0 $t2, $status
sw $t3, SS_EPC($sp) # Save EPC
sw $k1, SS_K1($sp) # Save k1 not saved on context switch
mfc0 $t1, $epc
mfc0 $t0, $status
sw $t1,SS_EPC($sp) # Save EPC
sw $k1,SS_K1($sp) # Save k1, which is not saved during context switch
and $t4, $t2, REG_SAVE_MASK # Save only KSU, EXL, ERL, IE
li $t5, ~(0x1f)
and $t2, $t2, $t5 # Clear KSU, EXL, ERL
ori $t2, $t2, 0x1 # Set IE
and $t2, $t0, REG_SAVE_MASK # Save only KSU,EXL,ERL,IE
li $t3, ~(0x1f)
and $t0, $t0, $t3 # Clear KSU,EXL,ERL
ori $t0, $t0, 0x1 # Set IE
 
sw $t4, SS_STATUS($sp)
mtc0 $t2, $status
sw $t2,SS_STATUS($sp)
mtc0 $t0, $status
 
#
# Call the higher level system call handler
# We are going to reuse part of the unused exception stack frame
#
sw $t0, STACK_ARG4($sp) # save the 5th argument on the stack
sw $t1, STACK_ARG5($sp) # save the 6th argument on the stack
# CALL Syscall handler
jal syscall_handler
sw $v0, STACK_ARG6($sp) # save the syscall number on the stack
sw $v0, SS_ARG4($sp) # save v0 - arg4 to stack
 
# restore status
mfc0 $t2, $status
lw $t3, SS_STATUS($sp)
mfc0 $t0, $status
lw $t1,SS_STATUS($sp)
 
# Change back to EXL = 1 (from last exception), otherwise
# an interrupt could rewrite the CP0 - EPC
li $t4, ~REG_SAVE_MASK # Mask UM, EXL, ERL, IE
and $t2, $t2, $t4
or $t2, $t2, $t3 # Copy saved UM, EXL, ERL, IE
mtc0 $t2, $status
# Change back to EXL=1(from last exception), otherwise
# an interrupt could rewrite the CP0-EPC
li $t2, ~REG_SAVE_MASK # Mask UM,EXL,ERL,IE
and $t0, $t0, $t2
or $t0, $t0, $t1 # Copy UM,EXL,ERL,IE from saved status
mtc0 $t0, $status
# restore epc + 4
lw $t2, SS_EPC($sp)
lw $k1, SS_K1($sp)
addi $t2, $t2, 4
mtc0 $t2, $epc
# restore epc+4
lw $t0,SS_EPC($sp)
lw $k1,SS_K1($sp)
addi $t0, $t0, 4
mtc0 $t0, $epc
lw $sp, SS_SP($sp) # restore sp
lw $sp,SS_SP($sp) # restore sp
eret
307,7 → 333,5
userspace_asm:
add $sp, $a0, 0
add $v0, $a1, 0
add $t9, $a2, 0 # Set up correct entry into PIC code
xor $a0, $a0, $a0 # $a0 is defined to hold pcb_ptr
# set it to 0
add $t9, $a2, 0 # Set up correct entry into PIC code
eret
/branches/arm/kernel/arch/mips32/src/debugger.c
33,22 → 33,19
*/
 
#include <arch/debugger.h>
#include <arch/barrier.h>
#include <memstr.h>
#include <console/kconsole.h>
#include <console/cmd.h>
#include <symtab.h>
#include <print.h>
#include <panic.h>
#include <arch.h>
#include <arch/cp0.h>
#include <func.h>
#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",
75,8 → 72,7
};
static cmd_info_t addbkpt_info = {
.name = "addbkpt",
.description = "addbkpt <&symbol> - new bkpoint. Break on J/Branch "
"insts unsupported.",
.description = "addbkpt <&symbol> - new bkpoint. Break on J/Branch insts unsupported.",
.func = cmd_add_breakpoint,
.argc = 1,
.argv = &add_argv
88,8 → 84,7
};
static cmd_info_t addbkpte_info = {
.name = "addbkpte",
.description = "addebkpte <&symbol> <&func> - new bkpoint. Call "
"func(or Nothing if 0).",
.description = "addebkpte <&symbol> <&func> - new bkpoint. Call func(or Nothing if 0).",
.func = cmd_add_breakpoint,
.argc = 2,
.argv = adde_argv
98,7 → 93,7
static struct {
uint32_t andmask;
uint32_t value;
} jmpinstr[] = {
}jmpinstr[] = {
{0xf3ff0000, 0x41000000}, /* BCzF */
{0xf3ff0000, 0x41020000}, /* BCzFL */
{0xf3ff0000, 0x41010000}, /* BCzT */
122,21 → 117,19
{0xfc000000, 0x08000000}, /* J */
{0xfc000000, 0x0c000000}, /* JAL */
{0xfc1f07ff, 0x00000009}, /* JALR */
{0, 0} /* EndOfTable */
{0,0} /* EndOfTable */
};
 
 
/** Test, if the given instruction is a jump or branch instruction
*
* @param instr Instruction code
* @return true - it is jump instruction, false otherwise
*
*/
static bool is_jump(unative_t instr)
{
int i;
 
for (i = 0; jmpinstr[i].andmask; i++) {
for (i=0;jmpinstr[i].andmask;i++) {
if ((instr & jmpinstr[i].andmask) == jmpinstr[i].value)
return true;
}
159,23 → 152,21
spinlock_lock(&bkpoint_lock);
 
/* Check, that the breakpoints do not conflict */
for (i = 0; i < BKPOINTS_MAX; i++) {
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 ==
(uintptr_t)argv->intval - sizeof(unative_t)) {
printf("Adjacent breakpoints not supported, conflict "
"with %d.\n", i);
spinlock_unlock(&bkpoint_lock);
} else if (breakpoints[i].address == (uintptr_t)argv->intval + sizeof(unative_t) || \
breakpoints[i].address == (uintptr_t)argv->intval - sizeof(unative_t)) {
printf("Adjacent breakpoints not supported, conflict with %d.\n", i);
spinlock_unlock(&bkpoints_lock);
return 0;
}
}
 
for (i = 0; i < BKPOINTS_MAX; i++)
for (i=0; i<BKPOINTS_MAX; i++)
if (!breakpoints[i].address) {
cur = &breakpoints[i];
break;
194,7 → 185,7
cur->flags = 0;
} else { /* We are add extended */
cur->flags = BKPOINT_FUNCCALL;
cur->bkfunc = (void (*)(void *, istate_t *)) argv[1].intval;
cur->bkfunc = (void (*)(void *, istate_t *)) argv[1].intval;
}
if (is_jump(cur->instruction))
cur->flags |= BKPOINT_ONESHOT;
202,7 → 193,6
 
/* Set breakpoint */
*((unative_t *)cur->address) = 0x0d;
smc_coherence(cur->address);
 
spinlock_unlock(&bkpoint_lock);
interrupts_restore(ipl);
210,6 → 200,8
return 1;
}
 
 
 
/** Remove breakpoint from table */
int cmd_del_breakpoint(cmd_arg_t *argv)
{
216,7 → 208,7
bpinfo_t *cur;
ipl_t ipl;
 
if (argv->intval > BKPOINTS_MAX) {
if (argv->intval < 0 || argv->intval > BKPOINTS_MAX) {
printf("Invalid breakpoint number.\n");
return 0;
}
237,9 → 229,7
return 0;
}
((uint32_t *)cur->address)[0] = cur->instruction;
smc_coherence(((uint32_t *)cur->address)[0]);
((uint32_t *)cur->address)[1] = cur->nextinstruction;
smc_coherence(((uint32_t *)cur->address)[1]);
 
cur->address = NULL;
 
251,54 → 241,50
/** Print table of active breakpoints */
int cmd_print_breakpoints(cmd_arg_t *argv)
{
unsigned int i;
int i;
char *symbol;
printf("# Count Address INPROG ONESHOT FUNCCALL In symbol\n");
printf("-- ----- ---------- ------ ------- -------- ---------\n");
for (i = 0; i < BKPOINTS_MAX; i++)
 
printf("Breakpoint table.\n");
for (i=0; i < BKPOINTS_MAX; i++)
if (breakpoints[i].address) {
symbol = symtab_fmt_name_lookup(
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" :
"false"), ((breakpoints[i].flags & BKPOINT_ONESHOT)
? "true" : "false"), ((breakpoints[i].flags &
BKPOINT_FUNCCALL) ? "true" : "false"), symbol);
symbol = get_symtab_entry(breakpoints[i].address);
printf("%d. %p in %s\n",i,
breakpoints[i].address, symbol);
printf(" Count(%d) ", breakpoints[i].counter);
if (breakpoints[i].flags & BKPOINT_INPROG)
printf("INPROG ");
if (breakpoints[i].flags & BKPOINT_ONESHOT)
printf("ONESHOT ");
if (breakpoints[i].flags & BKPOINT_FUNCCALL)
printf("FUNCCALL ");
printf("\n");
}
return 1;
}
 
#endif
 
/** Initialize debugger */
void debugger_init()
{
int i;
 
for (i = 0; i < BKPOINTS_MAX; i++)
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,19 → 303,19
 
/* 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++) {
for (i=0; i<BKPOINTS_MAX; i++) {
/* Normal breakpoint */
if (fireaddr == breakpoints[i].address &&
!(breakpoints[i].flags & BKPOINT_REINST)) {
if (fireaddr == breakpoints[i].address \
&& !(breakpoints[i].flags & BKPOINT_REINST)) {
cur = &breakpoints[i];
break;
}
/* Reinst only breakpoint */
if ((breakpoints[i].flags & BKPOINT_REINST) &&
(fireaddr == breakpoints[i].address + sizeof(unative_t))) {
if ((breakpoints[i].flags & BKPOINT_REINST) \
&& (fireaddr ==breakpoints[i].address+sizeof(unative_t))) {
cur = &breakpoints[i];
break;
}
338,10 → 324,8
if (cur->flags & BKPOINT_REINST) {
/* Set breakpoint on first instruction */
((uint32_t *)cur->address)[0] = 0x0d;
smc_coherence(((uint32_t *)cur->address)[0]);
/* Return back the second */
((uint32_t *)cur->address)[1] = cur->nextinstruction;
smc_coherence(((uint32_t *)cur->address)[1]);
cur->flags &= ~BKPOINT_REINST;
spinlock_unlock(&bkpoint_lock);
return;
349,14 → 333,12
if (cur->flags & BKPOINT_INPROG)
printf("Warning: breakpoint recursion\n");
if (!(cur->flags & BKPOINT_FUNCCALL)) {
printf("***Breakpoint %d: %p in %s.\n", i, fireaddr,
symtab_fmt_name_lookup(istate->epc));
}
if (!(cur->flags & BKPOINT_FUNCCALL))
printf("***Breakpoint %d: %p in %s.\n", i,
fireaddr, get_symtab_entry(istate->epc));
 
/* Return first instruction back */
((uint32_t *)cur->address)[0] = cur->instruction;
smc_coherence(cur->address);
 
if (! (cur->flags & BKPOINT_ONESHOT)) {
/* Set Breakpoint on next instruction */
365,9 → 347,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 → 359,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/mm/tlb.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup mips32mm
/** @addtogroup mips32mm
* @{
*/
/** @file
40,21 → 40,25
#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 *);
static void tlb_modified_fail(istate_t *);
static void tlb_refill_fail(istate_t *istate);
static void tlb_invalid_fail(istate_t *istate);
static void tlb_modified_fail(istate_t *istate);
 
static pte_t *find_mapping_and_check(uintptr_t, int, istate_t *, int *);
static pte_t *find_mapping_and_check(uintptr_t badvaddr, int access, istate_t *istate, int *pfrc);
 
/** Initialize TLB.
static void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, uintptr_t pfn);
static void prepare_entry_hi(entry_hi_t *hi, asid_t asid, uintptr_t addr);
 
/** Initialize TLB
*
* Initialize TLB.
* Invalidate all entries and mark wired entries.
*/
void tlb_arch_init(void)
72,6 → 76,7
cp0_index_write(i);
tlbwi();
}
 
/*
* The kernel is going to make use of some wired
80,9 → 85,11
cp0_wired_write(TLB_WIRED);
}
 
/** Process TLB Refill Exception.
/** Process TLB Refill Exception
*
* @param istate Interrupted register context.
* Process TLB Refill Exception.
*
* @param istate Interrupted register context.
*/
void tlb_refill(istate_t *istate)
{
92,15 → 99,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 → 122,7
page_table_unlock(AS, true);
return;
default:
panic("Unexpected pfrc (%d).", pfrc);
panic("unexpected pfrc (%d)\n", pfrc);
}
}
 
124,15 → 131,14
*/
pte->a = 1;
 
tlb_prepare_entry_hi(&hi, asid, badvaddr);
tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable,
pte->pfn);
prepare_entry_hi(&hi, asid, badvaddr);
prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn);
 
/*
* New entry is to be inserted into TLB
*/
cp0_entry_hi_write(hi.value);
if ((badvaddr / PAGE_SIZE) % 2 == 0) {
if ((badvaddr/PAGE_SIZE) % 2 == 0) {
cp0_entry_lo0_write(lo.value);
cp0_entry_lo1_write(0);
}
151,9 → 157,11
tlb_refill_fail(istate);
}
 
/** Process TLB Invalid Exception.
/** Process TLB Invalid Exception
*
* @param istate Interrupted register context.
* Process TLB Invalid Exception.
*
* @param istate Interrupted register context.
*/
void tlb_invalid(istate_t *istate)
{
170,7 → 178,7
* Locate the faulting entry in TLB.
*/
hi.value = cp0_entry_hi_read();
tlb_prepare_entry_hi(&hi, hi.asid, badvaddr);
prepare_entry_hi(&hi, hi.asid, badvaddr);
cp0_entry_hi_write(hi.value);
tlbp();
index.value = cp0_index_read();
199,7 → 207,7
page_table_unlock(AS, true);
return;
default:
panic("Unexpected pfrc (%d).", pfrc);
panic("unexpected pfrc (%d)\n", pfrc);
}
}
 
213,13 → 221,12
*/
pte->a = 1;
 
tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable,
pte->pfn);
prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn);
 
/*
* The entry is to be updated in TLB.
*/
if ((badvaddr / PAGE_SIZE) % 2 == 0)
if ((badvaddr/PAGE_SIZE) % 2 == 0)
cp0_entry_lo0_write(lo.value);
else
cp0_entry_lo1_write(lo.value);
234,9 → 241,11
tlb_invalid_fail(istate);
}
 
/** Process TLB Modified Exception.
/** Process TLB Modified Exception
*
* @param istate Interrupted register context.
* Process TLB Modified Exception.
*
* @param istate Interrupted register context.
*/
void tlb_modified(istate_t *istate)
{
253,7 → 262,7
* Locate the faulting entry in TLB.
*/
hi.value = cp0_entry_hi_read();
tlb_prepare_entry_hi(&hi, hi.asid, badvaddr);
prepare_entry_hi(&hi, hi.asid, badvaddr);
cp0_entry_hi_write(hi.value);
tlbp();
index.value = cp0_index_read();
282,11 → 291,17
page_table_unlock(AS, true);
return;
default:
panic("Unexpected pfrc (%d).", pfrc);
panic("unexpected pfrc (%d)\n", pfrc);
}
}
 
/*
* Fail if the page is not writable.
*/
if (!pte->w)
goto fail;
 
/*
* Read the faulting TLB entry.
*/
tlbr();
297,13 → 312,12
pte->a = 1;
pte->d = 1;
 
tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->w, pte->cacheable,
pte->pfn);
prepare_entry_lo(&lo, pte->g, pte->p, pte->w, pte->cacheable, pte->pfn);
 
/*
* The entry is to be updated in TLB.
*/
if ((badvaddr / PAGE_SIZE) % 2 == 0)
if ((badvaddr/PAGE_SIZE) % 2 == 0)
cp0_entry_lo0_write(lo.value);
else
cp0_entry_lo1_write(lo.value);
320,57 → 334,56
 
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.",
cp0_badvaddr_read());
panic("%x: TLB Refill Exception at %x (%s<-%s).", cp0_badvaddr_read(),
istate->epc, symbol, sym2);
char *s = get_symtab_entry(istate->epc);
if (s)
symbol = s;
s = get_symtab_entry(istate->ra);
if (s)
sym2 = s;
 
fault_if_from_uspace(istate, "TLB Refill Exception on %p", cp0_badvaddr_read());
panic("%x: TLB Refill Exception at %x(%s<-%s)\n", cp0_badvaddr_read(), istate->epc, symbol, sym2);
}
 
 
void tlb_invalid_fail(istate_t *istate)
{
char *symbol;
char *symbol = "";
 
symbol = symtab_fmt_name_lookup(istate->epc);
 
fault_if_from_uspace(istate, "TLB Invalid Exception on %p.",
cp0_badvaddr_read());
panic("%x: TLB Invalid Exception at %x (%s).", cp0_badvaddr_read(),
istate->epc, symbol);
char *s = get_symtab_entry(istate->epc);
if (s)
symbol = s;
fault_if_from_uspace(istate, "TLB Invalid Exception on %p", cp0_badvaddr_read());
panic("%x: TLB Invalid Exception at %x(%s)\n", cp0_badvaddr_read(), istate->epc, symbol);
}
 
void tlb_modified_fail(istate_t *istate)
{
char *symbol;
char *symbol = "";
 
symbol = symtab_fmt_name_lookup(istate->epc);
 
fault_if_from_uspace(istate, "TLB Modified Exception on %p.",
cp0_badvaddr_read());
panic("%x: TLB Modified Exception at %x (%s).", cp0_badvaddr_read(),
istate->epc, symbol);
char *s = get_symtab_entry(istate->epc);
if (s)
symbol = s;
fault_if_from_uspace(istate, "TLB Modified Exception on %p", cp0_badvaddr_read());
panic("%x: TLB Modified Exception at %x(%s)\n", cp0_badvaddr_read(), istate->epc, symbol);
}
 
/** Try to find PTE for faulting address.
/** Try to find PTE for faulting address
*
* Try to find PTE for faulting address.
* The AS->lock must be held on entry to this function.
*
* @param badvaddr Faulting virtual address.
* @param access Access mode that caused the fault.
* @param istate Pointer to interrupted state.
* @param pfrc Pointer to variable where as_page_fault() return code
* will be stored.
* @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.
* @return PTE on success, NULL otherwise.
*/
pte_t *
find_mapping_and_check(uintptr_t badvaddr, int access, istate_t *istate,
int *pfrc)
pte_t *find_mapping_and_check(uintptr_t badvaddr, int access, istate_t *istate, int *pfrc)
{
entry_hi_t hi;
pte_t *pte;
389,7 → 402,7
* Check if the mapping exists in page tables.
*/
pte = page_mapping_find(AS, badvaddr);
if (pte && pte->p && (pte->w || access != PF_ACCESS_WRITE)) {
if (pte && pte->p) {
/*
* Mapping found in page tables.
* Immediately succeed.
412,7 → 425,6
page_table_lock(AS, true);
pte = page_mapping_find(AS, badvaddr);
ASSERT(pte && pte->p);
ASSERT(pte->w || access != PF_ACCESS_WRITE);
return pte;
break;
case AS_PF_DEFER:
422,19 → 434,18
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);
}
}
}
 
void
tlb_prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable,
uintptr_t pfn)
void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, uintptr_t pfn)
{
lo->value = 0;
lo->g = g;
444,7 → 455,7
lo->pfn = pfn;
}
 
void tlb_prepare_entry_hi(entry_hi_t *hi, asid_t asid, uintptr_t addr)
void prepare_entry_hi(entry_hi_t *hi, asid_t asid, uintptr_t addr)
{
hi->value = ALIGN_DOWN(addr, PAGE_SIZE * 2);
hi->asid = asid;
456,13 → 467,11
page_mask_t mask;
entry_lo_t lo0, lo1;
entry_hi_t hi, hi_save;
unsigned int i;
int i;
 
hi_save.value = cp0_entry_hi_read();
printf("# ASID VPN2 MASK G V D C PFN\n");
printf("-- ---- ------ ---- - - - - ------\n");
 
printf("TLB:\n");
for (i = 0; i < TLB_ENTRY_COUNT; i++) {
cp0_index_write(i);
tlbr();
472,11 → 481,10
lo0.value = cp0_entry_lo0_read();
lo1.value = cp0_entry_lo1_read();
printf("%-2u %-4u %#6x %#4x %1u %1u %1u %1u %#6x\n",
i, hi.asid, hi.vpn2, mask.mask,
lo0.g, lo0.v, lo0.d, lo0.c, lo0.pfn);
printf(" %1u %1u %1u %1u %#6x\n",
lo1.g, lo1.v, lo1.d, lo1.c, lo1.pfn);
printf("%d: asid=%d, vpn2=%d, mask=%d\tg[0]=%d, v[0]=%d, d[0]=%d, c[0]=%hhd, pfn[0]=%d\n"
"\t\t\t\tg[1]=%d, v[1]=%d, d[1]=%d, c[1]=%hhd, pfn[1]=%d\n",
i, hi.asid, hi.vpn2, mask.mask, lo0.g, lo0.v, lo0.d, lo0.c, lo0.pfn,
lo1.g, lo1.v, lo1.d, lo1.c, lo1.pfn);
}
cp0_entry_hi_write(hi_save.value);
553,16 → 561,15
cp0_entry_hi_write(hi_save.value);
}
 
/** Invalidate TLB entries for specified page range belonging to specified
* address space.
/** Invalidate TLB entries for specified page range belonging to specified address space.
*
* @param asid Address space identifier.
* @param page First page whose TLB entry is to be invalidated.
* @param cnt Number of entries to invalidate.
* @param asid Address space identifier.
* @param page First page whose TLB entry is to be invalidated.
* @param cnt Number of entries to invalidate.
*/
void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt)
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt)
{
unsigned int i;
int i;
ipl_t ipl;
entry_lo_t lo0, lo1;
entry_hi_t hi, hi_save;
573,9 → 580,9
hi_save.value = cp0_entry_hi_read();
ipl = interrupts_disable();
 
for (i = 0; i < cnt + 1; i += 2) {
for (i = 0; i < cnt+1; i+=2) {
hi.value = 0;
tlb_prepare_entry_hi(&hi, asid, page + i * PAGE_SIZE);
prepare_entry_hi(&hi, asid, page + i * PAGE_SIZE);
cp0_entry_hi_write(hi.value);
 
tlbp();
582,10 → 589,7
index.value = cp0_index_read();
 
if (!index.p) {
/*
* Entry was found, index register contains valid
* index.
*/
/* Entry was found, index register contains valid index. */
tlbr();
 
lo0.value = cp0_entry_lo0_read();
/branches/arm/kernel/arch/mips32/src/mm/as.c
34,17 → 34,17
 
#include <arch/mm/as.h>
#include <genarch/mm/as_pt.h>
#include <genarch/mm/page_pt.h>
#include <genarch/mm/asid_fifo.h>
#include <arch/mm/tlb.h>
#include <mm/tlb.h>
#include <mm/as.h>
#include <arch/cp0.h>
#include <arch.h>
 
/** Architecture dependent address space init. */
void as_arch_init(void)
{
as_operations = &as_pt_operations;
as_operations = &as_pt_operations;
asid_fifo_init();
}
 
57,6 → 57,7
void as_install_arch(as_t *as)
{
entry_hi_t hi;
ipl_t ipl;
 
/*
* Install ASID.
63,8 → 64,12
*/
hi.value = cp0_entry_hi_read();
 
ipl = interrupts_disable();
spinlock_lock(&as->lock);
hi.asid = as->asid;
cp0_entry_hi_write(hi.value);
spinlock_unlock(&as->lock);
interrupts_restore(ipl);
}
 
/** @}
/branches/arm/kernel/arch/mips32/src/mm/frame.c
26,237 → 26,35
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup mips32mm
/** @addtogroup mips32mm
* @{
*/
/** @file
*/
 
#include <macros.h>
#include <arch/mm/frame.h>
#include <arch/mm/tlb.h>
#include <interrupt.h>
#include <mm/frame.h>
#include <mm/asid.h>
#include <config.h>
#include <arch/drivers/msim.h>
#include <print.h>
#include <arch/drivers/arc.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_VALUE_KSEG1(frame) \
(((volatile uint32_t *) (0xa0000000 + (frame << ZERO_PAGE_WIDTH)))[ZERO_PAGE_OFFSET])
 
#define MAX_REGIONS 32
 
typedef struct {
pfn_t start;
pfn_t count;
} phys_region_t;
 
static size_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.
* Returns false if given frame is used for physical memory
* mapped devices and cannot be used.
*
*/
static bool frame_available(pfn_t frame)
{
#ifdef MACHINE_msim
/* MSIM device (dprinter) */
if (frame == (KA2PA(MSIM_VIDEORAM) >> ZERO_PAGE_WIDTH))
return false;
/* MSIM device (dkeyboard) */
if (frame == (KA2PA(MSIM_KBD_ADDRESS) >> ZERO_PAGE_WIDTH))
return false;
#endif
#if defined(MACHINE_lgxemul) || defined(MACHINE_bgxemul)
/* gxemul devices */
if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE,
0x10000000, MB2SIZE(256)))
return false;
#endif
return true;
}
 
 
/** Check whether frame is safe to write
*
* Returns true if given frame is safe for read/write test.
* Returns false if given frame should not be touched.
*
*/
static bool frame_safe(pfn_t frame)
{
/* Kernel structures */
if ((frame << ZERO_PAGE_WIDTH) < KA2PA(config.base))
return false;
/* Kernel */
if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE,
KA2PA(config.base), config.kernel_size))
return false;
/* Kernel stack */
if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE,
KA2PA(config.stack_base), config.stack_size))
return false;
/* Init tasks */
bool safe = true;
size_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)) {
safe = false;
break;
}
return safe;
}
 
static void frame_add_region(pfn_t start_frame, pfn_t end_frame)
{
if (end_frame > start_frame) {
/* Convert 1M frames to 16K frames */
pfn_t first = ADDR2PFN(start_frame << ZERO_PAGE_WIDTH);
pfn_t count = ADDR2PFN((end_frame - start_frame) << ZERO_PAGE_WIDTH);
/* Interrupt vector frame is blacklisted */
pfn_t conf_frame;
if (first == 0)
conf_frame = 1;
else
conf_frame = first;
zone_create(first, count, conf_frame, 0);
if (phys_regions_count < MAX_REGIONS) {
phys_regions[phys_regions_count].start = first;
phys_regions[phys_regions_count].count = count;
phys_regions_count++;
}
}
}
 
 
/** Create memory zones
*
* Walk through available 256 KB chunks of physical
* memory and create zones.
*
* Note: It is assumed that the TLB is not yet being
* used in any way, thus there is no interference.
*
* If ARC is known, read information from ARC, otherwise
* assume some defaults.
* - blacklist first FRAME because there is an exception vector
*/
void frame_arch_init(void)
{
ipl_t ipl = interrupts_disable();
/* Clear and initialize TLB */
cp0_pagemask_write(ZERO_PAGE_MASK);
cp0_entry_lo0_write(0);
cp0_entry_lo1_write(0);
cp0_entry_hi_write(0);
 
size_t i;
for (i = 0; i < TLB_ENTRY_COUNT; i++) {
cp0_index_write(i);
tlbwi();
if (arc_enabled())
arc_frame_init();
else {
zone_create(0, ADDR2PFN(config.memory_size), 1, 0);
/*
* Blacklist interrupt vector
*/
frame_mark_unavailable(0, 1);
}
pfn_t start_frame = 0;
pfn_t frame;
bool avail = true;
/* Walk through all 1 MB frames */
for (frame = 0; frame < ZERO_FRAMES; frame++) {
if (!frame_available(frame))
avail = false;
else {
if (frame_safe(frame)) {
entry_lo_t lo0;
entry_lo_t lo1;
entry_hi_t hi;
tlb_prepare_entry_lo(&lo0, false, true, true, false, frame << (ZERO_PAGE_WIDTH - 12));
tlb_prepare_entry_lo(&lo1, false, false, false, false, 0);
tlb_prepare_entry_hi(&hi, ZERO_PAGE_ASID, ZERO_PAGE_ADDR);
cp0_pagemask_write(ZERO_PAGE_MASK);
cp0_entry_lo0_write(lo0.value);
cp0_entry_lo1_write(lo1.value);
cp0_entry_hi_write(hi.value);
cp0_index_write(ZERO_PAGE_TLBI);
tlbwi();
ZERO_PAGE_VALUE = 0;
if (ZERO_PAGE_VALUE != 0)
avail = false;
else {
ZERO_PAGE_VALUE = 0xdeadbeef;
if (ZERO_PAGE_VALUE != 0xdeadbeef)
avail = false;
#if defined(MACHINE_lgxemul) || defined(MACHINE_bgxemul)
else {
ZERO_PAGE_VALUE_KSEG1(frame) = 0xaabbccdd;
if (ZERO_PAGE_VALUE_KSEG1(frame) != 0xaabbccdd)
avail = false;
}
#endif
}
}
}
if (!avail) {
frame_add_region(start_frame, frame);
start_frame = frame + 1;
avail = true;
}
}
frame_add_region(start_frame, frame);
/* Blacklist interrupt vector frame */
frame_mark_unavailable(0, 1);
/* Cleanup */
cp0_pagemask_write(ZERO_PAGE_MASK);
cp0_entry_lo0_write(0);
cp0_entry_lo1_write(0);
cp0_entry_hi_write(0);
cp0_index_write(ZERO_PAGE_TLBI);
tlbwi();
interrupts_restore(ipl);
}
 
 
void physmem_print(void)
{
printf("Base Size\n");
printf("---------- ----------\n");
size_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/_link.ld.in
1,19 → 1,17
/*
* MIPS32 linker script
*
* MIPS32 linker script
*
* kernel text
* kernel data
*
*
*/
 
#undef mips
#define mips mips
 
#define KERNEL_LOAD_ADDRESS 0x80100000
 
OUTPUT_ARCH(mips)
ENTRY(kernel_image_start)
 
ENTRY(kernel_image_start)
 
SECTIONS {
. = KERNEL_LOAD_ADDRESS;
.text : {
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 = .;
33,23 → 31,30
*(.rodata*);
*(.sdata);
*(.reginfo);
*(.sbss);
*(.scommon);
*(.bss); /* uninitialized static variables */
*(COMMON); /* global variables */
/* Unfortunately IRIX does not allow us
* to include this as a last section :-(
* BSS/SBSS addresses will be wrong */
symbol_table = .;
*(symtab.*);
*(symtab.*);
}
_gp = . + 0x8000;
.lit8 : { *(.lit8) }
.lit4 : { *(.lit4) }
.sbss : {
*(.sbss);
*(.scommon);
}
.bss : {
*(.bss); /* uninitialized static variables */
*(COMMON); /* global variables */
}
 
kdata_end = .;
 
/DISCARD/ : {
*(.mdebug*);
*(.pdr);
*(.comment);
*(.note);
*(.mdebug*);
*(.pdr);
*(.comment);
*(.note);
}
}