summaryrefslogtreecommitdiff
path: root/i386/i386/apic.h
diff options
context:
space:
mode:
Diffstat (limited to 'i386/i386/apic.h')
-rw-r--r--i386/i386/apic.h146
1 files changed, 136 insertions, 10 deletions
diff --git a/i386/i386/apic.h b/i386/i386/apic.h
index add1b8cf..9eef0d8b 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 remote_read_status: 2; /* Read-only field */
+ 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 */
@@ -104,6 +193,7 @@ typedef struct ApicLocalUnit {
typedef struct IoApicData {
uint8_t apic_id;
+ uint8_t ngsis;
uint32_t addr;
uint32_t gsi_base;
ApicIoUnit *ioapic;
@@ -138,33 +228,46 @@ 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 apic_generate_cpu_id_lut(void);
+int apic_get_total_gsis(void);
void picdisable(void);
void lapic_eoi(void);
void ioapic_irq_eoi(int pin);
+void lapic_setup(void);
+void lapic_disable(void);
+void lapic_enable(void);
void lapic_enable_timer(void);
-void ioapic_mask_irqs(void);
+void calibrate_lapic_timer(void);
void ioapic_toggle(int pin, int mask);
void ioapic_configure(void);
+void hpet_init(void);
+void hpet_udelay(uint32_t us);
+void hpet_mdelay(uint32_t ms);
+
extern int timer_pin;
extern void intnull(int unit);
extern volatile ApicLocalUnit* lapic;
-extern inline void mask_irq (unsigned int irq_nr);
-extern inline void unmask_irq (unsigned int irq_nr);
+extern int cpu_id_lut[];
+extern uint32_t *hpet_addr;
#endif
#define APIC_IO_UNIT_ID 0x00
#define APIC_IO_VERSION 0x01
+# define APIC_IO_VERSION_SHIFT 0
+# define APIC_IO_ENTRIES_SHIFT 16
#define APIC_IO_REDIR_LOW(int_pin) (0x10+(int_pin)*2)
#define APIC_IO_REDIR_HIGH(int_pin) (0x11+(int_pin)*2)
@@ -174,9 +277,13 @@ extern inline void unmask_irq (unsigned int irq_nr);
# 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
@@ -187,7 +294,7 @@ extern inline void unmask_irq (unsigned int irq_nr);
#define LAPIC_TIMER_BASEDIV 0x100000
#define LAPIC_HAS_DIRECTED_EOI 0x1000000
-#define NINTR 24
+#define NINTR 64 /* Max 32 GSIs on each of two IOAPICs */
#define IOAPIC_FIXED 0
#define IOAPIC_PHYSICAL 0
#define IOAPIC_LOGICAL 1
@@ -200,6 +307,11 @@ extern inline void unmask_irq (unsigned int irq_nr);
#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_X2APIC 0x400 /* LAPIC is in x2APIC mode */
+#define APIC_MSR_ENABLE 0x800 /* LAPIC is enabled */
+
/* 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) \
@@ -207,5 +319,19 @@ extern inline void unmask_irq (unsigned int irq_nr);
#define APIC_CLEAR_MASK_BIT(reg, bit) \
((reg)[(bit) >> 5].r &= ~(1 << ((bit) & 0x1f)))
+#ifndef __ASSEMBLER__
+
+#ifdef APIC
+static inline void mask_irq (unsigned int irq_nr) {
+ ioapic_toggle(irq_nr, IOAPIC_MASK_DISABLED);
+}
+
+static inline void unmask_irq (unsigned int irq_nr) {
+ ioapic_toggle(irq_nr, IOAPIC_MASK_ENABLED);
+}
+#endif
+
+#endif /* !__ASSEMBLER__ */
+
#endif /*_IMPS_APIC_*/