ARM support for system libraries

This commit is contained in:
Arun Thomas 2012-08-28 13:34:08 -04:00
parent 9a9d555f56
commit fd43d93ce5
33 changed files with 1066 additions and 101 deletions

View file

@ -0,0 +1,19 @@
# $NetBSD: Makefile,v 1.36 2007/12/20 23:46:12 ad Exp $
.include <bsd.own.mk>
INCSDIR= /usr/include/arm
INCS= ansi.h asm.h bswap.h byte_swap.h cdefs.h \
endian.h endian_machdep.h float.h ieee.h \
ieeefp.h int_const.h int_fmtio.h int_limits.h \
int_mwgwtypes.h int_types.h limits.h lock.h \
math.h mcontext.h param.h profile.h \
setjmp.h signal.h stdarg.h types.h \
vmparam.h wchar_limits.h \
archconst.h archtypes.h cpu.h diskparm.h \
interrupt.h memory.h multiboot.h partition.h \
stackframe.h vm.h elf.h elf_machdep.h mutex.h \
disklabel.h ipcconst.h
.include <bsd.kinc.mk>

View file

@ -31,6 +31,8 @@
* from: @(#)ansi.h 8.2 (Berkeley) 1/4/94
*/
/* These types are Minix specific. */
#ifndef _ANSI_H_
#define _ANSI_H_
@ -47,11 +49,11 @@
* #undef _BSD_SIZE_T_
* #endif
*/
#define _BSD_CLOCK_T_ unsigned int /* clock() */
#define _BSD_PTRDIFF_T_ long int /* ptr1 - ptr2 */
#define _BSD_SIZE_T_ unsigned long int /* sizeof() */
#define _BSD_SSIZE_T_ long int /* byte count or error */
#define _BSD_TIME_T_ __int64_t /* time() */
#define _BSD_CLOCK_T_ long /* clock() */
#define _BSD_PTRDIFF_T_ int /* ptr1 - ptr2 */
#define _BSD_SIZE_T_ unsigned int /* sizeof() */
#define _BSD_SSIZE_T_ int /* byte count or error */
#define _BSD_TIME_T_ long /* time() */
#if __GNUC_PREREQ__(2, 96)
#define _BSD_VA_LIST_ __builtin_va_list /* GCC built-in type */
#else
@ -59,8 +61,8 @@
#endif
#define _BSD_CLOCKID_T_ int /* clockid_t */
#define _BSD_TIMER_T_ int /* timer_t */
#define _BSD_SUSECONDS_T_ int /* suseconds_t */
#define _BSD_USECONDS_T_ unsigned int /* useconds_t */
#define _BSD_SUSECONDS_T_ long /* suseconds_t */
#define _BSD_USECONDS_T_ long /* useconds_t */
#define _BSD_WCHAR_T_ int /* wchar_t */
#define _BSD_WINT_T_ int /* wint_t */

View file

@ -0,0 +1,6 @@
#ifndef _ARM_CONST_H
#define _ARM_CONST_H
#define DEFAULT_HZ 1000
#endif /* #ifndef _ARM_CONST_H */

View file

@ -0,0 +1,26 @@
#ifndef _ARM_TYPES_H
#define _ARM_TYPES_H
#include <minix/sys_config.h>
#include <machine/stackframe.h>
#include <sys/cdefs.h>
typedef struct segframe {
reg_t p_ttbr; /* page table root */
u32_t *p_ttbr_v;
char *fpu_state;
} segframe_t;
struct cpu_info {
u32_t arch;
u32_t implementer;
u32_t part;
u32_t variant;
u32_t revision;
};
typedef u32_t atomic_t; /* access to an aligned 32bit value is atomic on ARM */
#endif /* #ifndef _ARM_TYPES_H */

View file

@ -0,0 +1,55 @@
#ifndef _ARM_CPU_H_
#define _ARM_CPU_H_
/* xPSR - Program Status Registers */
#define PSR_T (1 << 5) /* Thumb execution state bit */
#define PSR_F (1 << 6) /* FIQ mask bit */
#define PSR_I (1 << 7) /* IRQ mask bit */
#define PSR_A (1 << 8) /* Asynchronous abort mask bit */
#define PSR_E (1 << 9) /* Endianness execution state bit */
#define PSR_J (1 << 24) /* Jazelle bit */
#define PSR_Q (1 << 27) /* Cumulative saturation bit */
#define PSR_V (1 << 28) /* Overflow condition flag */
#define PSR_C (1 << 29) /* Carry condition flag */
#define PSR_Z (1 << 30) /* Zero condition flag */
#define PSR_N (1 << 31) /* Negative condition flag */
#define PSR_MODE_MASK 0x0000001F /* Mode field mask */
#define MODE_USR 0x10 /* User mode */
#define MODE_FIQ 0x11 /* FIQ mode */
#define MODE_IRQ 0x12 /* IRQ mode */
#define MODE_SVC 0x13 /* Supervisor mode */
#define MODE_MON 0x16 /* Monitor mode */
#define MODE_ABT 0x17 /* Abort mode */
#define MODE_HYP 0x1A /* Hyp mode */
#define MODE_UND 0x1B /* Undefined mode */
#define MODE_SYS 0x1F /* System mode */
/* SCTLR - System Control Register */
#define SCTLR_M (1 << 0) /* MMU enable */
#define SCTLR_A (1 << 1) /* Alignment check enable */
#define SCTLR_C (1 << 2) /* Data and Unified Cache enable */
#define SCTLR_CP15BEN (1 << 5) /* CP15 barrier enable */
#define SCTLR_SW (1 << 10) /* SWP and SWPB enable */
#define SCTLR_Z (1 << 11) /* Branch prediction enable */
#define SCTLR_I (1 << 12) /* Instruction cache enable */
#define SCTLR_V (1 << 13) /* (High) Vectors bit */
#define SCTLR_RR (1 << 14) /* Round Robin (cache) select */
#define SCTLR_HA (1 << 17) /* Hardware Access flag enable */
#define SCTLR_FI (1 << 21) /* Fast interrupts configuration enable */
#define SCTLR_VE (1 << 24) /* Interrupt Vectors Enable */
#define SCTLR_EE (1 << 25) /* Exception Endianness */
#define SCTLR_NMFI (1 << 27) /* Non-maskable FIQ (NMFI) support */
#define SCTLR_TRE (1 << 28) /* TEX remap enable */
#define SCTLR_AFE (1 << 29) /* Access flag enable */
#define SCTLR_TE (1 << 30) /* Thumb Exception enable */
/* ACTLR - Auxiliary Control Register */
#define A8_ACTLR_L1ALIAS (1 << 0) /* L1 Dcache hw alias check enable */
#define A8_ACTLR_L2EN (1 << 1) /* L2 cache enable */
#define A8_ACTLR_L1RSTDIS (1 << 30) /* L1 hw reset disable */
#define A8_ACTLR_L2RSTDIS (1 << 31) /* L2 hw reset disable */
#endif /* _ARM_CPU_H_ */

View file

@ -0,0 +1,20 @@
/* PC (and AT) BIOS structure to hold disk parameters. Under Minix, it is
* used mainly for formatting.
*/
#ifndef _DISKPARM_H
#define _DISKPARM_H
struct disk_parameter_s {
char spec1;
char spec2;
char motor_turnoff_sec;
char sector_size_code;
char sectors_per_cylinder;
char gap_length;
char dtl;
char gap_length_for_format;
char fill_byte_for_format;
char head_settle_msec;
char motor_start_eigth_sec;
};
#endif /* _DISKPARM_H */

View file

@ -0,0 +1,8 @@
/* Interrupt numbers and hardware vectors. */
#ifndef _INTERRUPT_H
#define _INTERRUPT_H
#define NR_IRQ_VECTORS 96
#endif /* _INTERRUPT_H */

View file

@ -0,0 +1,9 @@
#ifndef _ARM_IPCCONST_H_
#define _ARM_IPCCONST_H_
#define KERVEC 32 /* syscall trap to kernel */
#define IPCVEC 33 /* ipc trap to kernel */
#define IPC_STATUS_REG r1
#endif /* _ARM_IPCCONST_H_ */

View file

@ -0,0 +1,19 @@
#ifndef _MACHINE_MCONTEXT_H
#define _MACHINE_MCONTEXT_H
#include <machine/stackframe.h>
#define MCF_MAGIC 0xc0ffee
/* Context to describe processor state */
typedef struct __mcontext {
int mc_magic;
struct stackframe_s mc_p_reg;
} mcontext_t;
__BEGIN_DECLS
int setmcontext(const mcontext_t *mcp);
int getmcontext(mcontext_t *mcp);
__END_DECLS
#endif /* _MACHINE_MCONTEXT_H */

View file

@ -0,0 +1,6 @@
/* Physical memory layout */
#ifndef _ARM_MEMORY_H
#define _ARM_MEMORY_H
#endif /* _ARM_MEMORY_H */

View file

@ -0,0 +1,143 @@
#ifndef __MULTIBOOT_H__
#define __MULTIBOOT_H__
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
/* Must pass memory information to OS. */
#define MULTIBOOT_PAGE_ALIGN 0x00000001
#define MULTIBOOT_MEMORY_INFO 0x00000002
#define MULTIBOOT_VIDEO_MODE 0x00000004
#define MULTIBOOT_AOUT_KLUDGE 0x00010000
/* consts used for Multiboot pre-init */
#define MULTIBOOT_VIDEO_MODE_EGA 1
#define MULTIBOOT_VIDEO_BUFFER 0xB8000
/* Usable lower memory chunk has a upper bound */
#define MULTIBOOT_LOWER_MEM_MAX 0x7f800
#define MULTIBOOT_CONSOLE_LINES 25
#define MULTIBOOT_CONSOLE_COLS 80
#define MULTIBOOT_VIDEO_BUFFER_BYTES \
(MULTIBOOT_CONSOLE_LINES*MULTIBOOT_CONSOLE_COLS*2)
#define MULTIBOOT_STACK_SIZE 4096
#define MULTIBOOT_PARAM_BUF_SIZE 1024
#define MULTIBOOT_MAX_MODS 20
/* Flags to be set in the flags member of the multiboot info structure. */
#define MULTIBOOT_INFO_MEMORY 0x00000001
#define MULTIBOOT_INFO_MEM_MAP 0x00000040
/* Is there a boot device set? */
#define MULTIBOOT_INFO_BOOTDEV 0x00000002
/* Is the command-line defined? */
#define MULTIBOOT_INFO_CMDLINE 0x00000004
/* Are there modules to do something with? */
#define MULTIBOOT_INFO_MODS 0x00000008
#define MULTIBOOT_HIGH_MEM_BASE 0x100000
#ifndef __ASSEMBLY__
#include <minix/types.h>
/* The symbol table for a.out. */
struct multiboot_aout_symbol_table
{
u32_t tabsize;
u32_t strsize;
u32_t addr;
u32_t reserved;
};
/* The section header table for ELF. */
struct multiboot_elf_section_header_table
{
u32_t num;
u32_t size;
u32_t addr;
u32_t shndx;
};
typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t;
typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t;
struct multiboot_info
{
/* Multiboot info version number */
u32_t flags;
/* Available memory from BIOS */
u32_t mem_lower_unused; /* minix uses memmap instead */
u32_t mem_upper_unused;
/* "root" partition */
u32_t boot_device;
/* Kernel command line */
u32_t cmdline;
/* Boot-Module list */
u32_t mods_count;
u32_t mods_addr;
union
{
multiboot_aout_symbol_table_t aout_sym;
multiboot_elf_section_header_table_t elf_sec;
} u;
/* Memory Mapping buffer */
u32_t mmap_length;
u32_t mmap_addr;
/* Drive Info buffer */
u32_t drives_length;
u32_t drives_addr;
/* ROM configuration table */
u32_t config_table;
/* Boot Loader Name */
u32_t boot_loader_name;
/* APM table */
u32_t apm_table;
/* Video */
u32_t vbe_control_info;
u32_t vbe_mode_info;
u16_t vbe_mode;
u16_t vbe_interface_seg;
u16_t vbe_interface_off;
u16_t vbe_interface_len;
};
typedef struct multiboot_info multiboot_info_t;
struct multiboot_mod_list
{
/* Memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
u32_t mod_start;
u32_t mod_end;
/* Module command line */
u32_t cmdline;
/* Pad struct to 16 bytes (must be zero) */
u32_t pad;
};
typedef struct multiboot_mod_list multiboot_module_t;
#define MULTIBOOT_MEMORY_AVAILABLE 1
#define MULTIBOOT_MEMORY_RESERVED 2
struct multiboot_mmap_entry
{
u32_t size;
u64_t addr;
u64_t len;
#define MULTIBOOT_MEMORY_AVAILABLE 1
#define MULTIBOOT_MEMORY_RESERVED 2
u32_t type;
} __attribute__((packed));
typedef struct multiboot_mmap_entry multiboot_memory_map_t;
#endif /* __ASSEMBLY__ */
#endif /* __MULTIBOOT_H__ */

View file

@ -0,0 +1,58 @@
#ifndef _ARM_SIGNAL_H_
#define _ARM_SIGNAL_H_
#include <sys/featuretest.h>
typedef int sig_atomic_t;
/* The following structure should match the stackframe_s structure used
* by the kernel's context switching code. Floating point registers should
* be added in a different struct.
*/
#include <machine/stackframe.h>
typedef struct stackframe_s sigregs;
struct sigframe { /* stack frame created for signalled process */
void (*sf_retadr)(void);
int sf_signo;
int sf_code;
struct sigcontext *sf_scp;
int sf_fp;
void (*sf_retadr2)(void);
struct sigcontext *sf_scpcopy;
};
struct sigcontext {
int sc_flags; /* sigstack state to restore (including
* MF_FPU_INITIALIZED)
*/
long sc_mask; /* signal mask to restore */
sigregs sc_regs; /* register set to restore */
};
#define sc_retreg sc_regs.retreg
#define sc_r1 sc_regs.r1
#define sc_r2 sc_regs.r2
#define sc_r3 sc_regs.r3
#define sc_r4 sc_regs.r4
#define sc_r5 sc_regs.r5
#define sc_r6 sc_regs.r6
#define sc_r7 sc_regs.r7
#define sc_r8 sc_regs.r8
#define sc_r9 sc_regs.r9
#define sc_r10 sc_regs.r10
#define sc_fp sc_regs.fp
#define sc_r12 sc_regs.r12
#define sc_sp sc_regs.sp
#define sc_lr sc_regs.lr
#define sc_pc sc_regs.pc
#define sc_psr sc_regs.psr
#ifdef _MINIX
__BEGIN_DECLS
int sigreturn(struct sigcontext *_scp);
__END_DECLS
#endif /* _MINIX */
#endif /* !_ARM_SIGNAL_H_ */

View file

@ -0,0 +1,26 @@
#ifndef _ARM_STACKFRAME_H
#define _ARM_STACKFRAME_H
typedef u32_t reg_t; /* machine register */
struct stackframe_s {
reg_t retreg; /* r0 */
reg_t r1;
reg_t r2;
reg_t r3;
reg_t r4;
reg_t r5;
reg_t r6;
reg_t r7;
reg_t r8;
reg_t r9; /* sb */
reg_t r10; /* sl */
reg_t fp; /* r11 */
reg_t r12; /* ip */
reg_t sp; /* r13 */
reg_t lr; /* r14 */
reg_t pc; /* r15 */
reg_t psr;
};
#endif /* _ARM_STACKFRAME_H */

View file

@ -0,0 +1,132 @@
#ifndef __SYS_VM_ARM_H__
#define __SYS_VM_ARM_H__
/*
arm/vm.h
*/
#define ARM_PAGE_SIZE 4096 /* small page on ARM */
#define ARM_SECTION_SIZE (1024 * 1024) /* 1 MB section */
#define ARM_BIG_PAGE_SIZE (ARM_SECTION_SIZE)
/* Page table specific flags. */
#define ARM_VM_PAGETABLE (1 << 1) /* Page table */
#define ARM_VM_PTE_PRESENT (1 << 1) /* Page is present */
#define ARM_VM_PTE_BUFFERABLE (1 << 2) /* Bufferable */
#define ARM_VM_PTE_CACHEABLE (1 << 3) /* Cacheable */
#define ARM_VM_PTE_SUPER (0x1 << 4) /* Super access only AP[1:0] */
#define ARM_VM_PTE_USER (0x3 << 4) /* Super/User access AP[1:0] */
#define ARM_VM_PTE_RO (1 << 9) /* Read only access AP[2] */
#define ARM_VM_PTE_RW (0 << 9) /* Read-write access AP[2] */
#define ARM_VM_PTE_SHAREABLE (1 << 10) /* Shareable */
#define ARM_VM_PTE_NOTGLOBAL (1 << 11) /* Not Global */
/* inner and outer write-back, write-allocate */
#define ARM_VM_PTE_WB ((0x5 << 6) | ARM_VM_PTE_BUFFERABLE)
/* inner and outer write-through, no write-allocate */
#define ARM_VM_PTE_WT ((0x6 << 6) | ARM_VM_PTE_CACHEABLE)
/* shareable device */
#define ARM_VM_PTE_DEVICE (ARM_VM_PTE_BUFFERABLE)
#define ARM_VM_ADDR_MASK 0xFFFFF000 /* physical address */
#define ARM_VM_ADDR_MASK_1MB 0xFFF00000 /* physical address */
#define ARM_VM_OFFSET_MASK_1MB 0x000FFFFF /* physical address */
/* Big page (1MB section) specific flags. */
#define ARM_VM_SECTION (1 << 1) /* 1MB section */
#define ARM_VM_SECTION_PRESENT (1 << 1) /* Section is present */
#define ARM_VM_SECTION_BUFFERABLE (1 << 2) /* Bufferable */
#define ARM_VM_SECTION_CACHEABLE (1 << 3) /* Cacheable */
#define ARM_VM_SECTION_DOMAIN (0xF << 5) /* Domain Number */
#define ARM_VM_SECTION_SUPER (0x1 << 10) /* Super access only AP[1:0] */
#define ARM_VM_SECTION_USER (0x3 << 10) /* Super/User access AP[1:0] */
#define ARM_VM_SECTION_RO (1 << 15) /* Read only access AP[2] */
#define ARM_VM_SECTION_SHAREABLE (1 << 16) /* Shareable */
#define ARM_VM_SECTION_NOTGLOBAL (1 << 17) /* Not Global */
/* inner and outer write-back, write-allocate */
#define ARM_VM_SECTION_WB ((0x5 << 12) | ARM_VM_SECTION_BUFFERABLE)
/* inner and outer write-through, no write-allocate */
#define ARM_VM_SECTION_WT ((0x6 << 12) | ARM_VM_SECTION_CACHEABLE)
/* shareable device */
#define ARM_VM_SECTION_DEVICE (ARM_VM_SECTION_BUFFERABLE)
#define ARM_VM_BIGPAGE (ARM_VM_SECTION) /* 1MB section */
/* Page directory specific flags. */
#define ARM_VM_PAGEDIR (1 << 0) /* Page directory */
#define ARM_VM_PDE_PRESENT (1 << 0) /* Page directory is present */
#define ARM_VM_PDE_DOMAIN (0xF << 5) /* Domain Number */
#define ARM_VM_PT_ENT_SIZE 4 /* Size of a page table entry */
#define ARM_VM_DIR_ENT_SIZE 4 /* Size of a page dir entry */
#define ARM_VM_DIR_ENTRIES 4096 /* Number of entries in a page dir */
#define ARM_VM_DIR_ENT_SHIFT 20 /* Shift to get entry in page dir. */
#define ARM_VM_PT_ENT_SHIFT 12 /* Shift to get entry in page table */
#define ARM_VM_PT_ENT_MASK 0xFF /* Mask to get entry in page table */
#define ARM_VM_PT_ENTRIES 256 /* Number of entries in a page table */
/* ARM paging 'functions' */
#define ARM_VM_PTE(v) (((v) >> ARM_VM_PT_ENT_SHIFT) & ARM_VM_PT_ENT_MASK)
#define ARM_VM_PDE(v) ( (v) >> ARM_VM_DIR_ENT_SHIFT)
#define ARM_VM_PFA(e) ( (e) & ARM_VM_ADDR_MASK)
#define ARM_VM_PTE_SHIFT 12
#define ARM_VM_PTE_MASK (~((1 << ARM_VM_PTE_SHIFT) - 1))
#define ARM_VM_PDE_SHIFT 10
#define ARM_VM_PDE_MASK (~((1 << ARM_VM_PDE_SHIFT) - 1))
#define ARM_VM_SECTION_SHIFT 20
#define ARM_VM_SECTION_MASK (~((1 << ARM_VM_SECTION_SHIFT) - 1))
#define ARM_VM_DIR_SIZE (ARM_VM_DIR_ENTRIES * ARM_VM_DIR_ENT_SIZE)
#define ARM_PAGEDIR_SIZE (ARM_VM_DIR_SIZE)
#define ARM_VM_PT_SIZE (ARM_VM_PT_ENTRIES * ARM_VM_PT_ENT_SIZE)
#define ARM_PAGETABLE_SIZE (ARM_VM_PT_SIZE)
/* ARM pagefault status bits */
#define ARM_VM_PFE_ALIGN 0x01 /* Pagefault caused by Alignment fault */
#define ARM_VM_PFE_IMAINT 0x04 /* Caused by Instruction cache
maintenance fault */
#define ARM_VM_PFE_TTWALK_L1ABORT 0x0c /* Caused by Synchronous external abort
* on translation table walk (Level 1)
*/
#define ARM_VM_PFE_TTWALK_L2ABORT 0x0e /* Caused by Synchronous external abort
* on translation table walk (Level 2)
*/
#define ARM_VM_PFE_TTWALK_L1PERR 0x1c /* Caused by Parity error
* on translation table walk (Level 1)
*/
#define ARM_VM_PFE_TTWALK_L2PERR 0x1e /* Caused by Parity error
* on translation table walk (Level 2)
*/
#define ARM_VM_PFE_L1TRANS 0x05 /* Caused by Translation fault (Level 1)
*/
#define ARM_VM_PFE_L2TRANS 0x07 /* Caused by Translation fault (Level 2)
*/
#define ARM_VM_PFE_L1ACCESS 0x03 /* Caused by Access flag fault (Level 1)
*/
#define ARM_VM_PFE_L2ACCESS 0x06 /* Caused by Access flag fault (Level 2)
*/
#define ARM_VM_PFE_L1DOMAIN 0x09 /* Caused by Domain fault (Level 1)
*/
#define ARM_VM_PFE_L2DOMAIN 0x0b /* Caused by Domain fault (Level 2)
*/
#define ARM_VM_PFE_L1PERM 0x0d /* Caused by Permission fault (Level 1)
*/
#define ARM_VM_PFE_L2PERM 0x0f /* Caused by Permission fault (Level 2)
*/
#define ARM_VM_PFE_DEBUG 0x02 /* Caused by Debug event */
#define ARM_VM_PFE_ABORT 0x08 /* Caused by Synchronous external abort
*/
#define ARM_VM_PFE_TLB_CONFLICT 0x10 /* Caused by TLB conflict abort
*/
#define ARM_VM_PFE_W (1<<11) /* Caused by write (otherwise read) */
#ifndef __ASSEMBLY__
#include <minix/type.h>
/* structure used by VM to pass data to the kernel while enabling paging */
struct vm_ep_data {
struct mem_map * mem_map;
vir_bytes data_seg_limit;
};
#endif
#endif /* __SYS_VM_ARM_H__ */

View file

@ -2,7 +2,9 @@
.include <bsd.own.mk>
.if !defined(__MINIX)
SRCS+= __sigaction14_sigtramp.c __sigtramp2.S
.endif
CPPFLAGS += -DSOFTFLOAT

View file

@ -17,9 +17,13 @@ SRCS+= setjmp.S
SRCS+= _setjmp.S
SRCS+= sigsetjmp.S
.if defined(__MINIX)
# Already defined in sys-minix
.else
SRCS+= makecontext.c resumecontext.c swapcontext.S
SRCS+= _lwp.c
.endif
LSRCS.arm.gen= Lint_bswap16.c Lint_bswap32.c Lint_swapcontext.c
LSRCS+= ${LSRCS.arm.gen}

View file

@ -0,0 +1,25 @@
# rts sources
HERE=${.CURDIR}/arch/${MACHINE_ARCH}/sys-minix
.PATH: ${HERE}
TMP=ucontextoffsets.h.tmp
INCLS=../../include
ARCHINCLS=$(INCLS)/arch/arm/include/
CF=ucontextoffsets.cf
INCS+=ucontextoffsets.h
ucontext.d: ucontextoffsets.h
SRCS+= \
__sigreturn.S \
_ipc.S \
_senda.S \
brksize.S \
ucontext.S
ucontextoffsets.h: $(CF) $(ARCHINCLS)/stackframe.h $(INCLS)/sys/ucontext.h
${_MKTARGET_CREATE}
cat ${HERE}/$(CF) | \
${TOOL_GENASSYM} -- ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} >$TMP && \
mv -f $TMP $@

