Merge commit '952e5a272b5077ce6550035fbc5e2d6c55d09670' into arm_hyp
Conflicts: include/arch/arm/arch/object/structures.h src/arch/arm/kernel/thread.c
This commit is contained in:
commit
91c474cb95
54 changed files with 684 additions and 307 deletions
40
CONTRIBUTING.md
Normal file
40
CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
Contributions to the seL4 kernel repository are welcome!
|
||||
|
||||
|
||||
## CLA
|
||||
|
||||
Please note that GD and NICTA require a contributor license agreement (CLA)
|
||||
to be signed for all external contributions. Please see
|
||||
https://seL4.systems/Contributing for details (it is a fairly short and
|
||||
standard CLA).
|
||||
|
||||
For the `seL4/seL4` repository, we can review pull requests directly on
|
||||
github if we have a signed CLA on file.
|
||||
|
||||
If you have only small trivial changes such as style, typos, comments, or
|
||||
white space and don't want to sign a CLA for that, please file an issue in
|
||||
the github issue tracker, we'll usually be happy to do the change ourselves
|
||||
and attribute your idea by linking to the github issue in the change set
|
||||
comment.
|
||||
|
||||
|
||||
## Kernel Development Process
|
||||
|
||||
Please read https://seL4.systems/Contributing
|
||||
|
||||
|
||||
## Build/Test
|
||||
|
||||
Generally, any contributions should pass the tests in the project
|
||||
https://github.com/seL4/sel4test. If new features or platforms are added,
|
||||
they should add corresponding tests in `sel4test`.
|
||||
|
||||
Contributions to `master` should additionally either be invisible to the
|
||||
proof in https://github.com/seL4/l4v, such as comments, documentation, style,
|
||||
unverified platform, etc, or they should come with proof updates to `l4v`.
|
||||
|
||||
|
||||
## Contact
|
||||
|
||||
If you have larger changes or additions, it might be a good idea to get in
|
||||
contact with us as <devel@sel4.systems>, so we can help you get started.
|
||||
|
|
@ -40,6 +40,7 @@ repository (in alphabetical order).
|
|||
* Anna Lyons, NICTA & UNSW
|
||||
* Stephanie McArthur, NICTA
|
||||
* Sam McNally, NICTA
|
||||
* Tim Newsham
|
||||
* Toby Murray, NICTA & UNSW
|
||||
* Ameya Palande, NICTA
|
||||
* Max R.D. Parmer
|
||||
|
|
@ -48,6 +49,7 @@ repository (in alphabetical order).
|
|||
* Sean Seefried, NICTA
|
||||
* Thomas Sewell, NICTA & UNSW
|
||||
* Michael von Tessin, NICTA & UNSW
|
||||
* Robbie Van Vossen
|
||||
* Adam Walker, NICTA
|
||||
* James Wilmot, NICTA
|
||||
* Simon Winwood, NICTA
|
||||
|
|
|
|||
9
Kconfig
9
Kconfig
|
|
@ -382,6 +382,15 @@ menu "Build Options"
|
|||
expense of dramatically decreasing performance. Primary use is for
|
||||
debugging.
|
||||
|
||||
config DEBUG_DISABLE_PREFETCHERS
|
||||
bool "Disable prefetchers"
|
||||
depends on ARCH_IA32
|
||||
default n
|
||||
help
|
||||
On ia32 platforms, this option disables the L2 hardware prefetcher, the L2
|
||||
adjacent cache line prefetcher, the DCU prefetcher and the DCU IP prefetcher.
|
||||
Currently unimplemented on other platforms.
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Errata"
|
||||
|
|
|
|||
2
Makefile
2
Makefile
|
|
@ -539,7 +539,7 @@ PRUNES = $(foreach file,${STATICSOURCES} ${STATICHEADERS}, \
|
|||
--prune ${file} )
|
||||
|
||||
TOPLEVELTYPES=cte_C tcb_C endpoint_C async_endpoint_C asid_pool_C pte_C \
|
||||
pde_C adglobs_struct user_data_C
|
||||
pde_C user_data_C
|
||||
TOPTYPES = $(foreach tp,${TOPLEVELTYPES}, \
|
||||
--toplevel ${tp} )
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
<syscall name="DebugHalt" />
|
||||
<syscall name="DebugCapIdentify" />
|
||||
<syscall name="DebugSnapshot" />
|
||||
<syscall name="DebugNameThread"/>
|
||||
</config>
|
||||
<config name="DANGEROUS_CODE_INJECTION">
|
||||
<syscall name="DebugRun"/>
|
||||
|
|
|
|||
|
|
@ -112,8 +112,8 @@ wordFromMessageInfo(message_info_t mi)
|
|||
#define userError(...) \
|
||||
do { \
|
||||
printf(ANSI_DARK "<<" ANSI_GREEN "seL4" ANSI_DARK \
|
||||
" [%s/%d T%x @%x]: ", \
|
||||
__func__, __LINE__, (int)ksCurThread, \
|
||||
" [%s/%d T%x \"%s\" @%x]: ", \
|
||||
__func__, __LINE__, (int)ksCurThread, ksCurThread->tcbName, \
|
||||
(int)getRestartPC(ksCurThread)); \
|
||||
printf(__VA_ARGS__); \
|
||||
printf(">>" ANSI_RESET "\n"); \
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
#include <types.h>
|
||||
|
||||
cap_t create_unmapped_it_frame_cap(pptr_t pptr, bool_t use_large);
|
||||
cap_t create_mapped_it_frame_cap(cap_t pd_cap, pptr_t pptr, vptr_t vptr, asid_t asid, bool_t use_large);
|
||||
cap_t create_mapped_it_frame_cap(cap_t pd_cap, pptr_t pptr, vptr_t vptr, asid_t asid, bool_t use_large, bool_t executable);
|
||||
|
||||
void init_kernel(
|
||||
paddr_t ui_p_reg_start,
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
#define IT_ASID 1 /* initial thread's ASID */
|
||||
|
||||
void map_it_pt_cap(cap_t pd_cap, cap_t pt_cap);
|
||||
void map_it_frame_cap(cap_t pd_cap, cap_t frame_cap);
|
||||
void map_it_frame_cap(cap_t pd_cap, cap_t frame_cap, bool_t executable);
|
||||
void map_kernel_window(void);
|
||||
void map_kernel_frame(paddr_t paddr, pptr_t vaddr, vm_rights_t vm_rights, vm_attributes_t vm_attributes);
|
||||
void activate_global_pd(void);
|
||||
|
|
|
|||
|
|
@ -33,6 +33,10 @@
|
|||
| PMODE_KERNEL \
|
||||
| CPSR_EXTRA_FLAGS )
|
||||
|
||||
#define CPSR_IDLETHREAD ( PMASK_FIRQ \
|
||||
| PMODE_SUPERVISOR \
|
||||
| CPSR_EXTRA_FLAGS )
|
||||
|
||||
#ifdef __ASSEMBLER__
|
||||
|
||||
/* Offsets within the user context, these need to match the order in
|
||||
|
|
|
|||
|
|
@ -200,6 +200,10 @@ struct tcb {
|
|||
* tcb->vcpu->tcb == tcb. */
|
||||
struct vcpu* vcpu;
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
/* Use any remaining space for a thread name */
|
||||
char tcbName[];
|
||||
#endif
|
||||
};
|
||||
typedef struct tcb tcb_t;
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ typedef struct ui_info {
|
|||
} ui_info_t;
|
||||
|
||||
cap_t create_unmapped_it_frame_cap(pptr_t pptr, bool_t use_large);
|
||||
cap_t create_mapped_it_frame_cap(cap_t pd_cap, pptr_t pptr, vptr_t vptr, asid_t asid, bool_t use_large);
|
||||
cap_t create_mapped_it_frame_cap(cap_t pd_cap, pptr_t pptr, vptr_t vptr, asid_t asid, bool_t use_large, bool_t executable);
|
||||
|
||||
bool_t init_node_state(
|
||||
p_region_t avail_p_reg,
|
||||
|
|
|
|||
|
|
@ -25,6 +25,29 @@
|
|||
#define IA32_SYSENTER_ESP_MSR 0x175
|
||||
#define IA32_SYSENTER_EIP_MSR 0x176
|
||||
|
||||
#define BROADWELL_MODEL_ID 0xD4
|
||||
#define HASWELL_MODEL_ID 0xC3
|
||||
#define IVY_BRIDGE_MODEL_ID 0xA9
|
||||
#define SANDY_BRIDGE_1_MODEL_ID 0x2A /* Sandy Bridge */
|
||||
#define SANDY_BRIDGE_2_MODEL_ID 0x2D /* Sandy Bridge-E, Sandy Bridge-EN and Sandy Bridge-EP */
|
||||
#define WESTMERE_1_MODEL_ID 0x25 /* Arrandale and Clarksdale */
|
||||
#define WESTMERE_2_MODEL_ID 0x2C /* Gulftown and Westmere-EP */
|
||||
#define WESTMERE_3_MODEL_ID 0x2F /* Westemere-EX */
|
||||
#define NEHALEM_1_MODEL_ID 0x1E /* Clarksfield, Lynnfield and Jasper Forest */
|
||||
#define NEHALEM_2_MODEL_ID 0x1A /* Bloomfield and Nehalem-EP */
|
||||
#define NEHALEM_3_MODEL_ID 0x2E /* Nehalem-EX */
|
||||
|
||||
#define MODEL_ID(x) ( ((x & 0xf0000) >> 16) + (x & 0xf0) )
|
||||
|
||||
/* This article discloses prefetcher control on Intel processors; Nehalem, Westmere, Sandy Bridge,
|
||||
Ivy Bridge, Haswell, and Broadwell. It is currently undocumented in the regular intel manuals.
|
||||
https://software.intel.com/en-us/articles/disclosure-of-hw-prefetcher-control-on-some-intel-processors */
|
||||
#define IA32_PREFETCHER_MSR 0x1A4
|
||||
#define IA32_PREFETCHER_MSR_L2 BIT(0)
|
||||
#define IA32_PREFETCHER_MSR_L2_ADJACENT BIT(1)
|
||||
#define IA32_PREFETCHER_MSR_DCU BIT(2)
|
||||
#define IA32_PREFETCHER_MSR_DCU_IP BIT(3)
|
||||
|
||||
word_t PURE getRestartPC(tcb_t *thread);
|
||||
void setNextPC(tcb_t *thread, word_t v);
|
||||
|
||||
|
|
@ -41,14 +64,29 @@ static inline void setCurrentPD(paddr_t addr)
|
|||
}
|
||||
|
||||
/* TLB control */
|
||||
void invalidateTLB(void);
|
||||
void invalidateTLBentry(vptr_t vptr);
|
||||
static inline void invalidateTLB(void)
|
||||
{
|
||||
/* rewrite the current page directory */
|
||||
write_cr3(ia32KSCurrentPD);
|
||||
}
|
||||
|
||||
static inline void invalidateTLBentry(vptr_t vptr)
|
||||
{
|
||||
asm volatile("invlpg (%[vptr])" :: [vptr] "r"(vptr));
|
||||
}
|
||||
|
||||
/* Invalidates page structures cache */
|
||||
void invalidatePageStructureCache(void);
|
||||
static inline void invalidatePageStructureCache(void)
|
||||
{
|
||||
/* invalidate an arbitrary line to invalidate the page structure cache */
|
||||
invalidateTLBentry(0);
|
||||
}
|
||||
|
||||
/* Flushes entire CPU Cache */
|
||||
void ia32_wbinvd(void);
|
||||
static inline void ia32_wbinvd(void)
|
||||
{
|
||||
asm volatile("wbinvd" ::: "memory");
|
||||
}
|
||||
|
||||
/* GDT installation */
|
||||
void ia32_install_gdt(gdt_idt_ptr_t* gdt_idt_ptr);
|
||||
|
|
@ -63,10 +101,19 @@ void ia32_install_ldt(uint32_t ldt_sel);
|
|||
void ia32_install_tss(uint32_t tss_sel);
|
||||
|
||||
/* Get page fault address from CR2 register */
|
||||
uint32_t getFaultAddr(void);
|
||||
static inline uint32_t getFaultAddr(void)
|
||||
{
|
||||
return read_cr2();
|
||||
}
|
||||
|
||||
/* Get current stack pointer */
|
||||
void* get_current_esp(void);
|
||||
static inline void* get_current_esp(void)
|
||||
{
|
||||
uint32_t stack;
|
||||
void *result;
|
||||
asm volatile("movl %[stack_address], %[result]" : [result] "=r"(result) : [stack_address] "r"(&stack));
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Cleaning memory before user-level access */
|
||||
static inline void clearMemory(void* ptr, unsigned int bits)
|
||||
|
|
@ -78,18 +125,63 @@ static inline void clearMemory(void* ptr, unsigned int bits)
|
|||
/* Initialises MSRs required to setup sysenter and sysexit */
|
||||
void init_sysenter_msrs(void);
|
||||
|
||||
static uint64_t ia32_rdmsr(const uint32_t reg)
|
||||
{
|
||||
uint64_t value;
|
||||
asm volatile("rdmsr" : "=A"(value) : "c"(reg));
|
||||
return value;
|
||||
}
|
||||
|
||||
/* Read model specific register */
|
||||
uint32_t ia32_rdmsr_low(const uint32_t reg);
|
||||
uint32_t ia32_rdmsr_high(const uint32_t reg);
|
||||
static inline uint32_t ia32_rdmsr_low(const uint32_t reg)
|
||||
{
|
||||
return (uint32_t)ia32_rdmsr(reg);
|
||||
}
|
||||
|
||||
static inline uint32_t ia32_rdmsr_high(const uint32_t reg)
|
||||
{
|
||||
return (uint32_t)(ia32_rdmsr(reg) >> 32ull);
|
||||
}
|
||||
|
||||
/* Write model specific register */
|
||||
void ia32_wrmsr(const uint32_t reg, const uint32_t val_high, const uint32_t val_low);
|
||||
static inline void ia32_wrmsr(const uint32_t reg, const uint32_t val_high, const uint32_t val_low)
|
||||
{
|
||||
uint64_t val = ((uint64_t)val_high << 32ull) | (uint64_t)val_low;
|
||||
asm volatile("wrmsr" :: "A"(val), "c"(reg));
|
||||
}
|
||||
|
||||
/* Read different parts of CPUID */
|
||||
uint32_t ia32_cpuid_edx(uint32_t eax, uint32_t ecx);
|
||||
static inline uint32_t ia32_cpuid_edx(uint32_t eax, uint32_t ecx)
|
||||
{
|
||||
uint32_t edx, ebx;
|
||||
asm volatile("cpuid"
|
||||
: "=a" (eax),
|
||||
"=b" (ebx),
|
||||
"=c" (ecx),
|
||||
"=d" (edx)
|
||||
: "a" (eax), "c" (ecx)
|
||||
: "memory");
|
||||
return edx;
|
||||
}
|
||||
|
||||
static inline uint32_t ia32_cpuid_eax(uint32_t eax, uint32_t ecx)
|
||||
{
|
||||
uint32_t edx, ebx;
|
||||
asm volatile("cpuid"
|
||||
: "=a" (eax),
|
||||
"=b" (ebx),
|
||||
"=c" (ecx),
|
||||
"=d" (edx)
|
||||
: "a" (eax), "c" (ecx)
|
||||
: "memory");
|
||||
return eax;
|
||||
}
|
||||
|
||||
/* Read/write memory fence */
|
||||
void ia32_mfence(void);
|
||||
static inline void ia32_mfence(void)
|
||||
{
|
||||
asm volatile("mfence" ::: "memory");
|
||||
}
|
||||
|
||||
/* sysenter entry point */
|
||||
void handle_syscall(void);
|
||||
|
|
|
|||
|
|
@ -47,7 +47,23 @@ static inline void write_cr0(uint32_t val)
|
|||
asm volatile("movl %0, %%cr0" :: "r"(val), "m"(__control_reg_order));
|
||||
}
|
||||
|
||||
uint32_t read_cr4(void);
|
||||
void write_cr4(uint32_t value);
|
||||
static inline uint32_t read_cr2(void)
|
||||
{
|
||||
uint32_t val;
|
||||
asm volatile("movl %%cr2, %0" : "=r"(val), "=m"(__control_reg_order));
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline uint32_t read_cr4(void)
|
||||
{
|
||||
uint32_t val;
|
||||
asm volatile("movl %%cr4, %0" : "=r"(val), "=m"(__control_reg_order));
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline void write_cr4(uint32_t value)
|
||||
{
|
||||
asm volatile("movl %0, %%cr4" :: "r"(value), "m"(__control_reg_order));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -28,13 +28,22 @@ void Arch_fpuThreadDelete(tcb_t *thread);
|
|||
exception_t handleUnimplementedDevice(void);
|
||||
|
||||
/* Store state in the FPU registers into memory. */
|
||||
void saveFpuState(user_fpu_state_t *dest);
|
||||
static inline void saveFpuState(user_fpu_state_t *dest)
|
||||
{
|
||||
asm volatile("fxsave %[dest]" : [dest] "=m"(*dest));
|
||||
}
|
||||
|
||||
/* Load FPU state from memory into the FPU registers. */
|
||||
void loadFpuState(user_fpu_state_t *src);
|
||||
static inline void loadFpuState(user_fpu_state_t *src)
|
||||
{
|
||||
asm volatile("fxrstor %[src]" :: [src] "m"(*src));
|
||||
}
|
||||
|
||||
/* Reset the FPU registers into their initial blank state. */
|
||||
void resetFpu(void);
|
||||
static inline void resetFpu(void)
|
||||
{
|
||||
asm volatile("finit" :: "m"(__control_reg_order));
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable the FPU to be used without faulting.
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#ifndef __ARCH_MACHINE_HARDWARE_H
|
||||
#define __ARCH_MACHINE_HARDWARE_H
|
||||
|
||||
#include <types.h>
|
||||
#include <config.h>
|
||||
#include <arch/types.h>
|
||||
#include <arch/linker.h>
|
||||
|
|
@ -84,7 +85,14 @@ uint32_t CONST getCacheLineSize(void);
|
|||
uint32_t CONST getCacheLineSizeBits(void);
|
||||
|
||||
/* Flushes a specific memory range from the CPU cache */
|
||||
void flushCacheLine(void* vaddr);
|
||||
static inline void flushCacheLine(void* vaddr)
|
||||
{
|
||||
asm volatile("clflush %[vaddr]" :: [vaddr] "m"(vaddr));
|
||||
}
|
||||
|
||||
void flushCacheRange(void* vaddr, uint32_t size_bits);
|
||||
|
||||
/* Disables a variety of prefetchers */
|
||||
bool_t disablePrefetchers(void);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -196,6 +196,11 @@ struct tcb {
|
|||
struct tcb* tcbSchedPrev;
|
||||
struct tcb* tcbEPNext;
|
||||
struct tcb* tcbEPPrev;
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Use any remaining space for a thread name */
|
||||
char tcbName[];
|
||||
#endif
|
||||
};
|
||||
typedef struct tcb tcb_t;
|
||||
|
||||
|
|
|
|||
41
include/basic_types.h
Normal file
41
include/basic_types.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright 2014, General Dynamics C4 Systems
|
||||
*
|
||||
* This software may be distributed and modified according to the terms of
|
||||
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
|
||||
* See "LICENSE_GPLv2.txt" for details.
|
||||
*
|
||||
* @TAG(GD_GPL)
|
||||
*/
|
||||
|
||||
#ifndef __BASIC_TYPES_H
|
||||
#define __BASIC_TYPES_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <arch/types.h>
|
||||
|
||||
enum _bool {
|
||||
false = 0,
|
||||
true = 1
|
||||
};
|
||||
typedef uint32_t bool_t;
|
||||
|
||||
typedef struct region {
|
||||
pptr_t start;
|
||||
pptr_t end;
|
||||
} region_t;
|
||||
|
||||
typedef struct p_region {
|
||||
paddr_t start;
|
||||
paddr_t end;
|
||||
} p_region_t;
|
||||
|
||||
typedef struct v_region {
|
||||
vptr_t start;
|
||||
vptr_t end;
|
||||
} v_region_t;
|
||||
|
||||
#define REG_EMPTY (region_t){ .start = 0, .end = 0 }
|
||||
#define P_REG_EMPTY (p_region_t){ .start = 0, .end = 0 }
|
||||
|
||||
#endif /* __BASIC_TYPES_H */
|
||||
38
include/compound_types.h
Normal file
38
include/compound_types.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright 2014, General Dynamics C4 Systems
|
||||
*
|
||||
* This software may be distributed and modified according to the terms of
|
||||
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
|
||||
* See "LICENSE_GPLv2.txt" for details.
|
||||
*
|
||||
* @TAG(GD_GPL)
|
||||
*/
|
||||
|
||||
#ifndef __COMPOUND_TYPES_H
|
||||
#define __COMPOUND_TYPES_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <api/types.h>
|
||||
#include <object/structures.h>
|
||||
#include <arch/types.h>
|
||||
|
||||
struct pde_range {
|
||||
pde_t *base;
|
||||
unsigned int length;
|
||||
};
|
||||
typedef struct pde_range pde_range_t;
|
||||
|
||||
struct pte_range {
|
||||
pte_t *base;
|
||||
unsigned int length;
|
||||
};
|
||||
typedef struct pte_range pte_range_t;
|
||||
|
||||
typedef cte_t *cte_ptr_t;
|
||||
|
||||
struct extra_caps {
|
||||
cte_ptr_t excaprefs[seL4_MsgMaxExtraCaps];
|
||||
};
|
||||
typedef struct extra_caps extra_caps_t;
|
||||
|
||||
#endif /* __COMPOUND_TYPES_H */
|
||||
|
|
@ -18,6 +18,11 @@
|
|||
#include <arch/object/tcb.h>
|
||||
#include <object/cnode.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Maximum length of the tcb name, including null terminator */
|
||||
#define TCB_NAME_LENGTH (BIT(TCB_SIZE_BITS) - sizeof(tcb_t))
|
||||
#endif
|
||||
|
||||
struct tcb_queue {
|
||||
tcb_t *head;
|
||||
tcb_t *end;
|
||||
|
|
@ -84,5 +89,8 @@ cptr_t PURE getExtraCPtr(word_t *bufferPtr, unsigned int i);
|
|||
void setExtraBadge(word_t *bufferPtr, word_t badge, unsigned int i);
|
||||
|
||||
exception_t lookupExtraCaps(tcb_t* thread, word_t *bufferPtr, message_info_t info);
|
||||
#ifdef DEBUG
|
||||
void setThreadName(tcb_t *thread, const char *name);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -16,11 +16,12 @@
|
|||
#define UART0_PPTR 0xfff02000
|
||||
#define DMTIMER0_PPTR 0xfff03000
|
||||
#define WDT1_PPTR 0xfff04000
|
||||
#define CMPER_PPTR 0xfff05000
|
||||
|
||||
|
||||
/* Other devices on the SoC. */
|
||||
#define INTC_PADDR 0x48200000
|
||||
#define UART0_PADDR 0x44E09000
|
||||
#define INTC_PADDR 0x48200000
|
||||
#define UART0_PADDR 0x44E09000
|
||||
#define DMTIMER0_PADDR 0x44E05000
|
||||
#define DMTIMER2_PADDR 0x48040000
|
||||
#define DMTIMER3_PADDR 0x48042000
|
||||
|
|
@ -28,7 +29,8 @@
|
|||
#define DMTIMER5_PADDR 0x48046000
|
||||
#define DMTIMER6_PADDR 0x48048000
|
||||
#define DMTIMER7_PADDR 0x4804A000
|
||||
#define WDT1_PADDR 0x44e35000
|
||||
#define WDT1_PADDR 0x44e35000
|
||||
#define CMPER_PADDR 0x44e00000
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -21,8 +21,19 @@ uint16_t in16(uint16_t port);
|
|||
uint32_t in32(uint16_t port);
|
||||
|
||||
/* these versions are linked to physical addresses */
|
||||
void out8_phys(uint16_t port, uint8_t value);
|
||||
uint8_t in8_phys(uint16_t port);
|
||||
static inline void SECTION(".phys.text")
|
||||
out8_phys(uint16_t port, uint8_t value)
|
||||
{
|
||||
asm volatile("outb %[value], %[port]" :: [port] "d"(port), [value] "a"(value));
|
||||
}
|
||||
|
||||
static inline uint8_t SECTION(".phys.text")
|
||||
in8_phys(uint16_t port)
|
||||
{
|
||||
uint8_t value;
|
||||
asm volatile("inb %[port], %[value]" : [value] "=a"(value) : [port] "d" (port));
|
||||
return value;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
|
|
|
|||
24
include/string.h
Normal file
24
include/string.h
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright 2014, General Dynamics C4 Systems
|
||||
*
|
||||
* This software may be distributed and modified according to the terms of
|
||||
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
|
||||
* See "LICENSE_GPLv2.txt" for details.
|
||||
*
|
||||
* @TAG(GD_GPL)
|
||||
*/
|
||||
|
||||
#ifndef __STRING_H
|
||||
#define __STRING_H
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
unsigned int strnlen(const char *s, unsigned int maxlen);
|
||||
unsigned int strlcpy(char *dest, const char *src, unsigned int size);
|
||||
unsigned int strlcat(char *dest, const char *src, unsigned int size);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -11,52 +11,7 @@
|
|||
#ifndef __TYPES_H
|
||||
#define __TYPES_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <api/types.h>
|
||||
#include <object/structures.h>
|
||||
#include <arch/types.h>
|
||||
|
||||
enum _bool {
|
||||
false = 0,
|
||||
true = 1
|
||||
};
|
||||
typedef uint32_t bool_t;
|
||||
|
||||
typedef struct region {
|
||||
pptr_t start;
|
||||
pptr_t end;
|
||||
} region_t;
|
||||
|
||||
typedef struct p_region {
|
||||
paddr_t start;
|
||||
paddr_t end;
|
||||
} p_region_t;
|
||||
|
||||
typedef struct v_region {
|
||||
vptr_t start;
|
||||
vptr_t end;
|
||||
} v_region_t;
|
||||
|
||||
#define REG_EMPTY (region_t){ .start = 0, .end = 0 }
|
||||
#define P_REG_EMPTY (p_region_t){ .start = 0, .end = 0 }
|
||||
|
||||
struct pde_range {
|
||||
pde_t *base;
|
||||
unsigned int length;
|
||||
};
|
||||
typedef struct pde_range pde_range_t;
|
||||
|
||||
struct pte_range {
|
||||
pte_t *base;
|
||||
unsigned int length;
|
||||
};
|
||||
typedef struct pte_range pte_range_t;
|
||||
|
||||
typedef cte_t *cte_ptr_t;
|
||||
|
||||
struct extra_caps {
|
||||
cte_ptr_t excaprefs[seL4_MsgMaxExtraCaps];
|
||||
};
|
||||
typedef struct extra_caps extra_caps_t;
|
||||
#include <basic_types.h>
|
||||
#include <compound_types.h>
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#define ROUND_UP(n, b) (((((n) - 1ul) >> (b)) + 1ul) << (b))
|
||||
#define CTZ(x) __builtin_ctz(x)
|
||||
#define CLZ(x) __builtin_clz(x)
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
|
|
|
|||
|
|
@ -9,25 +9,25 @@
|
|||
@TAG(NICTA_BSD)
|
||||
-->
|
||||
<api>
|
||||
<registers>
|
||||
<register name="PC"/>
|
||||
<register name="SP"/>
|
||||
<register name="CPSR"/>
|
||||
<register name="R0"/>
|
||||
<register name="R1"/>
|
||||
<register name="R8"/>
|
||||
<register name="R9"/>
|
||||
<register name="R10"/>
|
||||
<register name="R11"/>
|
||||
<register name="R12"/>
|
||||
<register name="R2"/>
|
||||
<register name="R3"/>
|
||||
<register name="R4"/>
|
||||
<register name="R5"/>
|
||||
<register name="R6"/>
|
||||
<register name="R7"/>
|
||||
<register name="R14"/>
|
||||
</registers>
|
||||
<struct name="seL4_UserContext">
|
||||
<member name="pc"/>
|
||||
<member name="sp"/>
|
||||
<member name="cpsr"/>
|
||||
<member name="r0"/>
|
||||
<member name="r1"/>
|
||||
<member name="r8"/>
|
||||
<member name="r9"/>
|
||||
<member name="r10"/>
|
||||
<member name="r11"/>
|
||||
<member name="r12"/>
|
||||
<member name="r2"/>
|
||||
<member name="r3"/>
|
||||
<member name="r4"/>
|
||||
<member name="r5"/>
|
||||
<member name="r6"/>
|
||||
<member name="r7"/>
|
||||
<member name="r14"/>
|
||||
</struct>
|
||||
<interface name="seL4_ARM_PageDirectory"/>
|
||||
|
||||
<interface name="seL4_ARM_PageDirectory">
|
||||
|
|
|
|||
|
|
@ -519,6 +519,23 @@ seL4_DebugCapIdentify(seL4_CPtr cap)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef SEL4_DEBUG_KERNEL
|
||||
|
||||
char *strcpy(char *, const char *);
|
||||
static inline void
|
||||
seL4_DebugNameThread(seL4_CPtr tcb, const char *name)
|
||||
{
|
||||
strcpy((char*)seL4_GetIPCBuffer()->msg, name);
|
||||
|
||||
register seL4_Word arg1 asm("r0") = tcb;
|
||||
register seL4_Word scno asm("r7") = seL4_SysDebugNameThread;
|
||||
asm volatile ("swi %[swi_num]"
|
||||
: "+r"(arg1)
|
||||
: [swi_num] "i" __SWINUM(seL4_SysDebugNameThread), "r"(scno)
|
||||
: "memory");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SEL4_DANGEROUS_CODE_INJECTION_KERNEL
|
||||
static inline void
|
||||
seL4_DebugRun(void (* userfn) (void *), void* userarg)
|
||||
|
|
|
|||
|
|
@ -9,21 +9,21 @@
|
|||
@TAG(NICTA_BSD)
|
||||
-->
|
||||
<api>
|
||||
<registers>
|
||||
<register name="EIP"/>
|
||||
<register name="ESP"/>
|
||||
<register name="EFlags"/>
|
||||
<register name="EAX"/>
|
||||
<register name="EBX"/>
|
||||
<register name="ECX"/>
|
||||
<register name="EDX"/>
|
||||
<register name="ESI"/>
|
||||
<register name="EDI"/>
|
||||
<register name="EBP"/>
|
||||
<register name="TLS_Base"/>
|
||||
<register name="FS"/>
|
||||
<register name="GS"/>
|
||||
</registers>
|
||||
<struct name="seL4_UserContext">
|
||||
<member name="eip"/>
|
||||
<member name="esp"/>
|
||||
<member name="eflags"/>
|
||||
<member name="eax"/>
|
||||
<member name="ebx"/>
|
||||
<member name="ecx"/>
|
||||
<member name="edx"/>
|
||||
<member name="esi"/>
|
||||
<member name="edi"/>
|
||||
<member name="ebp"/>
|
||||
<member name="tls_base"/>
|
||||
<member name="fs"/>
|
||||
<member name="gs"/>
|
||||
</struct>
|
||||
<interface name="seL4_IA32_PageDirectory">
|
||||
<method id="IA32PageDirectoryMap" name="Map">
|
||||
<param dir="in" name="pdpt" type="seL4_IA32_PageDirectory"/>
|
||||
|
|
|
|||
|
|
@ -501,6 +501,27 @@ seL4_DebugCapIdentify(seL4_CPtr cap)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef SEL4_DEBUG_KERNEL
|
||||
char *strcpy(char *, const char *);
|
||||
static inline void
|
||||
seL4_DebugNameThread(seL4_CPtr tcb, const char *name)
|
||||
{
|
||||
strcpy((char*)seL4_GetIPCBuffer()->msg, name);
|
||||
|
||||
asm volatile (
|
||||
"pushl %%ebp \n"
|
||||
"movl %%esp, %%ecx \n"
|
||||
"leal 1f, %%edx \n"
|
||||
"1: \n"
|
||||
"sysenter \n"
|
||||
"popl %%ebp \n"
|
||||
:
|
||||
: "a"(seL4_SysDebugNameThread), "b"(tcb)
|
||||
: "%ecx", "%edx", "%esi", "%edi", "memory"
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SEL4_DANGEROUS_CODE_INJECTION_KERNEL)
|
||||
static inline void
|
||||
seL4_DebugRun(void (*userfn) (void *), void* userarg)
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
<syscall name="DebugHalt" />
|
||||
<syscall name="DebugCapIdentify" />
|
||||
<syscall name="DebugSnapshot" />
|
||||
<syscall name="DebugNameThread"/>
|
||||
</config>
|
||||
<config name="DANGEROUS_CODE_INJECTION">
|
||||
<syscall name="DebugRun"/>
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@ typedef enum {
|
|||
seL4_CanRead = 0x02,
|
||||
seL4_CanGrant = 0x04,
|
||||
seL4_AllRights = 0x07, /* seL4_CanWrite | seL4_CanRead | seL4_CanGrant */
|
||||
seL4_Transfer_Mint = 0x100,
|
||||
SEL4_FORCE_LONG_ENUM(seL4_CapRights),
|
||||
} seL4_CapRights;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,12 +8,13 @@
|
|||
@TAG(NICTA_BSD)
|
||||
-->
|
||||
|
||||
<!ELEMENT api (registers*,interface*)>
|
||||
<!ELEMENT api (struct*,interface*)>
|
||||
|
||||
<!ELEMENT registers (register*)>
|
||||
<!ELEMENT struct (member*)>
|
||||
<!ATTLIST struct name CDATA #REQUIRED>
|
||||
|
||||
<!ELEMENT register EMPTY>
|
||||
<!ATTLIST register name CDATA #REQUIRED>
|
||||
<!ELEMENT member EMPTY>
|
||||
<!ATTLIST member name CDATA #REQUIRED>
|
||||
|
||||
<!ELEMENT interface (method*)>
|
||||
<!ATTLIST interface name CDATA #REQUIRED>
|
||||
|
|
|
|||
|
|
@ -235,6 +235,12 @@ arch_types = {
|
|||
]
|
||||
}
|
||||
|
||||
# Retrieve a member list for a given struct type
|
||||
def struct_members(type, structs):
|
||||
members = [member for struct_name, member in structs if struct_name == type.name]
|
||||
assert len(members) == 1
|
||||
return members[0]
|
||||
|
||||
# Keep increasing the given number 'x' until 'x % a == 0'.
|
||||
def align_up(x, a):
|
||||
if x % a == 0:
|
||||
|
|
@ -287,7 +293,7 @@ def generate_param_list(input_params, output_params):
|
|||
return ", ".join(params)
|
||||
|
||||
|
||||
def generate_marshal_expressions(params, num_mrs, registers):
|
||||
def generate_marshal_expressions(params, num_mrs, structs):
|
||||
"""
|
||||
Generate marshalling expressions for the given set of inputs.
|
||||
|
||||
|
|
@ -335,7 +341,7 @@ def generate_marshal_expressions(params, num_mrs, registers):
|
|||
assert target_offset == 0
|
||||
num_words = num_bits / WORD_SIZE_BITS
|
||||
for i in range(num_words):
|
||||
expr = param.type.c_expression(param.name, i, registers);
|
||||
expr = param.type.c_expression(param.name, i, struct_members(param.type, structs));
|
||||
word_array[target_word + i].append(expr)
|
||||
|
||||
|
||||
|
|
@ -437,7 +443,7 @@ def generate_result_struct(interface_name, method_name, output_params):
|
|||
|
||||
return "\n".join(result)
|
||||
|
||||
def generate_stub(arch, interface_name, method_name, method_id, input_params, output_params, registers, use_only_ipc_buffer):
|
||||
def generate_stub(arch, interface_name, method_name, method_id, input_params, output_params, structs, use_only_ipc_buffer):
|
||||
result = []
|
||||
|
||||
if use_only_ipc_buffer:
|
||||
|
|
@ -478,7 +484,7 @@ def generate_stub(arch, interface_name, method_name, method_id, input_params, ou
|
|||
#
|
||||
# Get a list of expressions for our caps and inputs.
|
||||
#
|
||||
input_expressions = generate_marshal_expressions(standard_params, num_mrs, registers)
|
||||
input_expressions = generate_marshal_expressions(standard_params, num_mrs, structs)
|
||||
cap_expressions = [x.name for x in cap_params]
|
||||
service_cap = cap_expressions[0]
|
||||
cap_expressions = cap_expressions[1:]
|
||||
|
|
@ -561,8 +567,9 @@ def generate_stub(arch, interface_name, method_name, method_id, input_params, ou
|
|||
unmashalled_params = generate_unmarshal_expressions(output_params)
|
||||
for (param, words) in unmashalled_params:
|
||||
if param.type.pass_by_reference():
|
||||
members = struct_members(param.type, structs);
|
||||
for i in range(len(words)):
|
||||
result.append("\t%s->%s = %s;" % (param.name, registers[i], words[i] % source_words))
|
||||
result.append("\t%s->%s = %s;" % (param.name, members[i], words[i] % source_words))
|
||||
else:
|
||||
if param.type.double_word:
|
||||
result.append("\tresult.%s = ((uint64_t)%s + ((uint64_t)%s << 32));" % (param.name, words[0] % source_words, words[1] % source_words))
|
||||
|
|
@ -598,12 +605,16 @@ def parse_xml_file(input_file, valid_types):
|
|||
|
||||
# Parse the XML to generate method structures.
|
||||
methods = []
|
||||
registers = []
|
||||
structs = []
|
||||
doc = xml.dom.minidom.parse(input_file)
|
||||
|
||||
for register in doc.getElementsByTagName("register"):
|
||||
register_name = (register.getAttribute("name")).lower()
|
||||
registers.append(register_name)
|
||||
for struct in doc.getElementsByTagName("struct"):
|
||||
struct_members = []
|
||||
struct_name = struct.getAttribute("name")
|
||||
for members in struct.getElementsByTagName("member"):
|
||||
member_name = members.getAttribute("name")
|
||||
struct_members.append(member_name)
|
||||
structs.append( (struct_name, struct_members) )
|
||||
|
||||
for interface in doc.getElementsByTagName("interface"):
|
||||
interface_name = interface.getAttribute("name")
|
||||
|
|
@ -631,7 +642,7 @@ def parse_xml_file(input_file, valid_types):
|
|||
output_params.append(Parameter(param_name, param_type))
|
||||
methods.append((interface_name, method_name, method_id, input_params, output_params))
|
||||
|
||||
return (methods, registers)
|
||||
return (methods, structs)
|
||||
|
||||
def generate_stub_file(arch, input_files, output_file, use_only_ipc_buffer):
|
||||
"""
|
||||
|
|
@ -646,11 +657,11 @@ def generate_stub_file(arch, input_files, output_file, use_only_ipc_buffer):
|
|||
|
||||
# Parse XML
|
||||
methods = []
|
||||
registers = []
|
||||
structs = []
|
||||
for file in input_files:
|
||||
method, register = parse_xml_file(file, types + arch_types[arch])
|
||||
method, struct = parse_xml_file(file, types + arch_types[arch])
|
||||
methods += method
|
||||
registers += register
|
||||
structs += struct
|
||||
|
||||
# Print header.
|
||||
result.append("""
|
||||
|
|
@ -712,7 +723,7 @@ def generate_stub_file(arch, input_files, output_file, use_only_ipc_buffer):
|
|||
result.append(" */")
|
||||
for (interface_name, method_name, method_id, inputs, outputs) in methods:
|
||||
result.append(generate_stub(arch, interface_name, method_name,
|
||||
method_id, inputs, outputs, registers, use_only_ipc_buffer))
|
||||
method_id, inputs, outputs, structs, use_only_ipc_buffer))
|
||||
|
||||
# Print footer.
|
||||
result.append("#endif /* __LIBSEL4_SEL4_CLIENT_H */")
|
||||
|
|
|
|||
|
|
@ -16,5 +16,6 @@ include ${SOURCE_ROOT}/src/machine/Makefile
|
|||
|
||||
C_SOURCES += src/inlines.c \
|
||||
src/assert.c \
|
||||
src/util.c
|
||||
src/util.c \
|
||||
src/string.c
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include <machine/io.h>
|
||||
#include <object/interrupt.h>
|
||||
#include <model/statedata.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <arch/machine/capdl.h>
|
||||
|
|
@ -71,6 +72,32 @@ handleUnknownSyscall(word_t w)
|
|||
setRegister(ksCurThread, capRegister, cap_type);
|
||||
return EXCEPTION_NONE;
|
||||
}
|
||||
if (w == SysDebugNameThread) {
|
||||
/* This is a syscall meant to aid debugging, so if anything goes wrong wrong
|
||||
* then assume the system is completely misconfigured and halt */
|
||||
const char *name;
|
||||
word_t cptr = getRegister(ksCurThread, capRegister);
|
||||
lookupCapAndSlot_ret_t lu_ret = lookupCapAndSlot(ksCurThread, cptr);
|
||||
/* ensure we got a TCB cap */
|
||||
uint32_t cap_type = cap_get_capType(lu_ret.cap);
|
||||
if (cap_type != cap_thread_cap) {
|
||||
userError("SysDebugNameThread: cap is not a TCB, halting");
|
||||
halt();
|
||||
}
|
||||
/* Add 1 to the IPC buffer to skip the message info word */
|
||||
name = (const char*)(lookupIPCBuffer(true, ksCurThread) + 1);
|
||||
if (!name) {
|
||||
userError("SysDebugNameThread: Failed to lookup IPC buffer, halting");
|
||||
halt();
|
||||
}
|
||||
/* ensure the name isn't too long */
|
||||
if (name[strnlen(name, seL4_MsgMaxLength * sizeof(word_t))] != '\0') {
|
||||
userError("SysDebugNameThread: Name too long, halting");
|
||||
halt();
|
||||
}
|
||||
setThreadName(TCB_PTR(cap_thread_cap_get_capTCBPtr(lu_ret.cap)), name);
|
||||
return EXCEPTION_NONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DANGEROUS_CODE_INJECTION
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ check_export_arch_timer(void)
|
|||
v |= CNTKCTL_PL0PCTEN;
|
||||
#endif
|
||||
#ifdef CONFIG_EXPORT_VCNT_USER
|
||||
v |= CNTKCTL_PL0PCTEN;
|
||||
v |= CNTKCTL_PL0VCTEN;
|
||||
#endif
|
||||
MCR(CNTKCTL, v);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -172,10 +172,10 @@ create_unmapped_it_frame_cap(pptr_t pptr, bool_t use_large)
|
|||
}
|
||||
|
||||
BOOT_CODE cap_t
|
||||
create_mapped_it_frame_cap(cap_t pd_cap, pptr_t pptr, vptr_t vptr, asid_t asid, bool_t use_large)
|
||||
create_mapped_it_frame_cap(cap_t pd_cap, pptr_t pptr, vptr_t vptr, asid_t asid, bool_t use_large, bool_t executable)
|
||||
{
|
||||
cap_t cap = create_it_frame_cap(pptr, vptr, asid, use_large);
|
||||
map_it_frame_cap(pd_cap, cap);
|
||||
map_it_frame_cap(pd_cap, cap, executable);
|
||||
return cap;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ map_it_pt_cap(cap_t pd_cap, cap_t pt_cap)
|
|||
}
|
||||
|
||||
BOOT_CODE void
|
||||
map_it_frame_cap(cap_t pd_cap, cap_t frame_cap)
|
||||
map_it_frame_cap(cap_t pd_cap, cap_t frame_cap, bool_t executable)
|
||||
{
|
||||
pte_t* pt;
|
||||
pte_t* targetSlot;
|
||||
|
|
@ -189,7 +189,7 @@ map_it_frame_cap(cap_t pd_cap, cap_t frame_cap)
|
|||
APFromVMRights(VMReadWrite),
|
||||
1, /* cacheable */
|
||||
1, /* write-back caching */
|
||||
0 /* executable */
|
||||
!executable
|
||||
);
|
||||
#else
|
||||
*targetSlot = pte_pte_small_new(
|
||||
|
|
@ -364,7 +364,7 @@ map_kernel_window(void)
|
|||
PPTR_GLOBALS_PAGE,
|
||||
VMReadOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
true, /* armParityEnabled */
|
||||
true /* armPageCacheable */
|
||||
)
|
||||
|
|
@ -376,7 +376,7 @@ map_kernel_window(void)
|
|||
PPTR_KERNEL_STACK,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
true, /* armParityEnabled */
|
||||
true /* armPageCacheable */
|
||||
)
|
||||
|
|
@ -1839,6 +1839,7 @@ decodeARMFrameInvocation(word_t label, unsigned int length,
|
|||
|
||||
find_ret = findPDForASID(asid);
|
||||
if (unlikely(find_ret.status != EXCEPTION_NONE)) {
|
||||
userError("ARMPageMap: No PD for ASID");
|
||||
current_syscall_error.type =
|
||||
seL4_FailedLookup;
|
||||
current_syscall_error.failedLookupWasSource =
|
||||
|
|
@ -1958,6 +1959,7 @@ decodeARMFrameInvocation(word_t label, unsigned int length,
|
|||
|
||||
find_ret = findPDForASID(mappedASID);
|
||||
if (unlikely(find_ret.status != EXCEPTION_NONE)) {
|
||||
userError("ARMPageRemap: No PD for ASID");
|
||||
current_syscall_error.type =
|
||||
seL4_FailedLookup;
|
||||
current_syscall_error.failedLookupWasSource = false;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include <arch/machine/fpu.h>
|
||||
#include <arch/object/ioport.h>
|
||||
#include <arch/linker.h>
|
||||
#include <util.h>
|
||||
|
||||
#ifdef CONFIG_IOMMU
|
||||
#include <plat/machine/intel-vtd.h>
|
||||
|
|
@ -95,7 +96,7 @@ create_unmapped_it_frame_cap(pptr_t pptr, bool_t use_large)
|
|||
}
|
||||
|
||||
BOOT_CODE cap_t
|
||||
create_mapped_it_frame_cap(cap_t vspace_cap, pptr_t pptr, vptr_t vptr, asid_t asid, bool_t use_large)
|
||||
create_mapped_it_frame_cap(cap_t vspace_cap, pptr_t pptr, vptr_t vptr, asid_t asid, bool_t use_large, bool_t executable UNUSED)
|
||||
{
|
||||
cap_t cap = create_it_frame_cap(pptr, vptr, asid, use_large);
|
||||
map_it_frame_cap(vspace_cap, cap);
|
||||
|
|
@ -575,5 +576,11 @@ init_node_cpu(
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_DISABLE_PREFETCHERS
|
||||
if (!disablePrefetchers()) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,3 +82,38 @@ void flushCacheRange(void* vaddr, uint32_t size_bits)
|
|||
}
|
||||
ia32_mfence();
|
||||
}
|
||||
|
||||
/* Disables as many prefetchers as possible */
|
||||
BOOT_CODE bool_t
|
||||
disablePrefetchers()
|
||||
{
|
||||
uint32_t version_info;
|
||||
uint32_t low, high;
|
||||
int i;
|
||||
|
||||
uint32_t valid_models[] = { BROADWELL_MODEL_ID, HASWELL_MODEL_ID, IVY_BRIDGE_MODEL_ID,
|
||||
SANDY_BRIDGE_1_MODEL_ID, SANDY_BRIDGE_2_MODEL_ID, WESTMERE_1_MODEL_ID, WESTMERE_2_MODEL_ID,
|
||||
WESTMERE_3_MODEL_ID, NEHALEM_1_MODEL_ID, NEHALEM_2_MODEL_ID, NEHALEM_3_MODEL_ID
|
||||
};
|
||||
|
||||
version_info = ia32_cpuid_eax(0x1, 0x0);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(valid_models); ++i) {
|
||||
if (MODEL_ID(version_info) == valid_models[i]) {
|
||||
low = ia32_rdmsr_low(IA32_PREFETCHER_MSR);
|
||||
high = ia32_rdmsr_high(IA32_PREFETCHER_MSR);
|
||||
|
||||
low |= IA32_PREFETCHER_MSR_L2;
|
||||
low |= IA32_PREFETCHER_MSR_L2_ADJACENT;
|
||||
low |= IA32_PREFETCHER_MSR_DCU;
|
||||
low |= IA32_PREFETCHER_MSR_DCU_IP;
|
||||
|
||||
ia32_wrmsr(IA32_PREFETCHER_MSR, high, low);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
printf("Disabling prefetchers not implemented for CPU model: %x\n", MODEL_ID(version_info));
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,44 +10,8 @@
|
|||
|
||||
#include <machine/assembler.h>
|
||||
|
||||
.section .phys.text
|
||||
|
||||
BEGIN_FUNC(out8_phys)
|
||||
movb 8(%esp), %al
|
||||
movw 4(%esp), %dx
|
||||
outb %al, %dx
|
||||
ret
|
||||
END_FUNC(out8_phys)
|
||||
|
||||
BEGIN_FUNC(in8_phys)
|
||||
movw 4(%esp), %dx
|
||||
inb %dx, %al
|
||||
ret
|
||||
END_FUNC(in8_phys)
|
||||
|
||||
.section .boot.text
|
||||
|
||||
BEGIN_FUNC(ia32_rdmsr_low)
|
||||
movl 4(%esp), %ecx # MSR register index
|
||||
rdmsr # 8 bytes output will be in EDX:EAX
|
||||
ret
|
||||
END_FUNC(ia32_rdmsr_low)
|
||||
|
||||
BEGIN_FUNC(ia32_rdmsr_high)
|
||||
movl 4(%esp), %ecx # MSR register index
|
||||
rdmsr # 8 bytes output will be in EDX:EAX
|
||||
movl %edx, %eax # Move the high bytes to the return register
|
||||
ret
|
||||
END_FUNC(ia32_rdmsr_high)
|
||||
|
||||
BEGIN_FUNC(ia32_wrmsr)
|
||||
movl 4(%esp), %ecx # MSR register index
|
||||
movl 8(%esp), %edx # 4 most significant bytes
|
||||
movl 12(%esp), %eax # 4 least significant bytes
|
||||
wrmsr
|
||||
ret
|
||||
END_FUNC(ia32_wrmsr)
|
||||
|
||||
BEGIN_FUNC(ia32_install_gdt)
|
||||
movl 4(%esp), %eax
|
||||
lgdt (%eax) # load gdtr register with gdt pointer
|
||||
|
|
@ -78,23 +42,6 @@ BEGIN_FUNC(ia32_install_tss)
|
|||
ret
|
||||
END_FUNC(ia32_install_tss)
|
||||
|
||||
BEGIN_FUNC(read_cr4)
|
||||
movl %cr4, %eax
|
||||
ret
|
||||
END_FUNC(read_cr4)
|
||||
|
||||
BEGIN_FUNC(write_cr0)
|
||||
movl 4(%esp), %eax
|
||||
movl %eax, %cr0
|
||||
ret
|
||||
END_FUNC(write_cr0)
|
||||
|
||||
BEGIN_FUNC(write_cr4)
|
||||
movl 4(%esp), %eax
|
||||
movl %eax, %cr4
|
||||
ret
|
||||
END_FUNC(write_cr4)
|
||||
|
||||
BEGIN_FUNC(getCacheLineSize)
|
||||
pushl %ebx
|
||||
movl $1, %eax
|
||||
|
|
@ -107,81 +54,8 @@ BEGIN_FUNC(getCacheLineSize)
|
|||
ret
|
||||
END_FUNC(getCacheLineSize)
|
||||
|
||||
BEGIN_FUNC(ia32_cpuid_edx)
|
||||
movl 4(%esp), %eax
|
||||
movl 8(%esp), %ecx
|
||||
pushl %ebx
|
||||
cpuid
|
||||
popl %ebx
|
||||
movl %edx, %eax
|
||||
ret
|
||||
END_FUNC(ia32_cpuid_edx)
|
||||
|
||||
.section .text
|
||||
|
||||
BEGIN_FUNC(invalidateTLB)
|
||||
movl %cr3, %eax
|
||||
movl %eax, %cr3
|
||||
ret
|
||||
END_FUNC(invalidateTLB)
|
||||
|
||||
BEGIN_FUNC(invalidateTLBentry)
|
||||
movl 4(%esp), %eax
|
||||
invlpg (%eax)
|
||||
ret
|
||||
END_FUNC(invalidateTLBentry)
|
||||
|
||||
BEGIN_FUNC(invalidatePageStructureCache)
|
||||
// Force an invalidate by flushing an arbitrary entry
|
||||
// from the TLB
|
||||
movl $0, %eax
|
||||
invlpg (%eax)
|
||||
ret
|
||||
END_FUNC(invalidatePageStructureCache)
|
||||
|
||||
BEGIN_FUNC(flushCacheLine)
|
||||
movl 4(%esp), %eax
|
||||
clflush (%eax)
|
||||
ret
|
||||
END_FUNC(flushCacheLine)
|
||||
|
||||
BEGIN_FUNC(getFaultAddr)
|
||||
movl %cr2, %eax
|
||||
ret
|
||||
END_FUNC(getFaultAddr)
|
||||
|
||||
BEGIN_FUNC(get_current_esp)
|
||||
movl %esp, %eax
|
||||
ret
|
||||
END_FUNC(get_current_esp)
|
||||
|
||||
BEGIN_FUNC(ia32_wbinvd)
|
||||
wbinvd
|
||||
ret
|
||||
END_FUNC(ia32_wbinvd)
|
||||
|
||||
BEGIN_FUNC(ia32_mfence)
|
||||
mfence
|
||||
ret
|
||||
END_FUNC(ia32_mfence)
|
||||
|
||||
BEGIN_FUNC(saveFpuState)
|
||||
movl 4(%esp), %eax
|
||||
fxsave (%eax)
|
||||
ret
|
||||
END_FUNC(saveFpuState)
|
||||
|
||||
BEGIN_FUNC(loadFpuState)
|
||||
movl 4(%esp), %eax
|
||||
fxrstor (%eax)
|
||||
ret
|
||||
END_FUNC(loadFpuState)
|
||||
|
||||
BEGIN_FUNC(resetFpu)
|
||||
finit
|
||||
ret
|
||||
END_FUNC(resetFpu)
|
||||
|
||||
BEGIN_FUNC(out8)
|
||||
movb 8(%esp), %al
|
||||
movw 4(%esp), %dx
|
||||
|
|
|
|||
|
|
@ -218,7 +218,7 @@ create_ipcbuf_frame(cap_t root_cnode_cap, cap_t pd_cap, vptr_t vptr)
|
|||
clearMemory((void*)pptr, PAGE_BITS);
|
||||
|
||||
/* create a cap of it and write it into the root CNode */
|
||||
cap = create_mapped_it_frame_cap(pd_cap, pptr, vptr, IT_ASID, false);
|
||||
cap = create_mapped_it_frame_cap(pd_cap, pptr, vptr, IT_ASID, false, false);
|
||||
write_slot(SLOT_PTR(pptr_of_cap(root_cnode_cap), BI_CAP_IT_IPCBUF), cap);
|
||||
|
||||
return cap;
|
||||
|
|
@ -235,7 +235,7 @@ create_bi_frame_cap(
|
|||
cap_t cap;
|
||||
|
||||
/* create a cap of it and write it into the root CNode */
|
||||
cap = create_mapped_it_frame_cap(pd_cap, pptr, vptr, IT_ASID, false);
|
||||
cap = create_mapped_it_frame_cap(pd_cap, pptr, vptr, IT_ASID, false, false);
|
||||
write_slot(SLOT_PTR(pptr_of_cap(root_cnode_cap), BI_CAP_BI_FRAME), cap);
|
||||
}
|
||||
|
||||
|
|
@ -300,7 +300,7 @@ create_frames_of_region(
|
|||
|
||||
for (f = reg.start; f < reg.end; f += BIT(PAGE_BITS)) {
|
||||
if (do_map) {
|
||||
frame_cap = create_mapped_it_frame_cap(pd_cap, f, f - BASE_OFFSET - pv_offset, IT_ASID, false);
|
||||
frame_cap = create_mapped_it_frame_cap(pd_cap, f, f - BASE_OFFSET - pv_offset, IT_ASID, false, true);
|
||||
} else {
|
||||
frame_cap = create_unmapped_it_frame_cap(f, false);
|
||||
}
|
||||
|
|
@ -427,6 +427,10 @@ create_initial_thread(
|
|||
cap = cap_thread_cap_new(TCB_REF(tcb));
|
||||
write_slot(SLOT_PTR(pptr_of_cap(root_cnode_cap), BI_CAP_IT_TCB), cap);
|
||||
|
||||
#ifdef DEBUG
|
||||
setThreadName(tcb, "rootserver");
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ handleDoubleFault(tcb_t *tptr, fault_t ex1)
|
|||
print_fault(ex2);
|
||||
printf("\nwhile trying to handle:\n");
|
||||
print_fault(ex1);
|
||||
printf("\nin thread 0x%x ", (unsigned int)tptr);
|
||||
printf("\nin thread 0x%x \"%s\" ", (unsigned int)tptr, tptr->tcbName);
|
||||
printf("at address 0x%x\n", (unsigned int)getRestartPC(tptr));
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include <kernel/vspace.h>
|
||||
#include <machine.h>
|
||||
#include <util.h>
|
||||
#include <string.h>
|
||||
|
||||
word_t getObjectSize(word_t t, word_t userObjSize)
|
||||
{
|
||||
|
|
@ -513,6 +514,12 @@ createObject(object_t t, void *regionBase, word_t userSize)
|
|||
tcb->tcbTimeSlice = CONFIG_TIME_SLICE;
|
||||
tcb->tcbDomain = ksCurDomain;
|
||||
|
||||
#ifdef DEBUG
|
||||
strlcpy(tcb->tcbName, "child of: '", TCB_NAME_LENGTH);
|
||||
strlcat(tcb->tcbName, ksCurThread->tcbName, TCB_NAME_LENGTH);
|
||||
strlcat(tcb->tcbName, "'", TCB_NAME_LENGTH);
|
||||
#endif
|
||||
|
||||
return cap_thread_cap_new(TCB_REF(tcb));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include <kernel/vspace.h>
|
||||
#include <model/statedata.h>
|
||||
#include <util.h>
|
||||
#include <string.h>
|
||||
|
||||
static inline PURE
|
||||
unsigned int
|
||||
|
|
@ -989,3 +990,11 @@ invokeTCB_WriteRegisters(tcb_t *dest, bool_t resumeTarget,
|
|||
|
||||
return EXCEPTION_NONE;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
setThreadName(tcb_t *tcb, const char *name)
|
||||
{
|
||||
strlcpy(tcb->tcbName, name, TCB_NAME_LENGTH);
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ map_kernel_devices(void)
|
|||
TIMER0_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
@ -95,7 +95,7 @@ map_kernel_devices(void)
|
|||
GIC_CONTROLLER_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
@ -105,7 +105,7 @@ map_kernel_devices(void)
|
|||
GIC_DISTRIBUTOR_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
@ -118,7 +118,7 @@ map_kernel_devices(void)
|
|||
UART0_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
|
|||
|
|
@ -42,16 +42,15 @@ BOOT_CODE p_region_t get_avail_p_reg(unsigned int i)
|
|||
|
||||
const p_region_t BOOT_RODATA dev_p_regs[] = {
|
||||
/* SoC devices: */
|
||||
#ifndef DEBUG
|
||||
{ /* .start = */ UART0_PADDR, /* .end = */ UART0_PADDR + (1 << PAGE_BITS) },
|
||||
#endif
|
||||
{ /* .start = */ UART0_PADDR, /* .end = */ UART0_PADDR + (1 << PAGE_BITS) },
|
||||
{ /* .start = */ DMTIMER2_PADDR, /* .end = */ DMTIMER2_PADDR + (1 << PAGE_BITS) },
|
||||
{ /* .start = */ DMTIMER3_PADDR, /* .end = */ DMTIMER3_PADDR + (1 << PAGE_BITS) },
|
||||
{ /* .start = */ DMTIMER4_PADDR, /* .end = */ DMTIMER4_PADDR + (1 << PAGE_BITS) },
|
||||
{ /* .start = */ DMTIMER5_PADDR, /* .end = */ DMTIMER5_PADDR + (1 << PAGE_BITS) },
|
||||
{ /* .start = */ DMTIMER6_PADDR, /* .end = */ DMTIMER6_PADDR + (1 << PAGE_BITS) },
|
||||
{ /* .start = */ DMTIMER7_PADDR, /* .end = */ DMTIMER7_PADDR + (1 << PAGE_BITS) },
|
||||
{ /* .start = */ WDT1_PADDR, /* .end = */ WDT1_PADDR + (1 << PAGE_BITS) },
|
||||
{ /* .start = */ WDT1_PADDR, /* .end = */ WDT1_PADDR + (1 << PAGE_BITS) },
|
||||
{ /* .start = */ CMPER_PADDR, /* .end = */ CMPER_PADDR + (1 << PAGE_BITS) },
|
||||
/* Board devices. */
|
||||
/* TODO: This should ultimately be replaced with a more general solution. */
|
||||
};
|
||||
|
|
@ -76,7 +75,7 @@ map_kernel_devices(void)
|
|||
DMTIMER0_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
@ -88,7 +87,7 @@ map_kernel_devices(void)
|
|||
INTC_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
@ -100,7 +99,19 @@ map_kernel_devices(void)
|
|||
WDT1_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
);
|
||||
|
||||
/* map kernel device: CMPER */
|
||||
map_kernel_frame(
|
||||
CMPER_PADDR,
|
||||
CMPER_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
@ -113,7 +124,7 @@ map_kernel_devices(void)
|
|||
UART0_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
@ -121,6 +132,13 @@ map_kernel_devices(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
#define CMPER_REG(base, off) ((volatile uint32_t *)((base) + (off)))
|
||||
#define CMPER_TIMER3_CLKCTRL 0x84
|
||||
#define CMPER_CLKCTRL_DISABLE 0
|
||||
#define CMPER_CLKCTRL_ENABLE 2
|
||||
#define CMPER_CLKSEL_TIMER3 0x50c
|
||||
#define CMPER_CKLSEL_MOSC 1
|
||||
|
||||
|
||||
#define INTCPS_SYSCONFIG_SOFTRESET BIT(1)
|
||||
#define INTCPS_SYSSTATUS_RESETDONE BIT(0)
|
||||
|
|
@ -297,6 +315,29 @@ disableWatchdog(void)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable DMTIMER clocks, otherwise their registers wont be accessible.
|
||||
* This could be moved out of kernel.
|
||||
*/
|
||||
static BOOT_CODE void
|
||||
enableTimers(void)
|
||||
{
|
||||
uint32_t cmper = CMPER_PPTR;
|
||||
|
||||
/* XXX repeat this for DMTIMER4..7 */
|
||||
/* select clock */
|
||||
*CMPER_REG(cmper, CMPER_CLKSEL_TIMER3) = CMPER_CKLSEL_MOSC;
|
||||
while ((*CMPER_REG(cmper, CMPER_CLKSEL_TIMER3) & 3) != CMPER_CKLSEL_MOSC) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* enable clock */
|
||||
*CMPER_REG(cmper, CMPER_TIMER3_CLKCTRL) = CMPER_CLKCTRL_ENABLE;
|
||||
while ((*CMPER_REG(cmper, CMPER_TIMER3_CLKCTRL) & 3) != CMPER_CLKCTRL_ENABLE) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Configure dmtimer0 as kernel preemption timer */
|
||||
/**
|
||||
DONT_TRANSLATE
|
||||
|
|
@ -307,6 +348,7 @@ initTimer(void)
|
|||
int timeout;
|
||||
|
||||
disableWatchdog();
|
||||
enableTimers();
|
||||
|
||||
timer->cfg = TIOCP_CFG_SOFTRESET;
|
||||
|
||||
|
|
|
|||
|
|
@ -319,7 +319,7 @@ map_kernel_devices(void)
|
|||
TIMER_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
@ -330,7 +330,7 @@ map_kernel_devices(void)
|
|||
GIC_CONTROLLER_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
@ -340,7 +340,7 @@ map_kernel_devices(void)
|
|||
GIC_DISTRIBUTOR_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
@ -353,7 +353,7 @@ map_kernel_devices(void)
|
|||
UART_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
|
|||
|
|
@ -235,7 +235,7 @@ map_kernel_devices(void)
|
|||
MCT_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
@ -247,7 +247,7 @@ map_kernel_devices(void)
|
|||
GIC_CONTROLLER_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
@ -257,7 +257,7 @@ map_kernel_devices(void)
|
|||
GIC_DISTRIBUTOR_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
@ -269,7 +269,7 @@ map_kernel_devices(void)
|
|||
L2CC_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
@ -282,7 +282,7 @@ map_kernel_devices(void)
|
|||
UART_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
|
|||
|
|
@ -318,7 +318,7 @@ map_kernel_devices(void)
|
|||
MCT_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
@ -330,7 +330,7 @@ map_kernel_devices(void)
|
|||
GIC_CONTROLLER_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
@ -340,7 +340,7 @@ map_kernel_devices(void)
|
|||
GIC_DISTRIBUTOR_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
@ -364,7 +364,7 @@ map_kernel_devices(void)
|
|||
UART_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ map_kernel_devices(void)
|
|||
EPIT_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
@ -240,7 +240,7 @@ map_kernel_devices(void)
|
|||
AVIC_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
@ -252,7 +252,7 @@ map_kernel_devices(void)
|
|||
L2CC_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
@ -265,7 +265,7 @@ map_kernel_devices(void)
|
|||
UART_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
|
|||
|
|
@ -205,7 +205,7 @@ map_kernel_devices(void)
|
|||
ARM_MP_PPTR1,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
@ -217,7 +217,7 @@ map_kernel_devices(void)
|
|||
ARM_MP_PPTR2,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
@ -229,7 +229,7 @@ map_kernel_devices(void)
|
|||
L2CC_PL310_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
@ -243,7 +243,7 @@ map_kernel_devices(void)
|
|||
UART_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ map_kernel_devices(void)
|
|||
GPTIMER11_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
@ -190,7 +190,7 @@ map_kernel_devices(void)
|
|||
INTC_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
@ -203,7 +203,7 @@ map_kernel_devices(void)
|
|||
UART3_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ map_kernel_devices(void)
|
|||
ARM_MP_PPTR1,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
@ -149,7 +149,7 @@ map_kernel_devices(void)
|
|||
ARM_MP_PPTR2,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
@ -161,7 +161,7 @@ map_kernel_devices(void)
|
|||
L2CC_PL310_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
@ -175,7 +175,7 @@ map_kernel_devices(void)
|
|||
UART_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
true, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
|
|
|
|||
49
src/string.c
Normal file
49
src/string.c
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright 2014, General Dynamics C4 Systems
|
||||
*
|
||||
* This software may be distributed and modified according to the terms of
|
||||
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
|
||||
* See "LICENSE_GPLv2.txt" for details.
|
||||
*
|
||||
* @TAG(GD_GPL)
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
unsigned int strnlen(const char *s, unsigned int maxlen)
|
||||
{
|
||||
unsigned int len;
|
||||
for (len = 0; len < maxlen && s[len]; len++);
|
||||
return len;
|
||||
}
|
||||
|
||||
unsigned int strlcpy(char *dest, const char *src, unsigned int size)
|
||||
{
|
||||
unsigned int len;
|
||||
for (len = 0; len + 1 < size && src[len]; len++) {
|
||||
dest[len] = src[len];
|
||||
}
|
||||
dest[len] = '\0';
|
||||
return len;
|
||||
}
|
||||
|
||||
unsigned int strlcat(char *dest, const char *src, unsigned int size)
|
||||
{
|
||||
unsigned int len;
|
||||
/* get to the end of dest */
|
||||
for (len = 0; len < size && dest[len]; len++);
|
||||
/* check that dest was at least 'size' length to prevent inserting
|
||||
* a null byte when we shouldn't */
|
||||
if (len < size) {
|
||||
for (; len + 1 < size && *src; len++, src++) {
|
||||
dest[len] = *src;
|
||||
}
|
||||
dest[len] = '\0';
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
#endif
|
||||
Loading…
Reference in a new issue