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:
Adrian Danis 2015-07-21 09:40:06 +10:00
commit 91c474cb95
54 changed files with 684 additions and 307 deletions

40
CONTRIBUTING.md Normal file
View 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.

View file

@ -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

View file

@ -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"

View file

@ -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} )

View file

@ -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"/>

View file

@ -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"); \

View file

@ -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,

View file

@ -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);

View file

@ -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

View file

@ -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;

View file

@ -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,

View file

@ -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);

View file

@ -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

View file

@ -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.

View file

@ -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

View file

@ -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
View 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
View 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 */

View file

@ -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

View file

@ -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

View file

@ -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
View 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

View file

@ -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

View file

@ -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__

View file

@ -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">

View file

@ -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)

View file

@ -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"/>

View file

@ -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)

View file

@ -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"/>

View file

@ -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;

View file

@ -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>

View file

@ -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 */")

View file

@ -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

View file

@ -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

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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));
}

View file

@ -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

View file

@ -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 */
)

View file

@ -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;

View file

@ -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 */
)

View file

@ -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 */
)

View file

@ -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 */
)

View file

@ -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 */
)

View file

@ -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 */
)

View file

@ -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 */
)

View file

@ -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
View 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