1 /* See COPYRIGHT for copyright information. */
6 #include <ros/memlayout.h>
7 #include <ros/common.h>
8 #include <ros/resource.h>
9 #include <ros/atomic.h>
10 #include <ros/arch/arch.h>
13 #define PROCINFO_MAX_ARGP 32
14 #define PROCINFO_ARGBUF_SIZE 3072
17 #include <sys/queue.h>
18 #endif /* ROS_KERNEL */
20 /* Not necessary to expose all of this, but it doesn't hurt, and is convenient
21 * for the kernel. Need to do some acrobatics for the TAILQ_ENTRY. */
25 TAILQ_ENTRY(vcore) list;
29 #endif /* ROS_KERNEL */
32 uint32_t nr_preempts_sent; /* these two differ when a preempt*/
33 uint32_t nr_preempts_done; /* is in flight. */
34 uint64_t preempt_pending;
42 typedef struct procinfo {
48 /* for traditional forks, these two need to be memcpy'd over: */
49 char* argp[PROCINFO_MAX_ARGP];
50 char argbuf[PROCINFO_ARGBUF_SIZE];
51 /* glibc relies on stuff above this point. if you change it, you need to
53 bool is_mcp; /* is in multi mode */
54 unsigned long res_grant[MAX_NUM_RESOURCES];
55 struct vcore vcoremap[MAX_NUM_CPUS];
57 struct pcore pcoremap[MAX_NUM_CPUS];
58 seq_ctr_t coremap_seqctr;
60 #define PROCINFO_NUM_PAGES ((sizeof(procinfo_t)-1)/PGSIZE + 1)
63 procinfo_pack_args(procinfo_t* p, char* const* argv, char* const* envp)
65 int nargv = 0, nenvp = 0;
66 if(argv) while(argv[nargv]) nargv++;
67 if(envp) while(envp[nenvp]) nenvp++;
69 if(nargv+nenvp+2 > PROCINFO_MAX_ARGP)
73 for(int i = 0; i < nargv; i++)
75 int len = strlen(argv[i])+1;
76 if(pos+len > PROCINFO_ARGBUF_SIZE)
78 p->argp[i] = ((procinfo_t*)UINFO)->argbuf+pos;
79 memcpy(p->argbuf+pos,argv[i],len);
84 for(int i = 0; i < nenvp; i++)
86 int len = strlen(envp[i])+1;
87 if(pos+len > PROCINFO_ARGBUF_SIZE)
89 p->argp[nargv+1+i] = ((procinfo_t*)UINFO)->argbuf+pos;
90 memcpy(p->argbuf+pos,envp[i],len);
93 p->argp[nargv+nenvp+1] = 0;
98 // this is how user programs access the procinfo page
100 # define __procinfo (*(procinfo_t*)UINFO)
102 #include <ros/common.h>
103 #include <ros/atomic.h>
104 #include <ros/syscall.h>
106 /* Figure out what your vcoreid is from your pcoreid and procinfo. Only low
107 * level or debugging code should call this. */
108 static inline uint32_t __get_vcoreid_from_procinfo(void)
110 /* The assumption is that any IPIs/KMSGs would knock userspace into the
111 * kernel before it could read the closing of the seqctr. Put another way,
112 * there is a 'memory barrier' between the IPI write and the seqctr write.
113 * I think this is true. */
114 uint32_t kpcoreid, kvcoreid;
118 old_seq = __procinfo.coremap_seqctr;
119 kpcoreid = __ros_syscall(SYS_getpcoreid, 0, 0, 0, 0, 0, 0, NULL);
120 if (!__procinfo.pcoremap[kpcoreid].valid)
122 kvcoreid = __procinfo.pcoremap[kpcoreid].vcoreid;
123 } while (seqctr_retry(old_seq, __procinfo.coremap_seqctr));
127 static inline uint32_t __get_vcoreid(void)
129 /* since sys_getvcoreid could lie (and might never change) */
130 return __get_vcoreid_from_procinfo();
133 #endif /* ifndef ROS_KERNEL */
135 #endif // !ROS_PROCDATA_H