View file

@ -0,0 +1,9 @@
/* This routine is the low-level code for returning from signals. */
/* It calls _sigreturn, which is the normal "system call" routine. */
/* Both __sigreturn and _sigreturn are needed. */
#include <machine/asm.h>
IMPORT(_sigreturn)
ENTRY(__sigreturn)
add sp, sp, #16
b _C_LABEL(_sigreturn)

View file

@ -0,0 +1,84 @@
#include <minix/ipcconst.h>
#include <machine/asm.h>
/**========================================================================* */
/* IPC assembly routines * */
/**========================================================================* */
ENTRY(_send)
push {fp}
mov fp, sp
mov r2, r1 /* r2 = msg ptr */
mov r1, r0 /* r1 = src_dest */
mov r0, #SEND /* _send(dest, ptr) */
mov r3, #IPCVEC /* r3 determines the SVC type */
svc #0 /* trap to kernel */
pop {fp}
bx lr
ENTRY(_receive)
push {fp}
mov fp, sp
push {r2} /* save status ptr */
mov r2, r1 /* r2 = msg ptr */
mov r1, r0 /* r1 = src_dest */
mov r0, #RECEIVE /* _receive(src, ptr) */
mov r3, #IPCVEC /* r3 determines the SVC type */
svc #0 /* trap to kernel */
pop {r2} /* restore status ptr */
str r1, [r2]
pop {fp}
bx lr
ENTRY(_sendrec)
push {fp}
mov fp, sp
mov r2, r1 /* r2 = msg ptr */
mov r1, r0 /* r1 = src_dest */
mov r0, #SENDREC /* _sendrec(srcdest, ptr) */
mov r3, #IPCVEC /* r3 determines the SVC type */
svc #0 /* trap to kernel */
pop {fp}
bx lr
ENTRY(_minix_kernel_info_struct)
push {fp}
mov fp, sp
push {r0}
mov r1, #0
mov r2, #0
mov r0, #MINIX_KERNINFO /* kerninfo() */
mov r3, #IPCVEC /* r3 determines the SVC type */
svc #0 /* trap to kernel */
pop {r0} /* r0 = return struct ptr */
ldr r0, [r0]
mov r0, r1
pop {fp}
bx lr
ENTRY(_notify)
push {fp}
mov fp, sp
mov r1, r0 /* r1 = src_dest */
mov r0, #NOTIFY /* _notify(srcdst) */
mov r3, #IPCVEC /* r3 determines the SVC type */
svc #0 /* trap to kernel */
pop {fp}
bx lr
ENTRY(_sendnb)
push {fp}
mov fp, sp
mov r2, r1 /* r2 = msg ptr */
mov r1, r0 /* r1 = src_dest */
mov r0, #SENDNB /* _sendnb(dest, ptr) */
mov r3, #IPCVEC /* r3 determines the SVC type */
svc #0 /* trap to kernel */
pop {fp}
bx lr
ENTRY(_do_kernel_call)
/* r0 already holds msg ptr */
mov r3, #KERVEC /* r3 determines the SVC type */
svc #0 /* trap to kernel */
bx lr

