mirror of
https://github.com/ipxe/ipxe
synced 2025-12-25 00:17:57 +03:00
[hyperv] Add support for Hyper-V hypervisor
Add support for detecting and communicating with the Hyper-V hypervisor. Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER );
|
||||
|
||||
#include <ipxe/io.h>
|
||||
#include <pic8259.h>
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Minimal support for the 8259 Programmable Interrupt Controller
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Send non-specific EOI(s)
|
||||
*
|
||||
* @v irq IRQ number
|
||||
*
|
||||
* This seems to be inherently unsafe.
|
||||
*/
|
||||
static inline void send_nonspecific_eoi ( unsigned int irq ) {
|
||||
DBG ( "Sending non-specific EOI for IRQ %d\n", irq );
|
||||
if ( irq >= IRQ_PIC_CUTOFF ) {
|
||||
outb ( ICR_EOI_NON_SPECIFIC, PIC2_ICR );
|
||||
}
|
||||
outb ( ICR_EOI_NON_SPECIFIC, PIC1_ICR );
|
||||
}
|
||||
|
||||
/**
|
||||
* Send specific EOI(s)
|
||||
*
|
||||
* @v irq IRQ number
|
||||
*/
|
||||
static inline void send_specific_eoi ( unsigned int irq ) {
|
||||
DBG ( "Sending specific EOI for IRQ %d\n", irq );
|
||||
if ( irq >= IRQ_PIC_CUTOFF ) {
|
||||
outb ( ( ICR_EOI_SPECIFIC | ICR_VALUE ( CHAINED_IRQ ) ),
|
||||
ICR_REG ( CHAINED_IRQ ) );
|
||||
}
|
||||
outb ( ( ICR_EOI_SPECIFIC | ICR_VALUE ( irq ) ), ICR_REG ( irq ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Send End-Of-Interrupt to the PIC
|
||||
*
|
||||
* @v irq IRQ number
|
||||
*/
|
||||
void send_eoi ( unsigned int irq ) {
|
||||
send_specific_eoi ( irq );
|
||||
}
|
||||
72
src/arch/i386/include/bits/hyperv.h
Normal file
72
src/arch/i386/include/bits/hyperv.h
Normal file
@@ -0,0 +1,72 @@
|
||||
#ifndef _BITS_HYPERV_H
|
||||
#define _BITS_HYPERV_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Hyper-V interface
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER );
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <ipxe/io.h>
|
||||
|
||||
/**
|
||||
* Issue hypercall
|
||||
*
|
||||
* @v hv Hyper-V hypervisor
|
||||
* @v code Call code
|
||||
* @v in Input parameters
|
||||
* @v out Output parameters
|
||||
* @ret status Status code
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) int
|
||||
hv_call ( struct hv_hypervisor *hv, unsigned int code, const void *in,
|
||||
void *out ) {
|
||||
void *hypercall = hv->hypercall;
|
||||
uint32_t in_phys;
|
||||
uint32_t out_phys;
|
||||
uint32_t discard_ecx;
|
||||
uint32_t discard_edx;
|
||||
uint16_t result;
|
||||
|
||||
in_phys = ( ( __builtin_constant_p ( in ) && ( in == NULL ) )
|
||||
? 0 : virt_to_phys ( in ) );
|
||||
out_phys = ( ( __builtin_constant_p ( out ) && ( out == NULL ) )
|
||||
? 0 : virt_to_phys ( out ) );
|
||||
__asm__ __volatile__ ( "call *%9"
|
||||
: "=a" ( result ), "=c" ( discard_ecx ),
|
||||
"=d" ( discard_edx )
|
||||
: "d" ( 0 ), "a" ( code ),
|
||||
"b" ( 0 ), "c" ( in_phys ),
|
||||
"D" ( 0 ), "S" ( out_phys ),
|
||||
"m" ( hypercall ) );
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set bit atomically
|
||||
*
|
||||
* @v bits Bit field
|
||||
* @v bit Bit to set
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
hv_set_bit ( void *bits, unsigned int bit ) {
|
||||
struct {
|
||||
uint32_t dword[ ( bit / 32 ) + 1 ];
|
||||
} *dwords = bits;
|
||||
|
||||
/* Set bit using "lock bts". Inform compiler that any memory
|
||||
* from the start of the bit field up to and including the
|
||||
* dword containing this bit may be modified. (This is
|
||||
* overkill but shouldn't matter in practice since we're
|
||||
* unlikely to subsequently read other bits from the same bit
|
||||
* field.)
|
||||
*/
|
||||
__asm__ __volatile__ ( "lock bts %1, %0"
|
||||
: "+m" ( *dwords ) : "Ir" ( bit ) );
|
||||
}
|
||||
|
||||
#endif /* _BITS_HYPERV_H */
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Basic support for controlling the 8259 Programmable Interrupt Controllers.
|
||||
*
|
||||
* Initially written by Michael Brown (mcb30).
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER );
|
||||
|
||||
#ifndef PIC8259_H
|
||||
#define PIC8259_H
|
||||
|
||||
#include <ipxe/io.h>
|
||||
|
||||
/* For segoff_t */
|
||||
#include "realmode.h"
|
||||
|
||||
#define IRQ_PIC_CUTOFF 8
|
||||
|
||||
/* 8259 register locations */
|
||||
#define PIC1_ICW1 0x20
|
||||
#define PIC1_OCW2 0x20
|
||||
#define PIC1_OCW3 0x20
|
||||
#define PIC1_ICR 0x20
|
||||
#define PIC1_IRR 0x20
|
||||
#define PIC1_ISR 0x20
|
||||
#define PIC1_ICW2 0x21
|
||||
#define PIC1_ICW3 0x21
|
||||
#define PIC1_ICW4 0x21
|
||||
#define PIC1_IMR 0x21
|
||||
#define PIC2_ICW1 0xa0
|
||||
#define PIC2_OCW2 0xa0
|
||||
#define PIC2_OCW3 0xa0
|
||||
#define PIC2_ICR 0xa0
|
||||
#define PIC2_IRR 0xa0
|
||||
#define PIC2_ISR 0xa0
|
||||
#define PIC2_ICW2 0xa1
|
||||
#define PIC2_ICW3 0xa1
|
||||
#define PIC2_ICW4 0xa1
|
||||
#define PIC2_IMR 0xa1
|
||||
|
||||
/* Register command values */
|
||||
#define OCW3_ID 0x08
|
||||
#define OCW3_READ_IRR 0x03
|
||||
#define OCW3_READ_ISR 0x02
|
||||
#define ICR_EOI_NON_SPECIFIC 0x20
|
||||
#define ICR_EOI_NOP 0x40
|
||||
#define ICR_EOI_SPECIFIC 0x60
|
||||
#define ICR_EOI_SET_PRIORITY 0xc0
|
||||
|
||||
/* Macros to enable/disable IRQs */
|
||||
#define IMR_REG(x) ( (x) < IRQ_PIC_CUTOFF ? PIC1_IMR : PIC2_IMR )
|
||||
#define IMR_BIT(x) ( 1 << ( (x) % IRQ_PIC_CUTOFF ) )
|
||||
#define irq_enabled(x) ( ( inb ( IMR_REG(x) ) & IMR_BIT(x) ) == 0 )
|
||||
#define enable_irq(x) outb ( inb( IMR_REG(x) ) & ~IMR_BIT(x), IMR_REG(x) )
|
||||
#define disable_irq(x) outb ( inb( IMR_REG(x) ) | IMR_BIT(x), IMR_REG(x) )
|
||||
|
||||
/* Macros for acknowledging IRQs */
|
||||
#define ICR_REG( irq ) ( (irq) < IRQ_PIC_CUTOFF ? PIC1_ICR : PIC2_ICR )
|
||||
#define ICR_VALUE( irq ) ( (irq) % IRQ_PIC_CUTOFF )
|
||||
#define CHAINED_IRQ 2
|
||||
|
||||
/* Utility macros to convert IRQ numbers to INT numbers and INT vectors */
|
||||
#define IRQ_INT( irq ) ( ( ( (irq) - IRQ_PIC_CUTOFF ) ^ 0x70 ) & 0x7f )
|
||||
|
||||
/* Other constants */
|
||||
#define IRQ_MAX 15
|
||||
#define IRQ_NONE -1U
|
||||
|
||||
/* Function prototypes
|
||||
*/
|
||||
void send_eoi ( unsigned int irq );
|
||||
|
||||
#endif /* PIC8259_H */
|
||||
Reference in New Issue
Block a user