bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 01/12 gnumach] i386: Fix lapic and ioapic for smp


From: Samuel Thibault
Subject: Re: [PATCH 01/12 gnumach] i386: Fix lapic and ioapic for smp
Date: Tue, 31 Jan 2023 20:30:01 +0100
User-agent: NeoMutt/20170609 (1.8.3)

Applied, thanks!

Damien Zammit, le mar. 31 janv. 2023 09:35:21 +0000, a ecrit:
> Also-by: Almudena Garcia <liberamenso10000@gmail.com>
> ---
>  i386/i386/apic.c     |  87 ++++++++++++++++++++++++++++++---
>  i386/i386/apic.h     | 114 ++++++++++++++++++++++++++++++++++++++++---
>  i386/i386/smp.c      |  89 ++++++++++++++++++++++++++++++++-
>  i386/i386/smp.h      |   7 +++
>  i386/i386at/ioapic.c |  97 ++++++++++--------------------------
>  5 files changed, 307 insertions(+), 87 deletions(-)
> 
> diff --git a/i386/i386/apic.c b/i386/i386/apic.c
> index d30084e2..e53d4749 100644
> --- a/i386/i386/apic.c
> +++ b/i386/i386/apic.c
> @@ -19,6 +19,8 @@
>     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
> 
>  #include <i386/apic.h>
> +#include <i386/cpu.h>
> +#include <i386at/idt.h>
>  #include <string.h>
>  #include <vm/vm_kern.h>
>  #include <kern/printf.h>
> @@ -112,7 +114,7 @@ acpi_get_irq_override(uint8_t pin)
>   * apic_get_cpu_apic_id: returns the apic_id of a cpu.
>   * Receives as input the kernel ID of a CPU.
>   */
> -uint16_t
> +int
>  apic_get_cpu_apic_id(int kernel_id)
>  {
>      if (kernel_id >= NCPUS)
> @@ -121,6 +123,24 @@ apic_get_cpu_apic_id(int kernel_id)
>      return apic_data.cpu_lapic_list[kernel_id];
>  }
> 
> +
> +/*
> + * apic_get_cpu_kernel_id: returns the kernel_id of a cpu.
> + * Receives as input the APIC ID of a CPU.
> + */
> +int
> +apic_get_cpu_kernel_id(uint16_t apic_id)
> +{
> +    int i;
> +
> +    for (i = 0; i < apic_data.ncpus; i++) {
> +        if (apic_data.cpu_lapic_list[i] == apic_id)
> +            return i;
> +    }
> +
> +    return -1;
> +}
> +
>  /* apic_get_lapic: returns a reference to the common memory address for 
> Local APIC. */
>  volatile ApicLocalUnit*
>  apic_get_lapic(void)
> @@ -158,17 +178,13 @@ apic_get_num_ioapics(void)
>  /*
>   * apic_get_current_cpu: returns the apic_id of current cpu.
>   */
> -uint16_t
> +int
>  apic_get_current_cpu(void)
>  {
> -    uint16_t apic_id;
> -
>      if(lapic == NULL)
> -        apic_id = 0;
> -    else
> -        apic_id = lapic->apic_id.r;
> +        return -1;
> 
> -    return apic_id;
> +    return (lapic->apic_id.r >> 24) & 0xff;
>  }
> 
> 
> @@ -235,6 +251,61 @@ void apic_print_info(void)
>      }
>  }
> 
> +void apic_send_ipi(unsigned dest_shorthand, unsigned deliv_mode, unsigned 
> dest_mode, unsigned level, unsigned trig_mode, unsigned vector, unsigned 
> dest_id)
> +{
> +    IcrLReg icrl_values;
> +    IcrHReg icrh_values;
> +
> +    icrl_values.destination_shorthand = dest_shorthand;
> +    icrl_values.delivery_mode = deliv_mode;
> +    icrl_values.destination_mode = dest_mode;
> +    icrl_values.level = level;
> +    icrl_values.trigger_mode = trig_mode;
> +    icrl_values.vector = vector;
> +    icrh_values.destination_field = dest_id;
> +
> +    lapic->icr_high = icrh_values;
> +    lapic->icr_low = icrl_values;
> +}
> +
> +void
> +lapic_enable(void)
> +{
> +    unsigned long flags;
> +    int apic_id;
> +    volatile uint32_t dummy;
> +
> +    cpu_intr_save(&flags);
> +
> +    apic_id = apic_get_current_cpu();
> +
> +    dummy = lapic->dest_format.r;
> +    lapic->dest_format.r = 0xffffffff;               /* flat model */
> +    dummy = lapic->logical_dest.r;
> +    lapic->logical_dest.r = lapic->apic_id.r;        /* target self */
> +    dummy = lapic->lvt_lint0.r;
> +    lapic->lvt_lint0.r = dummy | LAPIC_DISABLE;
> +    dummy = lapic->lvt_lint1.r;
> +    lapic->lvt_lint1.r = dummy | LAPIC_DISABLE;
> +    dummy = lapic->lvt_performance_monitor.r;
> +    lapic->lvt_performance_monitor.r = dummy | LAPIC_DISABLE;
> +    if (apic_id != 0)
> +      {
> +        dummy = lapic->lvt_timer.r;
> +        lapic->lvt_timer.r = dummy | LAPIC_DISABLE;
> +      }
> +    dummy = lapic->task_pri.r;
> +    lapic->task_pri.r = 0;
> +
> +    /* Enable LAPIC to send or recieve IPI/SIPIs */
> +    dummy = lapic->spurious_vector.r;
> +    lapic->spurious_vector.r = dummy | LAPIC_ENABLE;
> +
> +    lapic->error_status.r = 0;
> +
> +    cpu_intr_restore(flags);
> +}
> +
>  void
>  lapic_eoi(void)
>  {
> diff --git a/i386/i386/apic.h b/i386/i386/apic.h
> index 0bb1bd73..ac083d26 100644
> --- a/i386/i386/apic.h
> +++ b/i386/i386/apic.h
> @@ -61,10 +61,99 @@ union ioapic_route_entry_union {
>      struct ioapic_route_entry both;
>  };
> 
> +
> +/* Grateful to trasterlabs for this snippet */
> +
> +typedef union u_icr_low
> +{
> +    uint32_t value[4];
> +    struct
> +    {
> +        uint32_t r;    // FEE0 0300H - 4 bytes
> +        unsigned :32;  // FEE0 0304H
> +        unsigned :32;  // FEE0 0308H
> +        unsigned :32;  // FEE0 030CH
> +    };
> +    struct
> +    {
> +        unsigned vector: 8; /* Vector of interrupt. Lowest 8 bits of routine 
> address */
> +        unsigned delivery_mode : 3;
> +        unsigned destination_mode: 1;
> +        unsigned delivery_status: 1;
> +        unsigned :1;
> +        unsigned level: 1;
> +        unsigned trigger_mode: 1;
> +        unsigned :2;
> +        unsigned destination_shorthand: 2;
> +        unsigned :12;
> +    };
> +} IcrLReg;
> +
> +typedef union u_icr_high
> +{
> +    uint32_t value[4];
> +    struct
> +    {
> +        uint32_t r; // FEE0 0310H - 4 bytes
> +        unsigned :32;  // FEE0 0314H
> +        unsigned :32;  // FEE0 0318H
> +        unsigned :32;  // FEE0 031CH
> +    };
> +    struct
> +    {
> +        unsigned :24; // FEE0 0310H - 4 bytes
> +        unsigned destination_field :8; /* APIC ID (in physical mode) or MDA 
> (in logical) of destination processor */
> +    };
> +} IcrHReg;
> +
> +
> +typedef enum e_icr_dest_shorthand
> +{
> +        NO_SHORTHAND = 0,
> +        SELF = 1,
> +        ALL_INCLUDING_SELF = 2,
> +        ALL_EXCLUDING_SELF = 3
> +} icr_dest_shorthand;
> +
> +typedef enum e_icr_deliv_mode
> +{
> +        FIXED = 0,
> +        LOWEST_PRIORITY = 1,
> +        SMI = 2,
> +        NMI = 4,
> +        INIT = 5,
> +        STARTUP = 6,
> +} icr_deliv_mode;
> +
> +typedef enum e_icr_dest_mode
> +{
> +        PHYSICAL = 0,
> +        LOGICAL = 1
> +} icr_dest_mode;
> +
> +typedef enum e_icr_deliv_status
> +{
> +        IDLE = 0,
> +        SEND_PENDING = 1
> +} icr_deliv_status;
> +
> +typedef enum e_icr_level
> +{
> +        DE_ASSERT = 0,
> +        ASSERT = 1
> +} icr_level;
> +
> +typedef enum e_irc_trigger_mode
> +{
> +        EDGE = 0,
> +        LEVEL = 1
> +} irc_trigger_mode;
> +
> +
>  typedef struct ApicLocalUnit {
>          ApicReg reserved0;               /* 0x000 */
>          ApicReg reserved1;               /* 0x010 */
> -        ApicReg apic_id;                 /* 0x020 */
> +        ApicReg apic_id;                 /* 0x020. Hardware ID of current 
> processor */
>          ApicReg version;                 /* 0x030 */
>          ApicReg reserved4;               /* 0x040 */
>          ApicReg reserved5;               /* 0x050 */
> @@ -84,8 +173,8 @@ typedef struct ApicLocalUnit {
>          ApicReg error_status;            /* 0x280 */
>          ApicReg reserved28[6];           /* 0x290 */
>          ApicReg lvt_cmci;                /* 0x2f0 */
> -        ApicReg icr_low;                 /* 0x300 */
> -        ApicReg icr_high;                /* 0x310 */
> +        IcrLReg icr_low;                 /* 0x300. Store the information to 
> send an IPI (Inter-processor Interrupt) */
> +        IcrHReg icr_high;                /* 0x310. Store the IPI destination 
>  */
>          ApicReg lvt_timer;               /* 0x320 */
>          ApicReg lvt_thermal;             /* 0x330 */
>          ApicReg lvt_performance_monitor; /* 0x340 */
> @@ -138,24 +227,27 @@ void apic_add_cpu(uint16_t apic_id);
>  void apic_lapic_init(ApicLocalUnit* lapic_ptr);
>  void apic_add_ioapic(struct IoApicData);
>  void apic_add_irq_override(struct IrqOverrideData irq_over);
> +void apic_send_ipi(unsigned dest_shorthand, unsigned deliv_mode, unsigned 
> dest_mode, unsigned level, unsigned trig_mode, unsigned vector, unsigned 
> dest_id);
>  IrqOverrideData *acpi_get_irq_override(uint8_t gsi);
> -uint16_t apic_get_cpu_apic_id(int kernel_id);
> +int apic_get_cpu_apic_id(int kernel_id);
> +int apic_get_cpu_kernel_id(uint16_t apic_id);
>  volatile ApicLocalUnit* apic_get_lapic(void);
>  struct IoApicData *apic_get_ioapic(int kernel_id);
>  uint8_t apic_get_numcpus(void);
>  uint8_t apic_get_num_ioapics(void);
> -uint16_t apic_get_current_cpu(void);
> +int apic_get_current_cpu(void);
>  void apic_print_info(void);
>  int apic_refit_cpulist(void);
>  void picdisable(void);
>  void lapic_eoi(void);
>  void ioapic_irq_eoi(int pin);
> +void lapic_enable(void);
>  void lapic_enable_timer(void);
>  void ioapic_mask_irqs(void);
>  void ioapic_toggle(int pin, int mask);
>  void ioapic_configure(void);
> 
> -extern int timer_pin;
> +extern int duplicate_pin;
>  extern void intnull(int unit);
>  extern volatile ApicLocalUnit* lapic;
> 
> @@ -172,9 +264,13 @@ extern volatile ApicLocalUnit* lapic;
>  # define IMCR_USE_PIC  0
>  # define IMCR_USE_APIC 1
> 
> +#define LAPIC_LOW_PRIO                 0x100
> +#define LAPIC_NMI                      0x400
> +#define LAPIC_EXTINT                   0x700
> +#define LAPIC_LEVEL_TRIGGERED          0x8000
> +
>  #define LAPIC_ENABLE                   0x100
>  #define LAPIC_FOCUS                    0x200
> -#define LAPIC_NMI                      0x400
>  #define LAPIC_ENABLE_DIRECTED_EOI      0x1000
>  #define LAPIC_DISABLE                  0x10000
>  #define LAPIC_TIMER_PERIODIC           0x20000
> @@ -198,6 +294,10 @@ extern volatile ApicLocalUnit* lapic;
>  #define IOAPIC_MASK_ENABLED            0
>  #define IOAPIC_MASK_DISABLED           1
> 
> +#define APIC_MSR                       0x1b
> +#define APIC_MSR_BSP                   0x100 /* Processor is a BSP */
> +#define APIC_MSR_ENABLE                0x800
> +
>  /* Set or clear a bit in a 255-bit APIC mask register.
>     These registers are spread through eight 32-bit registers.  */
>  #define APIC_SET_MASK_BIT(reg, bit) \
> diff --git a/i386/i386/smp.c b/i386/i386/smp.c
> index d7523a73..c351efaa 100644
> --- a/i386/i386/smp.c
> +++ b/i386/i386/smp.c
> @@ -18,11 +18,18 @@
>     along with this program; if not, write to the Free Software
>     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
> 
> -#include <i386/i386/apic.h>
> -#include <i386/i386/smp.h>
> +#include <i386/apic.h>
> +#include <i386/smp.h>
> +#include <i386/cpu.h>
> +#include <i386/pit.h>
> +#include <i386at/idt.h>
> +#include <i386at/acpi_parse_apic.h>
> +#include <kern/printf.h>
> +#include <mach/machine.h>
> 
>  #include <kern/smp.h>
> 
> +#define pause_memory asm volatile ("pause" : : : "memory")
> 
>  /*
>   * smp_data_init: initialize smp_data structure
> @@ -33,6 +40,84 @@ static void smp_data_init(void)
>  {
>      uint8_t numcpus = apic_get_numcpus();
>      smp_set_numcpus(numcpus);
> +
> +    for(int i = 0; i < numcpus; i++){
> +            machine_slot[i].is_cpu = TRUE;
> +    }
> +
> +}
> +
> +void smp_pmap_update(unsigned apic_id)
> +{
> +    unsigned long flags;
> +
> +    cpu_intr_save(&flags);
> +
> +    printf("Sending IPI(%u) to call TLB shootdown...", apic_id);
> +    apic_send_ipi(NO_SHORTHAND, FIXED, PHYSICAL, ASSERT, EDGE, 
> CALL_SINGLE_FUNCTION_BASE, apic_id);
> +
> +    do {
> +        pause_memory;
> +    } while(lapic->icr_low.delivery_status == SEND_PENDING);
> +
> +    printf("done\n");
> +
> +    cpu_intr_restore(flags);
> +}
> +
> +/* See Intel IA32/64 Software Developer's Manual 3A Section 8.4.4.1 */
> +void smp_startup_cpu(unsigned apic_id, unsigned vector)
> +{
> +    /* Clear APIC errors */
> +    lapic->error_status.r = 0;
> +
> +    printf("Sending IPIs to APIC ID %u...", apic_id);
> +
> +    /* Assert INIT IPI */
> +    apic_send_ipi(NO_SHORTHAND, INIT, PHYSICAL, ASSERT, LEVEL, 0, apic_id);
> +
> +    /* Wait for delivery */
> +    do {
> +        pause_memory;
> +    } while(lapic->icr_low.delivery_status == SEND_PENDING);
> +
> +    /* Deassert INIT IPI */
> +    apic_send_ipi(NO_SHORTHAND, INIT, PHYSICAL, DE_ASSERT, LEVEL, 0, 
> apic_id);
> +
> +    /* Wait for delivery */
> +    do {
> +        pause_memory;
> +    } while(lapic->icr_low.delivery_status == SEND_PENDING);
> +
> +    /* Wait 10 msec */
> +    pit_mdelay(10);
> +
> +    /* Clear APIC errors */
> +    lapic->error_status.r = 0;
> +
> +    /* First StartUp IPI */
> +    apic_send_ipi(NO_SHORTHAND, STARTUP, PHYSICAL, ASSERT, LEVEL, vector >> 
> 12, apic_id);
> +
> +    /* Wait 200 usec */
> +    pit_udelay(200);
> +
> +    /* Wait for delivery */
> +    do {
> +        pause_memory;
> +    } while(lapic->icr_low.delivery_status == SEND_PENDING);
> +
> +    /* Second StartUp IPI */
> +    apic_send_ipi(NO_SHORTHAND, STARTUP, PHYSICAL, ASSERT, LEVEL, vector >> 
> 12, apic_id);
> +
> +    /* Wait 200 usec */
> +    pit_udelay(200);
> +
> +    /* Wait for delivery */
> +    do {
> +        pause_memory;
> +    } while(lapic->icr_low.delivery_status == SEND_PENDING);
> +
> +    printf("done\n");
>  }
> 
>  /*
> diff --git a/i386/i386/smp.h b/i386/i386/smp.h
> index b36ead08..79337022 100644
> --- a/i386/i386/smp.h
> +++ b/i386/i386/smp.h
> @@ -18,4 +18,11 @@
>     along with this program; if not, write to the Free Software
>     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
> 
> +#ifndef _SMP_H_
> +#define _SMP_H_
> +
>  int smp_init(void);
> +void smp_pmap_update(unsigned apic_id);
> +void smp_startup_cpu(unsigned apic_id, unsigned vector);
> +
> +#endif
> diff --git a/i386/i386at/ioapic.c b/i386/i386at/ioapic.c
> index c5eb3536..d4269ef0 100644
> --- a/i386/i386at/ioapic.c
> +++ b/i386/i386at/ioapic.c
> @@ -32,8 +32,7 @@
>  #include <kern/printf.h>
> 
>  static int has_irq_specific_eoi = 1; /* FIXME: Assume all machines have this 
> */
> -static int timer_gsi;
> -int timer_pin;
> +int duplicate_pin;
> 
>  uint32_t lapic_timer_val = 0;
>  uint32_t calibrated_ticks = 0;
> @@ -78,6 +77,7 @@ void
>  picdisable(void)
>  {
>      asm("cli");
> +    curr_ipl = SPLHI;
> 
>      /*
>      ** Disable PIC
> @@ -147,40 +147,13 @@ ioapic_toggle_entry(int apic, int pin, int mask)
>      ioapic_write(apic, APIC_IO_REDIR_LOW(pin), entry.lo);
>  }
> 
> -static void
> -cpu_rdmsr(uint32_t msr, uint32_t *lo, uint32_t *hi)
> -{
> -   __asm__ __volatile__("rdmsr" : "=a"(*lo), "=d"(*hi) : "c"(msr));
> -}
> -
> -static void
> -cpu_wrmsr(uint32_t msr, uint32_t lo, uint32_t hi)
> -{
> -   __asm__ __volatile__("wrmsr" : : "a"(lo), "d"(hi), "c"(msr));
> -}
> -
> -static void
> -global_enable_apic(void)
> -{
> -    uint32_t lo = 0;
> -    uint32_t hi = 0;
> -    uint32_t msr = 0x1b;
> -
> -    cpu_rdmsr(msr, &lo, &hi);
> -
> -    if (!(lo & (1 << 11))) {
> -        lo |= (1 << 11);
> -        cpu_wrmsr(msr, lo, hi);
> -    }
> -}
> -
>  static uint32_t
>  pit_measure_apic_hz(void)
>  {
>      uint32_t start = 0xffffffff;
> 
> -    /* Prepare accurate delay for 1/100 seconds */
> -    pit_prepare_sleep(100);
> +    /* Prepare accurate delay for 1/hz seconds */
> +    pit_prepare_sleep(hz);
> 
>      /* Set APIC timer */
>      lapic->init_count.r = start;
> @@ -189,7 +162,7 @@ pit_measure_apic_hz(void)
>      pit_sleep();
> 
>      /* Stop APIC timer */
> -    lapic->lvt_timer.r = LAPIC_DISABLE;
> +    lapic->lvt_timer.r |= LAPIC_DISABLE;
> 
>      return start - lapic->cur_count.r;
>  }
> @@ -203,26 +176,18 @@ void lapic_update_timer(void)
>  void
>  lapic_enable_timer(void)
>  {
> -    spl_t s;
> -
> -    s = sploff();
> -    asm("cli");
> -
>      /* Set up counter */
>      lapic->init_count.r = calibrated_ticks;
>      lapic->divider_config.r = LAPIC_TIMER_DIVIDE_16;
> 
>      /* Set the timer to interrupt periodically on remapped timer GSI */
> -    lapic->lvt_timer.r = (IOAPIC_INT_BASE + timer_gsi) | 
> LAPIC_TIMER_PERIODIC;
> +    lapic->lvt_timer.r = IOAPIC_INT_BASE | LAPIC_TIMER_PERIODIC;
> 
>      /* Some buggy hardware requires this set again */
>      lapic->divider_config.r = LAPIC_TIMER_DIVIDE_16;
> 
> -    /* Unmask the remapped timer pin and pin 0 always */
> -    ioapic_toggle(0, IOAPIC_MASK_ENABLED);
> -    ioapic_toggle(timer_pin, IOAPIC_MASK_ENABLED);
> -
> -    splon(s);
> +    /* Enable interrupts for the first time on BSP */
> +    asm("sti");
>      printf("LAPIC timer configured\n");
>  }
> 
> @@ -239,6 +204,9 @@ ioapic_irq_eoi(int pin)
>      int apic = 0;
>      union ioapic_route_entry_union oldentry, entry;
> 
> +    if (pin == 0)
> +        goto skip_specific_eoi;
> +
>      if (!has_irq_specific_eoi) {
>          /* Workaround for old IOAPICs with no specific EOI */
> 
> @@ -258,6 +226,7 @@ ioapic_irq_eoi(int pin)
>          ioapic->eoi.r = entry.both.vector;
>      }
> 
> +skip_specific_eoi:
>      lapic_eoi ();
>  }
> 
> @@ -303,12 +272,12 @@ ioapic_configure(void)
>      /* Assume first IO APIC maps to GSI base 0 */
>      int gsi, apic = 0, bsp = 0, pin;
>      IrqOverrideData *irq_over;
> +    int timer_gsi;
> 
>      /* Disable IOAPIC interrupts and set spurious interrupt */
>      lapic->spurious_vector.r = IOAPIC_SPURIOUS_BASE;
> 
>      union ioapic_route_entry_union entry = {{0, 0}};
> -    union ioapic_route_entry_union timer_entry = {{0, 0}};
> 
>      entry.both.delvmode = IOAPIC_FIXED;
>      entry.both.destmode = IOAPIC_PHYSICAL;
> @@ -332,16 +301,17 @@ ioapic_configure(void)
>          if (pin == 0) {
>              /* Save timer info */
>              timer_gsi = gsi;
> -            timer_entry = entry;
>          } else {
> -            /* Get the actual timer pin by assuming that the pin
> -             * with duplicated gsi from pin 0 maps to the timer pin */
> +            /* Disable duplicated timer gsi */
>              if (gsi == timer_gsi) {
> -                timer_pin = pin;
> -                /* Remap pin 0 interrupt vector to GSI base
> +                duplicate_pin = pin;
> +                /* Remap this interrupt pin to GSI base
>                   * so we don't duplicate vectors */
> -                timer_entry.both.vector = IOAPIC_INT_BASE;
> -                ioapic_write_entry(apic, 0, timer_entry.both);
> +                entry.both.vector = IOAPIC_INT_BASE;
> +                ioapic_write_entry(apic, duplicate_pin, entry.both);
> +                /* Mask the ioapic pin with deduplicated vector as
> +              * we will never use it, since timer is on another gsi */
> +                mask_irq(duplicate_pin);
>              }
>          }
>      }
> @@ -361,16 +331,7 @@ ioapic_configure(void)
>      }
> 
>      /* Start the IO APIC receiving interrupts */
> -    lapic->apic_id.r = apic_get_cpu_apic_id(bsp);
> -    lapic->dest_format.r = 0xffffffff;       /* flat model */
> -    lapic->logical_dest.r = 0x01000000;      /* target bsp */
> -    lapic->lvt_timer.r = LAPIC_DISABLE;
> -    lapic->lvt_performance_monitor.r = LAPIC_NMI;
> -    lapic->lvt_lint0.r = LAPIC_DISABLE;
> -    lapic->lvt_lint1.r = LAPIC_DISABLE;
> -    lapic->task_pri.r = 0;
> -
> -    global_enable_apic();
> +    lapic_enable();
> 
>      /* Enable IOAPIC processor focus */
>      lapic->spurious_vector.r |= LAPIC_FOCUS;
> @@ -381,23 +342,19 @@ ioapic_configure(void)
>          lapic->spurious_vector.r |= LAPIC_ENABLE_DIRECTED_EOI;
>      }
> 
> -    /* Enable IOAPIC interrupts */
> -    lapic->spurious_vector.r |= LAPIC_ENABLE;
> -
>      /* Set one-shot timer */
>      lapic->divider_config.r = LAPIC_TIMER_DIVIDE_16;
> -    lapic->lvt_timer.r = IOAPIC_INT_BASE + timer_gsi;
> +    lapic->lvt_timer.r = IOAPIC_INT_BASE;
> 
> -    /* Measure number of APIC timer ticks in 10ms */
> -    calibrated_ticks = pit_measure_apic_hz();
> +    /* Measure number of APIC timer ticks in 1/hz seconds
> +     * but calibrate the timer to expire at rate of hz */
> +    calibrated_ticks = pit_measure_apic_hz() * hz;
> 
>      /* Set up counter later */
>      lapic->lvt_timer.r = LAPIC_DISABLE;
> 
> -    /* Install clock interrupt handler on both remapped timer pin and pin 0
> -     * since nobody knows how all x86 timers are wired up */
> +    /* Install clock interrupt handler on pin 0 */
>      ivect[0] = (interrupt_handler_fn)hardclock;
> -    ivect[timer_pin] = (interrupt_handler_fn)hardclock;
> 
>      printf("IOAPIC 0 configured\n");
>  }
> --
> 2.34.1
> 
> 
> 

-- 
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]