mirror of
https://github.com/drasko/codezero.git
synced 2026-10-25 19:27:28 +01:00
Changes since April
Clean up of build directories. Simplifications to capability model.
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Generic cache api calls
|
||||
*
|
||||
* Copyright (C) 2010 B Labs Ltd.
|
||||
*
|
||||
* Author: Bahadir Balban
|
||||
*/
|
||||
#ifndef __GLUE_CACHE_H__
|
||||
#define __GLUE_CACHE_H__
|
||||
|
||||
//#include INC_SUBARCH(mmu_ops.h)
|
||||
|
||||
/* Lowest byte is reserved for and used by capability permissions */
|
||||
#define ARCH_INVALIDATE_ICACHE 0x10
|
||||
#define ARCH_INVALIDATE_DCACHE 0x20
|
||||
#define ARCH_CLEAN_DCACHE 0x30
|
||||
#define ARCH_CLEAN_INVALIDATE_DCACHE 0x40
|
||||
#define ARCH_INVALIDATE_TLB 0x50
|
||||
|
||||
void arch_invalidate_dcache(unsigned long start, unsigned long end);
|
||||
void arch_clean_invalidate_dcache(unsigned long start, unsigned long end);
|
||||
void arch_invalidate_icache(unsigned long start, unsigned long end);
|
||||
void arch_invalidate_tlb(unsigned long start, unsigned long end);
|
||||
void arch_clean_dcache(unsigned long start, unsigned long end);
|
||||
|
||||
#endif /* __GLUE_CACHE_H__ */
|
||||
@@ -0,0 +1,53 @@
|
||||
#ifndef __ARM_CONTEXT_H__
|
||||
#define __ARM_CONTEXT_H__
|
||||
|
||||
#include <l4lib/types.h>
|
||||
|
||||
/*
|
||||
* This describes the register context of each task. Simply set
|
||||
* them and they'll be copied onto real registers upon a context
|
||||
* switch to that task. exchange_registers() system call is
|
||||
* designed for this, whose input structure is defined further
|
||||
* below.
|
||||
*/
|
||||
typedef struct arm_context {
|
||||
u32 spsr; /* 0x0 */
|
||||
u32 r0; /* 0x4 */
|
||||
u32 r1; /* 0x8 */
|
||||
u32 r2; /* 0xC */
|
||||
u32 r3; /* 0x10 */
|
||||
u32 r4; /* 0x14 */
|
||||
u32 r5; /* 0x18 */
|
||||
u32 r6; /* 0x1C */
|
||||
u32 r7; /* 0x20 */
|
||||
u32 r8; /* 0x24 */
|
||||
u32 r9; /* 0x28 */
|
||||
u32 r10; /* 0x2C */
|
||||
u32 r11; /* 0x30 */
|
||||
u32 r12; /* 0x34 */
|
||||
u32 sp; /* 0x38 */
|
||||
u32 lr; /* 0x3C */
|
||||
u32 pc; /* 0x40 */
|
||||
} __attribute__((__packed__)) task_context_t;
|
||||
|
||||
|
||||
typedef struct arm_exregs_context {
|
||||
u32 r0; /* 0x4 */
|
||||
u32 r1; /* 0x8 */
|
||||
u32 r2; /* 0xC */
|
||||
u32 r3; /* 0x10 */
|
||||
u32 r4; /* 0x14 */
|
||||
u32 r5; /* 0x18 */
|
||||
u32 r6; /* 0x1C */
|
||||
u32 r7; /* 0x20 */
|
||||
u32 r8; /* 0x24 */
|
||||
u32 r9; /* 0x28 */
|
||||
u32 r10; /* 0x2C */
|
||||
u32 r11; /* 0x30 */
|
||||
u32 r12; /* 0x34 */
|
||||
u32 sp; /* 0x38 */
|
||||
u32 lr; /* 0x3C */
|
||||
u32 pc; /* 0x40 */
|
||||
} __attribute__((__packed__)) exregs_context_t;
|
||||
|
||||
#endif /* __ARM_CONTEXT_H__ */
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Virtual memory layout of ARM systems.
|
||||
*/
|
||||
|
||||
#ifndef __MEMLAYOUT_H__
|
||||
#define __MEMLAYOUT_H__
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#include L4LIB_INC_GLUE(memory.h)
|
||||
#endif
|
||||
|
||||
#define KERNEL_AREA_START 0xF0000000
|
||||
#define KERNEL_AREA_END 0xF8000000 /* 128 MB */
|
||||
#define KERNEL_AREA_SIZE (KERNEL_AREA_END - KERNEL_AREA_START)
|
||||
#define KERNEL_AREA_SECTIONS (KERNEL_AREA_SIZE / ARM_SECTION_SIZE)
|
||||
|
||||
#define UTCB_SIZE (sizeof(int) * 64)
|
||||
|
||||
#define IO_AREA_START 0xF9000000
|
||||
#define IO_AREA_END 0xFF000000
|
||||
#define IO_AREA_SIZE (IO_AREA_END - IO_AREA_START)
|
||||
#define IO_AREA_SECTIONS (IO_AREA_SIZE / ARM_SECTION_SIZE)
|
||||
|
||||
#define USER_KIP_PAGE 0xFF000000
|
||||
|
||||
/* ARM-specific offset in KIP that tells the address of UTCB page */
|
||||
#define UTCB_KIP_OFFSET 0x50
|
||||
|
||||
#define IO_AREA0_VADDR IO_AREA_START
|
||||
#define IO_AREA1_VADDR (IO_AREA_START + (SZ_1MB*1))
|
||||
#define IO_AREA2_VADDR (IO_AREA_START + (SZ_1MB*2))
|
||||
#define IO_AREA3_VADDR (IO_AREA_START + (SZ_1MB*3))
|
||||
#define IO_AREA4_VADDR (IO_AREA_START + (SZ_1MB*4))
|
||||
#define IO_AREA5_VADDR (IO_AREA_START + (SZ_1MB*5))
|
||||
#define IO_AREA6_VADDR (IO_AREA_START + (SZ_1MB*6))
|
||||
#define IO_AREA7_VADDR (IO_AREA_START + (SZ_1MB*7))
|
||||
|
||||
/*
|
||||
* IO_AREA8_VADDR
|
||||
* The beginning page in this slot is used for userspace uart mapping
|
||||
*/
|
||||
|
||||
#define ARM_HIGH_VECTOR 0xFFFF0000
|
||||
#define ARM_SYSCALL_VECTOR 0xFFFFFF00
|
||||
|
||||
#if !defined(__LINUX_CONTAINER__)
|
||||
#define KERNEL_OFFSET (KERNEL_AREA_START - PLATFORM_PHYS_MEM_START)
|
||||
#endif
|
||||
|
||||
/* User tasks define them differently */
|
||||
#if defined (__KERNEL__) && !defined(__LINUX_CONTAINER__)
|
||||
#define phys_to_virt(addr) ((unsigned int)(addr) + KERNEL_OFFSET)
|
||||
#define virt_to_phys(addr) ((unsigned int)(addr) - KERNEL_OFFSET)
|
||||
#endif
|
||||
|
||||
#define KERN_ADDR(x) ((x >= KERNEL_AREA_START) && (x < KERNEL_AREA_END))
|
||||
#define UTCB_ADDR(x) ((x >= UTCB_AREA_START) && (x < UTCB_AREA_END))
|
||||
#define is_kernel_address(x) (KERN_ADDR(x) || (x >= ARM_HIGH_VECTOR) || \
|
||||
(x >= IO_AREA_START && x < IO_AREA_END))
|
||||
|
||||
#endif /* __MEMLAYOUT_H__ */
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Includes memory-related architecture specific definitions and their
|
||||
* corresponding generic wrappers.
|
||||
*
|
||||
* Copyright (C) 2007 Bahadir Balban
|
||||
*/
|
||||
#ifndef __GLUE_ARM_MEMORY_H__
|
||||
#define __GLUE_ARM_MEMORY_H__
|
||||
|
||||
#include L4LIB_INC_GLUE(memlayout.h) /* Important generic definitions */
|
||||
#include L4LIB_INC_SUBARCH(mm.h)
|
||||
|
||||
/* Generic definitions */
|
||||
#define PFN_SHIFT 12
|
||||
#define PAGE_BITS PFN_SHIFT
|
||||
#if !defined(__LINUX_CONTAINER__)
|
||||
#define PAGE_SIZE SZ_4K
|
||||
#define PAGE_MASK (PAGE_SIZE - 1)
|
||||
#endif
|
||||
|
||||
/* Aligns to the upper page (ceiling) FIXME: Must add a wraparound checker. */
|
||||
#define page_align_up(addr) ((((unsigned long)(addr)) + PAGE_MASK) & \
|
||||
(~PAGE_MASK))
|
||||
|
||||
/* Aligns to the lower page (floor) */
|
||||
#define page_align(addr) (((unsigned long)(addr)) & \
|
||||
(~PAGE_MASK))
|
||||
|
||||
#define is_aligned(val, size) (!(((unsigned long)(val)) & (((unsigned long)size) - 1)))
|
||||
#define is_page_aligned(val) (!(((unsigned long)(val)) & PAGE_MASK))
|
||||
#define page_boundary(x) is_page_aligned(x)
|
||||
|
||||
/*
|
||||
* Align to given size.
|
||||
*
|
||||
* Note it must be an alignable size i.e. one that is a power of two.
|
||||
* E.g. 0x1000 would work but 0x1010 would not.
|
||||
*/
|
||||
#define align(addr, size) (((unsigned int)(addr)) & (~((unsigned long)size-1)))
|
||||
#define align_up(addr, size) ((((unsigned long)(addr)) + \
|
||||
((size) - 1)) & (~(((unsigned long)size) - 1)))
|
||||
|
||||
/* The bytes left until the end of the page that x is in */
|
||||
#define TILL_PAGE_ENDS(x) (PAGE_SIZE - ((unsigned long)(x) & PAGE_MASK))
|
||||
|
||||
/* Extract page frame number from address and vice versa. */
|
||||
#define __pfn(x) (((unsigned long)(x)) >> PAGE_BITS)
|
||||
#define __pfn_to_addr(x) (((unsigned long)(x)) << PAGE_BITS)
|
||||
|
||||
/* Extract physical address from page table entry (pte) */
|
||||
#define __pte_to_addr(x) (((unsigned long)(x)) & ~PAGE_MASK)
|
||||
|
||||
/* Minimum excess needed for word alignment */
|
||||
#define SZ_WORD sizeof(unsigned int)
|
||||
#define WORD_BITS 32
|
||||
#define WORD_BITS_LOG2 5
|
||||
#define BITWISE_GETWORD(x) ((x) >> WORD_BITS_LOG2) /* Divide by 32 */
|
||||
#define BITWISE_GETBIT(x) (1 << ((x) % WORD_BITS))
|
||||
|
||||
/* Minimum stack alignment restriction across functions, exceptions */
|
||||
#define STACK_ALIGNMENT 8
|
||||
|
||||
#if !defined(__LINUX_CONTAINER__)
|
||||
/* Endianness conversion */
|
||||
static inline void be32_to_cpu(unsigned int x)
|
||||
{
|
||||
char *p = (char *)&x;
|
||||
char tmp;
|
||||
|
||||
/* Swap bytes */
|
||||
tmp = p[0];
|
||||
p[0] = p[3];
|
||||
p[3] = tmp;
|
||||
|
||||
tmp = p[1];
|
||||
p[1] = p[2];
|
||||
p[2] = tmp;
|
||||
}
|
||||
|
||||
struct ktcb;
|
||||
void task_init_registers(struct ktcb *task, unsigned long pc);
|
||||
#endif /* !_LINUX_CONTAINER__ */
|
||||
|
||||
#endif /* __GLUE_ARM_MEMORY_H__ */
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Userspace thread control block
|
||||
*
|
||||
* Copyright (C) 2007-2009 Bahadir Bilgehan Balban
|
||||
*/
|
||||
#ifndef __GLUE_ARM_MESSAGE_H__
|
||||
#define __GLUE_ARM_MESSAGE_H__
|
||||
|
||||
/*
|
||||
* Here's a summary of how ARM registers are used during IPC:
|
||||
*
|
||||
* System registers:
|
||||
* r0 - r2: Passed as arguments to ipc() call. They are the registers
|
||||
* the microkernel will read and they have system-wide meaning.
|
||||
*
|
||||
* Primary message registers:
|
||||
* r3 - r8: These 6 registers are the primary message registers MR0-MR6.
|
||||
* Their format is application-specific, i.e. the microkernel imposes no
|
||||
* format restrictions on them.
|
||||
*
|
||||
* TODO: The only exception is that, for ANYTHREAD receivers the predefined
|
||||
* MR_SENDER is touched by the kernel to indicate the sender. This register
|
||||
* is among the primary MRs and it may be better fit to put it into one of
|
||||
* the system registers.
|
||||
*
|
||||
* l4lib registers: (MR_TAG, MR_SENDER, MR_RETURN)
|
||||
* Some of the primary message registers are used by the l4lib convenience
|
||||
* library for operations necessary on most or all common ipcs. For example
|
||||
* every ipc has a tag that specifies the ipc reason. Also send/receive
|
||||
* operations require a return value. Threads that are open to receive from
|
||||
* all threads require the sender id. These values are passed in predefined
|
||||
* primary message registers, but the microkernel has no knowledge about them.
|
||||
*
|
||||
* System call registers: L4SYS_ARG0 to ARG4.(See syslib.h for definitions)
|
||||
* Finally the rest of the primary message registers are available for
|
||||
* implementing system call arguments. For example the POSIX services use
|
||||
* these arguments to pass posix system call information.
|
||||
*
|
||||
* Secondary Message Registers:
|
||||
* These are non-real registers and are present in the UTCB memory region.
|
||||
* Both real and non-real message registers have a location in the UTCB, but
|
||||
* non-real ones are copied only if the FULL IPC flag is set.
|
||||
*
|
||||
* The big picture:
|
||||
*
|
||||
* r0 System register
|
||||
* r1 System register
|
||||
* r2 System register
|
||||
* r3 Primary MR0 MR_RETURN, MR_TAG Present in UTCB, Short IPC
|
||||
* r4 Primary MR1 MR_SENDER Present in UTCB, Short IPC
|
||||
* r5 Primary MR2 L4SYS_ARG0 Present in UTCB, Short IPC
|
||||
* r6 Primary MR3 L4SYS_ARG1 Present in UTCB, Short IPC
|
||||
* r7 Primary MR4 L4SYS_ARG2 Present in UTCB, Short IPC
|
||||
* r8 Primary MR5 L4SYS_ARG3 Present in UTCB, Short IPC
|
||||
* x Secondary MR6 Present in UTCB, Full IPC only
|
||||
* x Secondary MR64 Present in UTCB, Full IPC only
|
||||
*
|
||||
* Complicated for you? Suggest a simpler design and it shall be implemented!
|
||||
*/
|
||||
|
||||
#define MR_REST ((UTCB_SIZE >> 2) - MR_TOTAL - 4) /* -4 is for fields on utcb */
|
||||
#define MR_TOTAL 6
|
||||
#define MR_TAG 0 /* Contains the purpose of message */
|
||||
#define MR_SENDER 1 /* For anythread receivers to discover sender */
|
||||
#define MR_RETURN 0 /* Contains the posix return value. */
|
||||
|
||||
/* These define the mr start - end range that isn't used by userspace syslib */
|
||||
#define MR_UNUSED_START 2 /* The first mr that's not used by syslib.h */
|
||||
#define MR_UNUSED_TOTAL (MR_TOTAL - MR_UNUSED_START)
|
||||
#define MR_USABLE_TOTAL MR_UNUSED_TOTAL
|
||||
|
||||
/* These are defined so that we don't hard-code register names */
|
||||
#define MR0_REGISTER r3
|
||||
#define MR_RETURN_REGISTER r3
|
||||
|
||||
#define TASK_NOTIFY_SLOTS 8
|
||||
#define TASK_NOTIFY_MAXVALUE 255
|
||||
|
||||
/* Primaries aren't used for memcopy. Those ops use this as a parameter */
|
||||
#define L4_UTCB_FULL_BUFFER_SIZE (MR_REST * sizeof(int))
|
||||
|
||||
#include L4LIB_INC_GLUE(memlayout.h)
|
||||
|
||||
#if !defined (__ASSEMBLY__)
|
||||
struct utcb {
|
||||
u32 mr[MR_TOTAL]; /* MRs that are mapped to real registers */
|
||||
u32 saved_tag; /* Saved tag field for stacked ipcs */
|
||||
u32 saved_sender; /* Saved sender field for stacked ipcs */
|
||||
u8 notify[TASK_NOTIFY_SLOTS]; /* Irq notification slots */
|
||||
u32 mr_rest[MR_REST]; /* Complete the utcb for up to 64 words */
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __GLUE_ARM_MESSAGE_H__ */
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* ARM-specific system call details.
|
||||
*
|
||||
* Copyright (C) 2007 Bahadir Balban
|
||||
*/
|
||||
|
||||
#ifndef __ARM_GLUE_SYSCALL_H__
|
||||
#define __ARM_GLUE_SYSCALL_H__
|
||||
|
||||
#include <l4lib/types.h>
|
||||
#include L4LIB_INC_GLUE(message.h)
|
||||
|
||||
/* Only specific call is the trap that gives back the kip address
|
||||
* from which other system calls can be discovered. */
|
||||
#define L4_TRAP_KIP 0xB4
|
||||
|
||||
/* Used in the kernel to refer to virtual address of this page.
|
||||
* User space discovers it from the KIP */
|
||||
#define ARM_SYSCALL_PAGE 0xFFFFF000
|
||||
|
||||
extern unsigned int __syscall_page_start;
|
||||
|
||||
/*
|
||||
* This structure is saved on the kernel stack
|
||||
* just after entering a system call exception.
|
||||
*/
|
||||
typedef struct syscall_context {
|
||||
u32 spsr;
|
||||
u32 r0;
|
||||
u32 r1;
|
||||
u32 r2;
|
||||
u32 r3; /* MR0 */
|
||||
u32 r4; /* MR1 */
|
||||
u32 r5; /* MR2 */
|
||||
u32 r6; /* MR3 */
|
||||
u32 r7; /* MR4 */
|
||||
u32 r8; /* MR5 */
|
||||
u32 r9;
|
||||
u32 r10;
|
||||
u32 r11;
|
||||
u32 r12;
|
||||
u32 sp_usr;
|
||||
u32 lr_usr;
|
||||
} __attribute__((__packed__)) syscall_context_t;
|
||||
|
||||
typedef struct msg_regs {
|
||||
u32 mr0;
|
||||
u32 mr1;
|
||||
u32 mr2;
|
||||
u32 mr3;
|
||||
u32 mr4;
|
||||
u32 mr5;
|
||||
} msg_regs_t;
|
||||
|
||||
/* NOTE:
|
||||
* These references are valid only when they have been explicitly set
|
||||
* by a kernel entry point, e.g. a system call, a data abort handler
|
||||
* that imitates a page fault ipc etc.
|
||||
*
|
||||
* Second note:
|
||||
* _If_ these refer to real utcb's in the future, make sure to have
|
||||
* utcb_map_lazily() check so that they're safe accesses.
|
||||
*/
|
||||
#define KTCB_REF_ARG0(ktcb) (&(ktcb)->syscall_regs->r0)
|
||||
#define KTCB_REF_MR0(ktcb) (&(ktcb)->syscall_regs->MR0_REGISTER)
|
||||
|
||||
/* Represents each syscall. We get argument registers
|
||||
* from stack for now. This is slower but the simplest. */
|
||||
typedef int (*syscall_fn_t)(struct syscall_context *regs);
|
||||
|
||||
/* Entry point for syscall dispatching. Called from asm */
|
||||
int syscall(struct syscall_context *regs, unsigned long);
|
||||
|
||||
/* Syscall-related initialiser called during system init. */
|
||||
void syscall_init(void);
|
||||
void kip_init_syscalls(void);
|
||||
|
||||
#endif /* __ARM_GLUE_SYSCALL_H__ */
|
||||
Reference in New Issue
Block a user