View file

@ -0,0 +1,13 @@
#include <minix/ipcconst.h>
#include <machine/asm.h>
ENTRY(_senda)
push {fp}
mov fp, sp
mov r2, r0 /* r2 = table */
/* r1 already holds count */
mov r0, #SENDA /* _senda(table, count) */
mov r3, #IPCVEC /* r3 determines the SVC type */
svc #0 /* trap to kernel */
pop {fp}
bx lr

View file

@ -0,0 +1,5 @@
.globl _end
.globl _brksize
.data
_brksize: .long _end

View file

@ -0,0 +1,157 @@
#include <machine/asm.h>
#include <ucontextoffsets.h>
IMPORT(getuctx)
IMPORT(setuctx)
IMPORT(resumecontext)
/* MCF_MAGIC value from <mcontext.h> */
#define MCF_MAGIC 0xc0ffee
/* Values from <sys/ucontext.h> */
#define UCF_IGNFPU 0x002
#define UCF_IGNSIGM 0x004
/* EINVAL from errno.h */
#define EFAULT 14
#define EINVAL 22
/* int getcontext(ucontext_t *ucp)
* Initialise the structure pointed to by ucp to the current user context
* of the calling thread. */
ENTRY(getcontext)
/* In case a process does not use the FPU and is neither interested in
* saving its signal mask, then we can skip the context switch to
* PM and kernel altogether and only save general-purpose registers. */
mov r3, lr /* Save return address:
* When setcontext or swapcontext is called,
* we jump to this address and continue
* running. */
/* r0 = ucp */
/* Check null pointer */
cmp r0, #0 /* ucp == NULL? */
bne 3f /* Not null, continue */
mov r1, #EFAULT
ldr r2, =_C_LABEL(errno)
str r1, [r2] /* errno = EFAULT */
mov r0, #-1 /* return -1 */
bx lr
3: /* Check flags */
ldr r1, [r0, #UC_FLAGS] /* r1 = ucp->uc_flags */
mov r2, #(UCF_IGNFPU | UCF_IGNSIGM)
cmp r1, r2 /* is UCF_IGNFPU or UCF_IGNSIGM set? */
beq 1f /* Both are set, skip getuctx */
0:
push {r0, r3}
bl _C_LABEL(getuctx) /* getuctx(ucp) */
pop {r0, r3}
1:
/* Save the context */
mov lr, r3 /* Restore lr */
str lr, [r0, #LRREG] /* Save lr */
str lr, [r0, #PCREG] /* Save real RTA in mcp struct */
str sp, [r0, #SPREG] /* Save stack pointer */
str fp, [r0, #FPREG] /* Save fp */
str r4, [r0, #REG4] /* Save r4 */
str r5, [r0, #REG5] /* Save r5 */
str r6, [r0, #REG6] /* Save r6 */
str r7, [r0, #REG7] /* Save r7 */
str r8, [r0, #REG8] /* Save r8 */
str r9, [r0, #REG9] /* Save r9 */
str r10, [r0, #REG10] /* Save r10 */
ldr r1, =MCF_MAGIC
str r1, [r0, #MAGIC] /* Set magic value */
mov r1, #0
str r1, [r0, #REG0] /* Return 0 */
mov r0, #0 /* Return 0 */
2:
bx lr /* Restore return address */
/* int setcontext(const ucontext_t *ucp)
* Restore the user context pointed to by ucp. A successful call to
* setcontext does not return; program execution resumes at the point
* specified by the ucp argument. If ucp was created with getcontext(),
* program execution continues as if the corresponding call of getcontext()
* had just returned. If ucp was created with makecontext(), program
* execution continues with the function passed to makecontext(). */
ENTRY(setcontext)
/* In case a process does not use the FPU and is neither interested in
* restoring its signal mask, then we can skip the context switch to
* PM and kernel altogether and restore state here. */
/* r0 = ucp */
/* Check null pointer */
cmp r0, #0 /* ucp == NULL? */
bne 3f /* Not null, continue */
mov r1, #EFAULT
ldr r2, =_C_LABEL(errno)
str r1, [r2] /* errno = EFAULT */
mov r0, #-1 /* return -1 */
bx lr
3: /* Check flags */
ldr r1, [r0, #MAGIC] /* r1 = ucp->mc_context.mc_magic */
ldr r2, =MCF_MAGIC
cmp r1, r2 /* is the magic value set (is context valid)?*/
beq 4f /* is set, proceed */
mov r1, #EINVAL /* not set, return error code */
ldr r2, =_C_LABEL(errno)
str r1, [r2] /* errno = EINVAL */
mov r0, #-1 /* return -1 */
bx lr
4: ldr r1, [r0, #UC_FLAGS] /* r1 = ucp->uc_flags */
mov r2, #(UCF_IGNFPU | UCF_IGNSIGM)
cmp r1, r2 /* Are UCF_IGNFPU and UCF_IGNSIGM flags set? */
beq 1f /* Both are set, so don't bother restoring FPU
* state and signal mask */
push {r0, r3}
0: bl _C_LABEL(setuctx) /* setuctx(ucp) */
pop {r0, r3}
1: /* Restore the registers */
ldr r1, [r0, #REG1] /* Restore r1 */
ldr r2, [r0, #REG2] /* Restore r2 */
ldr r3, [r0, #REG3] /* Restore r3 */
ldr r4, [r0, #REG4] /* Restore r4 */
ldr r5, [r0, #REG5] /* Restore r5 */
ldr r6, [r0, #REG6] /* Restore r6 */
ldr r7, [r0, #REG7] /* Restore r7 */
ldr r8, [r0, #REG8] /* Restore r8 */
ldr r9, [r0, #REG9] /* Restore r9 */
ldr r10, [r0, #REG10] /* Restore r10 */
ldr r12, [r0, #REG12] /* Restore r12 */
ldr fp, [r0, #FPREG] /* Restore fp */
ldr sp, [r0, #SPREG] /* Restore sp */
ldr lr, [r0, #LRREG] /* Restore lr */
mov r4, r0
ldr r0, [r4, #REG0] /* Restore r0 */
2:
ldr pc, [r4, #PCREG] /* Restore pc */
/* void ctx_start()
* A wrapper to call resumecontext. Makecontext puts the ucp in r4.
* This function moves the ucp into r0 so that the ucp is the first
* parameter for resumecontext. The call to resumecontext will start
* the next context in the linked list (or exit the program if there
* is no context). */
ENTRY(ctx_start)
mov r0, r4
b _C_LABEL(resumecontext)

View file

@ -0,0 +1,25 @@
include <minix/type.h>
include <sys/ucontext.h>
struct __ucontext
member UC_FLAGS uc_flags
member UC_LINK uc_link
member MAGIC uc_mcontext.mc_magic
member REG0 uc_mcontext.mc_p_reg.retreg
member REG1 uc_mcontext.mc_p_reg.r1
member REG2 uc_mcontext.mc_p_reg.r2
member REG3 uc_mcontext.mc_p_reg.r3
member REG4 uc_mcontext.mc_p_reg.r4
member REG5 uc_mcontext.mc_p_reg.r5
member REG6 uc_mcontext.mc_p_reg.r6
member REG7 uc_mcontext.mc_p_reg.r7
member REG8 uc_mcontext.mc_p_reg.r8
member REG9 uc_mcontext.mc_p_reg.r9
member REG10 uc_mcontext.mc_p_reg.r10
member FPREG uc_mcontext.mc_p_reg.fp
member REG12 uc_mcontext.mc_p_reg.r12
member SPREG uc_mcontext.mc_p_reg.sp
member LRREG uc_mcontext.mc_p_reg.lr
member PCREG uc_mcontext.mc_p_reg.pc

View file

@ -146,7 +146,66 @@ void makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
swapcontext will choke on this and return ENOMEM. */
if (stack_top == ucp->uc_stack.ss_sp)
ucp->uc_mcontext.mc_p_reg.sp = 0;
#elif defined(__arm__)
/* The caller provides a pointer to a stack that we can use to run our
context on. When the context starts, control is given to the
requested function. When the function finishes, it returns to the
_ctx_start wrapper that calls resumecontext (after setting up
resumecontext's parameter).
The first four arguments for the function will be passed in
regs r0-r3 as specified by the ABI, and the rest will go on
the stack. The ucp is saved in r4 so that we can
eventually pass it to resumecontext. The r4 register is
callee-preserved, so the ucp will remain valid in r4 when
_ctx_start runs. _ctx_start will move the ucp from r4 into
r0, so that the ucp is the first paramater for resumecontext.
Then, _ctx_start will call resumecontext. Resumecontext, in turn,
checks whether another context is ready to be executed
(i.e., uc_link != NULL) or exit(2)s the process. */
/* Find the top of the stack from which we grow downwards. */
stack_top = (unsigned int *) ((uintptr_t ) ucp->uc_stack.ss_sp +
ucp->uc_stack.ss_size);
/* Align the arguments to 16 bytes (we might lose a few bytes of stack
space here).*/
stack_top = (unsigned int *) ((uintptr_t) stack_top & ~0xf);
/* Make room for `func' routine arguments that don't fit in r0-r3 */
if (argc > 4)
stack_top -= argc - 4;
/* Adjust the machine context to point to the top of this stack and the
program counter to the 'func' entry point. Set lr to ctx_start, so
ctx_start runs after 'func'. Save ucp in r4 */
ucp->uc_mcontext.mc_p_reg.fp = 0; /* Clear frame pointer */
ucp->uc_mcontext.mc_p_reg.sp = (reg_t) stack_top;
ucp->uc_mcontext.mc_p_reg.pc = (reg_t) func;
ucp->uc_mcontext.mc_p_reg.lr = (reg_t) ctx_start;
ucp->uc_mcontext.mc_p_reg.r4 = (reg_t) ucp;
/* Copy arguments to r0-r3 and stack. */
va_start(ap, argc);
/* Pass up to four arguments in registers. */
if (argc-- > 0)
ucp->uc_mcontext.mc_p_reg.retreg = va_arg(ap, uintptr_t);
if (argc-- > 0)
ucp->uc_mcontext.mc_p_reg.r1 = va_arg(ap, uintptr_t);
if (argc-- > 0)
ucp->uc_mcontext.mc_p_reg.r2 = va_arg(ap, uintptr_t);
if (argc-- > 0)
ucp->uc_mcontext.mc_p_reg.r3 = va_arg(ap, uintptr_t);
/* Pass the rest on the stack. */
while (argc-- > 0) {
*stack_top++ = va_arg(ap, uintptr_t);
}
va_end(ap);
/* If we ran out of stack space, invalidate stack pointer. Eventually,
swapcontext will choke on this and return ENOMEM. */
if (stack_top == ucp->uc_stack.ss_sp)
ucp->uc_mcontext.mc_p_reg.sp = 0;
#else
# error "Unsupported platform"
#endif

View file

@ -0,0 +1,16 @@
#ifndef _COMPAT_MACHINE_JMP_BUF_H
#define _COMPAT_MACHINE_JMP_BUF_H
/* This file is strictly dependant on the libc's
* setjmp/longjmp code! Keep it in sync! */
/* This is used only by libddekit's src/thread.c.
* Being incredibly fragile (not to mention hardly
* portable, it would be a good idea to replace
* that code. */
#define JB_PC 148
#define JB_SP 144
#define JB_BP 136
#endif /* _COMPAT_MACHINE_JMP_BUF_H */

View file

@ -0,0 +1,5 @@
SRCS+= byte_swap_2.S byte_swap_4.S ffs.S
SRCS+= memchr.c memcmp.c memcpy.c memmove.c memset.c \
strcat.c strchr.c strcmp.c strcpy.c strlen.c \
strncmp.c strrchr.c
SRCS+= bcmp.c

View file

@ -0,0 +1 @@
SRCS+= get_bp.S

View file

@ -0,0 +1,10 @@
/* get_bp.s */
/* */
/* return fp in r0 */
/* */
#include <machine/asm.h>
ENTRY(get_bp)
mov r0, fp
bx lr

View file

@ -409,7 +409,7 @@ void *arg;
if (stackaddr == MAP_FAILED)
mthread_panic("Failed to allocate stack to thread");
#if defined(__i386__)
#if defined(__i386__) || defined(__arm__)
guard_start = stackaddr;
guard_end = stackaddr + MTHREAD_GUARDSIZE;
guarded_stacksize = stackaddr + stacksize - guard_end;

View file

@ -13,8 +13,6 @@ SRCS= \
env_parse.c \
env_prefix.c \
fkey_ctl.c \
get_randomness.c \
getidle.c \
getsysinfo.c \
getuptime.c \
getuptime2.c \
@ -25,7 +23,99 @@ SRCS= \
kputs.c \
optset.c \
panic.c \
pci_attr_r16.c \
safecopies.c \
sched_start.c \
sched_stop.c \
sef.c \
sef_init.c \
sef_liveupdate.c \
sef_ping.c \
sef_signal.c \
sqrt_approx.c \
stacktrace.c \
sys_abort.c \
sys_clear.c \
sys_cprof.c \
sys_endsig.c \
sys_exec.c \
sys_exit.c \
sys_fork.c \
sys_getinfo.c \
sys_getsig.c \
sys_hz.c \
sys_irqctl.c \
sys_kill.c \
sys_mcontext.c \
sys_memset.c \
sys_physcopy.c \
sys_privctl.c \
sys_profbuf.c \
sys_runctl.c \
sys_safecopy.c \
sys_safemap.c \
sys_schedctl.c \
sys_schedule.c \
sys_setalarm.c \
sys_setgrant.c \
sys_sigreturn.c \
sys_sigsend.c \
sys_sprof.c \
sys_statectl.c \
sys_stime.c \
sys_sysctl.c \
sys_times.c \
sys_trace.c \
sys_umap.c \
sys_update.c \
sys_vircopy.c \
sys_vmctl.c \
sys_vsafecopy.c \
sys_vtimer.c \
sys_vumap.c \
taskcall.c \
tickdelay.c \
timers.c \
vm_brk.c \
vm_dmacalls.c \
vm_exit.c \
vm_fork.c \
vm_info.c \
vm_map_phys.c \
vm_notify_sig.c \
vm_push_sig.c \
vm_umap.c \
vm_yield_get_block.c \
vm_procctl.c \
vprintf.c
.if ${MACHINE_ARCH} == "i386"
SRCS+= \
get_randomness.c \
getidle.c \
profile.c \
profile_extern.c \
ser_putc.c \
spin.c \
sys_eniop.c \
sys_in.c \
sys_int86.c \
sys_out.c \
sys_readbios.c \
sys_sdevio.c \
sys_umap_remote.c \
sys_vinb.c \
sys_vinl.c \
sys_vinw.c \
sys_voutb.c \
sys_voutl.c \
sys_voutw.c \
timing.c \
tsc_util.c \
vbox.c
.endif
.if ${MKPCI} != "no"
SRCS+= pci_attr_r16.c \
pci_attr_r32.c \
pci_attr_r8.c \
pci_attr_w16.c \
@ -42,91 +132,8 @@ SRCS= \
pci_rescan_bus.c \
pci_reserve.c \
pci_set_acl.c \
pci_slot_name.c \
profile.c \
profile_extern.c \
safecopies.c \
sched_start.c \
sched_stop.c \
sef.c \
sef_init.c \
sef_liveupdate.c \
sef_ping.c \
sef_signal.c \
ser_putc.c \
spin.c \
sqrt_approx.c \
stacktrace.c \
sys_abort.c \
sys_clear.c \
sys_cprof.c \
sys_endsig.c \
sys_eniop.c \
sys_exec.c \
sys_exit.c \
sys_fork.c \
sys_getinfo.c \
sys_getsig.c \
sys_hz.c \
sys_in.c \
sys_int86.c \
sys_irqctl.c \
sys_kill.c \
sys_mcontext.c \
sys_memset.c \
sys_out.c \
sys_physcopy.c \
sys_privctl.c \
sys_profbuf.c \
sys_readbios.c \
sys_runctl.c \
sys_safecopy.c \
sys_safemap.c \
sys_schedctl.c \
sys_schedule.c \
sys_sdevio.c \
sys_setalarm.c \
sys_setgrant.c \
sys_sigreturn.c \
sys_sigsend.c \
sys_sprof.c \
sys_statectl.c \
sys_stime.c \
sys_sysctl.c \
sys_times.c \
sys_trace.c \
sys_umap.c \
sys_umap_remote.c \
sys_update.c \
sys_vinb.c \
sys_vinl.c \
sys_vinw.c \
sys_vircopy.c \
sys_vmctl.c \
sys_voutb.c \
sys_voutl.c \
sys_voutw.c \
sys_vsafecopy.c \
sys_vtimer.c \
sys_vumap.c \
taskcall.c \
tickdelay.c \
timers.c \
timing.c \
tsc_util.c \
vbox.c \
vm_brk.c \
vm_dmacalls.c \
vm_exit.c \
vm_fork.c \
vm_info.c \
vm_map_phys.c \
vm_notify_sig.c \
vm_push_sig.c \
vm_umap.c \
vm_yield_get_block.c \
vm_procctl.c \
vprintf.c
pci_slot_name.c
.endif
.if ${MKCOVERAGE} != "no"
SRCS+= gcov.c \

View file

@ -748,8 +748,12 @@ _MKVARS.yes= \
MKYP
#MINIX-specific vars
_MKVARS.yes+= \
MKWATCHDOG MKACPI MKAPIC MKMCONTEXT MKDEBUGREG MKSYSDEBUG \
MKLIVEUPDATE MKSTATECTL MKTRACE MKINSTALLBOOT MKPCI
MKMCONTEXT MKSYSDEBUG MKLIVEUPDATE MKSTATECTL MKTRACE
.if (${MACHINE_ARCH} == "i386")
_MKVARS.yes+= \
MKWATCHDOG MKACPI MKAPIC MKDEBUGREG MKINSTALLBOOT MKPCI
.endif
.for var in ${_MKVARS.yes}
${var}?= yes
.endfor
@ -768,6 +772,10 @@ _MKVARS.no= \
#MINIX-specific vars
_MKVARS.no+= \
MKIMAGEONLY MKSMALL USETOOLS
.if (${MACHINE_ARCH} == "arm")
_MKVARS.no+= \
MKWATCHDOG MKACPI MKAPIC MKDEBUGREG MKINSTALLBOOT MKPCI
.endif
.for var in ${_MKVARS.no}
${var}?=no
.endfor

View file

@ -1,2 +1,8 @@
AFLAGS+=-D__ASSEMBLY__ -D_EM_WSIZE=4
CFLAGS+= -fno-builtin -Wall -march=i586 -Wno-sign-compare
AFLAGS+=-D__ASSEMBLY__
CPPFLAGS+= -fno-builtin -Wall -Wno-sign-compare
.if ${MACHINE_ARCH} == "i386"
CPPFLAGS+= -march=i586
.elif ${MACHINE_ARCH} == "arm"
CPPFLAGS+= -march=armv7-a
CPPFLAGS+= -D__minix
.endif

View file

@ -740,7 +740,7 @@ static void test_attributes(void)
/* Verify stack hypothesis; we assume a stack is used from the top and grows
* downwards.
*/
#if defined(__i386__)
#if defined(__i386__) || defined(__arm__)
if (stackp[0] != MAGIC) err(11, 66); /* End of the stack */
for (i = no_ints - 1 - 16; i < no_ints; i++)
if (stackp[i] != MAGIC) stack_untouched = 0;