sipi.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "u.h"
  10. #include "../port/lib.h"
  11. #include "mem.h"
  12. #include "dat.h"
  13. #include "fns.h"
  14. #include "apic.h"
  15. #undef DBG
  16. #define DBG print
  17. #define SIPIHANDLER (KZERO+0x3000)
  18. void
  19. sipi(void)
  20. {
  21. extern int b1978;
  22. Apic *apic;
  23. Mach *mach;
  24. int apicno, i;
  25. uint32_t *sipiptr;
  26. uintmem sipipa;
  27. uint8_t *alloc, *p;
  28. extern void squidboy(int);
  29. /*
  30. * Move the startup code into place,
  31. * must be aligned properly.
  32. */
  33. sipipa = mmuphysaddr(SIPIHANDLER);
  34. if((sipipa & (4*KiB - 1)) || sipipa > (1*MiB - 2*4*KiB))
  35. return;
  36. sipiptr = UINT2PTR(SIPIHANDLER);
  37. memmove(sipiptr, &b1978, 4096);
  38. DBG("sipiptr %#p sipipa %#llx\n", sipiptr, sipipa);
  39. /*
  40. * Notes:
  41. * The Universal Startup Algorithm described in the MP Spec. 1.4.
  42. * The data needed per-processor is the sum of the stack, page
  43. * table pages, vsvm page and the Mach page. The layout is similar
  44. * to that described in data.h for the bootstrap processor, but
  45. * with any unused space elided.
  46. */
  47. for(apicno = 0; apicno < Napic; apicno++){
  48. apic = &xlapic[apicno];
  49. if(!apic->useable || apic->Ioapic.addr || apic->Lapic.machno == 0)
  50. continue;
  51. /*
  52. * NOTE: for now, share the page tables with the
  53. * bootstrap processor, until the lsipi code is worked out,
  54. * so only the Mach and stack portions are used below.
  55. */
  56. alloc = mallocalign(MACHSTKSZ+4*PTSZ+4*KiB+MACHSZ, 4096, 0, 0);
  57. if(alloc == nil)
  58. continue;
  59. memset(alloc, 0, MACHSTKSZ+4*PTSZ+4*KiB+MACHSZ);
  60. p = alloc+MACHSTKSZ;
  61. sipiptr[-1] = mmuphysaddr(PTR2UINT(p));
  62. DBG("p %#p sipiptr[-1] %#x\n", p, sipiptr[-1]);
  63. p += 4*PTSZ+4*KiB;
  64. /*
  65. * Committed. If the AP startup fails, can't safely
  66. * release the resources, who knows what mischief
  67. * the AP is up to. Perhaps should try to put it
  68. * back into the INIT state?
  69. */
  70. mach = (Mach*)p;
  71. mach->machno = apic->Lapic.machno; /* NOT one-to-one... */
  72. mach->splpc = PTR2UINT(squidboy);
  73. mach->apicno = apicno;
  74. mach->stack = PTR2UINT(alloc);
  75. mach->vsvm = alloc+MACHSTKSZ+4*PTSZ;
  76. //OH OH mach->pml4 = (PTE*)(alloc+MACHSTKSZ);
  77. p = KADDR(0x467);
  78. *p++ = sipipa;
  79. *p++ = sipipa>>8;
  80. *p++ = 0;
  81. *p = 0;
  82. nvramwrite(0x0f, 0x0a);
  83. //print("APICSIPI: %d, %p\n", apicno, (void *)sipipa);
  84. apicsipi(apicno, sipipa);
  85. for(i = 0; i < 1000; i++){
  86. if(mach->splpc == 0)
  87. break;
  88. millidelay(5);
  89. }
  90. nvramwrite(0x0f, 0x00);
  91. /*DBG("mach %#p (%#p) apicid %d machno %2d %dMHz\n",
  92. mach, sys->machptr[mach->machno],
  93. apicno, mach->machno, mach->cpumhz);*/
  94. }
  95. }