1 /* The kernel call implemented in this file:
4 * The parameters for this kernel call are:
5 * m5_i1: CP_SRC_PROC_NR (process number)
6 * m5_s1: CP_SRC_SPACE (segment where address is: T, D, or S)
7 * m5_l1: CP_SRC_ADDR (virtual address)
8 * m5_l2: CP_DST_ADDR (returns physical address)
9 * m5_l3: CP_NR_BYTES (size of datastructure)
12 #include "kernel/system.h"
14 #include <minix/endpoint.h>
18 /*==========================================================================*
20 *==========================================================================*/
21 PUBLIC
int do_umap(struct proc
* caller
, message
* m_ptr
)
23 /* Map virtual address to physical, for non-kernel processes. */
24 int seg_type
= m_ptr
->CP_SRC_SPACE
& SEGMENT_TYPE
;
25 int seg_index
= m_ptr
->CP_SRC_SPACE
& SEGMENT_INDEX
;
26 vir_bytes offset
= m_ptr
->CP_SRC_ADDR
;
27 int count
= m_ptr
->CP_NR_BYTES
;
28 int endpt
= (int) m_ptr
->CP_SRC_ENDPT
;
31 phys_bytes phys_addr
= 0, lin_addr
= 0;
32 struct proc
*targetpr
;
34 /* Verify process number. */
36 proc_nr
= _ENDPOINT_P(caller
->p_endpoint
);
38 if (! isokendpt(endpt
, &proc_nr
))
40 targetpr
= proc_addr(proc_nr
);
42 /* See which mapping should be made. */
45 phys_addr
= lin_addr
= umap_local(targetpr
, seg_index
, offset
, count
);
46 if(!lin_addr
) return EFAULT
;
50 phys_addr
= lin_addr
= umap_remote(targetpr
, seg_index
, offset
, count
);
51 if(!lin_addr
) return EFAULT
;
55 if(seg_index
== MEM_GRANT
) {
59 cp_grant_id_t grant
= (cp_grant_id_t
) offset
;
61 if(verify_grant(targetpr
->p_endpoint
, ANY
, grant
, count
, 0, 0,
62 &newoffset
, &newep
) != OK
) {
63 printf("SYSTEM: do_umap: verify_grant in %s, grant %d, bytes 0x%lx, failed, caller %s\n", targetpr
->p_name
, offset
, count
, caller
->p_name
);
64 proc_stacktrace(caller
);
68 if(!isokendpt(newep
, &new_proc_nr
)) {
69 printf("SYSTEM: do_umap: isokendpt failed\n");
75 targetpr
= proc_addr(new_proc_nr
);
79 if(seg_index
== T
|| seg_index
== D
|| seg_index
== S
) {
80 phys_addr
= lin_addr
= umap_local(targetpr
, seg_index
, offset
, count
);
82 printf("SYSTEM: bogus seg type 0x%lx\n", seg_index
);
86 printf("SYSTEM:do_umap: umap_local failed\n");
89 if(vm_lookup(targetpr
, lin_addr
, &phys_addr
, NULL
) != OK
) {
90 printf("SYSTEM:do_umap: vm_lookup failed\n");
94 panic("vm_lookup returned zero physical address");
97 if((r
=arch_umap(targetpr
, offset
, count
, seg_type
, &lin_addr
))
100 phys_addr
= lin_addr
;
103 if(vm_running
&& !vm_contiguous(targetpr
, lin_addr
, count
)) {
104 printf("SYSTEM:do_umap: not contiguous\n");
108 m_ptr
->CP_DST_ADDR
= phys_addr
;
109 if(naughty
|| phys_addr
== 0) {
110 printf("kernel: umap 0x%x done by %d / %s, pc 0x%lx, 0x%lx -> 0x%lx\n",
111 seg_type
, caller
->p_endpoint
, caller
->p_name
,
112 caller
->p_reg
.pc
, offset
, phys_addr
);
113 printf("caller stack: ");
114 proc_stacktrace(caller
);
116 return (phys_addr
== 0) ? EFAULT
: OK
;
119 #endif /* USE_UMAP */