xref: /minix3/minix/kernel/arch/earm/klib.S (revision 433d6423c39e34ec4b79c950597bb2d236f886be)
1*433d6423SLionel Sambuc/* sections */
2*433d6423SLionel Sambuc
3*433d6423SLionel Sambuc
4*433d6423SLionel Sambuc#include <minix/config.h>
5*433d6423SLionel Sambuc#include <minix/const.h>
6*433d6423SLionel Sambuc#include <machine/asm.h>
7*433d6423SLionel Sambuc#include <machine/interrupt.h>
8*433d6423SLionel Sambuc#include <machine/vm.h>
9*433d6423SLionel Sambuc#include "archconst.h"
10*433d6423SLionel Sambuc#include "kernel/const.h"
11*433d6423SLionel Sambuc#include "sconst.h"
12*433d6423SLionel Sambuc#include <machine/multiboot.h>
13*433d6423SLionel Sambuc
14*433d6423SLionel Sambuc
15*433d6423SLionel Sambuc/*===========================================================================*/
16*433d6423SLionel Sambuc/*				copy_msg_from_user			     */
17*433d6423SLionel Sambuc/*===========================================================================*/
18*433d6423SLionel Sambuc/*
19*433d6423SLionel Sambuc * int copy_msg_from_user(message * user_mbuf, message * dst);
20*433d6423SLionel Sambuc *
21*433d6423SLionel Sambuc * Copies a message of 64 bytes from user process space to a kernel buffer. This
22*433d6423SLionel Sambuc * function assumes that the process address space is installed (ttbr loaded).
23*433d6423SLionel Sambuc *
24*433d6423SLionel Sambuc * This function from the callers point of view either succeeds or returns an
25*433d6423SLionel Sambuc * error which gives the caller a chance to respond accordingly. In fact it
26*433d6423SLionel Sambuc * either succeeds or if it generates a pagefault, general protection or other
27*433d6423SLionel Sambuc * exception, the trap handler has to redirect the execution to
28*433d6423SLionel Sambuc * __user_copy_msg_pointer_failure where the error is reported to the caller
29*433d6423SLionel Sambuc * without resolving the pagefault. It is not kernel's problem to deal with
30*433d6423SLionel Sambuc * wrong pointers from userspace and the caller should return an error to
31*433d6423SLionel Sambuc * userspace as if wrong values or request were passed to the kernel
32*433d6423SLionel Sambuc */
33*433d6423SLionel SambucENTRY(copy_msg_from_user)
34*433d6423SLionel Sambuc	push	{r4-r10, lr}
35*433d6423SLionel Sambuc	/* load the source pointer */
36*433d6423SLionel Sambuc	mov	r9, r0
37*433d6423SLionel Sambuc	/* load the destination pointer */
38*433d6423SLionel Sambuc	mov	r10, r1
39*433d6423SLionel Sambuc	/* do the copy, first 32 bytes */
40*433d6423SLionel Sambuc	ldm	r9,  {r0-r7}
41*433d6423SLionel Sambuc	stm	r10, {r0-r7}
42*433d6423SLionel Sambuc
43*433d6423SLionel Sambuc	/* next 32 bytes */
44*433d6423SLionel Sambuc	add	r9,  r9, #32
45*433d6423SLionel Sambuc	add	r10, r10, #32
46*433d6423SLionel Sambuc	ldm	r9,  {r0-r7}
47*433d6423SLionel Sambuc	stm	r10, {r0-r7}
48*433d6423SLionel Sambuc
49*433d6423SLionel SambucLABEL(__copy_msg_from_user_end)
50*433d6423SLionel Sambuc	pop	{r4-r10, lr}
51*433d6423SLionel Sambuc	mov	r0, #0
52*433d6423SLionel Sambuc	bx	lr
53*433d6423SLionel Sambuc
54*433d6423SLionel Sambuc/*===========================================================================*/
55*433d6423SLionel Sambuc/*				copy_msg_to_user			     */
56*433d6423SLionel Sambuc/*===========================================================================*/
57*433d6423SLionel Sambuc/*
58*433d6423SLionel Sambuc * void copy_msg_to_user(message * src, message * user_mbuf);
59*433d6423SLionel Sambuc *
60*433d6423SLionel Sambuc * Copies a message of 64 bytes to user process space from a kernel buffer.
61*433d6423SLionel Sambuc *
62*433d6423SLionel Sambuc * All the other copy_msg_from_user() comments apply here as well!
63*433d6423SLionel Sambuc */
64*433d6423SLionel SambucENTRY(copy_msg_to_user)
65*433d6423SLionel Sambuc	push	{r4-r10, lr}
66*433d6423SLionel Sambuc	/* load the source pointer */
67*433d6423SLionel Sambuc	mov	r9, r0
68*433d6423SLionel Sambuc	/* load the destination pointer */
69*433d6423SLionel Sambuc	mov	r10, r1
70*433d6423SLionel Sambuc	/* do the copy, first 32 bytes */
71*433d6423SLionel Sambuc	ldm	r9,  {r0-r7}
72*433d6423SLionel Sambuc	stm	r10, {r0-r7}
73*433d6423SLionel Sambuc
74*433d6423SLionel Sambuc	/* next 32 bytes */
75*433d6423SLionel Sambuc	add	r9,  r9,  #32
76*433d6423SLionel Sambuc	add	r10, r10, #32
77*433d6423SLionel Sambuc	ldm	r9,  {r0-r7}
78*433d6423SLionel Sambuc	stm	r10, {r0-r7}
79*433d6423SLionel Sambuc
80*433d6423SLionel SambucLABEL(__copy_msg_to_user_end)
81*433d6423SLionel Sambuc	pop	{r4-r10, lr}
82*433d6423SLionel Sambuc	mov	r0, #0
83*433d6423SLionel Sambuc	bx	lr
84*433d6423SLionel Sambuc
85*433d6423SLionel Sambuc/*
86*433d6423SLionel Sambuc * if a function from a selected set of copies from or to userspace fails, it is
87*433d6423SLionel Sambuc * because of a wrong pointer supplied by the userspace. We have to clean up and
88*433d6423SLionel Sambuc * and return -1 to indicated that something wrong has happend. The place it was
89*433d6423SLionel Sambuc * called from has to handle this situation. The exception handler redirect us
90*433d6423SLionel Sambuc * here to continue, clean up and report the error
91*433d6423SLionel Sambuc */
92*433d6423SLionel SambucENTRY(__user_copy_msg_pointer_failure)
93*433d6423SLionel Sambuc	pop	{r4-r10, lr}
94*433d6423SLionel Sambuc	mov	r0, #-1
95*433d6423SLionel Sambuc	bx	lr
96*433d6423SLionel Sambuc
97*433d6423SLionel SambucENTRY(intr_enable)
98*433d6423SLionel SambucENTRY(interrupts_enable)
99*433d6423SLionel Sambuc	dsb
100*433d6423SLionel Sambuc	cpsie if
101*433d6423SLionel Sambuc	bx lr
102*433d6423SLionel Sambuc
103*433d6423SLionel SambucENTRY(intr_disable)
104*433d6423SLionel SambucENTRY(interrupts_disable)
105*433d6423SLionel Sambuc	dsb
106*433d6423SLionel Sambuc	cpsid if
107*433d6423SLionel Sambuc	bx lr
108