arch.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  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. }
  50. /*
  51. * return the userpc the last exception happened at
  52. */
  53. uintptr
  54. userpc(void)
  55. {
  56. Ureg *ureg = up->dbgreg;
  57. return ureg->pc;
  58. }
  59. /* This routine must save the values of registers the user is not permitted
  60. * to write from devproc and then restore the saved values before returning.
  61. */
  62. void
  63. setregisters(Ureg* ureg, char* pureg, char* uva, int n)
  64. {
  65. USED(ureg, pureg, uva, n);
  66. }
  67. /*
  68. * this is the body for all kproc's
  69. */
  70. static void
  71. linkproc(void)
  72. {
  73. spllo();
  74. up->kpfun(up->kparg);
  75. pexit("kproc exiting", 0);
  76. }
  77. /*
  78. * setup stack and initial PC for a new kernel proc. This is architecture
  79. * dependent because of the starting stack location
  80. */
  81. void
  82. kprocchild(Proc *p, void (*func)(void*), void *arg)
  83. {
  84. p->sched.pc = PTR2UINT(linkproc);
  85. p->sched.sp = PTR2UINT(p->kstack+KSTACK);
  86. p->kpfun = func;
  87. p->kparg = arg;
  88. }
  89. /*
  90. * pc output by dumpaproc
  91. */
  92. uintptr
  93. dbgpc(Proc* p)
  94. {
  95. Ureg *ureg;
  96. ureg = p->dbgreg;
  97. if(ureg == 0)
  98. return 0;
  99. return ureg->pc;
  100. }
  101. /*
  102. * set mach dependent process state for a new process
  103. */
  104. void
  105. procsetup(Proc* p)
  106. {
  107. fpusysprocsetup(p);
  108. }
  109. /*
  110. * Save the mach dependent part of the process state.
  111. */
  112. void
  113. procsave(Proc* p)
  114. {
  115. fpuprocsave(p);
  116. }
  117. void
  118. procrestore(Proc* p)
  119. {
  120. uvlong t;
  121. if(p->kp)
  122. return;
  123. t = lcycles();
  124. p->pcycles -= t;
  125. fpuprocrestore(p);
  126. }
  127. int
  128. userureg(Ureg* ureg)
  129. {
  130. return (ureg->psr & PsrMask) == PsrMusr;
  131. }
  132. long
  133. _xdec(long *p)
  134. {
  135. int s, v;
  136. s = splhi();
  137. v = --*p;
  138. splx(s);
  139. return v;
  140. }
  141. void
  142. _xinc(long *p)
  143. {
  144. int s;
  145. s = splhi();
  146. ++*p;
  147. splx(s);
  148. }
  149. int
  150. cas32(void* addr, u32int old, u32int new)
  151. {
  152. int r, s;
  153. s = splhi();
  154. if(r = (*(u32int*)addr == old))
  155. *(u32int*)addr = new;
  156. splx(s);
  157. return r;
  158. }