spike_util.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /*
  2. * Copyright (c) 2013, The Regents of the University of California (Regents).
  3. * All Rights Reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * 3. Neither the name of the Regents nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
  17. * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
  18. * OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
  19. * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  20. *
  21. * REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  22. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  23. * PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
  24. * HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
  25. * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  26. */
  27. #include "u.h"
  28. #include "../port/lib.h"
  29. #include "mem.h"
  30. #include "dat.h"
  31. #include "fns.h"
  32. #include "spike_util.h"
  33. uintptr_t translate_address(uintptr_t vAddr) {
  34. // TODO: implement the page table translation algorithm
  35. //uintptr_t pageTableRoot = read_csr(sptbr);
  36. uintptr_t physAddrMask = 0xfffffff;
  37. uintptr_t translationResult = vAddr & physAddrMask;
  38. print("Translated virtual address 0x%llx to physical address 0x%llx\n", vAddr, translationResult);
  39. return translationResult;
  40. }
  41. uintptr_t mcall_query_memory(uintptr_t id, memory_block_info *p)
  42. {
  43. uintptr_t physicalAddr = translate_address((uintptr_t) p);
  44. memory_block_info *info = (memory_block_info*) physicalAddr;
  45. if (id == 0) {
  46. info->base = 0x1000000; // hard coded for now, but we can put these values somewhere later
  47. info->size = 0x7F000000 - info->base;
  48. return 0;
  49. }
  50. return -1;
  51. }
  52. uintptr_t mcall_send_ipi(uintptr_t recipient)
  53. {
  54. //if (recipient >= num_harts)
  55. //return -1;
  56. if (atomic_swap(&OTHER_HLS(recipient)->ipi_pending, 1) == 0) {
  57. mb();
  58. write_csr(send_ipi, recipient);
  59. }
  60. return 0;
  61. }
  62. uintptr_t mcall_clear_ipi(void)
  63. {
  64. // only clear SSIP if no other events are pending
  65. if (HLS()->device_response_queue_head == NULL) {
  66. clear_csr(mip, MIP_SSIP);
  67. mb();
  68. }
  69. return atomic_swap(&HLS()->ipi_pending, 0);
  70. }
  71. uintptr_t mcall_shutdown(void)
  72. {
  73. while (1) write_csr(mtohost, 1);
  74. return 0;
  75. }
  76. uintptr_t mcall_set_timer(unsigned long long when)
  77. {
  78. write_csr(mtimecmp, when);
  79. clear_csr(mip, MIP_STIP);
  80. set_csr(mie, MIP_MTIP);
  81. return 0;
  82. }
  83. uintptr_t mcall_dev_req(sbi_device_message *m)
  84. {
  85. if ((m->dev > 0xFFU) | (m->cmd > 0xFFU) | (m->data > 0x0000FFFFFFFFFFFFU)) return -EINVAL;
  86. while (swap_csr(mtohost, TOHOST_CMD(m->dev, m->cmd, m->data)) != 0);
  87. m->sbi_private_data = (uintptr_t)HLS()->device_request_queue_head;
  88. HLS()->device_request_queue_head = m;
  89. HLS()->device_request_queue_size++;
  90. return 0;
  91. }
  92. uintptr_t mcall_dev_resp(void)
  93. {
  94. htif_interrupt(0, 0);
  95. sbi_device_message* m = HLS()->device_response_queue_head;
  96. if (m) {
  97. //printm("resp %p\n", m);
  98. sbi_device_message* next = (void*)atomic_read(&m->sbi_private_data);
  99. HLS()->device_response_queue_head = next;
  100. if (!next) {
  101. HLS()->device_response_queue_tail = 0;
  102. // only clear SSIP if no other events are pending
  103. clear_csr(mip, MIP_SSIP);
  104. mb();
  105. if (HLS()->ipi_pending) set_csr(mip, MIP_SSIP);
  106. }
  107. }
  108. return (uintptr_t)m;
  109. }
  110. uintptr_t mcall_hart_id(void)
  111. {
  112. return HLS()->hart_id;
  113. }
  114. void hls_init(uint32_t hart_id)
  115. {
  116. memset(HLS(), 0, sizeof(*HLS()));
  117. HLS()->hart_id = hart_id;
  118. }
  119. uintptr_t htif_interrupt(uintptr_t mcause, uintptr_t* regs) {
  120. uintptr_t fromhost = swap_csr(mfromhost, 0);
  121. if (!fromhost)
  122. return 0;
  123. uintptr_t dev = FROMHOST_DEV(fromhost);
  124. uintptr_t cmd = FROMHOST_CMD(fromhost);
  125. uintptr_t data = FROMHOST_DATA(fromhost);
  126. sbi_device_message* m = HLS()->device_request_queue_head;
  127. sbi_device_message* prev = 0x0;
  128. unsigned long i, n;
  129. for (i = 0, n = HLS()->device_request_queue_size; i < n; i++) {
  130. /*
  131. if (!supervisor_paddr_valid(m, sizeof(*m))
  132. && EXTRACT_FIELD(read_csr(mstatus), MSTATUS_PRV1) != PRV_M)
  133. panic("htif: page fault");
  134. */
  135. sbi_device_message* next = (void*)m->sbi_private_data;
  136. if (m->dev == dev && m->cmd == cmd) {
  137. m->data = data;
  138. // dequeue from request queue
  139. if (prev)
  140. prev->sbi_private_data = (uintptr_t)next;
  141. else
  142. HLS()->device_request_queue_head = next;
  143. HLS()->device_request_queue_size = n-1;
  144. m->sbi_private_data = 0;
  145. // enqueue to response queue
  146. if (HLS()->device_response_queue_tail)
  147. {
  148. HLS()->device_response_queue_tail->sbi_private_data = (uintptr_t)m;
  149. }
  150. else
  151. {
  152. HLS()->device_response_queue_head = m;
  153. }
  154. HLS()->device_response_queue_tail = m;
  155. // signal software interrupt
  156. set_csr(mip, MIP_SSIP);
  157. return 0;
  158. }
  159. prev = m;
  160. m = (void*)atomic_read(&m->sbi_private_data);
  161. }
  162. //HLT();
  163. return 0;
  164. //panic("htif: no record");
  165. }
  166. uintptr_t mcall_console_putchar(uint8_t ch)
  167. {
  168. while (swap_csr(mtohost, TOHOST_CMD(1, 1, ch)) != 0);
  169. while (1) {
  170. uintptr_t fromhost = read_csr(mfromhost);
  171. if (FROMHOST_DEV(fromhost) != 1 || FROMHOST_CMD(fromhost) != 1) {
  172. if (fromhost)
  173. htif_interrupt(0, 0);
  174. continue;
  175. }
  176. write_csr(mfromhost, 0);
  177. break;
  178. }
  179. return 0;
  180. }
  181. void testPrint(void) {
  182. /* Print a test command to check Spike console output */
  183. mcall_console_putchar('h');
  184. mcall_console_putchar('e');
  185. mcall_console_putchar('l');
  186. mcall_console_putchar('l');
  187. mcall_console_putchar('o');
  188. mcall_console_putchar('\n');
  189. }