mailbox.c 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /*****************************************************************
  2. * mailbox.c
  3. * by Zhiyi Huang, [email protected]
  4. * University of Otago
  5. *
  6. ********************************************************************/
  7. #include "types.h"
  8. #include "defs.h"
  9. #include "param.h"
  10. #include "traps.h"
  11. #include "spinlock.h"
  12. #include "fs.h"
  13. #include "file.h"
  14. #include "memlayout.h"
  15. #include "mmu.h"
  16. #include "proc.h"
  17. #include "arm.h"
  18. #include "mailbox.h"
  19. /* Note: for more tags refer to
  20. https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface */
  21. /* Note for Matthew: support more than one tag in buffer */
  22. void
  23. create_request(volatile uint *mbuf, uint tag, uint buflen, uint len, uint *data)
  24. {
  25. int i;
  26. volatile uint *tag_info;
  27. uint nw, tag_len, total_len;
  28. tag_info = mbuf + POS_TAG;
  29. tag_info[POS_TAG_ID] = tag;
  30. tag_info[POS_TAG_BUFLEN] = buflen;
  31. tag_info[POS_TAG_DATALEN] = len & 0x7FFFFFFF;
  32. nw = buflen >> 2;
  33. if (!data)
  34. for (i = 0; i < nw; ++i) tag_info[POS_TAG_DATA + i] = 0;
  35. else
  36. for (i = 0; i < nw; ++i) tag_info[POS_TAG_DATA + i] = data[i];
  37. tag_info[POS_TAG_DATA+nw] = 0; // indicate end of tag
  38. tag_len = mbuf[MB_HEADER_LENGTH + POS_TAG_BUFLEN];
  39. total_len = (MB_HEADER_LENGTH*4) + (TAG_HEADER_LENGTH*4) + tag_len + 4;
  40. mbuf[POS_OVERALL_LENGTH] = total_len;
  41. mbuf[POS_RV] = MPI_REQUEST;
  42. }
  43. volatile uint *mailbuffer;
  44. void mailboxinit()
  45. {
  46. mailbuffer = (uint *)kalloc();
  47. }
  48. uint
  49. readmailbox(u8 channel)
  50. {
  51. uint x, y, z;
  52. again:
  53. while ((inw(MAILBOX_BASE+24) & 0x40000000) != 0);
  54. x = inw(MAILBOX_BASE);
  55. z = x & 0xf; y = (uint)(channel & 0xf);
  56. if(z != y) goto again;
  57. return x&0xfffffff0;
  58. }
  59. void
  60. writemailbox(uint *addr, u8 channel)
  61. {
  62. uint x, y, a;
  63. a = (uint)addr;
  64. a -= KERNBASE; /* convert to ARM physical address */
  65. a += 0x40000000; /* convert to VC address space */
  66. x = a & 0xfffffff0;
  67. y = x | (uint)(channel & 0xf);
  68. flush_dcache_all();
  69. while ((inw(MAILBOX_BASE+24) & 0x80000000) != 0);
  70. outw(MAILBOX_BASE+32, y);
  71. }