195 lines
7.1 KiB
C
195 lines
7.1 KiB
C
/*
|
|
* Copyright (C) 2018 Intel Corporation. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in
|
|
* the documentation and/or other materials provided with the
|
|
* distribution.
|
|
* * Neither the name of Intel Corporation nor the names of its
|
|
* contributors may be used to endorse or promote products derived
|
|
* from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#ifndef INTR_LAPIC_H
|
|
#define INTR_LAPIC_H
|
|
|
|
#define DEBUG_LAPIC 0
|
|
|
|
enum intr_lapic_icr_delivery_mode {
|
|
INTR_LAPIC_ICR_FIXED = 0x0,
|
|
INTR_LAPIC_ICR_LP = 0x1,
|
|
INTR_LAPIC_ICR_SMI = 0x2,
|
|
INTR_LAPIC_ICR_NMI = 0x4,
|
|
INTR_LAPIC_ICR_INIT = 0x5,
|
|
INTR_LAPIC_ICR_STARTUP = 0x6,
|
|
};
|
|
|
|
enum intr_lapic_icr_dest_mode {
|
|
INTR_LAPIC_ICR_PHYSICAL = 0x0,
|
|
INTR_LAPIC_ICR_LOGICAL = 0x1
|
|
};
|
|
|
|
enum intr_lapic_icr_level {
|
|
INTR_LAPIC_ICR_DEASSERT = 0x0,
|
|
INTR_LAPIC_ICR_ASSERT = 0x1,
|
|
};
|
|
|
|
enum intr_lapic_icr_trigger {
|
|
INTR_LAPIC_ICR_EDGE = 0x0,
|
|
INTR_LAPIC_ICR_LEVEL = 0x1,
|
|
};
|
|
|
|
enum intr_lapic_icr_shorthand {
|
|
INTR_LAPIC_ICR_USE_DEST_ARRAY = 0x0,
|
|
INTR_LAPIC_ICR_SELF = 0x1,
|
|
INTR_LAPIC_ICR_ALL_INC_SELF = 0x2,
|
|
INTR_LAPIC_ICR_ALL_EX_SELF = 0x3,
|
|
};
|
|
|
|
/* Default LAPIC base */
|
|
#define LAPIC_BASE 0xFEE00000
|
|
|
|
/* LAPIC register offset for memory mapped IO access */
|
|
#define LAPIC_ID_REGISTER 0x00000020
|
|
#define LAPIC_VERSION_REGISTER 0x00000030
|
|
#define LAPIC_TASK_PRIORITY_REGISTER 0x00000080
|
|
#define LAPIC_ARBITRATION_PRIORITY_REGISTER 0x00000090
|
|
#define LAPIC_PROCESSOR_PRIORITY_REGISTER 0x000000A0
|
|
#define LAPIC_EOI_REGISTER 0x000000B0
|
|
#define LAPIC_REMOTE_READ_REGISTER 0x000000C0
|
|
#define LAPIC_LOGICAL_DESTINATION_REGISTER 0x000000D0
|
|
#define LAPIC_DESTINATION_FORMAT_REGISTER 0x000000E0
|
|
#define LAPIC_SPURIOUS_VECTOR_REGISTER 0x000000F0
|
|
#define LAPIC_IN_SERVICE_REGISTER_0 0x00000100
|
|
#define LAPIC_IN_SERVICE_REGISTER_1 0x00000110
|
|
#define LAPIC_IN_SERVICE_REGISTER_2 0x00000120
|
|
#define LAPIC_IN_SERVICE_REGISTER_3 0x00000130
|
|
#define LAPIC_IN_SERVICE_REGISTER_4 0x00000140
|
|
#define LAPIC_IN_SERVICE_REGISTER_5 0x00000150
|
|
#define LAPIC_IN_SERVICE_REGISTER_6 0x00000160
|
|
#define LAPIC_IN_SERVICE_REGISTER_7 0x00000170
|
|
#define LAPIC_TRIGGER_MODE_REGISTER_0 0x00000180
|
|
#define LAPIC_TRIGGER_MODE_REGISTER_1 0x00000190
|
|
#define LAPIC_TRIGGER_MODE_REGISTER_2 0x000001A0
|
|
#define LAPIC_TRIGGER_MODE_REGISTER_3 0x000001B0
|
|
#define LAPIC_TRIGGER_MODE_REGISTER_4 0x000001C0
|
|
#define LAPIC_TRIGGER_MODE_REGISTER_5 0x000001D0
|
|
#define LAPIC_TRIGGER_MODE_REGISTER_6 0x000001E0
|
|
#define LAPIC_TRIGGER_MODE_REGISTER_7 0x000001F0
|
|
#define LAPIC_INT_REQUEST_REGISTER_0 0x00000200
|
|
#define LAPIC_INT_REQUEST_REGISTER_1 0x00000210
|
|
#define LAPIC_INT_REQUEST_REGISTER_2 0x00000220
|
|
#define LAPIC_INT_REQUEST_REGISTER_3 0x00000230
|
|
#define LAPIC_INT_REQUEST_REGISTER_4 0x00000240
|
|
#define LAPIC_INT_REQUEST_REGISTER_5 0x00000250
|
|
#define LAPIC_INT_REQUEST_REGISTER_6 0x00000260
|
|
#define LAPIC_INT_REQUEST_REGISTER_7 0x00000270
|
|
#define LAPIC_ERROR_STATUS_REGISTER 0x00000280
|
|
#define LAPIC_LVT_CMCI_REGISTER 0x000002F0
|
|
#define LAPIC_INT_COMMAND_REGISTER_0 0x00000300
|
|
#define LAPIC_INT_COMMAND_REGISTER_1 0x00000310
|
|
#define LAPIC_LVT_TIMER_REGISTER 0x00000320
|
|
#define LAPIC_LVT_THERMAL_SENSOR_REGISTER 0x00000330
|
|
#define LAPIC_LVT_PMC_REGISTER 0x00000340
|
|
#define LAPIC_LVT_LINT0_REGISTER 0x00000350
|
|
#define LAPIC_LVT_LINT1_REGISTER 0x00000360
|
|
#define LAPIC_LVT_ERROR_REGISTER 0x00000370
|
|
#define LAPIC_INITIAL_COUNT_REGISTER 0x00000380
|
|
#define LAPIC_CURRENT_COUNT_REGISTER 0x00000390
|
|
#define LAPIC_DIVIDE_CONFIGURATION_REGISTER 0x000003E0
|
|
|
|
/* LAPIC CPUID bit and bitmask definitions */
|
|
#define CPUID_OUT_RDX_APIC_PRESENT ((uint64_t) 1 << 9)
|
|
#define CPUID_OUT_RCX_X2APIC_PRESENT ((uint64_t) 1 << 21)
|
|
|
|
/* LAPIC MSR bit and bitmask definitions */
|
|
#define MSR_01B_XAPIC_GLOBAL_ENABLE ((uint64_t) 1 << 11)
|
|
|
|
/* LAPIC register bit and bitmask definitions */
|
|
#define LAPIC_SVR_VECTOR 0x000000FF
|
|
#define LAPIC_SVR_APIC_ENABLE_MASK 0x00000100
|
|
|
|
#define LAPIC_LVT_MASK 0x00010000
|
|
#define LAPIC_DELIVERY_MODE_EXTINT_MASK 0x00000700
|
|
|
|
/* LAPIC Timer bit and bitmask definitions */
|
|
#define LAPIC_TMR_ONESHOT ((uint32_t) 0x0 << 17)
|
|
#define LAPIC_TMR_PERIODIC ((uint32_t) 0x1 << 17)
|
|
#define LAPIC_TMR_TSC_DEADLINE ((uint32_t) 0x2 << 17)
|
|
|
|
enum intr_cpu_startup_shorthand {
|
|
INTR_CPU_STARTUP_USE_DEST,
|
|
INTR_CPU_STARTUP_ALL_EX_SELF,
|
|
INTR_CPU_STARTUP_UNKNOWN,
|
|
};
|
|
|
|
union lapic_id {
|
|
uint32_t value;
|
|
struct {
|
|
uint8_t xapic_id;
|
|
uint8_t rsvd[3];
|
|
} xapic;
|
|
union {
|
|
uint32_t value;
|
|
struct {
|
|
uint8_t xapic_id;
|
|
uint8_t xapic_edid;
|
|
uint8_t rsvd[2];
|
|
} ioxapic_view;
|
|
struct {
|
|
uint32_t x2apic_id:4;
|
|
uint32_t x2apic_cluster:28;
|
|
} ldr_view;
|
|
} x2apic;
|
|
};
|
|
|
|
struct lapic_regs {
|
|
uint32_t id;
|
|
uint32_t tpr;
|
|
uint32_t apr;
|
|
uint32_t ppr;
|
|
uint32_t ldr;
|
|
uint32_t dfr;
|
|
uint32_t tmr[8];
|
|
uint32_t svr;
|
|
uint32_t lvtt;
|
|
uint32_t lvt0;
|
|
uint32_t lvt1;
|
|
uint32_t lvterr;
|
|
uint32_t ticr;
|
|
uint32_t tccr;
|
|
uint32_t tdcr;
|
|
};
|
|
|
|
void write_lapic_reg32(uint32_t offset, uint32_t value);
|
|
void save_lapic(struct lapic_regs *regs);
|
|
int early_init_lapic(void);
|
|
int init_lapic(uint32_t cpu_id);
|
|
int send_lapic_eoi(void);
|
|
uint32_t get_cur_lapic_id(void);
|
|
int send_startup_ipi(enum intr_cpu_startup_shorthand cpu_startup_shorthand,
|
|
uint32_t cpu_startup_dest,
|
|
uint64_t cpu_startup_start_address);
|
|
/* API to send an IPI to a single guest */
|
|
void send_single_ipi(uint32_t pcpu_id, uint32_t vector);
|
|
|
|
#endif /* INTR_LAPIC_H */
|