Hi,<br><br>I am trying to execute a c program to send the INIT-SIPI-SIPI sequence to <br>a core after making it go offline (echo 0 &gt; /sys/devices/system/cpu/cpu3/online). But it seems <br>that the program is not working because when it reads back the apic register just after writing to it <br>
the value is not the same as what was written.Following is the code for the program. The apic id <br>of the core to be restarted is 5 as seen from cat /proc/cpuinfo. Please let me know if I am doing something wrong.<br><br>
Thanks<br>- Vaibhav Jain<br><b><u><br>Code :<br></u></b><br>typedef unsigned int u32;<br><br>#define MAP_LEN                 0x1000  //4 KB page<br>#define BUFLEN 100<br>#define APIC_BASE               0xfee00000<br>#define APIC_ICR_low            0xfee00300<br>
#define APIC_ICR_high           0xfee00310<br>#define APIC_ICR_init             0x00004500<br>#define APIC_ICR_start           0x00004600<br>#define BOUNCE_CODE        0x1000<br><br>int apic_reset_cpu(cpu); <br><br>int main() <br>
{<br>  int cpu;<br>  <br>  //make sure we have root permissions<br>  if(iopl(3))<br>  {<br>    printf(&quot;Cannot get I/O permissions (being root helps)\n&quot;);<br>    return -1;<br>  }<br><br>  cpu = 5;<br> <br>if ((apic_reset_cpu(cpu)) != 0)<br>
    printf(&quot;INIT &amp; Startup failed!\n&quot;);<br>  <br>  printf(&quot;INIT / SIPI sequence complete\n&quot;);<br>  <br>  return 0;<br>}<br><br><br>int apic_reset_cpu(int cpu)<br>{<br>  unsigned long tmpaddress, apic_icr, *apic_phy_addr;<br>
  int fd, sleep_now=0;<br><br>   //open the main memory file<br>  fd = open ( &quot;/dev/mem&quot;, O_RDWR);  <br><br>  printf(&quot;Assuming APIC physical base: %lx \n&quot;, APIC_BASE);<br>  tmpaddress = (unsigned long) mmap(NULL, MAP_LEN, PROT_READ|PROT_WRITE, MAP_SHARED, fd, (off_t)APIC_BASE);<br>
  <br>  if(tmpaddress == (unsigned long)MAP_FAILED) //check if it worked<br>  {<br>    perror(&quot;Mapping memory for absolute memory access failed.\n&quot;);<br>    return -3;<br>  }<br>  <br>  //prep ICR high<br>  apic_icr = tmpaddress;<br>
  apic_icr +=0x310;<br>  apic_phy_addr = (unsigned long *) apic_icr;<br>  *apic_phy_addr = cpu &lt;&lt; 24;<br>  <br>  //read the value back <br>   printf(&quot;\nICR high = %lx\n&quot;,*apic_phy_addr);<br> <br>  //prep ICR low Send INIT and wait<br>
  apic_icr = tmpaddress;<br>  apic_icr += 0x300;<br>  apic_phy_addr = (unsigned long *) apic_icr;<br>  *apic_phy_addr = APIC_ICR_init;<br>  sleep_now = usleep( 10000 ); //sleep 10 ms<br><br>  printf(&quot;\nINIT SENT\n&quot;);<br>
<br>//read the value back<br> printf(&quot;\nICR low = %lx\n&quot;,*apic_phy_addr);<br><br> //prep ICR high again*<br>  apic_icr = tmpaddress;<br>  apic_icr +=0x310;<br>  apic_phy_addr = (unsigned long *) apic_icr;<br>  *apic_phy_addr = cpu &lt;&lt; 24;<br>
<br><br>  //prep for SIPI<br>  apic_icr = tmpaddress;<br>  apic_icr += 0x300;<br>  apic_phy_addr = (unsigned long *) apic_icr;<br>  *apic_phy_addr = APIC_ICR_start | (BOUNCE_CODE &gt;&gt; 12);<br>  sleep_now = usleep( 500 ); //sleep 500 usec <br>
<br>  printf(&quot;\nSIPI SENT\n&quot;);<br>  <br> //read the value back<br>  printf(&quot;\nICR low = %lx\n&quot;,*apic_phy_addr);<br><br>  *apic_phy_addr = APIC_ICR_start | (BOUNCE_CODE &gt;&gt; 12);<br><br>  printf(&quot;\nSIPI SENT AGAIN\n&quot;);<br>
  <br> //read the value back<br>  printf(&quot;\nICR low = %lx\n&quot;,*apic_phy_addr);<br>  printf(&quot;Unmapping APIC Base page\n&quot;);<br><br>  tmpaddress &amp;= 0xfffff000;<br>  munmap(tmpaddress, MAP_LEN);  <br>  <br>
  return 0;<br>}<br>  <br>