/branches/arm/kernel/arch/arm32/include/machine_func.h |
---|
File deleted |
/branches/arm/kernel/arch/arm32/include/mainpage.h |
---|
File deleted |
/branches/arm/kernel/arch/arm32/include/mach/testarm/testarm.h |
---|
File deleted |
/branches/arm/kernel/arch/arm32/include/mach/integratorcp/integratorcp.h |
---|
File deleted |
/branches/arm/kernel/arch/arm32/include/types.h |
---|
30,17 → 30,14 |
* @{ |
*/ |
/** @file |
* @brief Type definitions. |
*/ |
#ifndef KERN_arm32_TYPES_H_ |
#define KERN_arm32_TYPES_H_ |
#ifndef DOXYGEN |
# define ATTRIBUTE_PACKED __attribute__ ((packed)) |
#else |
# define ATTRIBUTE_PACKED |
#endif |
#define NULL 0 |
#define false 0 |
#define true 1 |
typedef signed char int8_t; |
typedef signed short int16_t; |
53,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; |
62,39 → 61,77 |
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 "d" /**< Format for int32_t. */ |
#define PRId64 "lld" /**< Format for int64_t. */ |
#define PRIdn "d" /**< Format for native_t. */ |
typedef uint32_t __address; |
#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. |
* |
* |
* We have different structs for level 0 and level 1 page table entries. |
* See page.h for definition of pte_level*_t. |
*/ |
* */ |
typedef struct { |
unsigned dummy : 32; |
unsigned dummy : 32; |
} pte_t; |
/** Level 0 page table entry. */ |
typedef struct { |
/* 01b for coarse tables, see below for details */ |
unsigned descriptor_type : 2; |
unsigned impl_specific : 3; |
unsigned domain : 4; |
unsigned should_be_zero : 1; |
/* Pointer to the coarse 2nd level page table (holding entries for small (4KB) |
* or large (64KB) pages. ARM also supports fine 2nd level page tables that |
* may hold even tiny pages (1KB) but they are bigger (4KB per table in comparison |
* with 1KB per the coarse table) |
*/ |
unsigned coarse_table_addr : 22; |
} __attribute__ ((packed)) pte_level0_t; |
/** Level 1 page table entry (small (4KB) pages used) */ |
typedef struct { |
/* 0b10 for small pages */ |
unsigned descriptor_type : 2; |
unsigned bufferable : 1; |
unsigned cacheable : 1; |
/* access permissions for each of 4 subparts of a page |
* (for each 1KB when small pages used */ |
unsigned access_permission_0 : 2; |
unsigned access_permission_1 : 2; |
unsigned access_permission_2 : 2; |
unsigned access_permission_3 : 2; |
unsigned frame_base_addr : 20; |
} __attribute__ ((packed)) pte_level1_t; |
/* Level 1 page tables access permissions */ |
/** User mode: no access, privileged mode: no access */ |
#define pte_ap_user_no_kernel_no 0 |
/** User mode: no access, privileged mode: read/write */ |
#define pte_ap_user_no_kernel_rw 1 |
/** User mode: read only, privileged mode: read/write */ |
#define pte_ap_user_ro_kernel_rw 2 |
/// User mode: read/write, privileged mode: read/write |
#define pte_ap_user_rw_kernel_rw 3 |
/* pte_level0_t and pte_level1_t descriptor_type flags */ |
/** pte_level0_t and pte_level1_t "not present" flag (used in descriptor_type) */ |
#define pte_descriptor_not_preset 0 |
/** pte_level0_t coarse page table flag (used in descriptor_type) */ |
#define pte_descriptor_coarse_table 1 |
/** pte_level1_t small page table flag (used in descriptor type) */ |
#define pte_descriptor_small_page 2 |
#endif |
/** @} |
/branches/arm/kernel/arch/arm32/include/mm/page_fault.h |
---|
File deleted |
/branches/arm/kernel/arch/arm32/include/mm/frame.h |
---|
26,18 → 26,17 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32mm |
/** @addtogroup arm32mm |
* @{ |
*/ |
/** @file |
* @brief Frame related declarations. |
*/ |
#ifndef KERN_arm32_FRAME_H_ |
#define KERN_arm32_FRAME_H_ |
#define FRAME_WIDTH 12 /* 4KB frames */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#define FRAME_WIDTH 12 /* 4KB frames */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#ifdef KERNEL |
#ifndef __ASM__ |
44,17 → 43,9 |
#include <arch/types.h> |
#define BOOT_PAGE_TABLE_SIZE 0x4000 |
#define BOOT_PAGE_TABLE_ADDRESS 0x4000 |
extern __address last_frame; |
#define BOOT_PAGE_TABLE_START_FRAME (BOOT_PAGE_TABLE_ADDRESS >> FRAME_WIDTH) |
#define BOOT_PAGE_TABLE_SIZE_IN_FRAMES (BOOT_PAGE_TABLE_SIZE >> FRAME_WIDTH) |
extern uintptr_t last_frame; |
extern void frame_arch_init(void); |
extern void boot_page_table_free(void); |
#define physmem_print() |
#endif /* __ASM__ */ |
#endif /* KERNEL */ |
/branches/arm/kernel/arch/arm32/include/mm/page.h |
---|
30,7 → 30,6 |
* @{ |
*/ |
/** @file |
* @brief Paging related declarations. |
*/ |
#ifndef KERN_arm32_PAGE_H_ |
40,9 → 39,12 |
#include <mm/mm.h> |
#include <arch/exception.h> |
#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) |
53,235 → 55,155 |
#ifdef KERNEL |
/* Number of entries in each level. */ |
#define PTL0_ENTRIES_ARCH (2 << 12) /* 4096 */ |
#define PTL1_ENTRIES_ARCH 0 |
#define PTL2_ENTRIES_ARCH 0 |
/* coarse page tables used (256 * 4 = 1KB per page) */ |
#define PTL3_ENTRIES_ARCH (2 << 8) /* 256 */ |
#define PTL0_ENTRIES_ARCH (2<<12) // 4096 |
#define PTL1_ENTRIES_ARCH 0 |
#define PTL2_ENTRIES_ARCH 0 |
/* coarse page tables used (256*4 = 1KB per page) */ |
#define PTL3_ENTRIES_ARCH (2<<8) // 256 |
/* Page table sizes for each level. */ |
#define PTL0_SIZE_ARCH FOUR_FRAMES |
#define PTL1_SIZE_ARCH 0 |
#define PTL2_SIZE_ARCH 0 |
#define PTL3_SIZE_ARCH ONE_FRAME |
#define PTL0_SIZE_ARCH FOUR_FRAMES |
#define PTL1_SIZE_ARCH 0 |
#define PTL2_SIZE_ARCH 0 |
#define PTL3_SIZE_ARCH ONE_FRAME |
/* Macros calculating indices into page tables for each level. */ |
#define PTL0_INDEX_ARCH(vaddr) (((vaddr) >> 20) & 0xfff) |
#define PTL1_INDEX_ARCH(vaddr) 0 |
#define PTL2_INDEX_ARCH(vaddr) 0 |
#define PTL3_INDEX_ARCH(vaddr) (((vaddr) >> 12) & 0x0ff) |
#define PTL0_INDEX_ARCH(vaddr) (((vaddr) >> 20) & 0xfff) |
#define PTL1_INDEX_ARCH(vaddr) 0 |
#define PTL2_INDEX_ARCH(vaddr) 0 |
/* TODO: ?? 0xfff or 0x0ff */ |
#define PTL3_INDEX_ARCH(vaddr) (((vaddr) >> 12) & 0xfff) |
/* Get PTE address accessors for each level. */ |
#define GET_PTL1_ADDRESS_ARCH(ptl0, i) \ |
((pte_t *) ((((pte_level0_t *)(ptl0))[(i)]).coarse_table_addr << 10)) |
#define GET_PTL2_ADDRESS_ARCH(ptl1, i) \ |
(ptl1) |
#define GET_PTL3_ADDRESS_ARCH(ptl2, i) \ |
(ptl2) |
#define GET_FRAME_ADDRESS_ARCH(ptl3, i) \ |
((uintptr_t) ((((pte_level1_t *)(ptl3))[(i)]).frame_base_addr << 12)) |
#define GET_PTL1_ADDRESS_ARCH(ptl0, i) ((pte_t *)( (((pte_level0_t*)(ptl0))[(i)]).coarse_table_addr << 10 )) |
#define GET_PTL2_ADDRESS_ARCH(ptl1, i) (ptl1) |
#define GET_PTL3_ADDRESS_ARCH(ptl2, i) (ptl2) |
#define GET_FRAME_ADDRESS_ARCH(ptl3, i) ((uintptr_t)( (((pte_level1_t*)(ptl3))[(i)]).frame_base_addr << 12 )) |
/* Set PTE address accessors for each level. */ |
#define SET_PTL0_ADDRESS_ARCH(ptl0) \ |
(set_ptl0_addr((pte_level0_t *) (ptl0))) |
#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) \ |
(((pte_level0_t *) (ptl0))[(i)].coarse_table_addr = (a) >> 10) |
#define SET_PTL0_ADDRESS_ARCH(ptl0) (set_ptl0_addr((pte_level0_t *)(ptl0))) |
#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) (((pte_level0_t *)(ptl0))[(i)].coarse_table_addr = (a)>>10) |
#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a) |
#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a) |
#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) \ |
(((pte_level1_t *) (ptl3))[(i)].frame_base_addr = (a) >> 12) |
#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) (((pte_level1_t *)(ptl3))[(i)].frame_base_addr = (a)>>12) |
/* Get PTE flags accessors for each level. */ |
#define GET_PTL1_FLAGS_ARCH(ptl0, i) \ |
get_pt_level0_flags((pte_level0_t *) (ptl0), (size_t) (i)) |
#define GET_PTL2_FLAGS_ARCH(ptl1, i) \ |
PAGE_PRESENT |
#define GET_PTL3_FLAGS_ARCH(ptl2, i) \ |
PAGE_PRESENT |
#define GET_FRAME_FLAGS_ARCH(ptl3, i) \ |
get_pt_level1_flags((pte_level1_t *) (ptl3), (size_t) (i)) |
#define GET_PTL1_FLAGS_ARCH(ptl0, i) get_pt_level0_flags((pte_level0_t *)(ptl0), (index_t)(i)) |
#define GET_PTL2_FLAGS_ARCH(ptl1, i) PAGE_PRESENT |
#define GET_PTL3_FLAGS_ARCH(ptl2, i) PAGE_PRESENT |
#define GET_FRAME_FLAGS_ARCH(ptl3, i) get_pt_level1_flags((pte_level1_t *)(ptl3), (index_t)(i)) |
/* Set PTE flags accessors for each level. */ |
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \ |
set_pt_level0_flags((pte_level0_t *) (ptl0), (size_t) (i), (x)) |
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) set_pt_level0_flags((pte_level0_t *)(ptl0), (index_t)(i), (x)) |
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x) |
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x) |
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \ |
set_pt_level1_flags((pte_level1_t *) (ptl3), (size_t) (i), (x)) |
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) set_pt_level1_flags((pte_level1_t *)(ptl3), (index_t)(i), (x)) |
/* Macros for querying the last-level PTE entries. */ |
#define PTE_VALID_ARCH(pte) \ |
(*((uint32_t *) (pte)) != 0) |
#define PTE_PRESENT_ARCH(pte) \ |
(((pte_level0_t *) (pte))->descriptor_type != 0) |
#define PTE_GET_FRAME_ARCH(pte) \ |
(((pte_level1_t *) (pte))->frame_base_addr << FRAME_WIDTH) |
#define PTE_WRITABLE_ARCH(pte) \ |
(((pte_level1_t *) (pte))->access_permission_0 == \ |
PTE_AP_USER_RW_KERNEL_RW) |
#define PTE_EXECUTABLE_ARCH(pte) \ |
1 |
#define PTE_VALID_ARCH(pte) (*((uint32_t *) (pte)) != 0) |
// TODO: ?? != 0 |
#define PTE_PRESENT_ARCH(pte) ( ((pte_level0_t *)(pte))->descriptor_type != 0 ) |
#ifndef __ASM__ |
/* pte should point into ptl3 */ |
#define PTE_GET_FRAME_ARCH(pte) ( ((pte_level1_t *)(pte))->frame_base_addr << FRAME_WIDTH) |
/* pte should point into ptl3 */ |
#define PTE_WRITABLE_ARCH(pte) ( ((pte_level1_t *)(pte))->access_permission_0 == pte_ap_user_rw_kernel_rw ) |
/** Level 0 page table entry. */ |
typedef struct { |
/* 0b01 for coarse tables, see below for details */ |
unsigned descriptor_type : 2; |
unsigned impl_specific : 3; |
unsigned domain : 4; |
unsigned should_be_zero : 1; |
#define PTE_EXECUTABLE_ARCH(pte) 1 |
/* Pointer to the coarse 2nd level page table (holding entries for small |
* (4KB) or large (64KB) pages. ARM also supports fine 2nd level page |
* tables that may hold even tiny pages (1KB) but they are bigger (4KB |
* per table in comparison with 1KB per the coarse table) |
*/ |
unsigned coarse_table_addr : 22; |
} ATTRIBUTE_PACKED pte_level0_t; |
#ifndef __ASM__ |
/** Level 1 page table entry (small (4KB) pages used). */ |
typedef struct { |
/* 0b10 for small pages */ |
unsigned descriptor_type : 2; |
unsigned bufferable : 1; |
unsigned cacheable : 1; |
/* access permissions for each of 4 subparts of a page |
* (for each 1KB when small pages used */ |
unsigned access_permission_0 : 2; |
unsigned access_permission_1 : 2; |
unsigned access_permission_2 : 2; |
unsigned access_permission_3 : 2; |
unsigned frame_base_addr : 20; |
} ATTRIBUTE_PACKED pte_level1_t; |
/* Level 1 page tables access permissions */ |
/** User mode: no access, privileged mode: no access. */ |
#define PTE_AP_USER_NO_KERNEL_NO 0 |
/** User mode: no access, privileged mode: read/write. */ |
#define PTE_AP_USER_NO_KERNEL_RW 1 |
/** User mode: read only, privileged mode: read/write. */ |
#define PTE_AP_USER_RO_KERNEL_RW 2 |
/** User mode: read/write, privileged mode: read/write. */ |
#define PTE_AP_USER_RW_KERNEL_RW 3 |
/* pte_level0_t and pte_level1_t descriptor_type flags */ |
/** pte_level0_t and pte_level1_t "not present" flag (used in descriptor_type). */ |
#define PTE_DESCRIPTOR_NOT_PRESENT 0 |
/** pte_level0_t coarse page table flag (used in descriptor_type). */ |
#define PTE_DESCRIPTOR_COARSE_TABLE 1 |
/** pte_level1_t small page table flag (used in descriptor type). */ |
#define PTE_DESCRIPTOR_SMALL_PAGE 2 |
/** Sets the address of level 0 page table. |
/** |
* Sets the address of level 0 page table. |
* |
* @param pt Pointer to the page table to set. |
* \param pt pointer to the page table to set |
*/ |
static inline void set_ptl0_addr(pte_level0_t *pt) |
static inline void set_ptl0_addr( pte_level0_t* pt) |
{ |
asm volatile ( |
"mcr p15, 0, %[pt], c2, c0, 0\n" |
:: [pt] "r" (pt) |
); |
asm volatile ( "mcr p15, 0, %0, c2, c0, 0 \n" |
: |
: "r"(pt) |
); |
} |
/** Returns level 0 page table entry flags. |
/** |
* Returns level 0 page table entry flags. |
* |
* @param pt Level 0 page table. |
* @param i Index of the entry to return. |
* \param pt level 0 page table |
* \param i index of the entry to return |
*/ |
static inline int get_pt_level0_flags(pte_level0_t *pt, size_t i) |
static inline int get_pt_level0_flags(pte_level0_t *pt, index_t i) |
{ |
pte_level0_t *p = &pt[i]; |
int np = (p->descriptor_type == PTE_DESCRIPTOR_NOT_PRESENT); |
return (np << PAGE_PRESENT_SHIFT) | (1 << PAGE_USER_SHIFT) | |
(1 << PAGE_READ_SHIFT) | (1 << PAGE_WRITE_SHIFT) | |
(1 << PAGE_EXEC_SHIFT) | (1 << PAGE_CACHEABLE_SHIFT); |
return ( |
( p->descriptor_type != pte_descriptor_not_preset ) << PAGE_PRESENT_SHIFT | |
( 1 << PAGE_USER_SHIFT ) | |
( 1 << PAGE_READ_SHIFT ) | |
( 1 << PAGE_WRITE_SHIFT ) | |
( 1 << PAGE_EXEC_SHIFT ) | |
( 1 << PAGE_CACHEABLE_SHIFT ) |
); |
} |
/** Returns level 1 page table entry flags. |
/** |
* Returns level 1 page table entry flags. |
* |
* @param pt Level 1 page table. |
* @param i Index of the entry to return. |
* \param pt level 1 page table |
* \param i index of the entry to return |
*/ |
static inline int get_pt_level1_flags(pte_level1_t *pt, size_t i) |
static inline int get_pt_level1_flags(pte_level1_t *pt, index_t i) |
{ |
pte_level1_t *p = &pt[i]; |
int dt = p->descriptor_type; |
int ap = p->access_permission_0; |
return ((dt == PTE_DESCRIPTOR_NOT_PRESENT) << PAGE_PRESENT_SHIFT) | |
((ap == PTE_AP_USER_RO_KERNEL_RW) << PAGE_READ_SHIFT) | |
((ap == PTE_AP_USER_RW_KERNEL_RW) << PAGE_READ_SHIFT) | |
((ap == PTE_AP_USER_RW_KERNEL_RW) << PAGE_WRITE_SHIFT) | |
((ap != PTE_AP_USER_NO_KERNEL_RW) << PAGE_USER_SHIFT) | |
((ap == PTE_AP_USER_NO_KERNEL_RW) << PAGE_READ_SHIFT) | |
((ap == PTE_AP_USER_NO_KERNEL_RW) << PAGE_WRITE_SHIFT) | |
(1 << PAGE_EXEC_SHIFT) | |
(p->bufferable << PAGE_CACHEABLE); |
return ( |
( p->descriptor_type != pte_descriptor_not_preset ) << PAGE_PRESENT_SHIFT | |
( (p->access_permission_0 == pte_ap_user_ro_kernel_rw) << PAGE_READ_SHIFT ) | |
( (p->access_permission_0 == pte_ap_user_rw_kernel_rw) << PAGE_READ_SHIFT ) | |
( (p->access_permission_0 == pte_ap_user_rw_kernel_rw) << PAGE_WRITE_SHIFT ) | |
( (p->access_permission_0 != pte_ap_user_no_kernel_rw) << PAGE_USER_SHIFT ) | |
( 1 << PAGE_EXEC_SHIFT ) | |
( p->bufferable << PAGE_CACHEABLE ) |
); |
} |
/** Sets flags of level 0 page table entry. |
/** |
* Sets flags of level 0 page table entry. |
* |
* @param pt level 0 page table |
* @param i index of the entry to be changed |
* @param flags new flags |
* \param pt level 0 page table |
* \param i index of the entry to be changed |
* \param flags new flags |
* |
* TODO: why should_be_zero set to 1? |
*/ |
static inline void set_pt_level0_flags(pte_level0_t *pt, size_t i, int flags) |
static inline void set_pt_level0_flags(pte_level0_t *pt, index_t i, int flags) |
{ |
pte_level0_t *p = &pt[i]; |
if (flags & PAGE_NOT_PRESENT) { |
p->descriptor_type = PTE_DESCRIPTOR_NOT_PRESENT; |
/* |
* Ensures that the entry will be recognized as valid when |
* PTE_VALID_ARCH applied. |
*/ |
p->should_be_zero = 1; |
p->descriptor_type = pte_descriptor_not_preset; |
p->should_be_zero = 1; |
} else { |
p->descriptor_type = PTE_DESCRIPTOR_COARSE_TABLE; |
p->should_be_zero = 0; |
p->descriptor_type = pte_descriptor_coarse_table; |
p->should_be_zero = 0; |
} |
} |
/** Sets flags of level 1 page table entry. |
/** |
* Sets flags of level 1 page table entry. |
* |
* We use same access rights for the whole page. When page is not preset we |
* store 1 in acess_rigts_3 so that at least one bit is 1 (to mark correct |
* page entry, see #PAGE_VALID_ARCH). |
* We use same access rights for the whole page. When page is not preset then |
* store 1 in acess_rigts_3. |
* TODO: why access_right_3? |
* |
* @param pt Level 1 page table. |
* @param i Index of the entry to be changed. |
* @param flags New flags. |
* \param pt level 1 page table |
* \param i index of the entry to be changed |
* \param flags new flags |
*/ |
static inline void set_pt_level1_flags(pte_level1_t *pt, size_t i, int flags) |
static inline void set_pt_level1_flags(pte_level1_t *pt, index_t i, int flags) |
{ |
pte_level1_t *p = &pt[i]; |
if (flags & PAGE_NOT_PRESENT) { |
p->descriptor_type = PTE_DESCRIPTOR_NOT_PRESENT; |
p->access_permission_3 = 1; |
p->descriptor_type = pte_descriptor_not_preset; |
p->access_permission_3 = 1; |
} else { |
p->descriptor_type = PTE_DESCRIPTOR_SMALL_PAGE; |
p->access_permission_3 = p->access_permission_0; |
p->descriptor_type = pte_descriptor_small_page; |
p->access_permission_3 = p->access_permission_0; |
} |
p->cacheable = p->bufferable = (flags & PAGE_CACHEABLE) != 0; |
288,27 → 210,24 |
/* default access permission */ |
p->access_permission_0 = p->access_permission_1 = |
p->access_permission_2 = p->access_permission_3 = |
PTE_AP_USER_NO_KERNEL_RW; |
p->access_permission_2 = p->access_permission_3 = pte_ap_user_no_kernel_rw; |
if (flags & PAGE_USER) { |
if (flags & PAGE_READ) { |
p->access_permission_0 = p->access_permission_1 = |
p->access_permission_2 = p->access_permission_3 = |
PTE_AP_USER_RO_KERNEL_RW; |
p->access_permission_2 = p->access_permission_3 = |
pte_ap_user_ro_kernel_rw; |
} |
if (flags & PAGE_WRITE) { |
p->access_permission_0 = p->access_permission_1 = |
p->access_permission_2 = p->access_permission_3 = |
PTE_AP_USER_RW_KERNEL_RW; |
p->access_permission_2 = p->access_permission_3 = |
pte_ap_user_rw_kernel_rw; |
} |
} |
} |
extern void page_arch_init(void); |
#endif /* __ASM__ */ |
#endif /* KERNEL */ |
317,3 → 236,4 |
/** @} |
*/ |
/branches/arm/kernel/arch/arm32/include/mm/memory_init.h |
---|
0,0 → 1,45 |
/* |
* Copyright (c) 2007 Pavel Jancik |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32mm |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_arm32_MEMORY_INIT_H_ |
#define KERN_arm32_MEMORY_INIT_H_ |
#include <config.h> |
size_t get_memory_size(void); |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/arm32/include/mm/asid.h |
---|
30,9 → 30,6 |
* @{ |
*/ |
/** @file |
* @brief ASIDs related declarations. |
* |
* ARM CPUs doesn't support ASIDs. |
*/ |
#ifndef KERN_arm32_ASID_H_ |
44,12 → 41,11 |
typedef uint8_t asid_t; |
/* |
* This works due to fact that this file is never included alone but only |
* through "generic/include/mm/asid.h" where ASID_START is defined. |
*/ |
#define asid_get() (ASID_START + 1) |
#define asid_get() ( ASID_START + 1 ) |
/* this works due to that this file is never included alone but only throught |
"generic/include/mm/asid.h" where ASID_START is defined |
*/ |
#define asid_put(asid) |
#endif |
/branches/arm/kernel/arch/arm32/include/mm/tlb.h |
---|
30,12 → 30,14 |
* @{ |
*/ |
/** @file |
* @brief TLB related declarations. |
*/ |
#ifndef KERN_arm32_TLB_H_ |
#define KERN_arm32_TLB_H_ |
#define tlb_arch_init() |
#define tlb_print() |
#endif |
/** @} |
/branches/arm/kernel/arch/arm32/include/mm/as.h |
---|
30,7 → 30,6 |
* @{ |
*/ |
/** @file |
* @brief Address space manipulating functions declarations. |
*/ |
#ifndef KERN_arm32_AS_H_ |
/branches/arm/kernel/arch/arm32/include/exception.h |
---|
1,5 → 1,6 |
/* |
* Copyright (c) 2007 Michal Kebrt, Petr Stepan |
* Copyright (c) 2007 Michal Kebrt |
* Copyright (c) 2007 Petr Stepan |
* |
* All rights reserved. |
* |
31,7 → 32,6 |
* @{ |
*/ |
/** @file |
* @brief Exception declarations. |
*/ |
#ifndef KERN_arm32_EXCEPTION_H_ |
38,58 → 38,28 |
#define KERN_arm32_EXCEPTION_H_ |
#include <arch/types.h> |
#include <arch/regutils.h> |
/** If defined, forces using of high exception vectors. */ |
#define HIGH_EXCEPTION_VECTORS |
#ifdef HIGH_EXCEPTION_VECTORS |
#define EXC_BASE_ADDRESS 0xffff0000 |
#else |
#define EXC_BASE_ADDRESS 0x0 |
#endif |
/* Exception Vectors */ |
#define EXC_RESET_VEC (EXC_BASE_ADDRESS + 0x0) |
#define EXC_UNDEF_INSTR_VEC (EXC_BASE_ADDRESS + 0x4) |
#define EXC_SWI_VEC (EXC_BASE_ADDRESS + 0x8) |
#define EXC_PREFETCH_ABORT_VEC (EXC_BASE_ADDRESS + 0xc) |
#define EXC_DATA_ABORT_VEC (EXC_BASE_ADDRESS + 0x10) |
#define EXC_IRQ_VEC (EXC_BASE_ADDRESS + 0x18) |
#define EXC_FIQ_VEC (EXC_BASE_ADDRESS + 0x1c) |
#define EXC_RESET_VEC 0x0 |
#define EXC_UNDEF_INSTR_VEC 0x4 |
#define EXC_SWI_VEC 0x8 |
#define EXC_PREFETCH_ABORT_VEC 0xc |
#define EXC_DATA_ABORT_VEC 0x10 |
#define EXC_IRQ_VEC 0x18 |
#define EXC_FIQ_VEC 0x1c |
/* Exception numbers */ |
#define EXC_RESET 0 |
#define EXC_UNDEF_INSTR 1 |
#define EXC_SWI 2 |
#define EXC_PREFETCH_ABORT 3 |
#define EXC_DATA_ABORT 4 |
#define EXC_IRQ 5 |
#define EXC_FIQ 6 |
#define EXC_RESET 0 |
#define EXC_UNDEF_INSTR 1 |
#define EXC_SWI 2 |
#define EXC_PREFETCH_ABORT 3 |
#define EXC_DATA_ABORT 4 |
#define EXC_IRQ 5 |
#define EXC_FIQ 6 |
/** Kernel stack pointer. |
* |
* It is set when thread switches to user mode, |
* and then used for exception handling. |
*/ |
extern uintptr_t supervisor_sp; |
/** Temporary exception stack pointer. |
* |
* Temporary stack is used in exceptions handling routines |
* before switching to thread's kernel stack. |
*/ |
extern uintptr_t exc_stack; |
/** Struct representing CPU state saved when an exception occurs. */ |
typedef struct { |
uint32_t spsr; |
uint32_t sp; |
uint32_t lr; |
uint32_t r0; |
uint32_t r1; |
uint32_t r2; |
103,48 → 73,32 |
uint32_t r10; |
uint32_t r11; |
uint32_t r12; |
uint32_t sp; |
uint32_t lr; |
uint32_t pc; |
uint32_t spsr; |
} istate_t; |
/** Sets Program Counter member of given istate structure. |
* |
* @param istate istate structure |
* @param retaddr new value of istate's PC member |
*/ |
static inline void istate_set_retaddr(istate_t *istate, uintptr_t retaddr) |
{ |
istate->pc = retaddr; |
istate->lr = retaddr; |
} |
/** Returns true if exception happened while in userspace. */ |
/** Return true if exception happened while in userspace */ |
static inline int istate_from_uspace(istate_t *istate) |
{ |
return (istate->spsr & STATUS_REG_MODE_MASK) == USER_MODE; |
return !(istate->lr & 0x80000000); |
return 0; |
} |
/** Returns Program Counter member of given istate structure. */ |
static inline unative_t istate_get_pc(istate_t *istate) |
{ |
return istate->pc; |
return istate->lr; |
} |
extern void setup_exception_stacks(void); |
extern void install_exception_handlers(void); |
extern void exception_init(void); |
extern void print_istate(istate_t *istate); |
extern void reset_exception_entry(void); |
extern void irq_exception_entry(void); |
extern void fiq_exception_entry(void); |
extern void undef_instr_exception_entry(void); |
extern void prefetch_abort_exception_entry(void); |
extern void data_abort_exception_entry(void); |
extern void swi_exception_entry(void); |
#endif |
/** @} |
/branches/arm/kernel/arch/arm32/include/interrupt.h |
---|
27,32 → 27,20 |
*/ |
/** @addtogroup arm32interrupt |
* @ingroup interrupt |
* @{ |
*/ |
/** @file |
* @brief Declarations of interrupt controlling routines. |
*/ |
#ifndef KERN_arm32_INTERRUPT_H_ |
#define KERN_arm32_INTERRUPT_H_ |
#include <arch/types.h> |
#include <arch/exception.h> |
/** Initial size of exception dispatch table. */ |
#define IVT_ITEMS 6 |
/** Index of the first item in exception dispatch table. */ |
#define IVT_FIRST 0 |
void interrupt_init(void); |
extern void interrupt_init(void); |
extern ipl_t interrupts_disable(void); |
extern ipl_t interrupts_enable(void); |
extern void interrupts_restore(ipl_t ipl); |
extern ipl_t interrupts_read(void); |
#endif |
/** @} |
/branches/arm/kernel/arch/arm32/include/drivers/gxemul.h |
---|
0,0 → 1,47 |
/* |
* Copyright (c) 2007 Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_arm32_MSIM_GXEMUL_H_ |
#define KERN_arm32_MSIM_GXEMUL_H_ |
#include <console/chardev.h> |
void gxemul_console(devno_t devno); |
void gxemul_kbd_release(void); |
void gxemul_kbd_grab(void); |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/arm32/include/stack.h |
---|
30,7 → 30,6 |
* @{ |
*/ |
/** @file |
* @brief Stack constants. |
*/ |
#ifndef KERN_arm32_STACK_H_ |
38,9 → 37,7 |
#define STACK_ITEM_SIZE 4 |
/** See <a href="http://www.arm.com/support/faqdev/14269.html">ABI</a> for |
* details |
*/ |
/** see <a href="http://www.arm.com/support/faqdev/14269.html">ABI</a> for details */ |
#define STACK_ALIGNMENT 8 |
#endif |
/branches/arm/kernel/arch/arm32/include/atomic.h |
---|
26,102 → 26,53 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
* @brief Atomic operations. |
*/ |
#ifndef KERN_arm32_ATOMIC_H_ |
#define KERN_arm32_ATOMIC_H_ |
/** Atomic addition. |
#define atomic_inc(x) ((void) atomic_add(x, 1)) |
#define atomic_dec(x) ((void) atomic_add(x, -1)) |
#define atomic_postinc(x) (atomic_add(x, 1) - 1) |
#define atomic_postdec(x) (atomic_add(x, -1) + 1) |
#define atomic_preinc(x) atomic_add(x, 1) |
#define atomic_predec(x) atomic_add(x, -1) |
/* Atomic addition of immediate value. |
* |
* @param val Where to add. |
* @param i Value to be added. |
* @param val Memory location to which will be the immediate value added. |
* @param i Signed immediate that will be added to *val. |
* |
* @return Value after addition. |
* |
*/ |
static inline long atomic_add(atomic_t *val, int i) |
{ |
int ret; |
volatile long *mem = &(val->count); |
volatile long * mem = &(val->count); |
asm volatile ( |
"1:\n" |
"ldr r2, [%[mem]]\n" |
"add r3, r2, %[i]\n" |
"str r3, %[ret]\n" |
"swp r3, r3, [%[mem]]\n" |
"cmp r3, r2\n" |
"bne 1b\n" |
: [ret] "=m" (ret) |
: [mem] "r" (mem), [i] "r" (i) |
"1: \n" |
"ldr r2, [%1] \n" |
"add r3, r2, %2 \n" |
"str r3, %0 \n" |
"swp r3, r3, [%1] \n" |
"cmp r3, r2 \n" |
"bne 1b \n" |
: "=m" (ret) |
: "r" (mem), "r" (i) |
: "r3", "r2" |
); |
return ret; |
} |
} |
/** Atomic increment. |
* |
* @param val Variable to be incremented. |
*/ |
static inline void atomic_inc(atomic_t *val) |
{ |
atomic_add(val, 1); |
} |
/** Atomic decrement. |
* |
* @param val Variable to be decremented. |
*/ |
static inline void atomic_dec(atomic_t *val) { |
atomic_add(val, -1); |
} |
/** Atomic pre-increment. |
* |
* @param val Variable to be incremented. |
* @return Value after incrementation. |
*/ |
static inline long atomic_preinc(atomic_t *val) |
{ |
return atomic_add(val, 1); |
} |
/** Atomic pre-decrement. |
* |
* @param val Variable to be decremented. |
* @return Value after decrementation. |
*/ |
static inline long atomic_predec(atomic_t *val) |
{ |
return atomic_add(val, -1); |
} |
/** Atomic post-increment. |
* |
* @param val Variable to be incremented. |
* @return Value before incrementation. |
*/ |
static inline long atomic_postinc(atomic_t *val) |
{ |
return atomic_add(val, 1) - 1; |
} |
/** Atomic post-decrement. |
* |
* @param val Variable to be decremented. |
* @return Value before decrementation. |
*/ |
static inline long atomic_postdec(atomic_t *val) |
{ |
return atomic_add(val, -1) + 1; |
} |
#endif |
/** @} |
/branches/arm/kernel/arch/arm32/include/asm.h |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2007 Michal Kebrt |
* Copyright (c) 2003-2004 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
26,72 → 26,34 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
* @brief Declarations of functions implemented in assembly. |
*/ |
#ifndef KERN_arm32_ASM_H_ |
#define KERN_arm32_ASM_H_ |
#include <typedefs.h> |
#include <arch/types.h> |
#include <arch/stack.h> |
#include <config.h> |
#include <arch/interrupt.h> |
/** No such instruction on ARM to sleep CPU. */ |
static inline void cpu_sleep(void) |
{ |
// not implemented on gxemul |
} |
static inline void pio_write_8(ioport8_t *port, uint8_t v) |
{ |
*port = v; |
} |
static inline void pio_write_16(ioport16_t *port, uint16_t v) |
{ |
*port = v; |
} |
static inline void pio_write_32(ioport32_t *port, uint32_t v) |
{ |
*port = v; |
} |
static inline uint8_t pio_read_8(ioport8_t *port) |
{ |
return *port; |
} |
static inline uint16_t pio_read_16(ioport16_t *port) |
{ |
return *port; |
} |
static inline uint32_t pio_read_32(ioport32_t *port) |
{ |
return *port; |
} |
/** Return base address of current stack. |
* |
/** Return base address of current stack |
* |
* Return the base address of the current stack. |
* The stack is assumed to be STACK_SIZE bytes long. |
* The stack must start on page boundary. |
* |
*/ |
static inline uintptr_t get_stack_base(void) |
{ |
uintptr_t v; |
asm volatile ( |
"and %[v], sp, %[size]\n" |
: [v] "=r" (v) |
: [size] "r" (~(STACK_SIZE - 1)) |
); |
asm volatile ("and %0, sp, %1\n" : "=r" (v) : "r" (~(STACK_SIZE-1))); |
return v; |
} |
100,6 → 62,12 |
extern void userspace_asm(uintptr_t ustack, uintptr_t uspace_uarg, |
uintptr_t entry); |
extern ipl_t interrupts_disable(void); |
extern ipl_t interrupts_enable(void); |
extern void interrupts_restore(ipl_t ipl); |
extern ipl_t interrupts_read(void); |
#endif |
/** @} |
/branches/arm/kernel/arch/arm32/include/context.h |
---|
30,7 → 30,6 |
* @{ |
*/ |
/** @file |
* @brief Thread context. |
*/ |
#ifndef KERN_arm32_CONTEXT_H_ |
39,18 → 38,22 |
#include <align.h> |
#include <arch/stack.h> |
/* Put one item onto the stack to support get_stack_base() and align it up. */ |
/* |
* Put one item onto the stack to support get_stack_base() and align it up. |
*/ |
#define SP_DELTA (0 + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT)) |
#ifndef __ASM__ |
#include <arch/types.h> |
/** Thread context containing registers that must be preserved across function |
* calls. |
/* |
* Only save registers that must be preserved across |
* function calls. |
*/ |
typedef struct { |
uint32_t cpu_mode; |
uintptr_t sp; |
uintptr_t pc; |
59,14 → 62,12 |
uint32_t r6; |
uint32_t r7; |
uint32_t r8; |
uint32_t r9; |
uint32_t r10; |
uint32_t r11; |
ipl_t ipl; |
} context_t; |
#endif /* __ASM__ */ |
#endif |
/branches/arm/kernel/arch/arm32/include/cpu.h |
---|
30,7 → 30,6 |
* @{ |
*/ |
/** @file |
* @brief CPU identification. |
*/ |
#ifndef KERN_arm32_CPU_H_ |
39,25 → 38,20 |
#include <arch/types.h> |
#include <arch/asm.h> |
/** Struct representing ARM CPU identifiaction. */ |
typedef struct { |
/** Implementator (vendor) number. */ |
uint32_t imp_num; |
/** Variant number. */ |
uint32_t variant_num; |
/** Architecture number. */ |
uint32_t arch_num; |
/** Primary part number. */ |
uint32_t prim_part_num; |
/** Revision number. */ |
uint32_t rev_num; |
/** Implementator (vendor) number */ |
uint32_t imp_num; |
/** Variant number */ |
uint32_t variant_num; |
/** Architecture number */ |
uint32_t arch_num; |
/** Primary part number */ |
uint32_t prim_part_num; |
/** Revision number */ |
uint32_t rev_num; |
} cpu_arch_t; |
#endif |
/** @} |
/branches/arm/kernel/arch/arm32/include/regutils.h |
---|
26,66 → 26,64 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
/** @addtogroup arm32 |
* @{ |
*/ |
/** |
* @file |
* @brief Utilities for convenient manipulation with ARM registers. |
* @brief Utilities for convenient manipulation with ARM registries. |
*/ |
#ifndef KERN_arm32_REGUTILS_H_ |
#define KERN_arm32_REGUTILS_H_ |
#define STATUS_REG_IRQ_DISABLED_BIT (1 << 7) |
#define STATUS_REG_MODE_MASK 0x1f |
#define CP15_R1_HIGH_VECTORS_BIT (1 << 13) |
#define STATUS_REG_IE_ENABLED_BIT (1 << 7) |
#define STATUS_REG_MODE_MASK 0x1F |
/* ARM Processor Operation Modes */ |
#define USER_MODE 0x10 |
#define FIQ_MODE 0x11 |
#define IRQ_MODE 0x12 |
#define SUPERVISOR_MODE 0x13 |
#define ABORT_MODE 0x17 |
#define UNDEFINED_MODE 0x1b |
#define SYSTEM_MODE 0x1f |
#define USER_MODE 0x10 |
#define FIQ_MODE 0x11 |
#define IRQ_MODE 0x12 |
#define SUPERVISOR_MODE 0x13 |
#define ABORT_MODE 0x17 |
#define UNDEFINED_MODE 0x1b |
#define SYSTEM_MODE 0x1f |
/* [CS]PRS manipulation macros */ |
#define GEN_STATUS_READ(nm,reg) \ |
static inline uint32_t nm## _status_reg_read(void) \ |
{ \ |
uint32_t retval; \ |
asm volatile( \ |
"mrs %[retval], " #reg \ |
: [retval] "=r" (retval) \ |
); \ |
return retval; \ |
} |
static inline uint32_t nm## _status_reg_read(void) \ |
{ \ |
uint32_t retval; \ |
asm("mrs %0, " #reg : "=r"(retval)); \ |
return retval; \ |
} |
#define GEN_STATUS_WRITE(nm,reg,fieldname, field) \ |
static inline void nm## _status_reg_ ##fieldname## _write(uint32_t value) \ |
{ \ |
asm volatile( \ |
"msr " #reg "_" #field ", %[value]" \ |
:: [value] "r" (value) \ |
); \ |
} |
static void nm## _status_reg_ ##fieldname## _write(uint32_t value) \ |
{ \ |
asm("msr " #reg "_" #field ", %0" : : "r"(value)); \ |
} |
/** Returns the value of CPSR (Current Program Status Register). */ |
/** Returns the value of CPSR (Current Program Status Register). |
*/ |
GEN_STATUS_READ(current, cpsr) |
/** Sets control bits of CPSR. */ |
/** Sets control bits of CPSR |
*/ |
GEN_STATUS_WRITE(current, cpsr, control, c); |
/** Returns the value of SPSR (Saved Program Status Register). */ |
/** Returns the value of SPSR (Saved Program Status Register). |
*/ |
GEN_STATUS_READ(saved, spsr) |
#endif |
/** @} |
/branches/arm/kernel/arch/arm32/include/console.h |
---|
0,0 → 1,43 |
/* |
* Copyright (c) 2007 Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_arm32_CONSOLE_H_ |
#define KERN_arm32_CONSOLE_H_ |
extern void console_init(devno_t devno); |
#endif |
/** @} |
*/ |
/branches/arm/kernel/arch/arm32/include/asm/boot.h |
---|
26,19 → 26,19 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
* @brief Initial kernel start. |
*/ |
#ifndef KERN_arm32_ASM_BOOT_H_ |
#define KERN_arm32_ASM_BOOT_H_ |
/** Size of a temporary stack used for initial kernel start. */ |
#define TEMP_STACK_SIZE 0x100 |
/* Temporary stack size for boot process */ |
#define TEMP_STACK_SIZE 0x100 |
#endif |
/** @} |
/branches/arm/kernel/arch/arm32/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_arm32_BOOT_H_ |
#define KERN_arm32_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/arm32/include/fpu_context.h |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2007 Michal Kebrt |
* Copyright (c) 2005 Jakub Vana |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
30,9 → 30,6 |
* @{ |
*/ |
/** @file |
* @brief FPU context (not implemented). |
* |
* GXemul doesn't support FPU on its ARM CPU. |
*/ |
#ifndef KERN_arm32_FPU_CONTEXT_H_ |
40,7 → 37,7 |
#include <arch/types.h> |
#define FPU_CONTEXT_ALIGN 0 |
#define FPU_CONTEXT_ALIGN 0 /* TODO */ |
typedef struct { |
} fpu_context_t; |
/branches/arm/kernel/arch/arm32/include/cycle.h |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2007 Michal Kebrt |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
30,20 → 30,14 |
* @{ |
*/ |
/** @file |
* @brief Count of CPU cycles. |
*/ |
#ifndef KERN_arm32_CYCLE_H_ |
#define KERN_arm32_CYCLE_H_ |
/** Returns count of CPU cycles. |
* |
* No such instruction on ARM to get count of cycles. |
* |
* @return Count of CPU cycles. |
*/ |
static inline uint64_t get_cycle(void) |
{ |
/* TODO */ |
return 0; |
} |
/branches/arm/kernel/arch/arm32/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 arm32 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_arm32_BYTEORDER_H_ |
#define KERN_arm32_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/arm32/include/elf.h |
---|
30,7 → 30,6 |
* @{ |
*/ |
/** @file |
* @brief ARM ELF constants. |
*/ |
#ifndef KERN_arm32_ELF_H_ |
/branches/arm/kernel/arch/arm32/include/memstr.h |
---|
30,7 → 30,6 |
* @{ |
*/ |
/** @file |
* @brief Memory manipulating functions declarations. |
*/ |
#ifndef KERN_arm32_MEMSTR_H_ |
38,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/arm32/include/arg.h |
---|
30,7 → 30,6 |
* @{ |
*/ |
/** @file |
* @brief Empty. |
*/ |
#ifndef KERN_arm32_ARG_H_ |
/branches/arm/kernel/arch/arm32/include/arch.h |
---|
26,36 → 26,15 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
* @brief Empty. |
*/ |
#ifndef KERN_arm32_ARCH_H_ |
#define KERN_arm32_ARCH_H_ |
#define TASKMAP_MAX_RECORDS 32 |
#define CPUMAP_MAX_RECORDS 32 |
#define BOOTINFO_TASK_NAME_BUFLEN 32 |
#include <typedefs.h> |
typedef struct { |
uintptr_t addr; |
uint32_t size; |
char name[BOOTINFO_TASK_NAME_BUFLEN]; |
} utask_t; |
typedef struct { |
uint32_t cnt; |
utask_t tasks[TASKMAP_MAX_RECORDS]; |
} bootinfo_t; |
extern void arch_pre_main(void *entry, bootinfo_t *bootinfo); |
#endif |
/** @} |
/branches/arm/kernel/arch/arm32/include/proc/task.h |
---|
30,7 → 30,6 |
* @{ |
*/ |
/** @file |
* @brief Task related declarations. |
*/ |
#ifndef KERN_arm32_TASK_H_ |
/branches/arm/kernel/arch/arm32/include/proc/thread.h |
---|
30,7 → 30,6 |
* @{ |
*/ |
/** @file |
* @brief Thread related declarations. |
*/ |
#ifndef KERN_arm32_THREAD_H_ |
47,3 → 46,4 |
/** @} |
*/ |
/branches/arm/kernel/arch/arm32/include/faddr.h |
---|
30,7 → 30,6 |
* @{ |
*/ |
/** @file |
* @brief Function address conversion. |
*/ |
#ifndef KERN_arm32_FADDR_H_ |
38,10 → 37,6 |
#include <arch/types.h> |
/** Calculate absolute address of function referenced by fptr pointer. |
* |
* @param fptr Function pointer. |
*/ |
#define FADDR(fptr) ((uintptr_t) (fptr)) |
#endif |
/branches/arm/kernel/arch/arm32/include/debug.h |
---|
30,7 → 30,6 |
* @{ |
*/ |
/** @file |
* @brief Empty. |
*/ |
#ifndef KERN_arm32_DEBUG_H_ |
/branches/arm/kernel/arch/arm32/include/barrier.h |
---|
26,11 → 26,10 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
* @brief Memory barriers. |
*/ |
#ifndef KERN_arm32_BARRIER_H_ |
39,16 → 38,13 |
/* |
* TODO: implement true ARM memory barriers for macros below. |
*/ |
#define CS_ENTER_BARRIER() asm volatile ("" ::: "memory") |
#define CS_LEAVE_BARRIER() asm volatile ("" ::: "memory") |
#define CS_ENTER_BARRIER() asm volatile ("" ::: "memory") |
#define CS_LEAVE_BARRIER() asm volatile ("" ::: "memory") |
#define memory_barrier() asm volatile ("" ::: "memory") |
#define read_barrier() asm volatile ("" ::: "memory") |
#define write_barrier() asm volatile ("" ::: "memory") |
#define memory_barrier() asm volatile ("" ::: "memory") |
#define read_barrier() asm volatile ("" ::: "memory") |
#define write_barrier() asm volatile ("" ::: "memory") |
#define smc_coherence(a) |
#define smc_coherence_block(a, l) |
#endif |
/** @} |
/branches/arm/kernel/arch/arm32/src/userspace.c |
---|
File deleted |
/branches/arm/kernel/arch/arm32/src/machine_func.c |
---|
File deleted |
/branches/arm/kernel/arch/arm32/src/panic.S |
---|
File deleted |
/branches/arm/kernel/arch/arm32/src/exc_handler.S |
---|
File deleted |
/branches/arm/kernel/arch/arm32/src/mach/testarm/testarm.c |
---|
File deleted |
Property changes: |
Deleted: svn:mergeinfo |
/branches/arm/kernel/arch/arm32/src/mach/integratorcp/integratorcp.c |
---|
File deleted |
/branches/arm/kernel/arch/arm32/src/mm/page_fault.c |
---|
File deleted |
/branches/arm/kernel/arch/arm32/src/mm/frame.c |
---|
26,43 → 26,31 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32mm |
/** @addtogroup arm32mm |
* @{ |
*/ |
/** @file |
* @brief Frame related functions. |
*/ |
#include <mm/frame.h> |
#include <arch/mm/frame.h> |
#include <arch/machine.h> |
#include <config.h> |
#include "../aux_print/printf.h" |
/** Address of the last frame in the memory. */ |
uintptr_t last_frame = 0; |
__address last_frame = 0; |
/** Creates memory zones. */ |
/** Create memory zones. */ |
void frame_arch_init(void) |
{ |
last_frame = machine_get_memory_size(); |
/* All memory as one zone */ |
zone_create(0, ADDR2PFN(last_frame), |
BOOT_PAGE_TABLE_START_FRAME + BOOT_PAGE_TABLE_SIZE_IN_FRAMES, 0); |
/* blacklist boot page table */ |
frame_mark_unavailable(BOOT_PAGE_TABLE_START_FRAME, |
BOOT_PAGE_TABLE_SIZE_IN_FRAMES); |
aux_printf("frame_arch_init ... begin\n"); |
machine_frame_init(); |
} |
// all memory as one zone |
zone_create(0, ADDR2PFN(config.memory_size), 11, 0); |
last_frame = config.memory_size; |
/** Frees the boot page table. */ |
void boot_page_table_free(void) |
{ |
unsigned int i; |
for (i = 0; i < BOOT_PAGE_TABLE_SIZE_IN_FRAMES; i++) |
frame_free(i * FRAME_SIZE + BOOT_PAGE_TABLE_ADDRESS); |
/* Blacklist interrupt vector + Kernels from boot loader page table */ |
frame_mark_unavailable(0, 10); |
aux_printf("frame_arch_init ... end\n"); |
} |
/** @} |
/branches/arm/kernel/arch/arm32/src/mm/page.c |
---|
30,7 → 30,6 |
* @{ |
*/ |
/** @file |
* @brief Paging related functions. |
*/ |
#include <arch/mm/page.h> |
38,69 → 37,36 |
#include <mm/page.h> |
#include <align.h> |
#include <config.h> |
#include <arch/exception.h> |
#include <typedefs.h> |
#include <arch/types.h> |
#include <interrupt.h> |
#include <arch/mm/frame.h> |
#include "../aux_print/printf.h" |
/** Initializes page tables. |
* |
* 1:1 virtual-physical mapping is created in kernel address space. Mapping |
* for table with exception vectors is also created. |
*/ |
void page_arch_init(void) |
{ |
int flags = PAGE_CACHEABLE; |
uintptr_t cur; |
int flags; |
page_mapping_operations = &pt_mapping_operations; |
uintptr_t cur; |
/* Kernel identity mapping */ |
for (cur = 0; cur < last_frame; cur += FRAME_SIZE) |
flags = PAGE_CACHEABLE; |
/* PA2KA(identity) mapping for all frames until last_frame */ |
for (cur = 0; cur < last_frame; cur += FRAME_SIZE) { |
page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags); |
} |
/* Create mapping for exception table at high offset */ |
#ifdef HIGH_EXCEPTION_VECTORS |
void *virtaddr = frame_alloc(ONE_FRAME, FRAME_KA); |
page_mapping_insert(AS_KERNEL, EXC_BASE_ADDRESS, KA2PA(virtaddr), flags); |
#else |
#error "Only high exception vector supported now" |
#endif |
as_switch(NULL, AS_KERNEL); |
boot_page_table_free(); |
//SET_PTL0_ADDRESS_ARCH(AS_KERNEL->genarch.page_table); |
// note for Alf: kernel part of page table is copied in generic/mm/as_pt.c/ptl0_create |
// TODO: register fault routine |
} |
/** Maps device into the kernel space. |
* |
* Maps physical address of device into kernel virtual address space (so it can |
* be accessed only by kernel through virtual address). |
* |
* @param physaddr Physical address where device is connected. |
* @param size Length of area where device is present. |
* |
* @return Virtual address where device will be accessible. |
*/ |
/** Map device into kernel space. */ |
uintptr_t hw_map(uintptr_t physaddr, size_t size) |
{ |
if (last_frame + ALIGN_UP(size, PAGE_SIZE) > |
KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) { |
panic("Unable to map physical memory %p (%d bytes).", |
physaddr, size) |
} |
uintptr_t virtaddr = PA2KA(last_frame); |
pfn_t i; |
for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++) { |
page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), |
physaddr + PFN2ADDR(i), |
PAGE_NOT_CACHEABLE | PAGE_READ | PAGE_WRITE | PAGE_KERNEL); |
} |
last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE); |
return virtaddr; |
/* TODO */ |
return NULL; |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/arm32/src/mm/tlb.c |
---|
30,7 → 30,6 |
* @{ |
*/ |
/** @file |
* @brief TLB related functions. |
*/ |
#include <mm/tlb.h> |
39,15 → 38,13 |
#include <arch/types.h> |
#include <arch/mm/page.h> |
/** Invalidate all entries in TLB. |
* |
* @note See ARM Architecture reference section 3.7.7 for details. |
*/ |
/** Invalidate all entries in TLB. */ |
void tlb_invalidate_all(void) |
{ |
asm volatile ( |
"eor r1, r1\n" |
"mcr p15, 0, r1, c8, c7, 0\n" |
"MCR p15, 0, r1, c8, c7, 0\n" // see ARM Architecture reference relE 3.7.7 p.528 |
::: "r1" |
); |
} |
54,7 → 51,7 |
/** Invalidate all entries in TLB that belong to specified address space. |
* |
* @param asid Ignored as the ARM architecture doesn't support ASIDs. |
* @param asid This parameter is ignored as the ARM architecture doesn't support it. |
*/ |
void tlb_invalidate_asid(asid_t asid) |
{ |
62,25 → 59,25 |
} |
/** Invalidate single entry in TLB |
* |
* @param page Virtual adress of the page |
*/ |
static inline void invalidate_page(uintptr_t page) |
{ |
asm volatile ( |
"mcr p15, 0, %[page], c8, c7, 1\n" |
:: [page] "r" (page) |
"MCR p15, 0, %0, c8, c7, 1" |
: /* no output */ |
: "r"(page) /* input */ |
); |
} |
/** 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 Ignored as the ARM architecture doesn't support it. |
* @param asid This parameter is ignored as the ARM architecture doesn't support it. |
* @param page Address of the first page whose entry is to be invalidated. |
* @param cnt Number of entries to invalidate. |
*/ |
void tlb_invalidate_pages(asid_t asid __attribute__((unused)), uintptr_t page, size_t cnt) |
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt) |
{ |
unsigned int i; |
88,13 → 85,5 |
invalidate_page(page + i * PAGE_SIZE); |
} |
void tlb_arch_init(void) |
{ |
} |
void tlb_print(void) |
{ |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/arm32/src/mm/as.c |
---|
30,7 → 30,6 |
* @{ |
*/ |
/** @file |
* @brief Address space functions. |
*/ |
#include <arch/mm/as.h> |
39,14 → 38,12 |
#include <mm/as.h> |
#include <arch.h> |
/** Architecture dependent address space init. |
* |
* Since ARM supports page tables, #as_pt_operations are used. |
*/ |
/** Architecture dependent address space init. */ |
void as_arch_init(void) |
{ |
as_operations = &as_pt_operations; |
as_operations = &as_pt_operations; |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/arm32/src/mm/memory_init.c |
---|
0,0 → 1,51 |
/* |
* Copyright (c) 2007 Pavel Jancik |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32mm |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/mm/memory_init.h> |
#include <arch/mm/page.h> |
#include "../aux_print/printf.h" |
#define GXEMUL_MP_ADDRESS 0x11000000 |
#define GXEMUL_MP_MEMSIZE_OFFSET 0x0090 |
size_t get_memory_size(void) |
{ |
//TODO preprocessor don't work |
#if MACHINE == gxemul |
return *((int*)(GXEMUL_MP_ADDRESS+GXEMUL_MP_MEMSIZE_OFFSET)); |
#endif |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/arm32/src/exception.c |
---|
30,157 → 30,208 |
* @{ |
*/ |
/** @file |
* @brief Exception handlers and exception initialization routines. |
@brief Exception handlers and exception initialization routines. |
*/ |
#include <arch/exception.h> |
#include "aux_print/printf.h" |
#include <arch/memstr.h> |
#include <arch/regutils.h> |
#include <interrupt.h> |
#include <arch/mm/page_fault.h> |
#include <arch/barrier.h> |
#include <arch/machine.h> |
#include <print.h> |
#include <syscall/syscall.h> |
/** Offset used in calculation of exception handler's relative address. |
* |
* @see install_handler() |
#define PREFETCH_OFFSET 0x8 |
#define BRANCH_OPCODE 0xea000000 |
#define LDR_OPCODE 0xe59ff000 |
#define VALID_BRANCH_MASK 0xff000000 |
#define EXC_VECTORS_SIZE 0x20 |
#define EXC_VECTORS 0x8 |
/* GXEmul interrupt controller macros |
TODO might go to drivers/ together with servicing functions |
*/ |
/* IRQ Controller device is added in a special premium gxemul |
* edition at www.ms.mff.cuni.cz/~stepp3am/mygxemul-0.4.4.1.tar.gz |
* :) |
*/ |
#define PREFETCH_OFFSET 0x8 |
#define IRQ_CONTROLLER_CAUSE 0x0000000016000000 |
#define IRQ_CONTROLLER_MAX_IRQ 8 |
/** LDR instruction's code */ |
#define LDR_OPCODE 0xe59ff000 |
/* IRQs */ |
#define CONSOLE_IRQ 2 |
#define TIMER_IRQ 4 |
/** Number of exception vectors. */ |
#define EXC_VECTORS 8 |
/** Size of memory block occupied by exception vectors. */ |
#define EXC_VECTORS_SIZE (EXC_VECTORS * 4) |
#define SAVE_REGS_TO_STACK \ |
asm("stmfd sp!, {r0-r12, sp, lr}"); \ |
asm("mrs r14, spsr"); \ |
asm("stmfd sp!, {r14}"); |
#define CALL_EXC_DISPATCH(exception) \ |
asm("mov r0, %0" : : "i" (exception)); \ |
asm("mov r1, sp"); \ |
asm("bl exc_dispatch"); |
/**Loads registers from the stack and resets SPSR before exitting exception |
* handler. |
*/ |
#define LOAD_REGS_FROM_STACK \ |
asm("ldmfd sp!, {r14}"); \ |
asm("msr spsr, r14"); \ |
asm("ldmfd sp!, {r0-r12, sp, pc}^"); |
/** General exception handler. |
* Stores registers, dispatches the exception, |
* and finally restores registers and returns from exception processing. |
*/ |
#define PROCESS_EXCEPTION(exception) \ |
SAVE_REGS_TO_STACK \ |
CALL_EXC_DISPATCH(exception) \ |
LOAD_REGS_FROM_STACK |
/** Updates specified exception vector to jump to given handler. |
* |
* Addresses of handlers are stored in memory following exception vectors. |
* Addresses of handlers are stored in memory following exception vectors. |
*/ |
static void install_handler(unsigned handler_addr, unsigned *vector) |
static void install_handler (unsigned handler_addr, unsigned* vector) |
{ |
/* relative address (related to exc. vector) of the word |
* where handler's address is stored |
*/ |
volatile uint32_t handler_address_ptr = EXC_VECTORS_SIZE - |
PREFETCH_OFFSET; |
volatile uint32_t handler_address_ptr = EXC_VECTORS_SIZE - PREFETCH_OFFSET; |
/* make it LDR instruction and store at exception vector */ |
*vector = handler_address_ptr | LDR_OPCODE; |
smc_coherence(*vector); |
/* store handler's address */ |
*(vector + EXC_VECTORS) = handler_addr; |
} |
static void reset_exception_entry() |
{ |
PROCESS_EXCEPTION(EXC_RESET); |
} |
/** Software Interrupt handler. |
* |
* Dispatches the syscall. |
/** Low-level Software Interrupt Exception handler */ |
static void swi_exception_entry() |
{ |
PROCESS_EXCEPTION(EXC_SWI); |
} |
/** Low-level Undefined Instruction Exception handler */ |
static void undef_instr_exception_entry() |
{ |
PROCESS_EXCEPTION(EXC_UNDEF_INSTR); |
} |
/** Low-level Fast Interrupt Exception handler */ |
static void fiq_exception_entry() |
{ |
PROCESS_EXCEPTION(EXC_FIQ); |
} |
/** Low-level Prefetch Abort Exception handler */ |
static void prefetch_abort_exception_entry() |
{ |
asm("sub lr, lr, #4"); |
PROCESS_EXCEPTION(EXC_PREFETCH_ABORT); |
} |
/** Low-level Data Abort Exception handler */ |
static void data_abort_exception_entry() |
{ |
asm("sub lr, lr, #8"); |
PROCESS_EXCEPTION(EXC_DATA_ABORT); |
} |
/** Low-level Interrupt Exception handler */ |
static void irq_exception_entry() |
{ |
asm("sub lr, lr, #4"); |
PROCESS_EXCEPTION(EXC_IRQ); |
} |
/** Interrupt Exception handler. |
* Determines the sources of interrupt, and calls their handlers. |
*/ |
static void swi_exception(int exc_no, istate_t *istate) |
static void irq_exception(int exc_no, istate_t* istate) |
{ |
istate->r0 = syscall_handler(istate->r0, istate->r1, istate->r2, |
istate->r3, istate->r4, istate->r5, istate->r6); |
/* TODO this will call interrupt dispatching routine |
* |
*/ |
uint32_t sources = *(uint32_t*) IRQ_CONTROLLER_CAUSE; |
int i = 0; |
int noirq = 1; |
for (; i < IRQ_CONTROLLER_MAX_IRQ; i++) { |
if (sources & (1 << i)) { |
noirq = 0; |
if (i == CONSOLE_IRQ) { |
char readchar = *(char*)0x10000000; |
if (readchar == 0) { |
aux_puts("?"); |
} |
else { |
aux_printf("%c", readchar); |
} |
} |
else if (i == TIMER_IRQ) { |
aux_printf("\n.\n"); |
/* acknowledge */ |
*(uint32_t*)0x15000110 = 0; |
} |
} |
} |
if (noirq) |
aux_puts("IRQ exception without source\n"); |
} |
/** Fills exception vectors with appropriate exception handlers. */ |
/** Fills exception vectors with appropriate exception handlers. |
*/ |
void install_exception_handlers(void) |
{ |
install_handler((unsigned) reset_exception_entry, |
(unsigned *) EXC_RESET_VEC); |
install_handler((unsigned)reset_exception_entry, |
(unsigned*)EXC_RESET_VEC); |
install_handler((unsigned) undef_instr_exception_entry, |
(unsigned *) EXC_UNDEF_INSTR_VEC); |
install_handler((unsigned)undef_instr_exception_entry, |
(unsigned*)EXC_UNDEF_INSTR_VEC); |
install_handler((unsigned) swi_exception_entry, |
(unsigned *) EXC_SWI_VEC); |
install_handler((unsigned)swi_exception_entry, |
(unsigned*)EXC_SWI_VEC); |
install_handler((unsigned) prefetch_abort_exception_entry, |
(unsigned *) EXC_PREFETCH_ABORT_VEC); |
install_handler((unsigned)prefetch_abort_exception_entry, |
(unsigned*)EXC_PREFETCH_ABORT_VEC); |
install_handler((unsigned) data_abort_exception_entry, |
(unsigned *) EXC_DATA_ABORT_VEC); |
install_handler((unsigned)data_abort_exception_entry, |
(unsigned*)EXC_DATA_ABORT_VEC); |
install_handler((unsigned) irq_exception_entry, |
(unsigned *) EXC_IRQ_VEC); |
install_handler((unsigned)irq_exception_entry, |
(unsigned*)EXC_IRQ_VEC); |
install_handler((unsigned) fiq_exception_entry, |
(unsigned *) EXC_FIQ_VEC); |
install_handler((unsigned)fiq_exception_entry, |
(unsigned*)EXC_FIQ_VEC); |
} |
#ifdef HIGH_EXCEPTION_VECTORS |
/** Activates use of high exception vectors addresses. */ |
static void high_vectors(void) |
{ |
uint32_t control_reg; |
asm volatile ( |
"mrc p15, 0, %[control_reg], c1, c1" |
: [control_reg] "=r" (control_reg) |
); |
/* switch on the high vectors bit */ |
control_reg |= CP15_R1_HIGH_VECTORS_BIT; |
asm volatile ( |
"mcr p15, 0, %[control_reg], c1, c1" |
:: [control_reg] "r" (control_reg) |
); |
} |
#endif |
/** Interrupt Exception handler. |
* |
* Determines the sources of interrupt and calls their handlers. |
*/ |
static void irq_exception(int exc_no, istate_t *istate) |
{ |
machine_irq_exception(exc_no, istate); |
} |
/** Initializes exception handling. |
* |
* Installs low-level exception handlers and then registers |
* exceptions and their handlers to kernel exception dispatcher. |
*/ |
/** Registers exceptions and their handlers to kernel exception dispatcher. */ |
void exception_init(void) |
{ |
#ifdef HIGH_EXCEPTION_VECTORS |
high_vectors(); |
#endif |
install_exception_handlers(); |
exc_register(EXC_IRQ, "interrupt", (iroutine) irq_exception); |
exc_register(EXC_PREFETCH_ABORT, "prefetch abort", |
(iroutine) prefetch_abort); |
exc_register(EXC_DATA_ABORT, "data abort", (iroutine) data_abort); |
exc_register(EXC_SWI, "software interrupt", (iroutine) swi_exception); |
/* TODO add next */ |
} |
/** Prints #istate_t structure content. |
* |
* @param istate Structure to be printed. |
*/ |
void print_istate(istate_t *istate) |
/* TODO change soon, temporary hack. */ |
void setup_exception_stacks() |
{ |
printf("istate dump:\n"); |
printf(" r0: %x r1: %x r2: %x r3: %x\n", |
istate->r0, istate->r1, istate->r2, istate->r3); |
printf(" r4: %x r5: %x r6: %x r7: %x\n", |
istate->r4, istate->r5, istate->r6, istate->r7); |
printf(" r8: %x r8: %x r10: %x r11: %x\n", |
istate->r8, istate->r9, istate->r10, istate->r11); |
printf(" r12: %x sp: %x lr: %x spsr: %x\n", |
istate->r12, istate->sp, istate->lr, istate->spsr); |
printf(" pc: %x\n", istate->pc); |
/* switch to particular mode and set "sp" there */ |
uint32_t cspr = current_status_reg_read(); |
current_status_reg_control_write( |
(cspr & ~STATUS_REG_MODE_MASK) | IRQ_MODE |
); |
asm("ldr sp, =irq_stack"); |
current_status_reg_control_write( cspr); |
} |
/** @} |
/branches/arm/kernel/arch/arm32/src/arm32.c |
---|
30,166 → 30,96 |
* @{ |
*/ |
/** @file |
* @brief ARM32 architecture specific functions. |
*/ |
#include <arch.h> |
#include <arch/boot.h> |
#include <config.h> |
#include <genarch/fb/fb.h> |
#include <genarch/fb/visuals.h> |
#include <genarch/drivers/dsrln/dsrlnin.h> |
#include <genarch/drivers/dsrln/dsrlnout.h> |
#include <genarch/srln/srln.h> |
#include <sysinfo/sysinfo.h> |
#include <console/console.h> |
#include <ddi/irq.h> |
#include <arch/machine.h> |
#include <arch/console.h> |
#include <ddi/device.h> |
#include "aux_print/printf.h" |
#include <print.h> |
#include <config.h> |
#include <interrupt.h> |
#include <arch/regutils.h> |
#include <userspace.h> |
#include <macros.h> |
#include <string.h> |
bootinfo_t bootinfo; |
/** Performs arm32-specific initialization before main_bsp() is called. */ |
void arch_pre_main(void *entry __attribute__((unused)), bootinfo_t *bootinfo) |
void arch_pre_main(void) |
{ |
unsigned int i; |
init.cnt = bootinfo->cnt; |
for (i = 0; i < min3(bootinfo->cnt, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS); ++i) { |
init.tasks[i].addr = bootinfo->tasks[i].addr; |
init.tasks[i].size = bootinfo->tasks[i].size; |
str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN, |
bootinfo->tasks[i].name); |
aux_printf("arch_pre_main\n"); |
int i; |
init.cnt = bootinfo.cnt; |
printf("Used memmory\n"); |
for (i = 0; i < bootinfo.cnt; ++i) { |
init.tasks[i].addr = bootinfo.tasks[i].addr; |
init.tasks[i].size = bootinfo.tasks[i].size; |
// aux_printf("%L, %d\n", bootinfo.tasks[i].addr, bootinfo.tasks[i].size); |
} |
/* TODO this code just setups irq testing bed |
*/ |
setup_exception_stacks(); |
exception_init(); |
install_exception_handlers(); |
interrupts_enable(); |
/* activate timer interrupts */ |
*(uint32_t*)0x15000100 = 1; |
while(1) ; |
} |
/** Performs arm32 specific initialization before mm is initialized. */ |
#include <ddi/irq.h> |
void arch_pre_mm_init(void) |
{ |
/* It is not assumed by default */ |
interrupts_disable(); |
aux_printf("arch_pre_mm_init\n"); |
} |
/** Performs arm32 specific initialization afterr mm is initialized. */ |
void arch_post_mm_init(void) |
{ |
machine_init(); |
aux_printf("arch_post_mm_init\n"); |
// irq_init(8, 8); /// needs malloc ... so after mm init |
// console_init(device_assign_devno()); // need hash table of irq ... so after irq_init |
/* Initialize exception dispatch table */ |
exception_init(); |
interrupt_init(); |
#ifdef CONFIG_FB |
machine_fb_init(); |
#else |
#ifdef CONFIG_ARM_PRN |
machine_srlnout_init(); |
#endif /* CONFIG_ARM_PRN */ |
#endif /* CONFIG_FB */ |
/* TODO */ |
} |
/** Performs arm32 specific tasks needed after cpu is initialized. |
* |
* Currently the function is empty. |
*/ |
void arch_post_cpu_init(void) |
{ |
/* TODO */ |
} |
/** Performs arm32 specific tasks needed before the multiprocessing is |
* initialized. |
* |
* Currently the function is empty because SMP is not supported. |
*/ |
void arch_pre_smp_init(void) |
{ |
/* TODO */ |
} |
/** Performs arm32 specific tasks needed after the multiprocessing is |
* initialized. |
* |
* Currently the function is empty because SMP is not supported. |
*/ |
void arch_post_smp_init(void) |
{ |
machine_input_init(); |
/* TODO */ |
} |
/** Performs arm32 specific tasks needed before the new task is run. */ |
/** Perform arm32 specific tasks needed before the new task is run. */ |
void before_task_runs_arch(void) |
{ |
/* TODO */ |
} |
/** Performs arm32 specific tasks needed before the new thread is scheduled. |
* |
* It sets supervisor_sp. |
*/ |
/** Perform arm32 specific tasks needed before the new thread is scheduled. */ |
void before_thread_runs_arch(void) |
{ |
uint8_t *stck; |
tlb_invalidate_all(); |
stck = &THREAD->kstack[THREAD_STACK_SIZE - SP_DELTA]; |
supervisor_sp = (uintptr_t) stck; |
/* TODO */ |
} |
/** Performs arm32 specific tasks before a thread stops running. |
* |
* Currently the function is empty. |
*/ |
void after_thread_ran_arch(void) |
{ |
/* TODO */ |
} |
/** Halts CPU. */ |
void cpu_halt(void) |
{ |
machine_cpu_halt(); |
} |
/** Reboot. */ |
void arch_reboot() |
{ |
/* not implemented */ |
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; |
} |
/** Acquire console back for kernel. */ |
void arch_grab_console(void) |
{ |
machine_grab_console(); |
#ifdef CONFIG_FB |
fb_redraw(); |
#endif |
} |
/** Return console to userspace. */ |
void arch_release_console(void) |
{ |
machine_release_console(); |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/arm32/src/start.S |
---|
31,50 → 31,43 |
.text |
.global kernel_image_start |
.global exc_stack |
.global supervisor_sp |
.global irq_stack |
kernel_image_start: |
# initialize Stack pointer for exception modes |
mrs r4, cpsr |
bic r4, r4, #0x1f |
ldr sp, =end_stack |
cmp r2, #0 |
beq bootinfo_end |
#FIQ Mode |
orr r3, r4, #0x11 |
msr cpsr_c, r3 |
ldr sp, =exc_stack |
ldr r3, =bootinfo |
#IRQ Mode |
orr r3, r4, #0x12 |
msr cpsr_c, r3 |
ldr sp, =exc_stack |
bootinfo_loop: |
ldr r4, [r1] |
str r4, [r3] |
#ABORT Mode |
orr r3, r4, #0x17 |
msr cpsr_c, r3 |
ldr sp, =exc_stack |
add r1, r1, #4 |
add r3, r3, #4 |
add r2, r2, #-4 |
#UNDEFINED Mode |
orr r3, r4, #0x1b |
msr cpsr_c, r3 |
ldr sp, =exc_stack |
cmp r2, #0 |
bne bootinfo_loop |
bootinfo_end: |
# switch to supervisor mode |
orr r3, r4, #0x13 |
msr cpsr_c, r3 |
ldr sp, =temp_stack |
bl arch_pre_main |
bl main_bsp |
# bl main_bsp |
b halt |
.space TEMP_STACK_SIZE |
temp_stack: |
end_stack: |
.space 1024 |
exc_stack: |
irq_stack: |
supervisor_sp: |
.space 4 |
halt: |
ldr r0,=0x10000010 |
ldr r1, [r0] |
b halt |
/branches/arm/kernel/arch/arm32/src/drivers/gxemul.c |
---|
0,0 → 1,163 |
/* |
* Copyright (c) 2005-2007 Ondrej Palkovsky, Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
*/ |
#include <interrupt.h> |
#include <ipc/irq.h> |
#include <console/chardev.h> |
#include <arch/drivers/gxemul.h> |
#include <console/console.h> |
#include <sysinfo/sysinfo.h> |
#include <print.h> |
/** Address of devices. */ |
#define GXEMUL_VIDEORAM 0x10000000 |
#define GXEMUL_KBD_ADDRESS 0x10000000 |
#define GXEMUL_KBD_IRQ 0 |
static chardev_t console; |
static irq_t gxemul_irq; |
static void gxemul_write(chardev_t *dev, const char ch); |
static void gxemul_enable(chardev_t *dev); |
static void gxemul_disable(chardev_t *dev); |
static char gxemul_do_read(chardev_t *dev); |
static chardev_operations_t gxemul_ops = { |
.resume = gxemul_enable, |
.suspend = gxemul_disable, |
.write = gxemul_write, |
.read = gxemul_do_read, |
}; |
/** Putchar that works with gxemul */ |
void gxemul_write(chardev_t *dev, const char ch) |
{ |
*((char *) GXEMUL_VIDEORAM) = ch; |
} |
/* Called from getc(). */ |
void gxemul_enable(chardev_t *dev) |
{ |
// cp0_unmask_int(GXEMUL_KBD_IRQ); |
} |
/* Called from getc(). */ |
void gxemul_disable(chardev_t *dev) |
{ |
// cp0_mask_int(GXEMUL_KBD_IRQ); |
} |
/** Read character using polling, assume interrupts disabled */ |
static char gxemul_do_read(chardev_t *dev) |
{ |
char ch; |
while (1) { |
ch = *((volatile char *) GXEMUL_KBD_ADDRESS); |
if (ch) { |
if (ch == '\r') |
return '\n'; |
if (ch == 0x7f) |
return '\b'; |
return ch; |
} |
} |
} |
/** Process keyboard interrupt. */ |
static void gxemul_irq_handler(irq_t *irq, void *arg, ...) |
{ |
if ((irq->notif_cfg.notify) && (irq->notif_cfg.answerbox)) |
ipc_irq_send_notif(irq); |
else { |
char ch = 0; |
ch = *((char *) GXEMUL_KBD_ADDRESS); |
if (ch =='\r') |
ch = '\n'; |
if (ch == 0x7f) |
ch = '\b'; |
chardev_push_character(&console, ch); |
} |
} |
static irq_ownership_t gxemul_claim(void) |
{ |
return IRQ_ACCEPT; |
} |
void gxemul_kbd_grab(void) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&msim_irq.lock); |
gxemul_irq.notif_cfg.notify = false; |
spinlock_unlock(&gxemul_irq.lock); |
interrupts_restore(ipl); |
} |
void gxemul_kbd_release(void) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&gxemul_irq.lock); |
if (gxemul_irq.notif_cfg.answerbox) |
gxemul_irq.notif_cfg.notify = true; |
spinlock_unlock(&gxemul_irq.lock); |
interrupts_restore(ipl); |
} |
/* Return console object representing msim console */ |
void gxemul_console(devno_t devno) |
{ |
chardev_initialize("msim_console", &console, &gxemul_ops); |
stdin = &console; |
stdout = &console; |
irq_initialize(&gxemul_irq); |
gxemul_irq.devno = devno; |
gxemul_irq.inr = GXEMUL_KBD_IRQ; |
gxemul_irq.claim = gxemul_claim; |
gxemul_irq.handler = gxemul_irq_handler; |
irq_register(&gxemul_irq); |
// cp0_unmask_int(GXEMUL_KBD_IRQ); |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.devno", NULL, devno); |
sysinfo_set_item_val("kbd.inr", NULL, GXEMUL_KBD_IRQ); |
sysinfo_set_item_val("kbd.address.virtual", NULL, GXEMUL_KBD_ADDRESS); |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/arm32/src/console.c |
---|
0,0 → 1,61 |
/* |
* Copyright (c) 2007 Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
*/ |
#include <console/console.h> |
#include <arch/console.h> |
#include <arch/drivers/gxemul.h> |
void console_init(devno_t devno) |
{ |
gxemul_console(devno); |
} |
/** Acquire console back for kernel |
* |
*/ |
void arch_grab_console(void) |
{ |
gxemul_kbd_grab(); |
} |
/** Return console to userspace |
* |
*/ |
void arch_release_console(void) |
{ |
gxemul_kbd_release(); |
} |
/** @} |
*/ |
/branches/arm/kernel/arch/arm32/src/interrupt.c |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2007 Petr Stepan |
* Copyright (c) 2007 Petr Stepan, Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
30,19 → 30,16 |
* @{ |
*/ |
/** @file |
* @brief Interrupts controlling routines. |
*/ |
#include <arch/asm.h> |
#include <arch/regutils.h> |
#include <arch/machine.h> |
#include <ddi/irq.h> |
#include <ddi/device.h> |
#include <interrupt.h> |
/** Initial size of a table holding interrupt handlers. */ |
#define IRQ_COUNT 8 |
#define IRQ_COUNT 8 |
/** Disable interrupts. |
* |
* @return Old interrupt priority level. |
51,7 → 48,7 |
{ |
ipl_t ipl = current_status_reg_read(); |
current_status_reg_control_write(STATUS_REG_IRQ_DISABLED_BIT | ipl); |
current_status_reg_control_write(ipl & ~STATUS_REG_IE_ENABLED_BIT); |
return ipl; |
} |
64,8 → 61,8 |
{ |
ipl_t ipl = current_status_reg_read(); |
current_status_reg_control_write(ipl & ~STATUS_REG_IRQ_DISABLED_BIT); |
current_status_reg_control_write(ipl | STATUS_REG_IE_ENABLED_BIT); |
return ipl; |
} |
75,9 → 72,8 |
*/ |
void interrupts_restore(ipl_t ipl) |
{ |
current_status_reg_control_write( |
(current_status_reg_read() & ~STATUS_REG_IRQ_DISABLED_BIT) | |
(ipl & STATUS_REG_IRQ_DISABLED_BIT)); |
current_status_reg_control_write(current_status_reg_read() | |
(ipl & STATUS_REG_IE_ENABLED_BIT)); |
} |
/** Read interrupt priority level. |
89,14 → 85,8 |
return current_status_reg_read(); |
} |
/** Initialize basic tables for exception dispatching |
* and starts the timer. |
*/ |
void interrupt_init(void) |
{ |
void interrupt_init(void) { |
irq_init(IRQ_COUNT, IRQ_COUNT); |
machine_timer_irq_start(); |
} |
/** @} |
/branches/arm/kernel/arch/arm32/src/dummy.S |
---|
1,5 → 1,5 |
# |
# Copyright (c) 2007 Michal Kebry, Pavel Jancik, Petr Stepan |
# Copyright (c) 2003-2004 Jakub Jermar |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
30,35 → 30,78 |
.global calibrate_delay_loop |
.global asm_delay_loop |
.global dummy |
#.global arch_grab_console |
#.global arch_release_console |
.global cpu_halt |
.global fpu_context_restore |
.global fpu_context_save |
.global fpu_enable |
.global fpu_init |
#.global interrupts_disable |
#.global interrupts_enable |
#.global interrupts_read |
#.global interrupts_restore |
#.global memcpy |
#.global memcpy_from_uspace |
#.global memcpy_to_uspace |
#.global memsetb |
.global panic_printf |
.global symbol_table |
.global sys_tls_set |
.global dummy |
#.global tlb_invalidate_asid |
#.global tlb_invalidate_pages |
.global userspace |
calibrate_delay_loop: |
mov pc, lr |
# stop gxemul |
ldr r1, =0x10000010 |
eor r2, r2 |
strb r3, [r1, r2] |
bkpt |
asm_delay_loop: |
mov pc, lr |
mov pc, lr // ret |
cpu_halt: |
bkpt |
fpu_context_restore: |
mov pc, lr |
bkpt |
fpu_context_save: |
mov pc, lr |
bkpt |
fpu_enable: |
mov pc, lr |
bkpt |
fpu_init: |
mov pc, lr |
bkpt |
# not used on ARM |
panic_printf: |
bl aux_printf |
# stop gxemul |
ldr r1, =0x10000010 |
eor r2, r2 |
strb r3, [r1, r2] |
bkpt |
symbol_table: |
bkpt |
sys_tls_set: |
bkpt |
userspace: |
bkpt |
dummy: |
mov pc, lr |
0: |
bkpt |
/branches/arm/kernel/arch/arm32/src/cpu/cpu.c |
---|
30,36 → 30,32 |
* @{ |
*/ |
/** @file |
* @brief CPU identification. |
*/ |
#include <arch/cpu.h> |
#include <cpu.h> |
#include <arch.h> |
#include <print.h> |
#include <print.h> |
/** Number of indexes left out in the #imp_data array */ |
#define IMP_DATA_START_OFFSET 0x40 |
/** Implementators (vendor) names */ |
static char *imp_data[] = { |
"?", /* IMP_DATA_START_OFFSET */ |
"ARM Ltd", /* 0x41 */ |
"", /* 0x42 */ |
"", /* 0x43 */ |
"Digital Equipment Corporation", /* 0x44 */ |
"", "", "", "", "", "", "", "", "", "", /* 0x45 - 0x4e */ |
"", "", "", "", "", "", "", "", "", "", /* 0x4f - 0x58 */ |
"", "", "", "", "", "", "", "", "", "", /* 0x59 - 0x62 */ |
"", "", "", "", "", "", /* 0x63 - 0x68 */ |
"Intel Corporation" /* 0x69 */ |
static char * imp_data[] = { |
"?", |
"ARM Ltd", /* 0x41 */ |
"", /* 0x42 */ |
"", /* 0x43 */ |
"Digital Equipment Corporation", /* 0x44 */ |
"", "", "", "", "", "", "", "", "", "", "", /* 0x4f */ |
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", /* 0x5f */ |
"", "", "", "", "", "", "", "", "", /* 0x68 */ |
"Intel Corporation" /* 0x69 */ |
}; |
/** Length of the #imp_data array */ |
static unsigned int imp_data_length = sizeof(imp_data) / sizeof(char *); |
/** Length of imp_data array */ |
static int imp_data_length = sizeof(imp_data)/sizeof(char *); |
/** Architecture names */ |
static char *arch_data[] = { |
static char * arch_data[] = { |
"?", /* 0x0 */ |
"4", /* 0x1 */ |
"4T", /* 0x2 */ |
70,22 → 66,29 |
"6" /* 0x7 */ |
}; |
/** Length of the #arch_data array */ |
static unsigned int arch_data_length = sizeof(arch_data) / sizeof(char *); |
/** Length of arch_data array */ |
static int arch_data_length = sizeof(arch_data)/sizeof(char *); |
/** Retrieves processor identification from CP15 register 0. |
void cpu_arch_init(void) |
{ |
/* TODO */ |
} |
/** |
* Retrieves processor identification from CP15 register 0. |
* |
* @param cpu Structure for storing CPU identification. |
* @param cpu structure for storing identification |
*/ |
static void arch_cpu_identify(cpu_arch_t *cpu) |
static void arch_cpu_identify(cpu_arch_t * cpu) |
{ |
uint32_t ident; |
asm volatile ( |
"mrc p15, 0, %[ident], c0, c0, 0\n" |
: [ident] "=r" (ident) |
"mrc p15, 0, %0, c0, c0, 0 \n" |
: "=r" (ident) |
); |
cpu->imp_num = ident >> 24; |
cpu->variant_num = (ident << 8) >> 28; |
cpu->arch_num = (ident << 12) >> 28; |
93,18 → 96,13 |
cpu->rev_num = (ident << 28) >> 28; |
} |
/** Does nothing on ARM. */ |
void cpu_arch_init(void) |
{ |
} |
/** Retrieves processor identification and stores it to #CPU.arch */ |
void cpu_identify(void) |
{ |
arch_cpu_identify(&CPU->arch); |
} |
/** Prints CPU identification. */ |
void cpu_print_report(cpu_t *m) |
{ |
char * vendor = imp_data[0]; |
111,20 → 109,17 |
char * architecture = arch_data[0]; |
cpu_arch_t * cpu_arch = &m->arch; |
if ((cpu_arch->imp_num) > 0 && |
(cpu_arch->imp_num < (imp_data_length + IMP_DATA_START_OFFSET))) { |
vendor = imp_data[cpu_arch->imp_num - IMP_DATA_START_OFFSET]; |
if ( (cpu_arch->imp_num) > 0 && (cpu_arch->imp_num < (imp_data_length + 0x40)) ) { |
vendor = imp_data[cpu_arch->imp_num - 0x40]; |
} |
if ((cpu_arch->arch_num) > 0 && |
(cpu_arch->arch_num < arch_data_length)) { |
if ( (cpu_arch->arch_num) > 0 && (cpu_arch->arch_num < arch_data_length) ) { |
architecture = arch_data[cpu_arch->arch_num]; |
} |
printf("cpu%d: vendor=%s, architecture=ARM%s, part number=%x, " |
"variant=%x, revision=%x\n", |
m->id, vendor, architecture, cpu_arch->prim_part_num, |
cpu_arch->variant_num, cpu_arch->rev_num); |
printf("vendor: %s, architecture: ARM %s, part number: %x, variant: %x, revision: %x", |
vendor, architecture, cpu_arch->prim_part_num, cpu_arch->variant_num, cpu_arch->rev_num); |
} |
/** @} |
/branches/arm/kernel/arch/arm32/src/asm.S |
---|
30,7 → 30,11 |
.text |
.global memsetb |
.global memsetw |
memsetb: |
b _memsetb |
nop |
.global memcpy |
.global memcpy_from_uspace |
.global memcpy_to_uspace |
37,12 → 41,6 |
.global memcpy_from_uspace_failover_address |
.global memcpy_to_uspace_failover_address |
memsetb: |
b _memsetb |
memsetw: |
b _memsetw |
memcpy: |
memcpy_from_uspace: |
memcpy_to_uspace: |
49,55 → 47,55 |
add r3, r1, #3 |
bic r3, r3, #3 |
cmp r1, r3 |
stmdb sp!, {r4, r5, lr} |
mov r5, r0 /* save dst */ |
beq 4f |
1: |
stmdb sp!, {r4, lr} |
beq case_4 |
case_1: |
cmp r2, #0 |
movne ip, #0 |
beq 3f |
2: |
beq case_3 |
case_2: |
ldrb r3, [ip, r1] |
strb r3, [ip, r0] |
add ip, ip, #1 |
cmp ip, r2 |
bne 2b |
3: |
mov r0, r5 |
ldmia sp!, {r4, r5, pc} |
4: |
bne case_2 |
case_3: |
mov r0, r1 |
ldmia sp!, {r4, pc} |
case_4: |
add r3, r0, #3 |
bic r3, r3, #3 |
cmp r0, r3 |
bne 1b |
bne case_1 |
movs r4, r2, lsr #2 |
moveq lr, r4 |
beq 6f |
beq case_6 |
mov lr, #0 |
mov ip, lr |
5: |
case_5: |
ldr r3, [ip, r1] |
add lr, lr, #1 |
cmp lr, r4 |
str r3, [ip, r0] |
add ip, ip, #4 |
bne 5b |
6: |
bne case_5 |
case_6: |
ands r4, r2, #3 |
beq 3b |
beq case_3 |
mov r3, lr, lsl #2 |
add r0, r3, r0 |
add ip, r3, r1 |
mov r2, #0 |
7: |
case_7: |
ldrb r3, [r2, ip] |
strb r3, [r2, r0] |
add r2, r2, #1 |
cmp r2, r4 |
bne 7b |
b 3b |
bne case_7 |
b case_3 |
memcpy_from_uspace_failover_address: |
memcpy_to_uspace_failover_address: |
mov r0, #0 |
ldmia sp!, {r4, r5, pc} |
mov r0, #0 |
ldmia sp!, {r4, pc} |
/branches/arm/kernel/arch/arm32/src/context.S |
---|
1,5 → 1,5 |
# |
# Copyright (c) 2007 Petr Stepan |
# Copyright (c) 2003-2004 Jakub Jermar |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
32,28 → 32,24 |
.global context_restore_arch |
context_save_arch: |
stmfd sp!, {r1} |
mrs r1, cpsr |
and r1, r1, #0x1f |
stmia r0!, {r1} |
ldmfd sp!, {r1} |
stmia r0!, {sp, lr} |
stmia r0!, {r4-r11} |
stmia r0!, {r4-r8, r10-r11} |
mov r0, #1 |
mov pc, lr |
/* debug print |
ldr r0, =0x10000000 |
mov r1, #1 |
str r1, [r0] |
*/ |
context_restore_arch: |
ldmia r0!, {r4} |
mrs r5, cpsr |
bic r5, r5, #0x1f |
orr r5, r5, r4 |
msr cpsr_c, r5 |
ldmia r0!, {sp, lr} |
ldmia r0!, {r4-r11} |
ldmia r0!, {r4-r8, r10-r11} |
mov r0, #0 |
mov pc, lr |
/branches/arm/kernel/arch/arm32/src/aux_print/printf.c |
---|
0,0 → 1,243 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include "printf.h" |
#include "stdarg.h" |
#include "types.h" |
typedef char *char_ptr; |
static char digits[] = "0123456789abcdef"; /**< Hexadecimal characters */ |
void aux_puts(const char *str) |
{ |
int len = 0; |
while (str[len] != 0) |
len++; |
aux_write(str, len); |
} |
/** Print hexadecimal digits |
* |
* Print fixed count of hexadecimal digits from |
* the number num. The digits are printed in |
* natural left-to-right order starting with |
* the width-th digit. |
* |
* @param num Number containing digits. |
* @param width Count of digits to print. |
* |
*/ |
static void print_fixed_hex(const uint64_t num, const int width) |
{ |
int i; |
for (i = width * 8 - 4; i >= 0; i -= 4) |
aux_write(digits + ((num >> i) & 0xf), 1); |
} |
/** Print number in given base |
* |
* Print significant digits of a number in given |
* base. |
* |
* @param num Number to print. |
* @param base Base to print the number in (should |
* be in range 2 .. 16). |
* |
*/ |
static void print_number(const unative_t num, const unsigned int base) |
{ |
int val = num; |
char d[sizeof(unative_t) * 8 + 1]; /* this is good enough even for base == 2 */ |
int i = sizeof(unative_t) * 8 - 1; |
do { |
d[i--] = digits[val % base]; |
} while (val /= base); |
d[sizeof(unative_t) * 8] = 0; |
aux_puts(&d[i + 1]); |
} |
/** General formatted text print |
* |
* Print text formatted according the fmt parameter |
* and variant arguments. Each formatting directive |
* begins with \% (percentage) character and one of the |
* following character: |
* |
* \% Prints the percentage character. |
* |
* s The next variant argument is treated as char* |
* and printed as a NULL terminated string. |
* |
* c The next variant argument is treated as a single char. |
* |
* p The next variant argument is treated as a maximum |
* bit-width integer with respect to architecture |
* and printed in full hexadecimal width. |
* |
* P As with 'p', but '0x' is prefixed. |
* |
* q The next variant argument is treated as a 64b integer |
* and printed in full hexadecimal width. |
* |
* Q As with 'q', but '0x' is prefixed. |
* |
* l The next variant argument is treated as a 32b integer |
* and printed in full hexadecimal width. |
* |
* L As with 'l', but '0x' is prefixed. |
* |
* w The next variant argument is treated as a 16b integer |
* and printed in full hexadecimal width. |
* |
* W As with 'w', but '0x' is prefixed. |
* |
* b The next variant argument is treated as a 8b integer |
* and printed in full hexadecimal width. |
* |
* B As with 'b', but '0x' is prefixed. |
* |
* d The next variant argument is treated as integer |
* and printed in standard decimal format (only significant |
* digits). |
* |
* x The next variant argument is treated as integer |
* and printed in standard hexadecimal format (only significant |
* digits). |
* |
* X As with 'x', but '0x' is prefixed. |
* |
* All other characters from fmt except the formatting directives |
* are printed in verbatim. |
* |
* @param fmt Formatting NULL terminated string. |
*/ |
void aux_printf(const char *fmt, ...) |
{ |
int i = 0; |
va_list ap; |
char c; |
va_start(ap, fmt); |
while ((c = fmt[i++])) { |
switch (c) { |
/* control character */ |
case '%': |
switch (c = fmt[i++]) { |
/* percentile itself */ |
case '%': |
break; |
/* |
* String and character conversions. |
*/ |
case 's': |
aux_puts(va_arg(ap, char_ptr)); |
goto loop; |
case 'c': |
c = (char) va_arg(ap, int); |
break; |
/* |
* Hexadecimal conversions with fixed width. |
*/ |
case 'P': |
aux_puts("0x"); |
case 'p': |
print_fixed_hex(va_arg(ap, unative_t), sizeof(unative_t)); |
goto loop; |
case 'Q': |
aux_puts("0x"); |
case 'q': |
print_fixed_hex(va_arg(ap, uint64_t), INT64); |
goto loop; |
case 'L': |
aux_puts("0x"); |
case 'l': |
print_fixed_hex(va_arg(ap, unative_t), INT32); |
goto loop; |
case 'W': |
aux_puts("0x"); |
case 'w': |
print_fixed_hex(va_arg(ap, unative_t), INT16); |
goto loop; |
case 'B': |
aux_puts("0x"); |
case 'b': |
print_fixed_hex(va_arg(ap, unative_t), INT8); |
goto loop; |
/* |
* Decimal and hexadecimal conversions. |
*/ |
case 'd': |
print_number(va_arg(ap, unative_t), 10); |
goto loop; |
case 'X': |
aux_puts("0x"); |
case 'x': |
print_number(va_arg(ap, unative_t), 16); |
goto loop; |
/* |
* Bad formatting. |
*/ |
default: |
goto out; |
} |
default: |
aux_write(&c, 1); |
} |
loop: |
; |
} |
out: |
va_end(ap); |
} |
/branches/arm/kernel/arch/arm32/src/aux_print/gentypes.h |
---|
0,0 → 1,38 |
/* |
* 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 BOOT_GENTYPES_H_ |
#define BOOT_GENTYPES_H_ |
#define NULL 0 |
#define false 0 |
#define true 1 |
typedef unsigned long size_t; |
#endif |
/branches/arm/kernel/arch/arm32/src/aux_print/io.c |
---|
0,0 → 1,50 |
/* |
* Copyright (c) 2007 Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include "printf.h" |
#define PUTC_ADDRESS 0x10000000 |
/** |
* Prints a character to console. |
* |
* @param ch character to be printed |
*/ |
static void putc(char ch) { |
*((volatile char *)PUTC_ADDRESS) = ch; |
} |
void aux_write(const char *str, const int len) { |
int i; |
for (i = 0; i < len; ++i) { |
putc(str[i]); |
} |
} |
/branches/arm/kernel/arch/arm32/src/aux_print/printf.h |
---|
0,0 → 1,42 |
/* |
* 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 BOOT_PRINTF_H_ |
#define BOOT_PRINTF_H_ |
#define INT8 1 |
#define INT16 2 |
#define INT32 4 |
#define INT64 8 |
extern void aux_puts(const char *str); |
extern void aux_printf(const char *fmt, ...); |
extern void aux_write(const char *str, const int len); |
#endif |
/branches/arm/kernel/arch/arm32/src/aux_print/stdarg.h |
---|
0,0 → 1,38 |
/* |
* 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 STDARG_H__ |
#define STDARG_H__ |
typedef __builtin_va_list va_list; |
#define va_start(ap, last) __builtin_va_start(ap, last) |
#define va_arg(ap, type) __builtin_va_arg(ap, type) |
#define va_end(ap) __builtin_va_end(ap) |
#endif |
/branches/arm/kernel/arch/arm32/src/aux_print/types.h |
---|
0,0 → 1,44 |
/* |
* 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 TYPES_H__ |
#define TYPES_H__ |
#include "gentypes.h" |
typedef signed char int8_t; |
typedef unsigned char uint8_t; |
typedef unsigned short uint16_t; |
typedef unsigned int uint32_t; |
typedef unsigned long long uint64_t; |
typedef uint32_t uintptr_t; |
typedef uint32_t unative_t; |
#endif |
/branches/arm/kernel/arch/arm32/src/aux_print/README |
---|
0,0 → 1,0 |
TO BE DELETED, ONLY FOR DEBUGGING |
/branches/arm/kernel/arch/arm32/src/ddi/ddi.c |
---|
30,7 → 30,6 |
* @{ |
*/ |
/** @file |
* @brief DDI. |
*/ |
#include <ddi/ddi.h> |
/branches/arm/kernel/arch/arm32/Makefile.inc |
---|
1,5 → 1,6 |
# |
# Copyright (c) 2007 Jakub Jermar, Michal Kebrt |
# Copyright (c) 2005 Martin Decky |
# Copyright (c) 2007 Jakub Jermar |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
29,43 → 30,58 |
## Toolchain configuration |
# |
BFD_NAME = elf32-littlearm |
BFD_NAME = elf32-little |
BFD_ARCH = arm |
BFD = binary |
TARGET = arm-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/arm |
TOOLCHAIN_DIR = /usr/local/arm |
ATSIGN = % |
KERNEL_LOAD_ADDRESS = 0x80100000 |
GCC_CFLAGS += -fno-zero-initialized-in-bss |
CFLAGS += -fno-zero-initialized-in-bss |
BITS = 32 |
ENDIANESS = LE |
DEFS += -D__32_BITS__ -DMACHINE=$(MACHINE) -DKERNEL_LOAD_ADDRESS=$(KERNEL_LOAD_ADDRESS) |
CONFIG_GXEMUL = y |
DEFS += -DCONFIG_GXEMUL |
CONFIG_FB = y |
DEFS += -DCONFIG_FB |
## Compile with hierarchical page tables support. |
# |
CONFIG_PAGE_PT = y |
DEFS += -DCONFIG_PAGE_PT |
## Compile with support for address space identifiers. |
# |
# no HW support for ASIDs |
#CONFIG_ASID = y |
#CONFIG_ASID_FIFO = y |
## Compile with support with software division and multiplication. |
# |
CONFIG_SOFTINT = y |
ARCH_SOURCES = \ |
arch/$(KARCH)/src/start.S \ |
arch/$(KARCH)/src/asm.S \ |
arch/$(KARCH)/src/exc_handler.S \ |
arch/$(KARCH)/src/arm32.c \ |
arch/$(KARCH)/src/machine_func.c \ |
arch/$(KARCH)/src/context.S \ |
arch/$(KARCH)/src/dummy.S \ |
arch/$(KARCH)/src/panic.S \ |
arch/$(KARCH)/src/cpu/cpu.c \ |
arch/$(KARCH)/src/ddi/ddi.c \ |
arch/$(KARCH)/src/interrupt.c \ |
arch/$(KARCH)/src/exception.c \ |
arch/$(KARCH)/src/userspace.c \ |
arch/$(KARCH)/src/mm/as.c \ |
arch/$(KARCH)/src/mm/frame.c \ |
arch/$(KARCH)/src/mm/page.c \ |
arch/$(KARCH)/src/mm/tlb.c \ |
arch/$(KARCH)/src/mm/page_fault.c |
ifeq ($(MACHINE), testarm) |
ARCH_SOURCES += arch/$(KARCH)/src/mach/testarm/testarm.c |
else ifeq ($(MACHINE), integratorcp) |
ARCH_SOURCES += arch/$(KARCH)/src/mach/integratorcp/integratorcp.c |
endif |
ifeq ($(CONFIG_PL050), y) |
ARCH_SOURCES += genarch/src/drivers/pl050/pl050.c |
endif |
arch/$(ARCH)/src/start.S \ |
arch/$(ARCH)/src/asm.S \ |
arch/$(ARCH)/src/arm32.c \ |
arch/$(ARCH)/src/context.S \ |
arch/$(ARCH)/src/dummy.S \ |
arch/$(ARCH)/src/cpu/cpu.c \ |
arch/$(ARCH)/src/ddi/ddi.c \ |
arch/$(ARCH)/src/mm/as.c \ |
arch/$(ARCH)/src/mm/frame.c \ |
arch/$(ARCH)/src/mm/page.c \ |
arch/$(ARCH)/src/interrupt.c \ |
arch/$(ARCH)/src/mm/tlb.c \ |
arch/$(ARCH)/src/aux_print/printf.c \ |
arch/$(ARCH)/src/aux_print/io.c \ |
arch/$(ARCH)/src/console.c \ |
arch/$(ARCH)/src/drivers/gxemul.c \ |
arch/$(ARCH)/src/exception.c \ |
arch/$(ARCH)/src/mm/memory_init.c |
/branches/arm/kernel/arch/arm32/_link.ld.in |
---|
1,16 → 1,15 |
/* |
* ARM linker script |
* |
* ARM linker script |
* |
* kernel text |
* kernel data |
* |
* |
*/ |
#define KERNEL_LOAD_ADDRESS 0x80200000 |
OUTPUT_ARCH(arm) |
ENTRY(kernel_image_start) |
ENTRY(kernel_image_start) |
SECTIONS { |
. = KERNEL_LOAD_ADDRESS; |
.text : { |
20,29 → 19,32 |
} |
.data : { |
kdata_start = .; |
*(.data); /* initialized data */ |
*(.data); /* initialized data */ |
hardcoded_ktext_size = .; |
LONG(ktext_end - ktext_start); |
LONG(ktext_end - ktext_start); |
hardcoded_kdata_size = .; |
LONG(kdata_end - kdata_start); |
hardcoded_load_address = .; |
LONG(KERNEL_LOAD_ADDRESS); |
*(.bss); /* uninitialized static variables */ |
*(COMMON); /* global variables */ |
LONG(KERNEL_LOAD_ADDRESS); /* TODO */ |
*(.bss); /* uninitialized static variables */ |
*(COMMON); /* global variables */ |
*(.rodata*); |
*(.sdata); |
*(.reginfo); |
symbol_table = .; |
*(symtab.*); |
*(symtab.*); |
} |
_gp = . + 0x8000; |
.lit8 : { *(.lit8) } |
.lit4 : { *(.lit4) } |
.sbss : { |
*(.sbss); |
*(.scommon); |
} |
kdata_end = .; |
/DISCARD/ : { |
*(.mdebug*); |
*(.pdr); |
49,4 → 51,5 |
*(.comment); |
*(.note); |
} |
} |