arch.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  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 phase */
  50. l1cache->wbse(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. l1cache->wbse(p, sizeof *p); /* is this needed? */
  122. l1cache->wb(); /* is this needed? */
  123. }
  124. void
  125. procrestore(Proc* p)
  126. {
  127. uvlong t;
  128. if(p->kp)
  129. return;
  130. cycles(&t);
  131. p->pcycles -= t;
  132. wakewfi(); /* in case there's another runnable proc */
  133. /* let it fault in at first use */
  134. // fpuprocrestore(p);
  135. l1cache->wb(); /* system is more stable with this */
  136. }
  137. int
  138. userureg(Ureg* ureg)
  139. {
  140. return (ureg->psr & PsrMask) == PsrMusr;
  141. }