arch.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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. cycles(&t);
  45. tos->kcycles += t - up->kentry;
  46. tos->pcycles = up->pcycles;
  47. tos->cyclefreq = m->cpuhz;
  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. // TODO: save and restore VFPv3 FP state once 5[cal] know the new registers.
  121. fpuprocsave(p);
  122. }
  123. void
  124. procrestore(Proc* p)
  125. {
  126. uvlong t;
  127. if(p->kp)
  128. return;
  129. cycles(&t);
  130. p->pcycles -= t;
  131. fpuprocrestore(p);
  132. }
  133. int
  134. userureg(Ureg* ureg)
  135. {
  136. return (ureg->psr & PsrMask) == PsrMusr;
  137. }
  138. /*
  139. * atomic ops
  140. * make sure that we don't drag in the C library versions
  141. */
  142. long
  143. _xdec(long *p)
  144. {
  145. int s, v;
  146. s = splhi();
  147. v = --*p;
  148. splx(s);
  149. return v;
  150. }
  151. void
  152. _xinc(long *p)
  153. {
  154. int s;
  155. s = splhi();
  156. ++*p;
  157. splx(s);
  158. }
  159. int
  160. ainc(int *p)
  161. {
  162. int s, v;
  163. s = splhi();
  164. v = ++*p;
  165. splx(s);
  166. return v;
  167. }
  168. int
  169. adec(int *p)
  170. {
  171. int s, v;
  172. s = splhi();
  173. v = --*p;
  174. splx(s);
  175. return v;
  176. }
  177. int
  178. cas32(void* addr, u32int old, u32int new)
  179. {
  180. int r, s;
  181. s = splhi();
  182. if(r = (*(u32int*)addr == old))
  183. *(u32int*)addr = new;
  184. splx(s);
  185. if (r)
  186. coherence();
  187. return r;
  188. }