mmap local APIC address

Vaibhav Jain vjoss197 at gmail.com
Thu Oct 20 14:50:33 EDT 2011


On Wed, Oct 19, 2011 at 11:02 AM, Vaibhav Jain <vjoss197 at gmail.com> wrote:

>
>
> On Wed, Oct 19, 2011 at 10:57 AM, bob <ilikepie420 at live.com> wrote:
>
>> It would be nice to share your solution in case someone else comes into
>> the same problem.
>>
> Hi,
>
> It was stupid mistake. I forgot to initialize the file descriptor which was
> passed to  mmap and therefore it was throwing "Bad file descriptor" error.i
> realized it after looking the errors in "man mmap".
>
> Thanks
> Vaibhav Jain
>
>
>

Hi,

I am now having another problem with the code. It throws a segmentation
fault as soon as it tries to write something into the ICR of the APIC.(line
highlighted below).
Is is not possible to do this through a user-level program ?


Here's the code

typedef unsigned int u32;
#define MAP_LEN                 0x1000  //4 KB page
#define BUFLEN 100
#define APIC_BASE               0xfee00000
#define APIC_ICR_low            0xfee00300
#define APIC_ICR_high           0xfee00310
#define APIC_ICR_init           0x00000500
#define APIC_ICR_start          0x00000600
#define APIC_ICR_ASSERT_LVL_TRG 0x0000c000
#define BOUNCE_CODE        0x2000
int apic_reset_cpu(cpu);
int cpu = 2;
int main(){
if ((apic_reset_cpu(cpu)) != 0)
    printf("INIT & Startup failed!\n");
}

int apic_reset_cpu(int cpu)
{
  unsigned long tmpaddress, apic_icr, *apic_phy_addr;
  int fd, sleep_now=0;

  printf("Assuming APIC physical base: %lx \n", APIC_BASE);
  tmpaddress = (unsigned long) mmap(NULL, MAP_LEN, PROT_READ|PROT_WRITE,
MAP_SHARED, fd, (off_t)APIC_BASE);

  if(tmpaddress == (unsigned long)MAP_FAILED) //check if it worked
  {
    perror("Mapping memory for absolute memory access failed.\n");
    return -3;
  }

  //prep ICR high
  apic_icr = tmpaddress;
  apic_icr |= APIC_ICR_high;
  apic_phy_addr = (unsigned long *) apic_icr;
 * *apic_phy_addr = cpu << 24;
*
  //prep ICR low Send INIT and wait
  apic_icr = tmpaddress;
  apic_icr |= APIC_ICR_low;
  apic_phy_addr = (unsigned long *) apic_icr;
  *apic_phy_addr = APIC_ICR_init | APIC_ICR_ASSERT_LVL_TRG;
  sleep_now = usleep( 10000 ); //sleep 10 ms
  //prep for SIPI
  apic_icr = tmpaddress;
  apic_icr |= APIC_ICR_low;
  apic_phy_addr = (unsigned long *) apic_icr;
  *apic_phy_addr = APIC_ICR_start | (BOUNCE_CODE >> 12);
  sleep_now = usleep( 500 ); //sleep 500 usec
  printf("Unmapping APIC Base page\n");
  tmpaddress &= 0xfffff000;
  munmap(tmpaddress, MAP_LEN);

  return 0;
}



Thanks
Vaibhav Jain
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20111020/5e2f552e/attachment.html 


More information about the Kernelnewbies mailing list