arch.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. #include "u.h"
  2. #include "../port/lib.h"
  3. #include "mem.h"
  4. #include "dat.h"
  5. #include "fns.h"
  6. #include "../port/error.h"
  7. #include <tos.h>
  8. #include "ureg.h"
  9. #include "arm.h"
  10. /*
  11. * A lot of this stuff doesn't belong here
  12. * but this is a convenient dumping ground for
  13. * later sorting into the appropriate buckets.
  14. */
  15. /* Give enough context in the ureg to produce a kernel stack for
  16. * a sleeping process
  17. */
  18. void
  19. setkernur(Ureg* ureg, Proc* p)
  20. {
  21. ureg->pc = p->sched.pc;
  22. ureg->sp = p->sched.sp+4;
  23. ureg->r14 = PTR2UINT(sched);
  24. }
  25. /*
  26. * called in sysfile.c
  27. */
  28. void
  29. evenaddr(uintptr addr)
  30. {
  31. if(addr & 3){
  32. postnote(up, 1, "sys: odd address", NDebug);
  33. error(Ebadarg);
  34. }
  35. }
  36. /* go to user space */
  37. void
  38. kexit(Ureg*)
  39. {
  40. uvlong t;
  41. Tos *tos;
  42. /* precise time accounting, kernel exit */
  43. tos = (Tos*)(USTKTOP-sizeof(Tos));
  44. t = fastticks(nil);
  45. tos->kcycles += t - up->kentry;
  46. tos->pcycles = up->pcycles;
  47. tos->cyclefreq = Frequency;
  48. tos->pid = up->pid;
  49. /* make visible immediately to user proc */
  50. cachedwbinvse(tos, sizeof *tos);
  51. }
  52. /*
  53. * return the userpc the last exception happened at
  54. */
  55. uintptr
  56. userpc(void)
  57. {
  58. Ureg *ureg = up->dbgreg;
  59. return ureg->pc;
  60. }
  61. /* This routine must save the values of registers the user is not permitted
  62. * to write from devproc and then restore the saved values before returning.
  63. */
  64. void
  65. setregisters(Ureg* ureg, char* pureg, char* uva, int n)
  66. {
  67. USED(ureg, pureg, uva, n);
  68. }
  69. /*
  70. * this is the body for all kproc's
  71. */
  72. static void
  73. linkproc(void)
  74. {
  75. spllo();
  76. up->kpfun(up->kparg);
  77. pexit("kproc exiting", 0);
  78. }
  79. /*
  80. * setup stack and initial PC for a new kernel proc. This is architecture
  81. * dependent because of the starting stack location
  82. */
  83. void
  84. kprocchild(Proc *p, void (*func)(void*), void *arg)
  85. {
  86. p->sched.pc = PTR2UINT(linkproc);
  87. p->sched.sp = PTR2UINT(p->kstack+KSTACK);
  88. p->kpfun = func;
  89. p->kparg = arg;
  90. }
  91. /*
  92. * pc output by dumpaproc
  93. */
  94. uintptr
  95. dbgpc(Proc* p)
  96. {
  97. Ureg *ureg;
  98. ureg = p->dbgreg;
  99. if(ureg == 0)
  100. return 0;
  101. return ureg->pc;
  102. }
  103. /*
  104. * set mach dependent process state for a new process
  105. */
  106. void
  107. procsetup(Proc* p)
  108. {
  109. fpusysprocsetup(p);
  110. }
  111. /*
  112. * Save the mach dependent part of the process state.
  113. */
  114. void
  115. procsave(Proc* p)
  116. {
  117. uvlong t;
  118. cycles(&t);
  119. p->pcycles += t;
  120. fpuprocsave(p);
  121. }
  122. void
  123. procrestore(Proc* p)
  124. {
  125. uvlong t;
  126. if(p->kp)
  127. return;
  128. t = lcycles();
  129. p->pcycles -= t;
  130. fpuprocrestore(p);
  131. }
  132. int
  133. userureg(Ureg* ureg)
  134. {
  135. return (ureg->psr & PsrMask) == PsrMusr;
  136. }
  137. /*
  138. * atomic ops
  139. * make sure that we don't drag in the C library versions
  140. */
  141. long
  142. _xdec(long *p)
  143. {
  144. int s, v;
  145. s = splhi();
  146. v = --*p;
  147. splx(s);
  148. return v;
  149. }
  150. void
  151. _xinc(long *p)
  152. {
  153. int s;
  154. s = splhi();
  155. ++*p;
  156. splx(s);
  157. }
  158. int
  159. ainc(int *p)
  160. {
  161. int s, v;
  162. s = splhi();
  163. v = ++*p;
  164. splx(s);
  165. return v;
  166. }
  167. int
  168. adec(int *p)
  169. {
  170. int s, v;
  171. s = splhi();
  172. v = --*p;
  173. splx(s);
  174. return v;
  175. }
  176. int
  177. cas32(void* addr, u32int old, u32int new)
  178. {
  179. int r, s;
  180. s = splhi();
  181. if(r = (*(u32int*)addr == old))
  182. *(u32int*)addr = new;
  183. splx(s);
  184. if (r)
  185. coherence();
  186. return r;
  187. }