merge with xen-unstable.hg

This commit is contained in:
awilliam@xenbuild.aw committed 2006-11-28 10:37:36 -07:00
commit ec489b8435
197 files changed
+9836 -7317

No files matched your search

-1
View File
@@ -98,7 +98,6 @@
^tools/firmware/.*\.bin$
^tools/firmware/.*\.sym$
^tools/firmware/.*bios/.*bios.*\.txt$
^tools/firmware/hvmloader/acpi/acpigen$
^tools/firmware/hvmloader/hvmloader$
^tools/firmware/hvmloader/roms\.h$
^tools/firmware/rombios/BIOS-bochs-[^/]*$
+1 -1
View File
@@ -1,5 +1,5 @@
LINUX_SERIES = 2.6
LINUX_VER = 2.6.16.29
LINUX_VER = 2.6.16.32
EXTRAVERSION ?= xen
+4 -3
View File
@@ -55,9 +55,10 @@ EXTRA_SRC += arch/$(EXTRA_INC)
endif
ifeq ($(TARGET_ARCH),ia64)
CFLAGS += -mfixed-range=f12-f15,f32-f127
ASFLAGS += -x assembler-with-cpp -ansi -Wall
ASFLAGS += -mfixed-range=f12-f15,f32-f127
CFLAGS += -mfixed-range=f2-f5,f12-f15,f32-f127 -mconstant-gp
ASFLAGS += -x assembler-with-cpp -Wall
ASFLAGS += -mfixed-range=f2-f5,f12-f15,f32-f127 -fomit-frame-pointer
ASFLAGS += -fno-builtin -fno-common -fno-strict-aliasing -mconstant-gp
ARCH_LINKS = IA64_LINKS # Special link on ia64 needed
define arch_links
[ -e include/ia64/asm-xsi-offsets.h ] || ln -sf ../../../../xen/include/asm-ia64/asm-xsi-offsets.h include/ia64/asm-xsi-offsets.h
+428
View File
@@ -0,0 +1,428 @@
/*
****************************************************************************
* (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
* (C) 2005 - Grzegorz Milos - Intel Research Cambridge
****************************************************************************
*
* File: mm.c
* Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk)
* Changes: Grzegorz Milos
*
* Date: Aug 2003, chages Aug 2005
*
* Environment: Xen Minimal OS
* Description: memory management related functions
* contains buddy page allocator from Xen.
*
****************************************************************************
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <os.h>
#include <hypervisor.h>
#include <mm.h>
#include <types.h>
#include <lib.h>
#include <xmalloc.h>
#ifdef MM_DEBUG
#define DEBUG(_f, _a...) \
printk("MINI_OS(file=mm.c, line=%d) " _f "\n", __LINE__, ## _a)
#else
#define DEBUG(_f, _a...) ((void)0)
#endif
unsigned long *phys_to_machine_mapping;
extern char *stack;
extern void page_walk(unsigned long virt_addr);
void new_pt_frame(unsigned long *pt_pfn, unsigned long prev_l_mfn,
unsigned long offset, unsigned long level)
{
pgentry_t *tab = (pgentry_t *)start_info.pt_base;
unsigned long pt_page = (unsigned long)pfn_to_virt(*pt_pfn);
unsigned long prot_e, prot_t, pincmd;
mmu_update_t mmu_updates[1];
struct mmuext_op pin_request;
DEBUG("Allocating new L%d pt frame for pt_pfn=%lx, "
"prev_l_mfn=%lx, offset=%lx",
level, *pt_pfn, prev_l_mfn, offset);
/* We need to clear the page, otherwise we might fail to map it
as a page table page */
memset((unsigned long*)pfn_to_virt(*pt_pfn), 0, PAGE_SIZE);
switch ( level )
{
case L1_FRAME:
prot_e = L1_PROT;
prot_t = L2_PROT;
pincmd = MMUEXT_PIN_L1_TABLE;
break;
#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
case L2_FRAME:
prot_e = L2_PROT;
prot_t = L3_PROT;
pincmd = MMUEXT_PIN_L2_TABLE;
break;
#endif
#if defined(__x86_64__)
case L3_FRAME:
prot_e = L3_PROT;
prot_t = L4_PROT;
pincmd = MMUEXT_PIN_L3_TABLE;
break;
#endif
default:
printk("new_pt_frame() called with invalid level number %d\n", level);
do_exit();
break;
}
/* Update the entry */
#if defined(__x86_64__)
tab = pte_to_virt(tab[l4_table_offset(pt_page)]);
tab = pte_to_virt(tab[l3_table_offset(pt_page)]);
#endif
#if defined(CONFIG_X86_PAE)
tab = pte_to_virt(tab[l3_table_offset(pt_page)]);
#endif
mmu_updates[0].ptr = ((pgentry_t)tab[l2_table_offset(pt_page)] & PAGE_MASK) +
sizeof(pgentry_t) * l1_table_offset(pt_page);
mmu_updates[0].val = (pgentry_t)pfn_to_mfn(*pt_pfn) << PAGE_SHIFT |
(prot_e & ~_PAGE_RW);
if(HYPERVISOR_mmu_update(mmu_updates, 1, NULL, DOMID_SELF) < 0)
{
printk("PTE for new page table page could not be updated\n");
do_exit();
}
/* Pin the page to provide correct protection */
pin_request.cmd = pincmd;
pin_request.arg1.mfn = pfn_to_mfn(*pt_pfn);
if(HYPERVISOR_mmuext_op(&pin_request, 1, NULL, DOMID_SELF) < 0)
{
printk("ERROR: pinning failed\n");
do_exit();
}
/* Now fill the new page table page with entries.
Update the page directory as well. */
mmu_updates[0].ptr = ((pgentry_t)prev_l_mfn << PAGE_SHIFT) + sizeof(pgentry_t) * offset;
mmu_updates[0].val = (pgentry_t)pfn_to_mfn(*pt_pfn) << PAGE_SHIFT | prot_t;
if(HYPERVISOR_mmu_update(mmu_updates, 1, NULL, DOMID_SELF) < 0)
{
printk("ERROR: mmu_update failed\n");
do_exit();
}
*pt_pfn += 1;
}
/* Checks if a pagetable frame is needed (if weren't allocated by Xen) */
static int need_pt_frame(unsigned long virt_address, int level)
{
unsigned long hyp_virt_start = HYPERVISOR_VIRT_START;
#if defined(__x86_64__)
unsigned long hyp_virt_end = HYPERVISOR_VIRT_END;
#else
unsigned long hyp_virt_end = 0xffffffff;
#endif
/* In general frames will _not_ be needed if they were already
allocated to map the hypervisor into our VA space */
#if defined(__x86_64__)
if(level == L3_FRAME)
{
if(l4_table_offset(virt_address) >=
l4_table_offset(hyp_virt_start) &&
l4_table_offset(virt_address) <=
l4_table_offset(hyp_virt_end))
return 0;
return 1;
} else
#endif
#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
if(level == L2_FRAME)
{
#if defined(__x86_64__)
if(l4_table_offset(virt_address) >=
l4_table_offset(hyp_virt_start) &&
l4_table_offset(virt_address) <=
l4_table_offset(hyp_virt_end))
#endif
if(l3_table_offset(virt_address) >=
l3_table_offset(hyp_virt_start) &&
l3_table_offset(virt_address) <=
l3_table_offset(hyp_virt_end))
return 0;
return 1;
} else
#endif /* defined(__x86_64__) || defined(CONFIG_X86_PAE) */
/* Always need l1 frames */
if(level == L1_FRAME)
return 1;
printk("ERROR: Unknown frame level %d, hypervisor %llx,%llx\n",
level, hyp_virt_start, hyp_virt_end);
return -1;
}
void build_pagetable(unsigned long *start_pfn, unsigned long *max_pfn)
{
unsigned long start_address, end_address;
unsigned long pfn_to_map, pt_pfn = *start_pfn;
static mmu_update_t mmu_updates[L1_PAGETABLE_ENTRIES + 1];
pgentry_t *tab = (pgentry_t *)start_info.pt_base, page;
unsigned long mfn = pfn_to_mfn(virt_to_pfn(start_info.pt_base));
unsigned long offset;
int count = 0;
pfn_to_map = (start_info.nr_pt_frames - NOT_L1_FRAMES) * L1_PAGETABLE_ENTRIES;
if (*max_pfn >= virt_to_pfn(HYPERVISOR_VIRT_START))
{
printk("WARNING: Mini-OS trying to use Xen virtual space. "
"Truncating memory from %dMB to ",
((unsigned long)pfn_to_virt(*max_pfn) - (unsigned long)&_text)>>20);
*max_pfn = virt_to_pfn(HYPERVISOR_VIRT_START - PAGE_SIZE);
printk("%dMB\n",
((unsigned long)pfn_to_virt(*max_pfn) - (unsigned long)&_text)>>20);
}
start_address = (unsigned long)pfn_to_virt(pfn_to_map);
end_address = (unsigned long)pfn_to_virt(*max_pfn);
/* We worked out the virtual memory range to map, now mapping loop */
printk("Mapping memory range 0x%lx - 0x%lx\n", start_address, end_address);
while(start_address < end_address)
{
tab = (pgentry_t *)start_info.pt_base;
mfn = pfn_to_mfn(virt_to_pfn(start_info.pt_base));
#if defined(__x86_64__)
offset = l4_table_offset(start_address);
/* Need new L3 pt frame */
if(!(start_address & L3_MASK))
if(need_pt_frame(start_address, L3_FRAME))
new_pt_frame(&pt_pfn, mfn, offset, L3_FRAME);
page = tab[offset];
mfn = pte_to_mfn(page);
tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
#endif
#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
offset = l3_table_offset(start_address);
/* Need new L2 pt frame */
if(!(start_address & L2_MASK))
if(need_pt_frame(start_address, L2_FRAME))
new_pt_frame(&pt_pfn, mfn, offset, L2_FRAME);
page = tab[offset];
mfn = pte_to_mfn(page);
tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
#endif
offset = l2_table_offset(start_address);
/* Need new L1 pt frame */
if(!(start_address & L1_MASK))
if(need_pt_frame(start_address, L1_FRAME))
new_pt_frame(&pt_pfn, mfn, offset, L1_FRAME);
page = tab[offset];
mfn = pte_to_mfn(page);
offset = l1_table_offset(start_address);
mmu_updates[count].ptr = ((pgentry_t)mfn << PAGE_SHIFT) + sizeof(pgentry_t) * offset;
mmu_updates[count].val = (pgentry_t)pfn_to_mfn(pfn_to_map++) << PAGE_SHIFT | L1_PROT;
count++;
if (count == L1_PAGETABLE_ENTRIES || pfn_to_map == *max_pfn)
{
if(HYPERVISOR_mmu_update(mmu_updates, count, NULL, DOMID_SELF) < 0)
{
printk("PTE could not be updated\n");
do_exit();
}
count = 0;
}
start_address += PAGE_SIZE;
}
*start_pfn = pt_pfn;
}
void mem_test(unsigned long *start_add, unsigned long *end_add)
{
unsigned long mask = 0x10000;
unsigned long *pointer;
for(pointer = start_add; pointer < end_add; pointer++)
{
if(!(((unsigned long)pointer) & 0xfffff))
{
printk("Writing to %lx\n", pointer);
page_walk((unsigned long)pointer);
}
*pointer = (unsigned long)pointer & ~mask;
}
for(pointer = start_add; pointer < end_add; pointer++)
{
if(((unsigned long)pointer & ~mask) != *pointer)
printk("Read error at 0x%lx. Read: 0x%lx, should read 0x%lx\n",
(unsigned long)pointer,
*pointer,
((unsigned long)pointer & ~mask));
}
}
static pgentry_t *demand_map_pgt;
static void *demand_map_area_start;
void arch_init_demand_mapping_area(unsigned long max_pfn)
{
unsigned long mfn;
pgentry_t *tab;
unsigned long start_addr;
unsigned long pt_pfn;
unsigned offset;
/* Round up to four megs. + 1024 rather than + 1023 since we want
to be sure we don't end up in the same place we started. */
max_pfn = (max_pfn + L1_PAGETABLE_ENTRIES) & ~(L1_PAGETABLE_ENTRIES - 1);
if (max_pfn == 0 ||
(unsigned long)pfn_to_virt(max_pfn + L1_PAGETABLE_ENTRIES) >=
HYPERVISOR_VIRT_START) {
printk("Too much memory; no room for demand map hole.\n");
do_exit();
}
demand_map_area_start = pfn_to_virt(max_pfn);
printk("Demand map pfns start at %lx (%p).\n", max_pfn,
demand_map_area_start);
start_addr = (unsigned long)demand_map_area_start;
tab = (pgentry_t *)start_info.pt_base;
mfn = virt_to_mfn(start_info.pt_base);
pt_pfn = virt_to_pfn(alloc_page());
#if defined(__x86_64__)
offset = l4_table_offset(start_addr);
if (!(tab[offset] & _PAGE_PRESENT)) {
new_pt_frame(&pt_pfn, mfn, offset, L3_FRAME);
pt_pfn = virt_to_pfn(alloc_page());
}
ASSERT(tab[offset] & _PAGE_PRESENT);
mfn = pte_to_mfn(tab[offset]);
tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
#endif
#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
offset = l3_table_offset(start_addr);
if (!(tab[offset] & _PAGE_PRESENT)) {
new_pt_frame(&pt_pfn, mfn, offset, L2_FRAME);
pt_pfn = virt_to_pfn(alloc_page());
}
ASSERT(tab[offset] & _PAGE_PRESENT);
mfn = pte_to_mfn(tab[offset]);
tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
#endif
offset = l2_table_offset(start_addr);
if (tab[offset] & _PAGE_PRESENT) {
printk("Demand map area already has a page table covering it?\n");
BUG();
}
demand_map_pgt = pfn_to_virt(pt_pfn);
new_pt_frame(&pt_pfn, mfn, offset, L1_FRAME);
ASSERT(tab[offset] & _PAGE_PRESENT);
printk("Initialised demand area.\n");
}
void *map_frames(unsigned long *f, unsigned long n)
{
unsigned long x;
unsigned long y = 0;
mmu_update_t mmu_updates[16];
int rc;
if (n > 16) {
printk("Tried to map too many (%ld) frames at once.\n", n);
return NULL;
}
/* Find a run of n contiguous frames */
for (x = 0; x <= 1024 - n; x += y + 1) {
for (y = 0; y < n; y++)
if (demand_map_pgt[x+y] & _PAGE_PRESENT)
break;
if (y == n)
break;
}
if (y != n) {
printk("Failed to map %ld frames!\n", n);
return NULL;
}
/* Found it at x. Map it in. */
for (y = 0; y < n; y++) {
mmu_updates[y].ptr = virt_to_mach(&demand_map_pgt[x + y]);
mmu_updates[y].val = (f[y] << PAGE_SHIFT) | L1_PROT;
}
rc = HYPERVISOR_mmu_update(mmu_updates, n, NULL, DOMID_SELF);
if (rc < 0) {
printk("Map %ld failed: %d.\n", n, rc);
return NULL;
} else {
return (void *)(unsigned long)((unsigned long)demand_map_area_start +
x * PAGE_SIZE);
}
}
void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p)
{
unsigned long start_pfn, max_pfn;
printk(" _text: %p\n", &_text);
printk(" _etext: %p\n", &_etext);
printk(" _edata: %p\n", &_edata);
printk(" stack start: %p\n", &stack);
printk(" _end: %p\n", &_end);
/* First page follows page table pages and 3 more pages (store page etc) */
start_pfn = PFN_UP(to_phys(start_info.pt_base)) +
start_info.nr_pt_frames + 3;
max_pfn = start_info.nr_pages;
printk(" start_pfn: %lx\n", start_pfn);
printk(" max_pfn: %lx\n", max_pfn);
build_pagetable(&start_pfn, &max_pfn);
*start_pfn_p = start_pfn;
*max_pfn_p = max_pfn;
}
+150
View File
@@ -0,0 +1,150 @@
/*
****************************************************************************
* (C) 2005 - Grzegorz Milos - Intel Research Cambridge
****************************************************************************
*
* File: sched.c
* Author: Grzegorz Milos
* Changes: Robert Kaiser
*
* Date: Aug 2005
*
* Environment: Xen Minimal OS
* Description: simple scheduler for Mini-Os
*
* The scheduler is non-preemptive (cooperative), and schedules according
* to Round Robin algorithm.
*
****************************************************************************
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <os.h>
#include <hypervisor.h>
#include <time.h>
#include <mm.h>
#include <types.h>
#include <lib.h>
#include <xmalloc.h>
#include <list.h>
#include <sched.h>
#include <semaphore.h>
#ifdef SCHED_DEBUG
#define DEBUG(_f, _a...) \
printk("MINI_OS(file=sched.c, line=%d) " _f "\n", __LINE__, ## _a)
#else
#define DEBUG(_f, _a...) ((void)0)
#endif
void dump_stack(struct thread *thread)
{
unsigned long *bottom = (unsigned long *)(thread->stack + 2*4*1024);
unsigned long *pointer = (unsigned long *)thread->sp;
int count;
if(thread == current)
{
#ifdef __i386__
asm("movl %%esp,%0"
: "=r"(pointer));
#else
asm("movq %%rsp,%0"
: "=r"(pointer));
#endif
}
printk("The stack for \"%s\"\n", thread->name);
for(count = 0; count < 25 && pointer < bottom; count ++)
{
printk("[0x%lx] 0x%lx\n", pointer, *pointer);
pointer++;
}
if(pointer < bottom) printk(" ... continues.\n");
}
/* Gets run when a new thread is scheduled the first time ever,
defined in x86_[32/64].S */
extern void thread_starter(void);
/* Pushes the specified value onto the stack of the specified thread */
static void stack_push(struct thread *thread, unsigned long value)
{
thread->sp -= sizeof(unsigned long);
*((unsigned long *)thread->sp) = value;
}
struct thread* create_thread(char *name, void (*function)(void *), void *data)
{
struct thread *thread;
unsigned long flags;
thread = xmalloc(struct thread);
/* Allocate 2 pages for stack, stack will be 2pages aligned */
thread->stack = (char *)alloc_pages(1);
thread->name = name;
printk("Thread \"%s\": pointer: 0x%lx, stack: 0x%lx\n", name, thread,
thread->stack);
thread->sp = (unsigned long)thread->stack + 4096 * 2;
/* Save pointer to the thread on the stack, used by current macro */
*((unsigned long *)thread->stack) = (unsigned long)thread;
stack_push(thread, (unsigned long) function);
stack_push(thread, (unsigned long) data);
thread->ip = (unsigned long) thread_starter;
/* Not runable, not exited, not sleeping */
thread->flags = 0;
thread->wakeup_time = 0LL;
set_runnable(thread);
local_irq_save(flags);
if(idle_thread != NULL) {
list_add_tail(&thread->thread_list, &idle_thread->thread_list);
} else if(function != idle_thread_fn)
{
printk("BUG: Not allowed to create thread before initialising scheduler.\n");
BUG();
}
local_irq_restore(flags);
return thread;
}
void run_idle_thread(void)
{
/* Switch stacks and run the thread */
#if defined(__i386__)
__asm__ __volatile__("mov %0,%%esp\n\t"
"push %1\n\t"
"ret"
:"=m" (idle_thread->sp)
:"m" (idle_thread->ip));
#elif defined(__x86_64__)
__asm__ __volatile__("mov %0,%%rsp\n\t"
"push %1\n\t"
"ret"
:"=m" (idle_thread->sp)
:"m" (idle_thread->ip));
#endif
}
+15
View File
@@ -35,6 +35,21 @@ typedef struct _ev_action_t {
static ev_action_t ev_actions[NR_EVS];
void default_handler(evtchn_port_t port, struct pt_regs *regs, void *data);
void unbind_all_ports(void)
{
int i;
for(i=0;i<NR_EVS;i++)
{
if(ev_actions[i].handler != default_handler)
{
struct evtchn_close close;
mask_evtchn(i);
close.port = i;
HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
}
}
}
/*
* Demux events to different handlers.
+5 -170
View File
@@ -29,182 +29,15 @@
#include <xen/arch-x86_32.h>
#elif defined(__x86_64__)
#include <xen/arch-x86_64.h>
#elif defined(__ia64__)
#include <xen/arch-ia64.h>
#else
#error "Unsupported architecture"
#endif
#include <lib.h>
#include <arch_mm.h>
#define L1_FRAME 1
#define L2_FRAME 2
#define L3_FRAME 3
#define L1_PAGETABLE_SHIFT 12
#if defined(__i386__)
#if !defined(CONFIG_X86_PAE)
#define L2_PAGETABLE_SHIFT 22
#define L1_PAGETABLE_ENTRIES 1024
#define L2_PAGETABLE_ENTRIES 1024
#define PADDR_BITS 32
#define PADDR_MASK (~0UL)
#define NOT_L1_FRAMES 1
#define PRIpte "08lx"
typedef unsigned long pgentry_t;
#else /* defined(CONFIG_X86_PAE) */
#define L2_PAGETABLE_SHIFT 21
#define L3_PAGETABLE_SHIFT 30
#define L1_PAGETABLE_ENTRIES 512
#define L2_PAGETABLE_ENTRIES 512
#define L3_PAGETABLE_ENTRIES 4
#define PADDR_BITS 44
#define PADDR_MASK ((1ULL << PADDR_BITS)-1)
#define L2_MASK ((1UL << L3_PAGETABLE_SHIFT) - 1)
/*
* If starting from virtual address greater than 0xc0000000,
* this value will be 2 to account for final mid-level page
* directory which is always mapped in at this location.
*/
#define NOT_L1_FRAMES 3
#define PRIpte "016llx"
typedef uint64_t pgentry_t;
#endif /* !defined(CONFIG_X86_PAE) */
#elif defined(__x86_64__)
#define L2_PAGETABLE_SHIFT 21
#define L3_PAGETABLE_SHIFT 30
#define L4_PAGETABLE_SHIFT 39
#define L1_PAGETABLE_ENTRIES 512
#define L2_PAGETABLE_ENTRIES 512
#define L3_PAGETABLE_ENTRIES 512
#define L4_PAGETABLE_ENTRIES 512
/* These are page-table limitations. Current CPUs support only 40-bit phys. */
#define PADDR_BITS 52
#define VADDR_BITS 48
#define PADDR_MASK ((1UL << PADDR_BITS)-1)
#define VADDR_MASK ((1UL << VADDR_BITS)-1)
#define L2_MASK ((1UL << L3_PAGETABLE_SHIFT) - 1)
#define L3_MASK ((1UL << L4_PAGETABLE_SHIFT) - 1)
#define NOT_L1_FRAMES 3
#define PRIpte "016lx"
typedef unsigned long pgentry_t;
#endif
#define L1_MASK ((1UL << L2_PAGETABLE_SHIFT) - 1)
/* Given a virtual address, get an entry offset into a page table. */
#define l1_table_offset(_a) \
(((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1))
#define l2_table_offset(_a) \
(((_a) >> L2_PAGETABLE_SHIFT) & (L2_PAGETABLE_ENTRIES - 1))
#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
#define l3_table_offset(_a) \
(((_a) >> L3_PAGETABLE_SHIFT) & (L3_PAGETABLE_ENTRIES - 1))
#endif
#if defined(__x86_64__)
#define l4_table_offset(_a) \
(((_a) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES - 1))
#endif
#define _PAGE_PRESENT 0x001UL
#define _PAGE_RW 0x002UL
#define _PAGE_USER 0x004UL
#define _PAGE_PWT 0x008UL
#define _PAGE_PCD 0x010UL
#define _PAGE_ACCESSED 0x020UL
#define _PAGE_DIRTY 0x040UL
#define _PAGE_PAT 0x080UL
#define _PAGE_PSE 0x080UL
#define _PAGE_GLOBAL 0x100UL
#if defined(__i386__)
#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY |_PAGE_USER)
#if defined(CONFIG_X86_PAE)
#define L3_PROT (_PAGE_PRESENT)
#endif /* CONFIG_X86_PAE */
#elif defined(__x86_64__)
#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
#define L3_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
#define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
#endif /* __i386__ || __x86_64__ */
#ifndef CONFIG_X86_PAE
#define PAGE_SIZE (1UL << L1_PAGETABLE_SHIFT)
#else
#define PAGE_SIZE (1ULL << L1_PAGETABLE_SHIFT)
#endif
#define PAGE_SHIFT L1_PAGETABLE_SHIFT
#define PAGE_MASK (~(PAGE_SIZE-1))
#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> L1_PAGETABLE_SHIFT)
#define PFN_DOWN(x) ((x) >> L1_PAGETABLE_SHIFT)
#define PFN_PHYS(x) ((x) << L1_PAGETABLE_SHIFT)
/* to align the pointer to the (next) page boundary */
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
/* Definitions for machine and pseudophysical addresses. */
#ifdef CONFIG_X86_PAE
typedef unsigned long long paddr_t;
typedef unsigned long long maddr_t;
#else
typedef unsigned long paddr_t;
typedef unsigned long maddr_t;
#endif
extern unsigned long *phys_to_machine_mapping;
extern char _text, _etext, _edata, _end;
#define pfn_to_mfn(_pfn) (phys_to_machine_mapping[(_pfn)])
static __inline__ maddr_t phys_to_machine(paddr_t phys)
{
maddr_t machine = pfn_to_mfn(phys >> PAGE_SHIFT);
machine = (machine << PAGE_SHIFT) | (phys & ~PAGE_MASK);
return machine;
}
#define mfn_to_pfn(_mfn) (machine_to_phys_mapping[(_mfn)])
static __inline__ paddr_t machine_to_phys(maddr_t machine)
{
paddr_t phys = mfn_to_pfn(machine >> PAGE_SHIFT);
phys = (phys << PAGE_SHIFT) | (machine & ~PAGE_MASK);
return phys;
}
#define VIRT_START ((unsigned long)&_text)
#define to_phys(x) ((unsigned long)(x)-VIRT_START)
#define to_virt(x) ((void *)((unsigned long)(x)+VIRT_START))
#define virt_to_pfn(_virt) (PFN_DOWN(to_phys(_virt)))
#define virt_to_mfn(_virt) (pfn_to_mfn(virt_to_pfn(_virt)))
#define mach_to_virt(_mach) (to_virt(machine_to_phys(_mach)))
#define virt_to_mach(_virt) (phys_to_machine(to_phys(_virt)))
#define mfn_to_virt(_mfn) (to_virt(mfn_to_pfn(_mfn) << PAGE_SHIFT))
#define pfn_to_virt(_pfn) (to_virt((_pfn) << PAGE_SHIFT))
/* Pagetable walking. */
#define pte_to_mfn(_pte) (((_pte) & (PADDR_MASK&PAGE_MASK)) >> L1_PAGETABLE_SHIFT)
#define pte_to_virt(_pte) to_virt(mfn_to_pfn(pte_to_mfn(_pte)) << PAGE_SHIFT)
void init_mm(void);
unsigned long alloc_pages(int order);
@@ -220,6 +53,8 @@ static __inline__ int get_order(unsigned long size)
return order;
}
void arch_init_demand_mapping_area(unsigned long max_pfn);
void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p);
void *map_frames(unsigned long *f, unsigned long n);
+15 -11
View File
@@ -3,36 +3,40 @@
#include <list.h>
#include <time.h>
#include <arch_sched.h>
struct thread
{
char *name;
char *stack;
#if !defined(__ia64__)
unsigned long sp; /* Stack pointer */
unsigned long ip; /* Instruction pointer */
#else /* !defined(__ia64__) */
thread_regs_t regs;
#endif /* !defined(__ia64__) */
struct list_head thread_list;
u32 flags;
s_time_t wakeup_time;
};
extern struct thread *idle_thread;
void idle_thread_fn(void *unused);
#define RUNNABLE_FLAG 0x00000001
#define is_runnable(_thread) (_thread->flags & RUNNABLE_FLAG)
#define set_runnable(_thread) (_thread->flags |= RUNNABLE_FLAG)
#define clear_runnable(_thread) (_thread->flags &= ~RUNNABLE_FLAG)
#define switch_threads(prev, next) arch_switch_threads(prev, next)
void init_sched(void);
void run_idle_thread(void);
struct thread* create_thread(char *name, void (*function)(void *), void *data);
void schedule(void);
static inline struct thread* get_current(void)
{
struct thread **current;
#ifdef __i386__
__asm__("andl %%esp,%0; ":"=r" (current) : "r" (~8191UL));
#else
__asm__("andq %%rsp,%0; ":"=r" (current) : "r" (~8191UL));
#endif
return *current;
}
#define current get_current()
+209
View File
@@ -0,0 +1,209 @@
/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*-
*
* (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
* Copyright (c) 2005, Keir A Fraser
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _ARCH_MM_H_
#define _ARCH_MM_H_
#if defined(__i386__)
#include <xen/arch-x86_32.h>
#elif defined(__x86_64__)
#include <xen/arch-x86_64.h>
#else
#error "Unsupported architecture"
#endif
#define L1_FRAME 1
#define L2_FRAME 2
#define L3_FRAME 3
#define L1_PAGETABLE_SHIFT 12
#if defined(__i386__)
#if !defined(CONFIG_X86_PAE)
#define L2_PAGETABLE_SHIFT 22
#define L1_PAGETABLE_ENTRIES 1024
#define L2_PAGETABLE_ENTRIES 1024
#define PADDR_BITS 32
#define PADDR_MASK (~0UL)
#define NOT_L1_FRAMES 1
#define PRIpte "08lx"
typedef unsigned long pgentry_t;
#else /* defined(CONFIG_X86_PAE) */
#define L2_PAGETABLE_SHIFT 21
#define L3_PAGETABLE_SHIFT 30
#define L1_PAGETABLE_ENTRIES 512
#define L2_PAGETABLE_ENTRIES 512
#define L3_PAGETABLE_ENTRIES 4
#define PADDR_BITS 44
#define PADDR_MASK ((1ULL << PADDR_BITS)-1)
#define L2_MASK ((1UL << L3_PAGETABLE_SHIFT) - 1)
/*
* If starting from virtual address greater than 0xc0000000,
* this value will be 2 to account for final mid-level page
* directory which is always mapped in at this location.
*/
#define NOT_L1_FRAMES 3
#define PRIpte "016llx"
typedef uint64_t pgentry_t;
#endif /* !defined(CONFIG_X86_PAE) */
#elif defined(__x86_64__)
#define L2_PAGETABLE_SHIFT 21
#define L3_PAGETABLE_SHIFT 30
#define L4_PAGETABLE_SHIFT 39
#define L1_PAGETABLE_ENTRIES 512
#define L2_PAGETABLE_ENTRIES 512
#define L3_PAGETABLE_ENTRIES 512
#define L4_PAGETABLE_ENTRIES 512
/* These are page-table limitations. Current CPUs support only 40-bit phys. */
#define PADDR_BITS 52
#define VADDR_BITS 48
#define PADDR_MASK ((1UL << PADDR_BITS)-1)
#define VADDR_MASK ((1UL << VADDR_BITS)-1)
#define L2_MASK ((1UL << L3_PAGETABLE_SHIFT) - 1)
#define L3_MASK ((1UL << L4_PAGETABLE_SHIFT) - 1)
#define NOT_L1_FRAMES 3
#define PRIpte "016lx"
typedef unsigned long pgentry_t;
#endif
#define L1_MASK ((1UL << L2_PAGETABLE_SHIFT) - 1)
/* Given a virtual address, get an entry offset into a page table. */
#define l1_table_offset(_a) \
(((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1))
#define l2_table_offset(_a) \
(((_a) >> L2_PAGETABLE_SHIFT) & (L2_PAGETABLE_ENTRIES - 1))
#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
#define l3_table_offset(_a) \
(((_a) >> L3_PAGETABLE_SHIFT) & (L3_PAGETABLE_ENTRIES - 1))
#endif
#if defined(__x86_64__)
#define l4_table_offset(_a) \
(((_a) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES - 1))
#endif
#define _PAGE_PRESENT 0x001UL
#define _PAGE_RW 0x002UL
#define _PAGE_USER 0x004UL
#define _PAGE_PWT 0x008UL
#define _PAGE_PCD 0x010UL
#define _PAGE_ACCESSED 0x020UL
#define _PAGE_DIRTY 0x040UL
#define _PAGE_PAT 0x080UL
#define _PAGE_PSE 0x080UL
#define _PAGE_GLOBAL 0x100UL
#if defined(__i386__)
#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY |_PAGE_USER)
#if defined(CONFIG_X86_PAE)
#define L3_PROT (_PAGE_PRESENT)
#endif /* CONFIG_X86_PAE */
#elif defined(__x86_64__)
#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
#define L3_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
#define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
#endif /* __i386__ || __x86_64__ */
#ifndef CONFIG_X86_PAE
#define PAGE_SIZE (1UL << L1_PAGETABLE_SHIFT)
#else
#define PAGE_SIZE (1ULL << L1_PAGETABLE_SHIFT)
#endif
#define PAGE_SHIFT L1_PAGETABLE_SHIFT
#define PAGE_MASK (~(PAGE_SIZE-1))
#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> L1_PAGETABLE_SHIFT)
#define PFN_DOWN(x) ((x) >> L1_PAGETABLE_SHIFT)
#define PFN_PHYS(x) ((x) << L1_PAGETABLE_SHIFT)
#define PHYS_PFN(x) ((x) >> L1_PAGETABLE_SHIFT)
/* to align the pointer to the (next) page boundary */
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
/* Definitions for machine and pseudophysical addresses. */
#ifdef CONFIG_X86_PAE
typedef unsigned long long paddr_t;
typedef unsigned long long maddr_t;
#else
typedef unsigned long paddr_t;
typedef unsigned long maddr_t;
#endif
extern unsigned long *phys_to_machine_mapping;
extern char _text, _etext, _edata, _end;
#define pfn_to_mfn(_pfn) (phys_to_machine_mapping[(_pfn)])
static __inline__ maddr_t phys_to_machine(paddr_t phys)
{
maddr_t machine = pfn_to_mfn(phys >> PAGE_SHIFT);
machine = (machine << PAGE_SHIFT) | (phys & ~PAGE_MASK);
return machine;
}
#define mfn_to_pfn(_mfn) (machine_to_phys_mapping[(_mfn)])
static __inline__ paddr_t machine_to_phys(maddr_t machine)
{
paddr_t phys = mfn_to_pfn(machine >> PAGE_SHIFT);
phys = (phys << PAGE_SHIFT) | (machine & ~PAGE_MASK);
return phys;
}
#define VIRT_START ((unsigned long)&_text)
#define to_phys(x) ((unsigned long)(x)-VIRT_START)
#define to_virt(x) ((void *)((unsigned long)(x)+VIRT_START))
#define virt_to_pfn(_virt) (PFN_DOWN(to_phys(_virt)))
#define virt_to_mfn(_virt) (pfn_to_mfn(virt_to_pfn(_virt)))
#define mach_to_virt(_mach) (to_virt(machine_to_phys(_mach)))
#define virt_to_mach(_virt) (phys_to_machine(to_phys(_virt)))
#define mfn_to_virt(_mfn) (to_virt(mfn_to_pfn(_mfn) << PAGE_SHIFT))
#define pfn_to_virt(_pfn) (to_virt((_pfn) << PAGE_SHIFT))
/* Pagetable walking. */
#define pte_to_mfn(_pte) (((_pte) & (PADDR_MASK&PAGE_MASK)) >> L1_PAGETABLE_SHIFT)
#define pte_to_virt(_pte) to_virt(mfn_to_pfn(pte_to_mfn(_pte)) << PAGE_SHIFT)
#endif /* _ARCH_MM_H_ */
+58
View File
@@ -0,0 +1,58 @@
#ifndef __ARCH_SCHED_H__
#define __ARCH_SCHED_H__
static inline struct thread* get_current(void)
{
struct thread **current;
#ifdef __i386__
__asm__("andl %%esp,%0; ":"=r" (current) : "r" (~8191UL));
#else
__asm__("andq %%rsp,%0; ":"=r" (current) : "r" (~8191UL));
#endif
return *current;
}
#ifdef __i386__
#define arch_switch_threads(prev, next) do { \
unsigned long esi,edi; \
__asm__ __volatile__("pushfl\n\t" \
"pushl %%ebp\n\t" \
"movl %%esp,%0\n\t" /* save ESP */ \
"movl %4,%%esp\n\t" /* restore ESP */ \
"movl $1f,%1\n\t" /* save EIP */ \
"pushl %5\n\t" /* restore EIP */ \
"ret\n\t" \
"1:\t" \
"popl %%ebp\n\t" \
"popfl" \
:"=m" (prev->sp),"=m" (prev->ip), \
"=S" (esi),"=D" (edi) \
:"m" (next->sp),"m" (next->ip), \
"2" (prev), "d" (next)); \
} while (0)
#elif __x86_64__
#define arch_switch_threads(prev, next) do { \
unsigned long rsi,rdi; \
__asm__ __volatile__("pushfq\n\t" \
"pushq %%rbp\n\t" \
"movq %%rsp,%0\n\t" /* save RSP */ \
"movq %4,%%rsp\n\t" /* restore RSP */ \
"movq $1f,%1\n\t" /* save RIP */ \
"pushq %5\n\t" /* restore RIP */ \
"ret\n\t" \
"1:\t" \
"popq %%rbp\n\t" \
"popfq" \
:"=m" (prev->sp),"=m" (prev->ip), \
"=S" (rsi),"=D" (rdi) \
:"m" (next->sp),"m" (next->ip), \
"2" (prev), "d" (next)); \
} while (0)
#endif
#endif /* __ARCH_SCHED_H__ */
@@ -167,7 +167,7 @@ HYPERVISOR_fpu_taskswitch(
static inline int
HYPERVISOR_sched_op(
int cmd, unsigned long arg)
int cmd, void *arg)
{
return _hypercall2(int, sched_op, cmd, arg);
}
@@ -171,7 +171,7 @@ HYPERVISOR_fpu_taskswitch(
static inline int
HYPERVISOR_sched_op(
int cmd, unsigned long arg)
int cmd, void *arg)
{
return _hypercall2(int, sched_op, cmd, arg);
}
+5 -1
View File
@@ -159,5 +159,9 @@ void start_kernel(start_info_t *si)
void do_exit(void)
{
printk("Do_exit called!\n");
for ( ;; ) HYPERVISOR_sched_op(SCHEDOP_shutdown, SHUTDOWN_crash);
for( ;; )
{
struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_crash };
HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
}
}
+6 -370
View File
@@ -48,10 +48,6 @@
#define DEBUG(_f, _a...) ((void)0)
#endif
unsigned long *phys_to_machine_mapping;
extern char *stack;
extern void page_walk(unsigned long virt_addr);
/*********************
* ALLOCATION BITMAP
* One bit per page of memory. Bit set => page is allocated.
@@ -226,11 +222,11 @@ static void init_page_allocator(unsigned long min, unsigned long max)
/* All allocated by default. */
memset(alloc_bitmap, ~0, bitmap_size);
/* Free up the memory we've been given to play with. */
map_free(min>>PAGE_SHIFT, range>>PAGE_SHIFT);
map_free(PHYS_PFN(min), range>>PAGE_SHIFT);
/* The buddy lists are addressed in high memory. */
min += VIRT_START;
max += VIRT_START;
min = (unsigned long) to_virt(min);
max = (unsigned long) to_virt(max);
while ( range != 0 )
{
@@ -297,7 +293,7 @@ unsigned long alloc_pages(int order)
free_head[i] = spare_ch;
}
map_alloc(to_phys(alloc_ch)>>PAGE_SHIFT, 1<<order);
map_alloc(PHYS_PFN(to_phys(alloc_ch)), 1<<order);
return((unsigned long)alloc_ch);
@@ -365,350 +361,6 @@ void free_pages(void *pointer, int order)
}
void new_pt_frame(unsigned long *pt_pfn, unsigned long prev_l_mfn,
unsigned long offset, unsigned long level)
{
pgentry_t *tab = (pgentry_t *)start_info.pt_base;
unsigned long pt_page = (unsigned long)pfn_to_virt(*pt_pfn);
unsigned long prot_e, prot_t, pincmd;
mmu_update_t mmu_updates[1];
struct mmuext_op pin_request;
DEBUG("Allocating new L%d pt frame for pt_pfn=%lx, "
"prev_l_mfn=%lx, offset=%lx",
level, *pt_pfn, prev_l_mfn, offset);
/* We need to clear the page, otherwise we might fail to map it
as a page table page */
memset((unsigned long*)pfn_to_virt(*pt_pfn), 0, PAGE_SIZE);
switch ( level )
{
case L1_FRAME:
prot_e = L1_PROT;
prot_t = L2_PROT;
pincmd = MMUEXT_PIN_L1_TABLE;
break;
#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
case L2_FRAME:
prot_e = L2_PROT;
prot_t = L3_PROT;
pincmd = MMUEXT_PIN_L2_TABLE;
break;
#endif
#if defined(__x86_64__)
case L3_FRAME:
prot_e = L3_PROT;
prot_t = L4_PROT;
pincmd = MMUEXT_PIN_L3_TABLE;
break;
#endif
default:
printk("new_pt_frame() called with invalid level number %d\n", level);
do_exit();
break;
}
/* Update the entry */
#if defined(__x86_64__)
tab = pte_to_virt(tab[l4_table_offset(pt_page)]);
tab = pte_to_virt(tab[l3_table_offset(pt_page)]);
#endif
#if defined(CONFIG_X86_PAE)
tab = pte_to_virt(tab[l3_table_offset(pt_page)]);
#endif
mmu_updates[0].ptr = ((pgentry_t)tab[l2_table_offset(pt_page)] & PAGE_MASK) +
sizeof(pgentry_t) * l1_table_offset(pt_page);
mmu_updates[0].val = (pgentry_t)pfn_to_mfn(*pt_pfn) << PAGE_SHIFT |
(prot_e & ~_PAGE_RW);
if(HYPERVISOR_mmu_update(mmu_updates, 1, NULL, DOMID_SELF) < 0)
{
printk("PTE for new page table page could not be updated\n");
do_exit();
}
/* Pin the page to provide correct protection */
pin_request.cmd = pincmd;
pin_request.arg1.mfn = pfn_to_mfn(*pt_pfn);
if(HYPERVISOR_mmuext_op(&pin_request, 1, NULL, DOMID_SELF) < 0)
{
printk("ERROR: pinning failed\n");
do_exit();
}
/* Now fill the new page table page with entries.
Update the page directory as well. */
mmu_updates[0].ptr = ((pgentry_t)prev_l_mfn << PAGE_SHIFT) + sizeof(pgentry_t) * offset;
mmu_updates[0].val = (pgentry_t)pfn_to_mfn(*pt_pfn) << PAGE_SHIFT | prot_t;
if(HYPERVISOR_mmu_update(mmu_updates, 1, NULL, DOMID_SELF) < 0)
{
printk("ERROR: mmu_update failed\n");
do_exit();
}
*pt_pfn += 1;
}
/* Checks if a pagetable frame is needed (if weren't allocated by Xen) */
static int need_pt_frame(unsigned long virt_address, int level)
{
unsigned long hyp_virt_start = HYPERVISOR_VIRT_START;
#if defined(__x86_64__)
unsigned long hyp_virt_end = HYPERVISOR_VIRT_END;
#else
unsigned long hyp_virt_end = 0xffffffff;
#endif
/* In general frames will _not_ be needed if they were already
allocated to map the hypervisor into our VA space */
#if defined(__x86_64__)
if(level == L3_FRAME)
{
if(l4_table_offset(virt_address) >=
l4_table_offset(hyp_virt_start) &&
l4_table_offset(virt_address) <=
l4_table_offset(hyp_virt_end))
return 0;
return 1;
} else
#endif
#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
if(level == L2_FRAME)
{
#if defined(__x86_64__)
if(l4_table_offset(virt_address) >=
l4_table_offset(hyp_virt_start) &&
l4_table_offset(virt_address) <=
l4_table_offset(hyp_virt_end))
#endif
if(l3_table_offset(virt_address) >=
l3_table_offset(hyp_virt_start) &&
l3_table_offset(virt_address) <=
l3_table_offset(hyp_virt_end))
return 0;
return 1;
} else
#endif /* defined(__x86_64__) || defined(CONFIG_X86_PAE) */
/* Always need l1 frames */
if(level == L1_FRAME)
return 1;
printk("ERROR: Unknown frame level %d, hypervisor %llx,%llx\n",
level, hyp_virt_start, hyp_virt_end);
return -1;
}
void build_pagetable(unsigned long *start_pfn, unsigned long *max_pfn)
{
unsigned long start_address, end_address;
unsigned long pfn_to_map, pt_pfn = *start_pfn;
static mmu_update_t mmu_updates[L1_PAGETABLE_ENTRIES + 1];
pgentry_t *tab = (pgentry_t *)start_info.pt_base, page;
unsigned long mfn = pfn_to_mfn(virt_to_pfn(start_info.pt_base));
unsigned long offset;
int count = 0;
pfn_to_map = (start_info.nr_pt_frames - NOT_L1_FRAMES) * L1_PAGETABLE_ENTRIES;
if (*max_pfn >= virt_to_pfn(HYPERVISOR_VIRT_START))
{
printk("WARNING: Mini-OS trying to use Xen virtual space. "
"Truncating memory from %dMB to ",
((unsigned long)pfn_to_virt(*max_pfn) - (unsigned long)&_text)>>20);
*max_pfn = virt_to_pfn(HYPERVISOR_VIRT_START - PAGE_SIZE);
printk("%dMB\n",
((unsigned long)pfn_to_virt(*max_pfn) - (unsigned long)&_text)>>20);
}
start_address = (unsigned long)pfn_to_virt(pfn_to_map);
end_address = (unsigned long)pfn_to_virt(*max_pfn);
/* We worked out the virtual memory range to map, now mapping loop */
printk("Mapping memory range 0x%lx - 0x%lx\n", start_address, end_address);
while(start_address < end_address)
{
tab = (pgentry_t *)start_info.pt_base;
mfn = pfn_to_mfn(virt_to_pfn(start_info.pt_base));
#if defined(__x86_64__)
offset = l4_table_offset(start_address);
/* Need new L3 pt frame */
if(!(start_address & L3_MASK))
if(need_pt_frame(start_address, L3_FRAME))
new_pt_frame(&pt_pfn, mfn, offset, L3_FRAME);
page = tab[offset];
mfn = pte_to_mfn(page);
tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
#endif
#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
offset = l3_table_offset(start_address);
/* Need new L2 pt frame */
if(!(start_address & L2_MASK))
if(need_pt_frame(start_address, L2_FRAME))
new_pt_frame(&pt_pfn, mfn, offset, L2_FRAME);
page = tab[offset];
mfn = pte_to_mfn(page);
tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
#endif
offset = l2_table_offset(start_address);
/* Need new L1 pt frame */
if(!(start_address & L1_MASK))
if(need_pt_frame(start_address, L1_FRAME))
new_pt_frame(&pt_pfn, mfn, offset, L1_FRAME);
page = tab[offset];
mfn = pte_to_mfn(page);
offset = l1_table_offset(start_address);
mmu_updates[count].ptr = ((pgentry_t)mfn << PAGE_SHIFT) + sizeof(pgentry_t) * offset;
mmu_updates[count].val = (pgentry_t)pfn_to_mfn(pfn_to_map++) << PAGE_SHIFT | L1_PROT;
count++;
if (count == L1_PAGETABLE_ENTRIES || pfn_to_map == *max_pfn)
{
if(HYPERVISOR_mmu_update(mmu_updates, count, NULL, DOMID_SELF) < 0)
{
printk("PTE could not be updated\n");
do_exit();
}
count = 0;
}
start_address += PAGE_SIZE;
}
*start_pfn = pt_pfn;
}
void mem_test(unsigned long *start_add, unsigned long *end_add)
{
unsigned long mask = 0x10000;
unsigned long *pointer;
for(pointer = start_add; pointer < end_add; pointer++)
{
if(!(((unsigned long)pointer) & 0xfffff))
{
printk("Writing to %lx\n", pointer);
page_walk((unsigned long)pointer);
}
*pointer = (unsigned long)pointer & ~mask;
}
for(pointer = start_add; pointer < end_add; pointer++)
{
if(((unsigned long)pointer & ~mask) != *pointer)
printk("Read error at 0x%lx. Read: 0x%lx, should read 0x%lx\n",
(unsigned long)pointer,
*pointer,
((unsigned long)pointer & ~mask));
}
}
static pgentry_t *demand_map_pgt;
static void *demand_map_area_start;
static void init_demand_mapping_area(unsigned long max_pfn)
{
unsigned long mfn;
pgentry_t *tab;
unsigned long start_addr;
unsigned long pt_pfn;
unsigned offset;
/* Round up to four megs. + 1024 rather than + 1023 since we want
to be sure we don't end up in the same place we started. */
max_pfn = (max_pfn + L1_PAGETABLE_ENTRIES) & ~(L1_PAGETABLE_ENTRIES - 1);
if (max_pfn == 0 ||
(unsigned long)pfn_to_virt(max_pfn + L1_PAGETABLE_ENTRIES) >=
HYPERVISOR_VIRT_START) {
printk("Too much memory; no room for demand map hole.\n");
do_exit();
}
demand_map_area_start = pfn_to_virt(max_pfn);
printk("Demand map pfns start at %lx (%p).\n", max_pfn,
demand_map_area_start);
start_addr = (unsigned long)demand_map_area_start;
tab = (pgentry_t *)start_info.pt_base;
mfn = virt_to_mfn(start_info.pt_base);
pt_pfn = virt_to_pfn(alloc_page());
#if defined(__x86_64__)
offset = l4_table_offset(start_addr);
if (!(tab[offset] & _PAGE_PRESENT)) {
new_pt_frame(&pt_pfn, mfn, offset, L3_FRAME);
pt_pfn = virt_to_pfn(alloc_page());
}
ASSERT(tab[offset] & _PAGE_PRESENT);
mfn = pte_to_mfn(tab[offset]);
tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
#endif
#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
offset = l3_table_offset(start_addr);
if (!(tab[offset] & _PAGE_PRESENT)) {
new_pt_frame(&pt_pfn, mfn, offset, L2_FRAME);
pt_pfn = virt_to_pfn(alloc_page());
}
ASSERT(tab[offset] & _PAGE_PRESENT);
mfn = pte_to_mfn(tab[offset]);
tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
#endif
offset = l2_table_offset(start_addr);
if (tab[offset] & _PAGE_PRESENT) {
printk("Demand map area already has a page table covering it?\n");
BUG();
}
demand_map_pgt = pfn_to_virt(pt_pfn);
new_pt_frame(&pt_pfn, mfn, offset, L1_FRAME);
ASSERT(tab[offset] & _PAGE_PRESENT);
}
void *map_frames(unsigned long *f, unsigned long n)
{
unsigned long x;
unsigned long y = 0;
mmu_update_t mmu_updates[16];
int rc;
if (n > 16) {
printk("Tried to map too many (%ld) frames at once.\n", n);
return NULL;
}
/* Find a run of n contiguous frames */
for (x = 0; x <= 1024 - n; x += y + 1) {
for (y = 0; y < n; y++)
if (demand_map_pgt[x+y] & _PAGE_PRESENT)
break;
if (y == n)
break;
}
if (y != n) {
printk("Failed to map %ld frames!\n", n);
return NULL;
}
/* Found it at x. Map it in. */
for (y = 0; y < n; y++) {
mmu_updates[y].ptr = virt_to_mach(&demand_map_pgt[x + y]);
mmu_updates[y].val = (f[y] << PAGE_SHIFT) | L1_PROT;
}
rc = HYPERVISOR_mmu_update(mmu_updates, n, NULL, DOMID_SELF);
if (rc < 0) {
printk("Map %ld failed: %d.\n", n, rc);
return NULL;
} else {
return (void *)(unsigned long)((unsigned long)demand_map_area_start +
x * PAGE_SIZE);
}
}
void init_mm(void)
{
@@ -717,22 +369,7 @@ void init_mm(void)
printk("MM: Init\n");
printk(" _text: %p\n", &_text);
printk(" _etext: %p\n", &_etext);
printk(" _edata: %p\n", &_edata);
printk(" stack start: %p\n", &stack);
printk(" _end: %p\n", &_end);
/* First page follows page table pages and 3 more pages (store page etc) */
start_pfn = PFN_UP(to_phys(start_info.pt_base)) +
start_info.nr_pt_frames + 3;
max_pfn = start_info.nr_pages;
printk(" start_pfn: %lx\n", start_pfn);
printk(" max_pfn: %lx\n", max_pfn);
build_pagetable(&start_pfn, &max_pfn);
arch_init_mm(&start_pfn, &max_pfn);
/*
* now we can initialise the page allocator
*/
@@ -742,8 +379,7 @@ void init_mm(void)
init_page_allocator(PFN_PHYS(start_pfn), PFN_PHYS(max_pfn));
printk("MM: done\n");
init_demand_mapping_area(max_pfn);
printk("Initialised demand area.\n");
arch_init_demand_mapping_area(max_pfn);
}
void sanity_check(void)
-137
View File
@@ -54,82 +54,9 @@
#define DEBUG(_f, _a...) ((void)0)
#endif
#define RUNNABLE_FLAG 0x00000001
#define is_runnable(_thread) (_thread->flags & RUNNABLE_FLAG)
#define set_runnable(_thread) (_thread->flags |= RUNNABLE_FLAG)
#define clear_runnable(_thread) (_thread->flags &= ~RUNNABLE_FLAG)
struct thread *idle_thread = NULL;
LIST_HEAD(exited_threads);
void idle_thread_fn(void *unused);
void dump_stack(struct thread *thread)
{
unsigned long *bottom = (unsigned long *)(thread->stack + 2*4*1024);
unsigned long *pointer = (unsigned long *)thread->sp;
int count;
if(thread == current)
{
#ifdef __i386__
asm("movl %%esp,%0"
: "=r"(pointer));
#else
asm("movq %%rsp,%0"
: "=r"(pointer));
#endif
}
printk("The stack for \"%s\"\n", thread->name);
for(count = 0; count < 25 && pointer < bottom; count ++)
{
printk("[0x%lx] 0x%lx\n", pointer, *pointer);
pointer++;
}
if(pointer < bottom) printk(" ... continues.\n");
}
#ifdef __i386__
#define switch_threads(prev, next) do { \
unsigned long esi,edi; \
__asm__ __volatile__("pushfl\n\t" \
"pushl %%ebp\n\t" \
"movl %%esp,%0\n\t" /* save ESP */ \
"movl %4,%%esp\n\t" /* restore ESP */ \
"movl $1f,%1\n\t" /* save EIP */ \
"pushl %5\n\t" /* restore EIP */ \
"ret\n\t" \
"1:\t" \
"popl %%ebp\n\t" \
"popfl" \
:"=m" (prev->sp),"=m" (prev->ip), \
"=S" (esi),"=D" (edi) \
:"m" (next->sp),"m" (next->ip), \
"2" (prev), "d" (next)); \
} while (0)
#elif __x86_64__
#define switch_threads(prev, next) do { \
unsigned long rsi,rdi; \
__asm__ __volatile__("pushfq\n\t" \
"pushq %%rbp\n\t" \
"movq %%rsp,%0\n\t" /* save RSP */ \
"movq %4,%%rsp\n\t" /* restore RSP */ \
"movq $1f,%1\n\t" /* save RIP */ \
"pushq %5\n\t" /* restore RIP */ \
"ret\n\t" \
"1:\t" \
"popq %%rbp\n\t" \
"popfq" \
:"=m" (prev->sp),"=m" (prev->ip), \
"=S" (rsi),"=D" (rdi) \
:"m" (next->sp),"m" (next->ip), \
"2" (prev), "d" (next)); \
} while (0)
#endif
void inline print_runqueue(void)
{
struct list_head *it;
@@ -250,50 +177,6 @@ void exit_thread(void)
schedule();
}
/* Pushes the specified value onto the stack of the specified thread */
static void stack_push(struct thread *thread, unsigned long value)
{
thread->sp -= sizeof(unsigned long);
*((unsigned long *)thread->sp) = value;
}
struct thread* create_thread(char *name, void (*function)(void *), void *data)
{
struct thread *thread;
unsigned long flags;
thread = xmalloc(struct thread);
/* Allocate 2 pages for stack, stack will be 2pages aligned */
thread->stack = (char *)alloc_pages(1);
thread->name = name;
printk("Thread \"%s\": pointer: 0x%lx, stack: 0x%lx\n", name, thread,
thread->stack);
thread->sp = (unsigned long)thread->stack + 4096 * 2;
/* Save pointer to the thread on the stack, used by current macro */
*((unsigned long *)thread->stack) = (unsigned long)thread;
stack_push(thread, (unsigned long) function);
stack_push(thread, (unsigned long) data);
thread->ip = (unsigned long) thread_starter;
/* Not runable, not exited, not sleeping */
thread->flags = 0;
thread->wakeup_time = 0LL;
set_runnable(thread);
local_irq_save(flags);
if(idle_thread != NULL) {
list_add_tail(&thread->thread_list, &idle_thread->thread_list);
} else if(function != idle_thread_fn)
{
printk("BUG: Not allowed to create thread before initialising scheduler.\n");
BUG();
}
local_irq_restore(flags);
return thread;
}
void block(struct thread *thread)
{
thread->wakeup_time = 0LL;
@@ -327,26 +210,6 @@ void idle_thread_fn(void *unused)
}
}
void run_idle_thread(void)
{
/* Switch stacks and run the thread */
#if defined(__i386__)
__asm__ __volatile__("mov %0,%%esp\n\t"
"push %1\n\t"
"ret"
:"=m" (idle_thread->sp)
:"m" (idle_thread->ip));
#elif defined(__x86_64__)
__asm__ __volatile__("mov %0,%%rsp\n\t"
"push %1\n\t"
"ret"
:"=m" (idle_thread->sp)
:"m" (idle_thread->ip));
#endif
}
DECLARE_MUTEX(mutex);
void th_f1(void *data)
@@ -99,18 +99,6 @@ void xen_l4_entry_update(pgd_t *ptr, pgd_t val)
}
#endif /* CONFIG_X86_64 */
void xen_machphys_update(unsigned long mfn, unsigned long pfn)
{
mmu_update_t u;
if (xen_feature(XENFEAT_auto_translated_physmap)) {
BUG_ON(pfn != mfn);
return;
}
u.ptr = ((unsigned long long)mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE;
u.val = pfn;
BUG_ON(HYPERVISOR_mmu_update(&u, 1, NULL, DOMID_SELF) < 0);
}
void xen_pt_switch(unsigned long ptr)
{
struct mmuext_op op;
@@ -7,7 +7,10 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
timer_int.o )
ifdef CONFIG_XEN
oprofile-y := $(DRIVER_OBJS) xenoprof.o
XENOPROF_COMMON_OBJS = $(addprefix ../../../drivers/xen/xenoprof/, \
xenoprofile.o)
oprofile-y := $(DRIVER_OBJS) \
$(XENOPROF_COMMON_OBJS) xenoprof.o
else
oprofile-y := $(DRIVER_OBJS) init.o backtrace.o
oprofile-$(CONFIG_X86_LOCAL_APIC) += nmi_int.o op_model_athlon.o \
@@ -9,249 +9,83 @@
* Modified by Aravind Menon and Jose Renato Santos for Xen
* These modifications are:
* Copyright (C) 2005 Hewlett-Packard Co.
*
* x86-specific part
* Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
* VA Linux Systems Japan K.K.
*/
#include <linux/init.h>
#include <linux/notifier.h>
#include <linux/smp.h>
#include <linux/oprofile.h>
#include <linux/sysdev.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/vmalloc.h>
#include <asm/nmi.h>
#include <asm/msr.h>
#include <asm/apic.h>
#include <linux/sched.h>
#include <asm/pgtable.h>
#include <xen/evtchn.h>
#include "op_counter.h"
#include <xen/driver_util.h>
#include <xen/interface/xen.h>
#include <xen/interface/xenoprof.h>
#include <../../../drivers/oprofile/cpu_buffer.h>
#include <../../../drivers/oprofile/event_buffer.h>
#include <xen/xenoprof.h>
#include "op_counter.h"
#define MAX_XENOPROF_SAMPLES 16
static int xenoprof_start(void);
static void xenoprof_stop(void);
static int xenoprof_enabled = 0;
static unsigned int num_events = 0;
static int is_primary = 0;
static int active_defined;
/* sample buffers shared with Xen */
xenoprof_buf_t * xenoprof_buf[MAX_VIRT_CPUS];
/* Shared buffer area */
char * shared_buffer = NULL;
/* Number of buffers in shared area (one per VCPU) */
int nbuf;
/* Mappings of VIRQ_XENOPROF to irq number (per cpu) */
int ovf_irq[NR_CPUS];
/* cpu model type string - copied from Xen memory space on XENOPROF_init command */
char cpu_type[XENOPROF_CPU_TYPE_SIZE];
/* Passive sample buffers shared with Xen */
xenoprof_buf_t *p_xenoprof_buf[MAX_OPROF_DOMAINS][MAX_VIRT_CPUS];
/* Passive shared buffer area */
char *p_shared_buffer[MAX_OPROF_DOMAINS];
#ifdef CONFIG_PM
static int xenoprof_suspend(struct sys_device * dev, pm_message_t state)
void __init xenoprof_arch_init_counter(struct xenoprof_init *init)
{
if (xenoprof_enabled == 1)
xenoprof_stop();
return 0;
}
static int xenoprof_resume(struct sys_device * dev)
{
if (xenoprof_enabled == 1)
xenoprof_start();
return 0;
}
static struct sysdev_class oprofile_sysclass = {
set_kset_name("oprofile"),
.resume = xenoprof_resume,
.suspend = xenoprof_suspend
};
static struct sys_device device_oprofile = {
.id = 0,
.cls = &oprofile_sysclass,
};
static int __init init_driverfs(void)
{
int error;
if (!(error = sysdev_class_register(&oprofile_sysclass)))
error = sysdev_register(&device_oprofile);
return error;
}
static void __exit exit_driverfs(void)
{
sysdev_unregister(&device_oprofile);
sysdev_class_unregister(&oprofile_sysclass);
}
#else
#define init_driverfs() do { } while (0)
#define exit_driverfs() do { } while (0)
#endif /* CONFIG_PM */
unsigned long long oprofile_samples = 0;
unsigned long long p_oprofile_samples = 0;
unsigned int pdomains;
struct xenoprof_passive passive_domains[MAX_OPROF_DOMAINS];
static void xenoprof_add_pc(xenoprof_buf_t *buf, int is_passive)
{
int head, tail, size;
head = buf->event_head;
tail = buf->event_tail;
size = buf->event_size;
if (tail > head) {
while (tail < size) {
oprofile_add_pc(buf->event_log[tail].eip,
buf->event_log[tail].mode,
buf->event_log[tail].event);
if (!is_passive)
oprofile_samples++;
else
p_oprofile_samples++;
tail++;
}
tail = 0;
num_events = init->num_events;
/* just in case - make sure we do not overflow event list
(i.e. counter_config list) */
if (num_events > OP_MAX_COUNTER) {
num_events = OP_MAX_COUNTER;
init->num_events = num_events;
}
while (tail < head) {
oprofile_add_pc(buf->event_log[tail].eip,
buf->event_log[tail].mode,
buf->event_log[tail].event);
if (!is_passive)
oprofile_samples++;
else
p_oprofile_samples++;
tail++;
}
buf->event_tail = tail;
}
static void xenoprof_handle_passive(void)
{
int i, j;
int flag_domain, flag_switch = 0;
for (i = 0; i < pdomains; i++) {
flag_domain = 0;
for (j = 0; j < passive_domains[i].nbuf; j++) {
xenoprof_buf_t *buf = p_xenoprof_buf[i][j];
if (buf->event_head == buf->event_tail)
continue;
if (!flag_domain) {
if (!oprofile_add_domain_switch(passive_domains[i].
domain_id))
goto done;
flag_domain = 1;
}
xenoprof_add_pc(buf, 1);
flag_switch = 1;
}
}
done:
if (flag_switch)
oprofile_add_domain_switch(COORDINATOR_DOMAIN);
}
static irqreturn_t
xenoprof_ovf_interrupt(int irq, void * dev_id, struct pt_regs * regs)
{
struct xenoprof_buf * buf;
int cpu;
static unsigned long flag;
cpu = smp_processor_id();
buf = xenoprof_buf[cpu];
xenoprof_add_pc(buf, 0);
if (is_primary && !test_and_set_bit(0, &flag)) {
xenoprof_handle_passive();
smp_mb__before_clear_bit();
clear_bit(0, &flag);
}
return IRQ_HANDLED;
}
static void unbind_virq(void)
void xenoprof_arch_counter(void)
{
int i;
struct xenoprof_counter counter;
for_each_cpu(i) {
if (ovf_irq[i] >= 0) {
unbind_from_irqhandler(ovf_irq[i], NULL);
ovf_irq[i] = -1;
}
for (i=0; i<num_events; i++) {
counter.ind = i;
counter.count = (uint64_t)counter_config[i].count;
counter.enabled = (uint32_t)counter_config[i].enabled;
counter.event = (uint32_t)counter_config[i].event;
counter.kernel = (uint32_t)counter_config[i].kernel;
counter.user = (uint32_t)counter_config[i].user;
counter.unit_mask = (uint64_t)counter_config[i].unit_mask;
HYPERVISOR_xenoprof_op(XENOPROF_counter,
&counter);
}
}
static int bind_virq(void)
void xenoprof_arch_start(void)
{
int i, result;
for_each_cpu(i) {
result = bind_virq_to_irqhandler(VIRQ_XENOPROF,
i,
xenoprof_ovf_interrupt,
SA_INTERRUPT,
"xenoprof",
NULL);
if (result < 0) {
unbind_virq();
return result;
}
ovf_irq[i] = result;
}
return 0;
/* nothing */
}
static int map_xenoprof_buffer(int max_samples)
void xenoprof_arch_stop(void)
{
struct xenoprof_get_buffer get_buffer;
struct xenoprof_buf *buf;
int npages, ret, i;
/* nothing */
}
void xenoprof_arch_unmap_shared_buffer(struct xenoprof_shared_buffer * sbuf)
{
if (sbuf->buffer) {
vunmap(sbuf->buffer);
sbuf->buffer = NULL;
}
}
int xenoprof_arch_map_shared_buffer(struct xenoprof_get_buffer * get_buffer,
struct xenoprof_shared_buffer * sbuf)
{
int npages, ret;
struct vm_struct *area;
if ( shared_buffer )
return 0;
get_buffer.max_samples = max_samples;
if ( (ret = HYPERVISOR_xenoprof_op(XENOPROF_get_buffer, &get_buffer)) )
sbuf->buffer = NULL;
if ( (ret = HYPERVISOR_xenoprof_op(XENOPROF_get_buffer, get_buffer)) )
return ret;
nbuf = get_buffer.nbuf;
npages = (get_buffer.bufsize * nbuf - 1) / PAGE_SIZE + 1;
npages = (get_buffer->bufsize * get_buffer->nbuf - 1) / PAGE_SIZE + 1;
area = alloc_vm_area(npages * PAGE_SIZE);
if (area == NULL)
@@ -259,231 +93,55 @@ static int map_xenoprof_buffer(int max_samples)
if ( (ret = direct_kernel_remap_pfn_range(
(unsigned long)area->addr,
get_buffer.buf_maddr >> PAGE_SHIFT,
npages * PAGE_SIZE, __pgprot(_KERNPG_TABLE), DOMID_SELF)) ) {
get_buffer->buf_gmaddr >> PAGE_SHIFT,
npages * PAGE_SIZE, __pgprot(_KERNPG_TABLE),
DOMID_SELF)) ) {
vunmap(area->addr);
return ret;
}
shared_buffer = area->addr;
for (i=0; i< nbuf; i++) {
buf = (struct xenoprof_buf*)
&shared_buffer[i * get_buffer.bufsize];
BUG_ON(buf->vcpu_id >= MAX_VIRT_CPUS);
xenoprof_buf[buf->vcpu_id] = buf;
}
return 0;
sbuf->buffer = area->addr;
return ret;
}
static int xenoprof_setup(void)
int xenoprof_arch_set_passive(struct xenoprof_passive * pdomain,
struct xenoprof_shared_buffer * sbuf)
{
int ret;
int i;
if ( (ret = map_xenoprof_buffer(MAX_XENOPROF_SAMPLES)) )
return ret;
if ( (ret = bind_virq()) )
return ret;
if (is_primary) {
struct xenoprof_counter counter;
/* Define dom0 as an active domain if not done yet */
if (!active_defined) {
domid_t domid;
ret = HYPERVISOR_xenoprof_op(XENOPROF_reset_active_list, NULL);
if (ret)
goto err;
domid = 0;
ret = HYPERVISOR_xenoprof_op(XENOPROF_set_active, &domid);
if (ret)
goto err;
active_defined = 1;
}
ret = HYPERVISOR_xenoprof_op(XENOPROF_reserve_counters, NULL);
if (ret)
goto err;
for (i=0; i<num_events; i++) {
counter.ind = i;
counter.count = (uint64_t)counter_config[i].count;
counter.enabled = (uint32_t)counter_config[i].enabled;
counter.event = (uint32_t)counter_config[i].event;
counter.kernel = (uint32_t)counter_config[i].kernel;
counter.user = (uint32_t)counter_config[i].user;
counter.unit_mask = (uint64_t)counter_config[i].unit_mask;
HYPERVISOR_xenoprof_op(XENOPROF_counter,
&counter);
}
ret = HYPERVISOR_xenoprof_op(XENOPROF_setup_events, NULL);
if (ret)
goto err;
}
ret = HYPERVISOR_xenoprof_op(XENOPROF_enable_virq, NULL);
if (ret)
goto err;
xenoprof_enabled = 1;
return 0;
err:
unbind_virq();
return ret;
}
static void xenoprof_shutdown(void)
{
xenoprof_enabled = 0;
HYPERVISOR_xenoprof_op(XENOPROF_disable_virq, NULL);
if (is_primary) {
HYPERVISOR_xenoprof_op(XENOPROF_release_counters, NULL);
active_defined = 0;
}
unbind_virq();
}
static int xenoprof_start(void)
{
int ret = 0;
if (is_primary)
ret = HYPERVISOR_xenoprof_op(XENOPROF_start, NULL);
return ret;
}
static void xenoprof_stop(void)
{
if (is_primary)
HYPERVISOR_xenoprof_op(XENOPROF_stop, NULL);
}
static int xenoprof_set_active(int * active_domains,
unsigned int adomains)
{
int ret = 0;
int i;
int set_dom0 = 0;
domid_t domid;
if (!is_primary)
return 0;
if (adomains > MAX_OPROF_DOMAINS)
return -E2BIG;
ret = HYPERVISOR_xenoprof_op(XENOPROF_reset_active_list, NULL);
if (ret)
return ret;
for (i=0; i<adomains; i++) {
domid = active_domains[i];
if (domid != active_domains[i]) {
ret = -EINVAL;
goto out;
}
ret = HYPERVISOR_xenoprof_op(XENOPROF_set_active, &domid);
if (ret)
goto out;
if (active_domains[i] == 0)
set_dom0 = 1;
}
/* dom0 must always be active but may not be in the list */
if (!set_dom0) {
domid = 0;
ret = HYPERVISOR_xenoprof_op(XENOPROF_set_active, &domid);
}
out:
if (ret)
HYPERVISOR_xenoprof_op(XENOPROF_reset_active_list, NULL);
active_defined = !ret;
return ret;
}
static int xenoprof_set_passive(int * p_domains,
unsigned int pdoms)
{
int ret;
int i, j;
int npages;
struct xenoprof_buf *buf;
struct vm_struct *area;
pgprot_t prot = __pgprot(_KERNPG_TABLE);
if (!is_primary)
return 0;
if (pdoms > MAX_OPROF_DOMAINS)
return -E2BIG;
ret = HYPERVISOR_xenoprof_op(XENOPROF_reset_passive_list, NULL);
sbuf->buffer = NULL;
ret = HYPERVISOR_xenoprof_op(XENOPROF_set_passive, pdomain);
if (ret)
return ret;
goto out;
for (i = 0; i < pdoms; i++) {
passive_domains[i].domain_id = p_domains[i];
passive_domains[i].max_samples = 2048;
ret = HYPERVISOR_xenoprof_op(XENOPROF_set_passive,
&passive_domains[i]);
if (ret)
goto out;
npages = (passive_domains[i].bufsize * passive_domains[i].nbuf - 1) / PAGE_SIZE + 1;
area = alloc_vm_area(npages * PAGE_SIZE);
if (area == NULL) {
ret = -ENOMEM;
goto out;
}
ret = direct_kernel_remap_pfn_range(
(unsigned long)area->addr,
passive_domains[i].buf_maddr >> PAGE_SHIFT,
npages * PAGE_SIZE, prot, DOMID_SELF);
if (ret) {
vunmap(area->addr);
goto out;
}
p_shared_buffer[i] = area->addr;
for (j = 0; j < passive_domains[i].nbuf; j++) {
buf = (struct xenoprof_buf *)
&p_shared_buffer[i][j * passive_domains[i].bufsize];
BUG_ON(buf->vcpu_id >= MAX_VIRT_CPUS);
p_xenoprof_buf[i][buf->vcpu_id] = buf;
}
npages = (pdomain->bufsize * pdomain->nbuf - 1) / PAGE_SIZE + 1;
area = alloc_vm_area(npages * PAGE_SIZE);
if (area == NULL) {
ret = -ENOMEM;
goto out;
}
pdomains = pdoms;
return 0;
ret = direct_kernel_remap_pfn_range(
(unsigned long)area->addr,
pdomain->buf_gmaddr >> PAGE_SHIFT,
npages * PAGE_SIZE, prot, DOMID_SELF);
if (ret) {
vunmap(area->addr);
goto out;
}
sbuf->buffer = area->addr;
out:
for (j = 0; j < i; j++) {
vunmap(p_shared_buffer[j]);
p_shared_buffer[j] = NULL;
}
return ret;
return ret;
}
struct op_counter_config counter_config[OP_MAX_COUNTER];
static int xenoprof_create_files(struct super_block * sb, struct dentry * root)
int xenoprof_create_files(struct super_block * sb, struct dentry * root)
{
unsigned int i;
@@ -510,75 +168,12 @@ static int xenoprof_create_files(struct super_block * sb, struct dentry * root)
return 0;
}
struct oprofile_operations xenoprof_ops = {
.create_files = xenoprof_create_files,
.set_active = xenoprof_set_active,
.set_passive = xenoprof_set_passive,
.setup = xenoprof_setup,
.shutdown = xenoprof_shutdown,
.start = xenoprof_start,
.stop = xenoprof_stop
};
/* in order to get driverfs right */
static int using_xenoprof;
int __init oprofile_arch_init(struct oprofile_operations * ops)
{
struct xenoprof_init init;
int ret, i;
ret = HYPERVISOR_xenoprof_op(XENOPROF_init, &init);
if (!ret) {
num_events = init.num_events;
is_primary = init.is_primary;
/* just in case - make sure we do not overflow event list
(i.e. counter_config list) */
if (num_events > OP_MAX_COUNTER)
num_events = OP_MAX_COUNTER;
/* cpu_type is detected by Xen */
cpu_type[XENOPROF_CPU_TYPE_SIZE-1] = 0;
strncpy(cpu_type, init.cpu_type, XENOPROF_CPU_TYPE_SIZE - 1);
xenoprof_ops.cpu_type = cpu_type;
init_driverfs();
using_xenoprof = 1;
*ops = xenoprof_ops;
for (i=0; i<NR_CPUS; i++)
ovf_irq[i] = -1;
active_defined = 0;
}
printk(KERN_INFO "oprofile_arch_init: ret %d, events %d, "
"is_primary %d\n", ret, num_events, is_primary);
return ret;
return xenoprofile_init(ops);
}
void __exit oprofile_arch_exit(void)
void oprofile_arch_exit(void)
{
int i;
if (using_xenoprof)
exit_driverfs();
if (shared_buffer) {
vunmap(shared_buffer);
shared_buffer = NULL;
}
if (is_primary) {
for (i = 0; i < pdomains; i++)
if (p_shared_buffer[i]) {
vunmap(p_shared_buffer[i]);
p_shared_buffer[i] = NULL;
}
HYPERVISOR_xenoprof_op(XENOPROF_shutdown, NULL);
}
xenoprofile_exit();
}
@@ -4,6 +4,7 @@ obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup.o
ifneq ($(CONFIG_ACPI_PROCESSOR),)
obj-y += processor.o
processor-y := ../../../i386/kernel/acpi/processor.o ../../../i386/kernel/acpi/cstate.o
endif
boot-$(CONFIG_XEN) := ../../../i386/kernel/acpi/boot-xen.o
@@ -12,6 +12,8 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
timer_int.o )
ifdef CONFIG_XEN
XENOPROF_COMMON_OBJS = $(addprefix ../../../drivers/xen/xenoprof/, \
xenoprofile.o)
OPROFILE-y := xenoprof.o
else
OPROFILE-y := init.o backtrace.o
@@ -19,4 +21,5 @@ OPROFILE-$(CONFIG_X86_LOCAL_APIC) += nmi_int.o op_model_athlon.o op_model_p4.o \
op_model_ppro.o
OPROFILE-$(CONFIG_X86_IO_APIC) += nmi_timer_int.o
endif
oprofile-y = $(DRIVER_OBJS) $(addprefix ../../i386/oprofile/, $(OPROFILE-y))
oprofile-y = $(DRIVER_OBJS) $(XENOPROF_COMMON_OBJS) \
$(addprefix ../../i386/oprofile/, $(OPROFILE-y))
@@ -215,9 +215,7 @@ static int increase_reservation(unsigned long nr_pages)
BUG_ON(!xen_feature(XENFEAT_auto_translated_physmap) &&
phys_to_machine_mapping_valid(pfn));
/* Update P->M and M->P tables. */
set_phys_to_machine(pfn, frame_list[i]);
xen_machphys_update(frame_list[i], pfn);
/* Link back into the page tables if not highmem. */
if (pfn < max_low_pfn) {
@@ -113,7 +113,7 @@ int vbd_create(blkif_t *blkif, blkif_vdev_t vdevice, unsigned major,
unsigned minor, int readonly);
void vbd_free(struct vbd *vbd);
unsigned long vbd_size(struct vbd *vbd);
unsigned long long vbd_size(struct vbd *vbd);
unsigned int vbd_info(struct vbd *vbd);
unsigned long vbd_secsize(struct vbd *vbd);
@@ -35,7 +35,7 @@
#define vbd_sz(_v) ((_v)->bdev->bd_part ? \
(_v)->bdev->bd_part->nr_sects : (_v)->bdev->bd_disk->capacity)
unsigned long vbd_size(struct vbd *vbd)
unsigned long long vbd_size(struct vbd *vbd)
{
return vbd_sz(vbd);
}
@@ -389,7 +389,7 @@ again:
if (err)
goto abort;
err = xenbus_printf(xbt, dev->nodename, "sectors", "%lu",
err = xenbus_printf(xbt, dev->nodename, "sectors", "%llu",
vbd_size(&be->blkif->vbd));
if (err) {
xenbus_dev_fatal(dev, err, "writing %s/sectors",
@@ -138,10 +138,10 @@ static int blkfront_resume(struct xenbus_device *dev)
DPRINTK("blkfront_resume: %s\n", dev->nodename);
blkif_free(info, 1);
blkif_free(info, info->connected == BLKIF_STATE_CONNECTED);
err = talk_to_backend(dev, info);
if (!err)
if (info->connected == BLKIF_STATE_SUSPENDED && !err)
blkif_recover(info);
return err;
@@ -298,7 +298,8 @@ static void backend_changed(struct xenbus_device *dev,
*/
static void connect(struct blkfront_info *info)
{
unsigned long sectors, sector_size;
unsigned long long sectors;
unsigned long sector_size;
unsigned int binfo;
int err;
@@ -309,7 +310,7 @@ static void connect(struct blkfront_info *info)
DPRINTK("blkfront.c:connect:%s.\n", info->xbdev->otherend);
err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
"sectors", "%lu", &sectors,
"sectors", "%llu", &sectors,
"info", "%u", &binfo,
"sector-size", "%lu", &sector_size,
NULL);
+37 -14
View File
@@ -28,13 +28,12 @@
#include <asm/io.h>
#include <asm/hypervisor.h>
static inline int uncached_access(struct file *file)
#ifndef ARCH_HAS_VALID_PHYS_ADDR_RANGE
static inline int valid_phys_addr_range(unsigned long addr, size_t *count)
{
if (file->f_flags & O_SYNC)
return 1;
/* Xen sets correct MTRR type on non-RAM for us. */
return 0;
return 1;
}
#endif
/*
* This funcion reads the *physical* memory. The f_pos points directly to the
@@ -47,6 +46,9 @@ static ssize_t read_mem(struct file * file, char __user * buf,
ssize_t read = 0, sz;
void __iomem *v;
if (!valid_phys_addr_range(p, &count))
return -EFAULT;
while (count > 0) {
/*
* Handle first page in case it's not aligned
@@ -58,13 +60,15 @@ static ssize_t read_mem(struct file * file, char __user * buf,
sz = min_t(unsigned long, sz, count);
if ((v = ioremap(p, sz)) == NULL) {
v = xlate_dev_mem_ptr(p, sz);
if (IS_ERR(v) || v == NULL) {
/*
* Some programs (e.g., dmidecode) groove off into weird RAM
* areas where no tables can possibly exist (because Xen will
* have stomped on them!). These programs get rather upset if
* we let them know that Xen failed their access, so we fake
* out a read of all zeroes. :-)
* Some programs (e.g., dmidecode) groove off into
* weird RAM areas where no tables can possibly exist
* (because Xen will have stomped on them!). These
* programs get rather upset if we let them know that
* Xen failed their access, so we fake out a read of
* all zeroes.
*/
if (clear_user(buf, count))
return -EFAULT;
@@ -73,7 +77,7 @@ static ssize_t read_mem(struct file * file, char __user * buf,
}
ignored = copy_to_user(buf, v, sz);
iounmap(v);
xlate_dev_mem_ptr_unmap(v);
if (ignored)
return -EFAULT;
buf += sz;
@@ -93,6 +97,9 @@ static ssize_t write_mem(struct file * file, const char __user * buf,
ssize_t written = 0, sz;
void __iomem *v;
if (!valid_phys_addr_range(p, &count))
return -EFAULT;
while (count > 0) {
/*
* Handle first page in case it's not aligned
@@ -104,11 +111,17 @@ static ssize_t write_mem(struct file * file, const char __user * buf,
sz = min_t(unsigned long, sz, count);
if ((v = ioremap(p, sz)) == NULL)
v = xlate_dev_mem_ptr(p, sz);
if (v == NULL)
break;
if (IS_ERR(v)) {
if (written == 0)
return PTR_ERR(v);
break;
}
ignored = copy_from_user(v, buf, sz);
iounmap(v);
xlate_dev_mem_ptr_unmap(v);
if (ignored) {
written += sz - ignored;
if (written)
@@ -125,6 +138,15 @@ static ssize_t write_mem(struct file * file, const char __user * buf,
return written;
}
#ifndef ARCH_HAS_DEV_MEM_MMAP_MEM
static inline int uncached_access(struct file *file)
{
if (file->f_flags & O_SYNC)
return 1;
/* Xen sets correct MTRR type on non-RAM for us. */
return 0;
}
static int mmap_mem(struct file * file, struct vm_area_struct * vma)
{
size_t size = vma->vm_end - vma->vm_start;
@@ -136,6 +158,7 @@ static int mmap_mem(struct file * file, struct vm_area_struct * vma)
return direct_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
size, vma->vm_page_prot, DOMID_IO);
}
#endif
/*
* The memory devices use the full 32/64 bits of the offset, and so we cannot
@@ -494,7 +494,7 @@ static int netbk_check_gop(int nr_frags, domid_t domid,
copy_op = npo->copy + npo->copy_cons++;
if (copy_op->status != GNTST_okay) {
DPRINTK("Bad status %d from copy to DOM%d.\n",
gop->status, domid);
copy_op->status, domid);
status = NETIF_RSP_ERROR;
}
} else {
@@ -39,9 +39,6 @@
#include <xen/platform-compat.h>
#endif
/* xenbus_probe.c */
extern char *kasprintf(const char *fmt, ...);
#define DPRINTK(fmt, args...) \
pr_debug("xenbus_client (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
@@ -88,7 +85,7 @@ int xenbus_watch_path2(struct xenbus_device *dev, const char *path,
const char **, unsigned int))
{
int err;
char *state = kasprintf("%s/%s", path, path2);
char *state = kasprintf(GFP_KERNEL, "%s/%s", path, path2);
if (!state) {
xenbus_dev_fatal(dev, -ENOMEM, "allocating path for watch");
return -ENOMEM;
@@ -156,7 +153,7 @@ EXPORT_SYMBOL_GPL(xenbus_frontend_closed);
*/
static char *error_path(struct xenbus_device *dev)
{
return kasprintf("error/%s", dev->nodename);
return kasprintf(GFP_KERNEL, "error/%s", dev->nodename);
}
@@ -444,27 +444,6 @@ static void xenbus_dev_release(struct device *dev)
kfree(to_xenbus_device(dev));
}
/* Simplified asprintf. */
char *kasprintf(const char *fmt, ...)
{
va_list ap;
unsigned int len;
char *p, dummy[1];
va_start(ap, fmt);
/* FIXME: vsnprintf has a bug, NULL should work */
len = vsnprintf(dummy, 0, fmt, ap);
va_end(ap);
p = kmalloc(len + 1, GFP_KERNEL);
if (!p)
return NULL;
va_start(ap, fmt);
vsprintf(p, fmt, ap);
va_end(ap);
return p;
}
static ssize_t xendev_show_nodename(struct device *dev,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
struct device_attribute *attr,
@@ -547,7 +526,7 @@ static int xenbus_probe_frontend(const char *type, const char *name)
char *nodename;
int err;
nodename = kasprintf("%s/%s/%s", xenbus_frontend.root, type, name);
nodename = kasprintf(GFP_KERNEL, "%s/%s/%s", xenbus_frontend.root, type, name);
if (!nodename)
return -ENOMEM;
@@ -644,7 +623,7 @@ void dev_changed(const char *node, struct xen_bus_type *bus)
rootlen = strsep_len(node, '/', bus->levels);
if (rootlen < 0)
return;
root = kasprintf("%.*s", rootlen, node);
root = kasprintf(GFP_KERNEL, "%.*s", rootlen, node);
if (!root)
return;
@@ -70,8 +70,5 @@ extern int xenbus_probe_devices(struct xen_bus_type *bus);
extern void dev_changed(const char *node, struct xen_bus_type *bus);
/* Simplified asprintf. Probably belongs in lib */
extern char *kasprintf(const char *fmt, ...);
#endif
@@ -188,7 +188,7 @@ static int xenbus_probe_backend_unit(const char *dir,
char *nodename;
int err;
nodename = kasprintf("%s/%s", dir, name);
nodename = kasprintf(GFP_KERNEL, "%s/%s", dir, name);
if (!nodename)
return -ENOMEM;
@@ -209,7 +209,7 @@ static int xenbus_probe_backend(const char *type, const char *domid)
DPRINTK("");
nodename = kasprintf("%s/%s/%s", xenbus_backend.root, type, domid);
nodename = kasprintf(GFP_KERNEL, "%s/%s/%s", xenbus_backend.root, type, domid);
if (!nodename)
return -ENOMEM;
@@ -51,9 +51,6 @@
#include <xen/platform-compat.h>
#endif
/* xenbus_probe.c */
extern char *kasprintf(const char *fmt, ...);
struct xs_stored_msg {
struct list_head list;
@@ -295,9 +292,9 @@ static char *join(const char *dir, const char *name)
char *buffer;
if (strlen(name) == 0)
buffer = kasprintf("%s", dir);
buffer = kasprintf(GFP_KERNEL, "%s", dir);
else
buffer = kasprintf("%s/%s", dir, name);
buffer = kasprintf(GFP_KERNEL, "%s/%s", dir, name);
return (!buffer) ? ERR_PTR(-ENOMEM) : buffer;
}
@@ -0,0 +1,500 @@
/**
* @file xenoprofile.c
*
* @remark Copyright 2002 OProfile authors
* @remark Read the file COPYING
*
* @author John Levon <levon@movementarian.org>
*
* Modified by Aravind Menon and Jose Renato Santos for Xen
* These modifications are:
* Copyright (C) 2005 Hewlett-Packard Co.
*
* Separated out arch-generic part
* Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
* VA Linux Systems Japan K.K.
*/
#include <linux/init.h>
#include <linux/notifier.h>
#include <linux/smp.h>
#include <linux/oprofile.h>
#include <linux/sysdev.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/vmalloc.h>
#include <asm/pgtable.h>
#include <xen/evtchn.h>
#include <xen/xenoprof.h>
#include <xen/driver_util.h>
#include <xen/interface/xen.h>
#include <xen/interface/xenoprof.h>
#include "../../../drivers/oprofile/cpu_buffer.h"
#include "../../../drivers/oprofile/event_buffer.h"
#define MAX_XENOPROF_SAMPLES 16
/* sample buffers shared with Xen */
xenoprof_buf_t * xenoprof_buf[MAX_VIRT_CPUS];
/* Shared buffer area */
struct xenoprof_shared_buffer shared_buffer;
/* Passive sample buffers shared with Xen */
xenoprof_buf_t *p_xenoprof_buf[MAX_OPROF_DOMAINS][MAX_VIRT_CPUS];
/* Passive shared buffer area */
struct xenoprof_shared_buffer p_shared_buffer[MAX_OPROF_DOMAINS];
static int xenoprof_start(void);
static void xenoprof_stop(void);
static int xenoprof_enabled = 0;
static int xenoprof_is_primary = 0;
static int active_defined;
/* Number of buffers in shared area (one per VCPU) */
int nbuf;
/* Mappings of VIRQ_XENOPROF to irq number (per cpu) */
int ovf_irq[NR_CPUS];
/* cpu model type string - copied from Xen memory space on XENOPROF_init command */
char cpu_type[XENOPROF_CPU_TYPE_SIZE];
#ifdef CONFIG_PM
static int xenoprof_suspend(struct sys_device * dev, pm_message_t state)
{
if (xenoprof_enabled == 1)
xenoprof_stop();
return 0;
}
static int xenoprof_resume(struct sys_device * dev)
{
if (xenoprof_enabled == 1)
xenoprof_start();
return 0;
}
static struct sysdev_class oprofile_sysclass = {
set_kset_name("oprofile"),
.resume = xenoprof_resume,
.suspend = xenoprof_suspend
};
static struct sys_device device_oprofile = {
.id = 0,
.cls = &oprofile_sysclass,
};
static int __init init_driverfs(void)
{
int error;
if (!(error = sysdev_class_register(&oprofile_sysclass)))
error = sysdev_register(&device_oprofile);
return error;
}
static void exit_driverfs(void)
{
sysdev_unregister(&device_oprofile);
sysdev_class_unregister(&oprofile_sysclass);
}
#else
#define init_driverfs() do { } while (0)
#define exit_driverfs() do { } while (0)
#endif /* CONFIG_PM */
unsigned long long oprofile_samples = 0;
unsigned long long p_oprofile_samples = 0;
unsigned int pdomains;
struct xenoprof_passive passive_domains[MAX_OPROF_DOMAINS];
static void xenoprof_add_pc(xenoprof_buf_t *buf, int is_passive)
{
int head, tail, size;
head = buf->event_head;
tail = buf->event_tail;
size = buf->event_size;
if (tail > head) {
while (tail < size) {
oprofile_add_pc(buf->event_log[tail].eip,
buf->event_log[tail].mode,
buf->event_log[tail].event);
if (!is_passive)
oprofile_samples++;
else
p_oprofile_samples++;
tail++;
}
tail = 0;
}
while (tail < head) {
oprofile_add_pc(buf->event_log[tail].eip,
buf->event_log[tail].mode,
buf->event_log[tail].event);
if (!is_passive)
oprofile_samples++;
else
p_oprofile_samples++;
tail++;
}
buf->event_tail = tail;
}
static void xenoprof_handle_passive(void)
{
int i, j;
int flag_domain, flag_switch = 0;
for (i = 0; i < pdomains; i++) {
flag_domain = 0;
for (j = 0; j < passive_domains[i].nbuf; j++) {
xenoprof_buf_t *buf = p_xenoprof_buf[i][j];
if (buf->event_head == buf->event_tail)
continue;
if (!flag_domain) {
if (!oprofile_add_domain_switch(passive_domains[i].
domain_id))
goto done;
flag_domain = 1;
}
xenoprof_add_pc(buf, 1);
flag_switch = 1;
}
}
done:
if (flag_switch)
oprofile_add_domain_switch(COORDINATOR_DOMAIN);
}
static irqreturn_t
xenoprof_ovf_interrupt(int irq, void * dev_id, struct pt_regs * regs)
{
struct xenoprof_buf * buf;
int cpu;
static unsigned long flag;
cpu = smp_processor_id();
buf = xenoprof_buf[cpu];
xenoprof_add_pc(buf, 0);
if (xenoprof_is_primary && !test_and_set_bit(0, &flag)) {
xenoprof_handle_passive();
smp_mb__before_clear_bit();
clear_bit(0, &flag);
}
return IRQ_HANDLED;
}
static void unbind_virq(void)
{
int i;
for_each_online_cpu(i) {
if (ovf_irq[i] >= 0) {
unbind_from_irqhandler(ovf_irq[i], NULL);
ovf_irq[i] = -1;
}
}
}
static int bind_virq(void)
{
int i, result;
for_each_online_cpu(i) {
result = bind_virq_to_irqhandler(VIRQ_XENOPROF,
i,
xenoprof_ovf_interrupt,
SA_INTERRUPT,
"xenoprof",
NULL);
if (result < 0) {
unbind_virq();
return result;
}
ovf_irq[i] = result;
}
return 0;
}
static void unmap_passive_list(void)
{
int i;
for (i = 0; i < pdomains; i++)
xenoprof_arch_unmap_shared_buffer(&p_shared_buffer[i]);
pdomains = 0;
}
static int map_xenoprof_buffer(int max_samples)
{
struct xenoprof_get_buffer get_buffer;
struct xenoprof_buf *buf;
int ret, i;
if ( shared_buffer.buffer )
return 0;
get_buffer.max_samples = max_samples;
ret = xenoprof_arch_map_shared_buffer(&get_buffer, &shared_buffer);
if (ret)
return ret;
nbuf = get_buffer.nbuf;
for (i=0; i< nbuf; i++) {
buf = (struct xenoprof_buf*)
&shared_buffer.buffer[i * get_buffer.bufsize];
BUG_ON(buf->vcpu_id >= MAX_VIRT_CPUS);
xenoprof_buf[buf->vcpu_id] = buf;
}
return 0;
}
static int xenoprof_setup(void)
{
int ret;
if ( (ret = map_xenoprof_buffer(MAX_XENOPROF_SAMPLES)) )
return ret;
if ( (ret = bind_virq()) )
return ret;
if (xenoprof_is_primary) {
/* Define dom0 as an active domain if not done yet */
if (!active_defined) {
domid_t domid;
ret = HYPERVISOR_xenoprof_op(XENOPROF_reset_active_list, NULL);
if (ret)
goto err;
domid = 0;
ret = HYPERVISOR_xenoprof_op(XENOPROF_set_active, &domid);
if (ret)
goto err;
active_defined = 1;
}
ret = HYPERVISOR_xenoprof_op(XENOPROF_reserve_counters, NULL);
if (ret)
goto err;
xenoprof_arch_counter();
ret = HYPERVISOR_xenoprof_op(XENOPROF_setup_events, NULL);
if (ret)
goto err;
}
ret = HYPERVISOR_xenoprof_op(XENOPROF_enable_virq, NULL);
if (ret)
goto err;
xenoprof_enabled = 1;
return 0;
err:
unbind_virq();
return ret;
}
static void xenoprof_shutdown(void)
{
xenoprof_enabled = 0;
HYPERVISOR_xenoprof_op(XENOPROF_disable_virq, NULL);
if (xenoprof_is_primary) {
HYPERVISOR_xenoprof_op(XENOPROF_release_counters, NULL);
active_defined = 0;
}
unbind_virq();
xenoprof_arch_unmap_shared_buffer(&shared_buffer);
if (xenoprof_is_primary)
unmap_passive_list();
}
static int xenoprof_start(void)
{
int ret = 0;
if (xenoprof_is_primary)
ret = HYPERVISOR_xenoprof_op(XENOPROF_start, NULL);
if (!ret)
xenoprof_arch_start();
return ret;
}
static void xenoprof_stop(void)
{
if (xenoprof_is_primary)
HYPERVISOR_xenoprof_op(XENOPROF_stop, NULL);
xenoprof_arch_stop();
}
static int xenoprof_set_active(int * active_domains,
unsigned int adomains)
{
int ret = 0;
int i;
int set_dom0 = 0;
domid_t domid;
if (!xenoprof_is_primary)
return 0;
if (adomains > MAX_OPROF_DOMAINS)
return -E2BIG;
ret = HYPERVISOR_xenoprof_op(XENOPROF_reset_active_list, NULL);
if (ret)
return ret;
for (i=0; i<adomains; i++) {
domid = active_domains[i];
if (domid != active_domains[i]) {
ret = -EINVAL;
goto out;
}
ret = HYPERVISOR_xenoprof_op(XENOPROF_set_active, &domid);
if (ret)
goto out;
if (active_domains[i] == 0)
set_dom0 = 1;
}
/* dom0 must always be active but may not be in the list */
if (!set_dom0) {
domid = 0;
ret = HYPERVISOR_xenoprof_op(XENOPROF_set_active, &domid);
}
out:
if (ret)
HYPERVISOR_xenoprof_op(XENOPROF_reset_active_list, NULL);
active_defined = !ret;
return ret;
}
static int xenoprof_set_passive(int * p_domains,
unsigned int pdoms)
{
int ret;
int i, j;
struct xenoprof_buf *buf;
if (!xenoprof_is_primary)
return 0;
if (pdoms > MAX_OPROF_DOMAINS)
return -E2BIG;
ret = HYPERVISOR_xenoprof_op(XENOPROF_reset_passive_list, NULL);
if (ret)
return ret;
unmap_passive_list();
for (i = 0; i < pdoms; i++) {
passive_domains[i].domain_id = p_domains[i];
passive_domains[i].max_samples = 2048;
ret = xenoprof_arch_set_passive(&passive_domains[i],
&p_shared_buffer[i]);
if (ret)
goto out;
for (j = 0; j < passive_domains[i].nbuf; j++) {
buf = (struct xenoprof_buf *)
&p_shared_buffer[i].buffer[j * passive_domains[i].bufsize];
BUG_ON(buf->vcpu_id >= MAX_VIRT_CPUS);
p_xenoprof_buf[i][buf->vcpu_id] = buf;
}
}
pdomains = pdoms;
return 0;
out:
for (j = 0; j < i; j++)
xenoprof_arch_unmap_shared_buffer(&p_shared_buffer[i]);
return ret;
}
struct oprofile_operations xenoprof_ops = {
#ifdef HAVE_XENOPROF_CREATE_FILES
.create_files = xenoprof_create_files,
#endif
.set_active = xenoprof_set_active,
.set_passive = xenoprof_set_passive,
.setup = xenoprof_setup,
.shutdown = xenoprof_shutdown,
.start = xenoprof_start,
.stop = xenoprof_stop
};
/* in order to get driverfs right */
static int using_xenoprof;
int __init xenoprofile_init(struct oprofile_operations * ops)
{
struct xenoprof_init init;
int ret, i;
ret = HYPERVISOR_xenoprof_op(XENOPROF_init, &init);
if (!ret) {
xenoprof_arch_init_counter(&init);
xenoprof_is_primary = init.is_primary;
/* cpu_type is detected by Xen */
cpu_type[XENOPROF_CPU_TYPE_SIZE-1] = 0;
strncpy(cpu_type, init.cpu_type, XENOPROF_CPU_TYPE_SIZE - 1);
xenoprof_ops.cpu_type = cpu_type;
init_driverfs();
using_xenoprof = 1;
*ops = xenoprof_ops;
for (i=0; i<NR_CPUS; i++)
ovf_irq[i] = -1;
active_defined = 0;
}
printk(KERN_INFO "%s: ret %d, events %d, xenoprof_is_primary %d\n",
__func__, ret, init.num_events, xenoprof_is_primary);
return ret;
}
void xenoprofile_exit(void)
{
if (using_xenoprof)
exit_driverfs();
xenoprof_arch_unmap_shared_buffer(&shared_buffer);
if (xenoprof_is_primary) {
unmap_passive_list();
HYPERVISOR_xenoprof_op(XENOPROF_shutdown, NULL);
}
}
@@ -98,7 +98,6 @@ void xen_pgd_pin(unsigned long ptr);
void xen_pgd_unpin(unsigned long ptr);
void xen_set_ldt(unsigned long ptr, unsigned long bytes);
void xen_machphys_update(unsigned long mfn, unsigned long pfn);
#ifdef CONFIG_SMP
#include <linux/cpumask.h>
@@ -54,7 +54,8 @@
* Convert a physical pointer to a virtual kernel pointer for /dev/mem
* access
*/
#define xlate_dev_mem_ptr(p) __va(p)
#define xlate_dev_mem_ptr(p, sz) ioremap(p, sz)
#define xlate_dev_mem_ptr_unmap(p) iounmap(p)
/*
* Convert a virtual cached pointer to an uncached pointer
@@ -9,6 +9,15 @@
#define FOREIGN_FRAME_BIT (1UL<<31)
#define FOREIGN_FRAME(m) ((m) | FOREIGN_FRAME_BIT)
/* Definitions for machine and pseudophysical addresses. */
#ifdef CONFIG_X86_PAE
typedef unsigned long long paddr_t;
typedef unsigned long long maddr_t;
#else
typedef unsigned long paddr_t;
typedef unsigned long maddr_t;
#endif
#ifdef CONFIG_XEN
extern unsigned long *phys_to_machine_mapping;
@@ -101,26 +110,6 @@ static inline void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
phys_to_machine_mapping[pfn] = mfn;
}
#else /* !CONFIG_XEN */
#define pfn_to_mfn(pfn) (pfn)
#define mfn_to_pfn(mfn) (mfn)
#define mfn_to_local_pfn(mfn) (mfn)
#define set_phys_to_machine(pfn, mfn) BUG_ON((pfn) != (mfn))
#define phys_to_machine_mapping_valid(pfn) (1)
#endif /* !CONFIG_XEN */
/* Definitions for machine and pseudophysical addresses. */
#ifdef CONFIG_X86_PAE
typedef unsigned long long paddr_t;
typedef unsigned long long maddr_t;
#else
typedef unsigned long paddr_t;
typedef unsigned long maddr_t;
#endif
static inline maddr_t phys_to_machine(paddr_t phys)
{
maddr_t machine = pfn_to_mfn(phys >> PAGE_SHIFT);
@@ -148,6 +137,19 @@ static inline paddr_t pte_machine_to_phys(maddr_t machine)
return phys;
}
#else /* !CONFIG_XEN */
#define pfn_to_mfn(pfn) (pfn)
#define mfn_to_pfn(mfn) (mfn)
#define mfn_to_local_pfn(mfn) (mfn)
#define set_phys_to_machine(pfn, mfn) BUG_ON((pfn) != (mfn))
#define phys_to_machine_mapping_valid(pfn) (1)
#define phys_to_machine(phys) ((maddr_t)(phys))
#define machine_to_phys(mach) ((paddr_t)(mach))
#define pte_machine_to_phys(mach) ((paddr_t)(mach))
#endif /* !CONFIG_XEN */
/* VIRT <-> MACHINE conversion */
#define virt_to_machine(v) (phys_to_machine(__pa(v)))
#define virt_to_mfn(v) (pfn_to_mfn(__pa(v) >> PAGE_SHIFT))
@@ -0,0 +1,48 @@
/******************************************************************************
* asm-i386/mach-xen/asm/xenoprof.h
*
* Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
* VA Linux Systems Japan K.K.
*
* 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
* (at your option) 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef __ASM_XENOPROF_H__
#define __ASM_XENOPROF_H__
#ifdef CONFIG_XEN
struct super_block;
struct dentry;
int xenoprof_create_files(struct super_block * sb, struct dentry * root);
#define HAVE_XENOPROF_CREATE_FILES
struct xenoprof_init;
void xenoprof_arch_init_counter(struct xenoprof_init *init);
void xenoprof_arch_counter(void);
void xenoprof_arch_start(void);
void xenoprof_arch_stop(void);
struct xenoprof_arch_shared_buffer {
/* nothing */
};
struct xenoprof_shared_buffer;
void xenoprof_arch_unmap_shared_buffer(struct xenoprof_shared_buffer* sbuf);
struct xenoprof_get_buffer;
int xenoprof_arch_map_shared_buffer(struct xenoprof_get_buffer* get_buffer, struct xenoprof_shared_buffer* sbuf);
struct xenoprof_passive;
int xenoprof_arch_set_passive(struct xenoprof_passive* pdomain, struct xenoprof_shared_buffer* sbuf);
#endif /* CONFIG_XEN */
#endif /* __ASM_XENOPROF_H__ */
@@ -96,11 +96,6 @@ mfn_to_local_pfn(unsigned long mfn)
#define virt_to_machine(virt) __pa(virt) // for tpmfront.c
#define set_phys_to_machine(pfn, mfn) do { } while (0)
#ifdef CONFIG_VMX_GUEST
extern void xen_machphys_update(unsigned long mfn, unsigned long pfn);
#else /* CONFIG_VMX_GUEST */
#define xen_machphys_update(mfn, pfn) do { } while (0)
#endif /* CONFIG_VMX_GUEST */
typedef unsigned long maddr_t; // to compile netback, netfront
@@ -346,7 +346,8 @@ extern int iommu_bio_merge;
* Convert a physical pointer to a virtual kernel pointer for /dev/mem
* access
*/
#define xlate_dev_mem_ptr(p) __va(p)
#define xlate_dev_mem_ptr(p, sz) ioremap(p, sz)
#define xlate_dev_mem_ptr_unmap(p) iounmap(p)
/*
* Convert a virtual cached pointer to an uncached pointer
@@ -9,6 +9,10 @@
#define FOREIGN_FRAME_BIT (1UL<<63)
#define FOREIGN_FRAME(m) ((m) | FOREIGN_FRAME_BIT)
/* Definitions for machine and pseudophysical addresses. */
typedef unsigned long paddr_t;
typedef unsigned long maddr_t;
#ifdef CONFIG_XEN
extern unsigned long *phys_to_machine_mapping;
@@ -99,20 +103,6 @@ static inline void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
phys_to_machine_mapping[pfn] = mfn;
}
#else /* !CONFIG_XEN */
#define pfn_to_mfn(pfn) (pfn)
#define mfn_to_pfn(mfn) (mfn)
#define mfn_to_local_pfn(mfn) (mfn)
#define set_phys_to_machine(pfn, mfn) BUG_ON((pfn) != (mfn))
#define phys_to_machine_mapping_valid(pfn) (1)
#endif /* !CONFIG_XEN */
/* Definitions for machine and pseudophysical addresses. */
typedef unsigned long paddr_t;
typedef unsigned long maddr_t;
static inline maddr_t phys_to_machine(paddr_t phys)
{
maddr_t machine = pfn_to_mfn(phys >> PAGE_SHIFT);
@@ -135,6 +125,19 @@ static inline paddr_t pte_machine_to_phys(maddr_t machine)
return phys;
}
#else /* !CONFIG_XEN */
#define pfn_to_mfn(pfn) (pfn)
#define mfn_to_pfn(mfn) (mfn)
#define mfn_to_local_pfn(mfn) (mfn)
#define set_phys_to_machine(pfn, mfn) BUG_ON((pfn) != (mfn))
#define phys_to_machine_mapping_valid(pfn) (1)
#define phys_to_machine(phys) ((maddr_t)(phys))
#define machine_to_phys(mach) ((paddr_t)(mach))
#define pte_machine_to_phys(mach) ((paddr_t)(mach))
#endif /* !CONFIG_XEN */
/* VIRT <-> MACHINE conversion */
#define virt_to_machine(v) (phys_to_machine(__pa(v)))
#define virt_to_mfn(v) (pfn_to_mfn(__pa(v) >> PAGE_SHIFT))
+12 -12
View File
@@ -974,15 +974,16 @@ static inline void skb_reserve(struct sk_buff *skb, int len)
#define NET_IP_ALIGN 2
#endif
extern int ___pskb_trim(struct sk_buff *skb, unsigned int len, int realloc);
extern int ___pskb_trim(struct sk_buff *skb, unsigned int len);
static inline void __skb_trim(struct sk_buff *skb, unsigned int len)
{
if (!skb->data_len) {
skb->len = len;
skb->tail = skb->data + len;
} else
___pskb_trim(skb, len, 0);
if (unlikely(skb->data_len)) {
WARN_ON(1);
return;
}
skb->len = len;
skb->tail = skb->data + len;
}
/**
@@ -992,6 +993,7 @@ static inline void __skb_trim(struct sk_buff *skb, unsigned int len)
*
* Cut the length of a buffer down by removing data from the tail. If
* the buffer is already under the length specified it is not modified.
* The skb must be linear.
*/
static inline void skb_trim(struct sk_buff *skb, unsigned int len)
{
@@ -1002,12 +1004,10 @@ static inline void skb_trim(struct sk_buff *skb, unsigned int len)
static inline int __pskb_trim(struct sk_buff *skb, unsigned int len)
{
if (!skb->data_len) {
skb->len = len;
skb->tail = skb->data+len;
return 0;
}
return ___pskb_trim(skb, len, 1);
if (skb->data_len)
return ___pskb_trim(skb, len);
__skb_trim(skb, len);
return 0;
}
static inline int pskb_trim(struct sk_buff *skb, unsigned int len)
@@ -0,0 +1,42 @@
/******************************************************************************
* xen/xenoprof.h
*
* Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
* VA Linux Systems Japan K.K.
*
* 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
* (at your option) 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef __XEN_XENOPROF_H__
#define __XEN_XENOPROF_H__
#ifdef CONFIG_XEN
#include <asm/xenoprof.h>
struct oprofile_operations;
int xenoprofile_init(struct oprofile_operations * ops);
void xenoprofile_exit(void);
struct xenoprof_shared_buffer {
char *buffer;
struct xenoprof_arch_shared_buffer arch;
};
#else
#define xenoprofile_init(ops) (-ENOSYS)
#define xenoprofile_exit() do { } while (0)
#endif /* CONFIG_XEN */
#endif /* __XEN_XENOPROF_H__ */
+1
View File
@@ -1535,6 +1535,7 @@ static inline void cow_user_page(struct page *dst, struct page *src, unsigned lo
if (__copy_from_user_inatomic(kaddr, uaddr, PAGE_SIZE))
memset(kaddr, 0, PAGE_SIZE);
kunmap_atomic(kaddr, KM_USER0);
flush_dcache_page(dst);
return;
}
+15 -2
View File
@@ -30,6 +30,10 @@
#include <asm/cacheflush.h>
#include <asm/tlb.h>
#ifndef arch_mmap_check
#define arch_mmap_check(addr, len, flags) (0)
#endif
static void unmap_region(struct mm_struct *mm,
struct vm_area_struct *vma, struct vm_area_struct *prev,
unsigned long start, unsigned long end);
@@ -906,6 +910,10 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
if (!len)
return -EINVAL;
error = arch_mmap_check(addr, len, flags);
if (error)
return error;
/* Careful about overflows.. */
len = PAGE_ALIGN(len);
if (!len || len > TASK_SIZE)
@@ -1846,6 +1854,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
unsigned long flags;
struct rb_node ** rb_link, * rb_parent;
pgoff_t pgoff = addr >> PAGE_SHIFT;
int error;
len = PAGE_ALIGN(len);
if (!len)
@@ -1854,6 +1863,12 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
if ((addr + len) > TASK_SIZE || (addr + len) < addr)
return -EINVAL;
flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
error = arch_mmap_check(addr, len, flags);
if (error)
return error;
/*
* mlock MCL_FUTURE?
*/
@@ -1894,8 +1909,6 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
if (security_vm_enough_memory(len >> PAGE_SHIFT))
return -ENOMEM;
flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
/* Can we just expand an old private anonymous mapping? */
if (vma_merge(mm, prev, addr, addr + len, flags,
NULL, NULL, pgoff, NULL))
+75 -32
View File
@@ -261,11 +261,11 @@ nodata:
}
static void skb_drop_fraglist(struct sk_buff *skb)
static void skb_drop_list(struct sk_buff **listp)
{
struct sk_buff *list = skb_shinfo(skb)->frag_list;
struct sk_buff *list = *listp;
skb_shinfo(skb)->frag_list = NULL;
*listp = NULL;
do {
struct sk_buff *this = list;
@@ -274,6 +274,11 @@ static void skb_drop_fraglist(struct sk_buff *skb)
} while (list);
}
static inline void skb_drop_fraglist(struct sk_buff *skb)
{
skb_drop_list(&skb_shinfo(skb)->frag_list);
}
static void skb_clone_fraglist(struct sk_buff *skb)
{
struct sk_buff *list;
@@ -604,6 +609,7 @@ struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask)
n->csum = skb->csum;
n->ip_summed = skb->ip_summed;
n->truesize += skb->data_len;
n->data_len = skb->data_len;
n->len = skb->len;
@@ -798,49 +804,86 @@ struct sk_buff *skb_pad(struct sk_buff *skb, int pad)
return nskb;
}
/* Trims skb to length len. It can change skb pointers, if "realloc" is 1.
* If realloc==0 and trimming is impossible without change of data,
* it is BUG().
/* Trims skb to length len. It can change skb pointers.
*/
int ___pskb_trim(struct sk_buff *skb, unsigned int len, int realloc)
int ___pskb_trim(struct sk_buff *skb, unsigned int len)
{
struct sk_buff **fragp;
struct sk_buff *frag;
int offset = skb_headlen(skb);
int nfrags = skb_shinfo(skb)->nr_frags;
int i;
int err;
for (i = 0; i < nfrags; i++) {
if (skb_cloned(skb) &&
unlikely((err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC))))
return err;
i = 0;
if (offset >= len)
goto drop_pages;
for (; i < nfrags; i++) {
int end = offset + skb_shinfo(skb)->frags[i].size;
if (end > len) {
if (skb_cloned(skb)) {
BUG_ON(!realloc);
if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
return -ENOMEM;
}
if (len <= offset) {
put_page(skb_shinfo(skb)->frags[i].page);
skb_shinfo(skb)->nr_frags--;
} else {
skb_shinfo(skb)->frags[i].size = len - offset;
}
if (end < len) {
offset = end;
continue;
}
offset = end;
skb_shinfo(skb)->frags[i++].size = len - offset;
drop_pages:
skb_shinfo(skb)->nr_frags = i;
for (; i < nfrags; i++)
put_page(skb_shinfo(skb)->frags[i].page);
if (skb_shinfo(skb)->frag_list)
skb_drop_fraglist(skb);
goto done;
}
if (offset < len) {
for (fragp = &skb_shinfo(skb)->frag_list; (frag = *fragp);
fragp = &frag->next) {
int end = offset + frag->len;
if (skb_shared(frag)) {
struct sk_buff *nfrag;
nfrag = skb_clone(frag, GFP_ATOMIC);
if (unlikely(!nfrag))
return -ENOMEM;
nfrag->next = frag->next;
kfree_skb(frag);
frag = nfrag;
*fragp = frag;
}
if (end < len) {
offset = end;
continue;
}
if (end > len &&
unlikely((err = pskb_trim(frag, len - offset))))
return err;
if (frag->next)
skb_drop_list(&frag->next);
break;
}
done:
if (len > skb_headlen(skb)) {
skb->data_len -= skb->len - len;
skb->len = len;
} else {
if (len <= skb_headlen(skb)) {
skb->len = len;
skb->data_len = 0;
skb->tail = skb->data + len;
if (skb_shinfo(skb)->frag_list && !skb_cloned(skb))
skb_drop_fraglist(skb);
} else {
skb->data_len -= skb->len - len;
skb->len = len;
}
skb->len = len;
skb->data_len = 0;
skb->tail = skb->data + len;
}
return 0;
+59
View File
@@ -0,0 +1,59 @@
commit e905914f96e11862b130dd229f73045dad9a34e8
Author: Jeremy Fitzhardinge <jeremy@xensource.com>
Date: Sun Jun 25 05:49:17 2006 -0700
[PATCH] Implement kasprintf
Implement kasprintf, a kernel version of asprintf. This allocates the
memory required for the formatted string, including the trailing '\0'.
Returns NULL on allocation failure.
Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com>
Signed-off-by: Chris Wright <chrisw@sous-sol.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 8c21aaa..3c5e4c2 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -117,6 +117,8 @@ extern int scnprintf(char * buf, size_t
__attribute__ ((format (printf, 3, 4)));
extern int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
__attribute__ ((format (printf, 3, 0)));
+extern char *kasprintf(gfp_t gfp, const char *fmt, ...)
+ __attribute__ ((format (printf, 2, 3)));
extern int sscanf(const char *, const char *, ...)
__attribute__ ((format (scanf, 2, 3)));
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index f595947..797428a 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -849,3 +849,26 @@ int sscanf(const char * buf, const char
}
EXPORT_SYMBOL(sscanf);
+
+
+/* Simplified asprintf. */
+char *kasprintf(gfp_t gfp, const char *fmt, ...)
+{
+ va_list ap;
+ unsigned int len;
+ char *p;
+
+ va_start(ap, fmt);
+ len = vsnprintf(NULL, 0, fmt, ap);
+ va_end(ap);
+
+ p = kmalloc(len+1, gfp);
+ if (!p)
+ return NULL;
+ va_start(ap, fmt);
+ vsnprintf(p, len+1, fmt, ap);
+ va_end(ap);
+ return p;
+}
+
+EXPORT_SYMBOL(kasprintf);
@@ -23,3 +23,5 @@ xenoprof-generic.patch
x86-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch
x86_64-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch
x86-elfnote-as-preprocessor-macro.patch
vsnprintf.patch
kasprintf.patch
+211
View File
@@ -0,0 +1,211 @@
commit f796937a062c7aeb44cd0e75e1586c8543634a7d
Author: Jeremy Fitzhardinge <jeremy@xensource.com>
Date: Sun Jun 25 05:49:17 2006 -0700
[PATCH] Fix bounds check in vsnprintf, to allow for a 0 size and NULL buffer
This change allows callers to use a 0-byte buffer and a NULL buffer pointer
with vsnprintf, so it can be used to determine how large the resulting
formatted string will be.
Previously the code effectively treated a size of 0 as a size of 4G (on
32-bit systems), with other checks preventing it from actually trying to
emit the string - but the terminal \0 would still be written, which would
crash if the buffer is NULL.
This change changes the boundary check so that 'end' points to the putative
location of the terminal '\0', which is only written if size > 0.
vsnprintf still allows the buffer size to be set very large, to allow
unbounded buffer sizes (to implement sprintf, etc).
[akpm@osdl.org: fix long-vs-longlong confusion]
Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com>
Signed-off-by: Chris Wright <chrisw@sous-sol.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index b07db5c..f595947 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -187,49 +187,49 @@ static char * number(char * buf, char *
size -= precision;
if (!(type&(ZEROPAD+LEFT))) {
while(size-->0) {
- if (buf <= end)
+ if (buf < end)
*buf = ' ';
++buf;
}
}
if (sign) {
- if (buf <= end)
+ if (buf < end)
*buf = sign;
++buf;
}
if (type & SPECIAL) {
if (base==8) {
- if (buf <= end)
+ if (buf < end)
*buf = '0';
++buf;
} else if (base==16) {
- if (buf <= end)
+ if (buf < end)
*buf = '0';
++buf;
- if (buf <= end)
+ if (buf < end)
*buf = digits[33];
++buf;
}
}
if (!(type & LEFT)) {
while (size-- > 0) {
- if (buf <= end)
+ if (buf < end)
*buf = c;
++buf;
}
}
while (i < precision--) {
- if (buf <= end)
+ if (buf < end)
*buf = '0';
++buf;
}
while (i-- > 0) {
- if (buf <= end)
+ if (buf < end)
*buf = tmp[i];
++buf;
}
while (size-- > 0) {
- if (buf <= end)
+ if (buf < end)
*buf = ' ';
++buf;
}
@@ -272,7 +272,8 @@ int vsnprintf(char *buf, size_t size, co
/* 'z' changed to 'Z' --davidm 1/25/99 */
/* 't' added for ptrdiff_t */
- /* Reject out-of-range values early */
+ /* Reject out-of-range values early. Large positive sizes are
+ used for unknown buffer sizes. */
if (unlikely((int) size < 0)) {
/* There can be only one.. */
static int warn = 1;
@@ -282,16 +283,17 @@ int vsnprintf(char *buf, size_t size, co
}
str = buf;
- end = buf + size - 1;
+ end = buf + size;
- if (end < buf - 1) {
- end = ((void *) -1);
- size = end - buf + 1;
+ /* Make sure end is always >= buf */
+ if (end < buf) {
+ end = ((void *)-1);
+ size = end - buf;
}
for (; *fmt ; ++fmt) {
if (*fmt != '%') {
- if (str <= end)
+ if (str < end)
*str = *fmt;
++str;
continue;
@@ -357,17 +359,17 @@ int vsnprintf(char *buf, size_t size, co
case 'c':
if (!(flags & LEFT)) {
while (--field_width > 0) {
- if (str <= end)
+ if (str < end)
*str = ' ';
++str;
}
}
c = (unsigned char) va_arg(args, int);
- if (str <= end)
+ if (str < end)
*str = c;
++str;
while (--field_width > 0) {
- if (str <= end)
+ if (str < end)
*str = ' ';
++str;
}
@@ -382,18 +384,18 @@ int vsnprintf(char *buf, size_t size, co
if (!(flags & LEFT)) {
while (len < field_width--) {
- if (str <= end)
+ if (str < end)
*str = ' ';
++str;
}
}
for (i = 0; i < len; ++i) {
- if (str <= end)
+ if (str < end)
*str = *s;
++str; ++s;
}
while (len < field_width--) {
- if (str <= end)
+ if (str < end)
*str = ' ';
++str;
}
@@ -426,7 +428,7 @@ int vsnprintf(char *buf, size_t size, co
continue;
case '%':
- if (str <= end)
+ if (str < end)
*str = '%';
++str;
continue;
@@ -449,11 +451,11 @@ int vsnprintf(char *buf, size_t size, co
break;
default:
- if (str <= end)
+ if (str < end)
*str = '%';
++str;
if (*fmt) {
- if (str <= end)
+ if (str < end)
*str = *fmt;
++str;
} else {
@@ -483,14 +485,13 @@ int vsnprintf(char *buf, size_t size, co
str = number(str, end, num, base,
field_width, precision, flags);
}
- if (str <= end)
- *str = '\0';
- else if (size > 0)
- /* don't write out a null byte if the buf size is zero */
- *end = '\0';
- /* the trailing null byte doesn't count towards the total
- * ++str;
- */
+ if (size > 0) {
+ if (str < end)
+ *str = '\0';
+ else
+ *end = '\0';
+ }
+ /* the trailing null byte doesn't count towards the total */
return str-buf;
}
+1 -1
View File
@@ -420,7 +420,7 @@ static int read_msg(int fd, int msgtype, void *ptr)
image->secsize = img->secsize;
image->info = img->info;
DPRINTF("Received CTLMSG_IMG: %lu, %lu, %lu\n",
DPRINTF("Received CTLMSG_IMG: %llu, %lu, %u\n",
image->size, image->secsize, image->info);
if(msgtype != CTLMSG_IMG) ret = 0;
break;
+3 -3
View File
@@ -30,19 +30,19 @@
*/
static inline long int tapdisk_get_size(blkif_t *blkif)
static inline unsigned long long tapdisk_get_size(blkif_t *blkif)
{
image_t *img = (image_t *)blkif->prv;
return img->size;
}
static inline long int tapdisk_get_secsize(blkif_t *blkif)
static inline unsigned long tapdisk_get_secsize(blkif_t *blkif)
{
image_t *img = (image_t *)blkif->prv;
return img->secsize;
}
static inline unsigned tapdisk_get_info(blkif_t *blkif)
static inline unsigned int tapdisk_get_info(blkif_t *blkif)
{
image_t *img = (image_t *)blkif->prv;
return img->info;
+3 -3
View File
@@ -74,9 +74,9 @@ struct td_state {
void *ring_info;
void *fd_entry;
char backing_file[1024]; /*Used by differencing disks, e.g. qcow*/
long int sector_size;
uint64_t size;
long int info;
unsigned long sector_size;
unsigned long long size;
unsigned int info;
};
/* Prototype of the callback to activate as requests complete. */
+6 -6
View File
@@ -97,9 +97,9 @@ typedef struct {
} pending_req_t;
struct blkif_ops {
long int (*get_size)(struct blkif *blkif);
long int (*get_secsize)(struct blkif *blkif);
unsigned (*get_info)(struct blkif *blkif);
unsigned long long (*get_size)(struct blkif *blkif);
unsigned long (*get_secsize)(struct blkif *blkif);
unsigned int (*get_info)(struct blkif *blkif);
};
typedef struct blkif {
@@ -156,9 +156,9 @@ typedef struct domid_translate {
} domid_translate_t ;
typedef struct image {
long int size;
long int secsize;
long int info;
unsigned long long size;
unsigned long secsize;
unsigned int info;
} image_t;
typedef struct msg_hdr {
+1 -1
View File
@@ -219,7 +219,7 @@ static void ueblktap_setup(struct xs_handle *h, char *bepath)
}
/* Supply the information about the device to xenstore */
er = xs_printf(h, be->backpath, "sectors", "%lu",
er = xs_printf(h, be->backpath, "sectors", "%llu",
be->blkif->ops->get_size(be->blkif));
if (er == 0) {
+16
View File
@@ -0,0 +1,16 @@
#!/bin/bash
# CHECK-BUILD
function error {
echo
echo " *** Check for python development environment FAILED"
exit 1
}
python -c '
import os.path, sys
for p in sys.path:
if os.path.exists(p + "/config/Makefile"):
sys.exit(0)
sys.exit(1)
' || error
+1 -1
View File
@@ -103,7 +103,7 @@ function handle_iptable()
if [ "$ip" != "" ]
then
local addr
for addr in "$ip"
for addr in $ip
do
frob_iptable -s "$addr"
done
+36
View File
@@ -14,6 +14,42 @@
#(logfile /var/log/xen/xend.log)
#(loglevel DEBUG)
# The Xen-API server configuration. (Please note that this server is
# available as an UNSUPPORTED PREVIEW in Xen 3.0.4, and should not be relied
# upon).
#
# This value configures the ports, interfaces, and access controls for the
# Xen-API server. Each entry in the list starts with either unix, a port
# number, or an address:port pair. If this is "unix", then a UDP socket is
# opened, and this entry applies to that. If it is a port, then Xend will
# listen on all interfaces on that TCP port, and if it is an address:port
# pair, then Xend will listen on the specified port, using the interface with
# the specified address.
#
# The subsequent string configures the user-based access control for the
# listener in question. This can be one of "none" or "pam", indicating either
# that users should be allowed access unconditionally, or that the local
# Pluggable Authentication Modules configuration should be used. If this
# string is missing or empty, then "pam" is used.
#
# The final string gives the host-based access control for that listener. If
# this is missing or empty, then all connections are accepted. Otherwise,
# this should be a space-separated sequence of regular expressions; any host
# with a fully-qualified domain name or an IP address that matches one of
# these regular expressions will be accepted.
#
# Example: listen on TCP port 9363 on all interfaces, accepting connections
# only from machines in example.com or localhost, and allow access through
# the unix domain socket unconditionally:
#
# (xen-api-server ((9363 pam '^localhost$ example\\.com$')
# (unix none)))
#
# Default:
# (xen-api-server ((unix)))
#(xend-http-server no)
#(xend-unix-server no)
#(xend-tcp-xmlrpc-server no)
+13 -5
View File
@@ -39,14 +39,18 @@ name = "ExampleHVMDomain"
#uuid = "06ed00fe-1162-4fc4-b5d8-11993ee4a8b9"
#-----------------------------------------------------------------------------
# the number of cpus guest platform has, default=1
# The number of cpus guest platform has, default=1
#vcpus=1
# enable/disable HVM guest PAE, default=0 (disabled)
#pae=0
# Enable/disable HVM guest PAE, default=1 (enabled)
#pae=1
# enable/disable HVM guest ACPI, default=0 (disabled)
#acpi=0
# Enable/disable HVM guest ACPI, default=1 (enabled)
#acpi=1
# Enable/disable HVM APIC mode, default=1 (enabled)
# Note that this option is ignored if vcpus > 1
#apic=1
# List of which CPUS this domain is allowed to use, default Xen picks
#cpus = "" # leave to Xen to pick
@@ -190,3 +194,7 @@ serial='pty'
# absolute mouse)
#usbdevice='mouse'
#usbdevice='tablet'
#-----------------------------------------------------------------------------
# Set keyboard layout, default is en-us keyboard.
#keymap='ja'
+4
View File
@@ -134,3 +134,7 @@ serial='pty'
# absolute mouse)
#usbdevice='mouse'
#usbdevice='tablet'
#-----------------------------------------------------------------------------
# Set keyboard layout, default is en-us keyboard.
#keymap='ja'
+7 -5
View File
@@ -40,25 +40,27 @@ OBJCOPY = objcopy
CFLAGS += $(DEFINES) -I. $(XENINC) -fno-builtin -O2 -msoft-float
LDFLAGS = -nostdlib -Wl,-N -Wl,-Ttext -Wl,$(LOADADDR)
SRCS = hvmloader.c acpi_madt.c mp_tables.c util.c smbios.c acpi_utils.c
SRCS = hvmloader.c mp_tables.c util.c smbios.c acpi_utils.c
OBJS = $(patsubst %.c,%.o,$(SRCS))
.PHONY: all
all: hvmloader
hvmloader: roms.h $(SRCS)
hvmloader: roms.h acpi/acpi.a $(SRCS)
$(CC) $(CFLAGS) -c $(SRCS)
$(CC) $(CFLAGS) $(LDFLAGS) -o hvmloader.tmp $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) -o hvmloader.tmp $(OBJS) acpi/acpi.a
$(OBJCOPY) hvmloader.tmp hvmloader
rm -f hvmloader.tmp
roms.h: ../rombios/BIOS-bochs-latest ../vgabios/VGABIOS-lgpl-latest.bin ../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../vmxassist/vmxassist.bin
.PHONY: acpi/acpi.a
acpi/acpi.a:
$(MAKE) -C acpi
roms.h: ../rombios/BIOS-bochs-latest ../vgabios/VGABIOS-lgpl-latest.bin ../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../vmxassist/vmxassist.bin
sh ./mkhex rombios ../rombios/BIOS-bochs-latest > roms.h
sh ./mkhex vgabios_stdvga ../vgabios/VGABIOS-lgpl-latest.bin >> roms.h
sh ./mkhex vgabios_cirrusvga ../vgabios/VGABIOS-lgpl-latest.cirrus.bin >> roms.h
sh ./mkhex vmxassist ../vmxassist/vmxassist.bin >> roms.h
sh ./mkhex acpi acpi/acpi.bin >> roms.h
.PHONY: clean
clean:
+10 -12
View File
@@ -15,21 +15,20 @@
# Place - Suite 330, Boston, MA 02111-1307 USA.
#
override XEN_TARGET_ARCH = x86_32
XEN_ROOT = ../../../..
CFLAGS := -I. -I.. -I$(XEN_ROOT)/tools/libxc
include $(XEN_ROOT)/tools/Rules.mk
HOSTCFLAGS += -I. -I.. -I$(XEN_ROOT)/tools/libxc
C_SRC = build.c dsdt.c gen.c static_tables.c
C_SRC = build.c dsdt.c static_tables.c
H_SRC = $(wildcard *.h)
ACPI_GEN = acpigen
ACPI_BIN = acpi.bin
OBJS = $(patsubst %.c,%.o,$(C_SRC))
IASL_VER = acpica-unix-20050513
IASL_URL = http://developer.intel.com/technology/iapc/acpi/downloads/$(IASL_VER).tar.gz
vpath iasl $(PATH)
all:$(ACPI_BIN)
all: acpi.a
dsdt.c: dsdt.asl
$(MAKE) iasl
@@ -50,14 +49,13 @@ iasl:
make -C $(IASL_VER)/compiler
$(INSTALL_PROG) $(IASL_VER)/compiler/iasl /usr/bin/iasl
$(ACPI_GEN): $(C_SRC) $(H_SRC)
$(HOSTCC) -o $(ACPI_GEN) $(HOSTCFLAGS) $(C_SRC)
acpi.a: $(OBJS)
$(AR) rc $@ $(OBJS)
$(ACPI_BIN): $(ACPI_GEN)
./$(ACPI_GEN) $(ACPI_BIN)
%.o: %.c $(H_SRC)
$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
clean:
rm -rf *.o $(ACPI_GEN) $(ACPI_BIN) $(IASL_VER)
rm -rf $(IASL_VER).tar.gz
rm -rf *.a *.o $(IASL_VER) $(IASL_VER).tar.gz
install: all
+9 -7
View File
@@ -249,7 +249,7 @@ struct acpi_20_facs {
/*
* Multiple APIC Description Table header definition (MADT).
*/
struct acpi_20_madt_header {
struct acpi_20_madt {
struct acpi_header header;
uint32_t lapic_addr;
uint32_t flags;
@@ -307,10 +307,13 @@ struct acpi_20_madt_ioapic {
uint32_t gsi_base;
};
struct acpi_20_madt {
struct acpi_20_madt_header header;
struct acpi_20_madt_ioapic io_apic[1];
struct acpi_20_madt_lapic lapic[32];
struct acpi_20_madt_intsrcovr {
uint8_t type;
uint8_t length;
uint8_t bus;
uint8_t source;
uint32_t gsi;
uint16_t flags;
};
/*
@@ -327,9 +330,8 @@ struct acpi_20_madt {
#pragma pack ()
#define ACPI_PHYSICAL_ADDRESS 0xEA000
#define ACPI_TABLE_SIZE (4*1024)
void AcpiBuildTable(uint8_t *buf);
int acpi_build_tables(uint8_t *);
#endif /* _ACPI_2_0_H_ */
+154 -189
View File
@@ -1,233 +1,198 @@
/*
* Copyright (c) 2004, Intel Corporation.
* Copyright (c) 2006, Keir Fraser, XenSource Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
* under the terms and conditions of the GNU General Public License, version
* 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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.
* This program is distributed in the hope 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., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307 USA.
*
*/
#include "acpi2_0.h"
#include "../config.h"
#include "../util.h"
extern struct acpi_20_rsdp Rsdp;
extern struct acpi_20_rsdt Rsdt;
extern struct acpi_20_xsdt Xsdt;
extern struct acpi_20_fadt Fadt;
extern struct acpi_20_madt Madt;
extern struct acpi_20_facs Facs;
extern unsigned char *AmlCode;
extern unsigned char AmlCode[];
extern int DsdtLen;
static void set_checksum(
void *table, uint32_t checksum_offset, uint32_t length)
{
uint8_t *p, sum = 0;
typedef struct _ACPI_TABLE_ALL{
struct acpi_20_rsdp *Rsdp;
struct acpi_20_rsdt *Rsdt;
struct acpi_20_xsdt *Xsdt;
struct acpi_20_fadt *Fadt;
struct acpi_20_madt *Madt;
struct acpi_20_facs *Facs;
unsigned char *Dsdt;
uint32_t RsdpOffset;
uint32_t RsdtOffset;
uint32_t XsdtOffset;
uint32_t FadtOffset;
uint32_t MadtOffset;
uint32_t FacsOffset;
uint32_t DsdtOffset;
}ACPI_TABLE_ALL;
p = table;
p[checksum_offset] = 0;
static
void
MemCopy(void* src, void* dst, int len){
while ( length-- )
sum = sum + *p++;
uint8_t* src0=src;
uint8_t* dst0=dst;
p = table;
p[checksum_offset] = -sum;
}
while(len--){
*(dst0++)=*(src0++);
int construct_madt(struct acpi_20_madt *madt)
{
struct acpi_20_madt_intsrcovr *intsrcovr;
struct acpi_20_madt_ioapic *io_apic;
struct acpi_20_madt_lapic *lapic;
int i, offset = 0;
memset(madt, 0, sizeof(*madt));
madt->header.signature = ACPI_2_0_MADT_SIGNATURE;
madt->header.revision = ACPI_2_0_MADT_REVISION;
strncpy(madt->header.oem_id, "INTEL ", 6);
madt->header.oem_table_id = ACPI_OEM_TABLE_ID;
madt->header.oem_revision = ACPI_OEM_REVISION;
madt->header.creator_id = ACPI_CREATOR_ID;
madt->header.creator_revision = ACPI_CREATOR_REVISION;
madt->lapic_addr = LAPIC_BASE_ADDRESS;
madt->flags = ACPI_PCAT_COMPAT;
offset += sizeof(*madt);
intsrcovr = (struct acpi_20_madt_intsrcovr *)(madt + 1);
for ( i = 0; i < 16; i++ )
{
if ( !(PCI_ISA_IRQ_MASK & (1U << i)) )
continue;
/* PCI: active-low level-triggered */
memset(intsrcovr, 0, sizeof(*intsrcovr));
intsrcovr->type = ACPI_INTERRUPT_SOURCE_OVERRIDE;
intsrcovr->length = sizeof(*intsrcovr);
intsrcovr->source = i;
intsrcovr->gsi = i;
intsrcovr->flags = 0xf;
offset += sizeof(*intsrcovr);
intsrcovr++;
}
}
static
void
SetCheckSum(
void* Table,
uint32_t ChecksumOffset,
uint32_t Length
)
/*
* Routine Description:
* Calculate Checksum and store the result in the checksum
* filed of the table
*
* INPUT:
* Table: Start pointer of table
* ChecksumOffset: Offset of checksum field in the table
* Length: Length of Table
*/
{
uint8_t Sum = 0;
uint8_t *Ptr;
io_apic = (struct acpi_20_madt_ioapic *)intsrcovr;
memset(io_apic, 0, sizeof(*io_apic));
io_apic->type = ACPI_IO_APIC;
io_apic->length = sizeof(*io_apic);
io_apic->ioapic_id = IOAPIC_ID;
io_apic->ioapic_addr = IOAPIC_BASE_ADDRESS;
offset += sizeof(*io_apic);
Ptr=Table;
Ptr[ChecksumOffset]=0;
while (Length--) {
Sum = (uint8_t)(Sum + (*Ptr++));
lapic = (struct acpi_20_madt_lapic *)(io_apic + 1);
for ( i = 0; i < get_vcpu_nr(); i++ )
{
memset(lapic, 0, sizeof(*lapic));
lapic->type = ACPI_PROCESSOR_LOCAL_APIC;
lapic->length = sizeof(*lapic);
lapic->acpi_processor_id = lapic->apic_id = i + 1;
lapic->flags = ACPI_LOCAL_APIC_ENABLED;
offset += sizeof(*lapic);
lapic++;
}
Ptr = Table;
Ptr[ChecksumOffset] = (uint8_t) (0xff - Sum + 1);
madt->header.length = offset;
set_checksum(madt, offsetof(struct acpi_header, checksum), offset);
return offset;
}
//
// FIELD_OFFSET - returns the byte offset to a field within a structure
//
#define FIELD_OFFSET(TYPE,Field) ((uint32_t)(&(((TYPE *) 0)->Field)))
static
void
UpdateTable(
ACPI_TABLE_ALL *table
)
/*
* Update the ACPI table:
* fill in the actuall physical address of RSDT, XSDT, FADT, MADT, FACS
* Caculate the checksum
* Copy all the ACPI table to buffer.
* Buffer layout: FACS, DSDT, FADT, MADT, XSDT, RSDT, RSDP.
*/
int acpi_build_tables(uint8_t *buf)
{
// RSDP Update
table->Rsdp->rsdt_address = (uint32_t)(ACPI_PHYSICAL_ADDRESS+
table->RsdtOffset);
table->Rsdp->xsdt_address = (uint64_t)(ACPI_PHYSICAL_ADDRESS+
table->XsdtOffset);
SetCheckSum(table->Rsdp,
FIELD_OFFSET(struct acpi_10_rsdp, checksum),
sizeof(struct acpi_10_rsdp)
);
SetCheckSum(table->Rsdp,
FIELD_OFFSET(struct acpi_20_rsdp,
extended_checksum),
sizeof(struct acpi_20_rsdp)
);
struct acpi_20_rsdp *rsdp;
struct acpi_20_rsdt *rsdt;
struct acpi_20_xsdt *xsdt;
struct acpi_20_fadt *fadt;
struct acpi_20_madt *madt = 0;
struct acpi_20_facs *facs;
unsigned char *dsdt;
int offset = 0, requires_madt;
//RSDT Update
table->Rsdt->entry[0] = (uint32_t)(ACPI_PHYSICAL_ADDRESS +
table->FadtOffset);
table->Rsdt->entry[1] = (uint32_t)(ACPI_PHYSICAL_ADDRESS +
table->MadtOffset);
table->Rsdt->header.length = sizeof (struct acpi_header) +
2*sizeof(uint32_t);
SetCheckSum(table->Rsdt,
FIELD_OFFSET(struct acpi_header, checksum),
table->Rsdt->header.length
);
requires_madt = ((get_vcpu_nr() > 1) || get_apic_mode());
//XSDT Update
table->Xsdt->entry[0] = (uint64_t)(ACPI_PHYSICAL_ADDRESS +
table->FadtOffset);
table->Xsdt->entry[1] = (uint64_t)(ACPI_PHYSICAL_ADDRESS +
table->MadtOffset);
table->Xsdt->header.length = sizeof (struct acpi_header) +
2*sizeof(uint64_t);
SetCheckSum(table->Xsdt,
FIELD_OFFSET(struct acpi_header, checksum),
table->Xsdt->header.length
);
#define inc_offset(sz) (offset = (offset + (sz) + 15) & ~15)
// FADT Update
table->Fadt->dsdt = (uint32_t)(ACPI_PHYSICAL_ADDRESS +
table->DsdtOffset);
table->Fadt->x_dsdt = (uint64_t)(ACPI_PHYSICAL_ADDRESS +
table->DsdtOffset);
table->Fadt->firmware_ctrl = (uint32_t)(ACPI_PHYSICAL_ADDRESS +
table->FacsOffset);
table->Fadt->x_firmware_ctrl = (uint64_t)(ACPI_PHYSICAL_ADDRESS +
table->FacsOffset);
SetCheckSum(table->Fadt,
FIELD_OFFSET(struct acpi_header, checksum),
sizeof(struct acpi_20_fadt)
);
// MADT update
SetCheckSum(table->Madt,
FIELD_OFFSET(struct acpi_header, checksum),
sizeof(struct acpi_20_madt)
);
}
facs = (struct acpi_20_facs *)&buf[offset];
memcpy(facs, &Facs, sizeof(struct acpi_20_facs));
inc_offset(sizeof(struct acpi_20_facs));
void
AcpiBuildTable(uint8_t* buf)
/*
* Copy all the ACPI table to buffer
* Buffer Layout:
* FACS
* RSDP
* RSDT
* XSDT
* FADT
* MADT
* DSDT
*
*/
{
ACPI_TABLE_ALL table;
int offset=0;
dsdt = (unsigned char *)&buf[offset];
memcpy(dsdt, &AmlCode, DsdtLen);
inc_offset(DsdtLen);
// FACS: should be 64-bit alignment
// so it is put at the start of buffer
// as the buffer is 64 bit alignment
table.FacsOffset = offset;
table.Facs = (struct acpi_20_facs *)(&buf[offset]);
MemCopy(&Facs, table.Facs, sizeof(struct acpi_20_facs));
offset += sizeof(struct acpi_20_facs);
fadt = (struct acpi_20_fadt *)&buf[offset];
memcpy(fadt, &Fadt, sizeof(struct acpi_20_fadt));
inc_offset(sizeof(struct acpi_20_fadt));
fadt->dsdt = (unsigned long)dsdt;
fadt->x_dsdt = (unsigned long)dsdt;
fadt->firmware_ctrl = (unsigned long)facs;
fadt->x_firmware_ctrl = (unsigned long)facs;
set_checksum(fadt,
offsetof(struct acpi_header, checksum),
sizeof(struct acpi_20_fadt));
// RSDP
table.RsdpOffset = offset;
table.Rsdp = (struct acpi_20_rsdp *)(&buf[offset]);
MemCopy(&Rsdp, table.Rsdp, sizeof(struct acpi_20_rsdp));
offset += sizeof(struct acpi_20_rsdp);
if ( requires_madt )
{
madt = (struct acpi_20_madt *)&buf[offset];
inc_offset(construct_madt(madt));
}
// RSDT
table.RsdtOffset = offset;
table.Rsdt = (struct acpi_20_rsdt *)(&buf[offset]);
MemCopy(&Rsdt, table.Rsdt, sizeof(struct acpi_20_rsdt));
offset += sizeof(struct acpi_20_rsdt);
// XSDT
table.XsdtOffset = offset;
table.Xsdt = (struct acpi_20_xsdt *)(&buf[offset]);
MemCopy(&Xsdt, table.Xsdt, sizeof(struct acpi_20_xsdt));
offset += sizeof(struct acpi_20_xsdt);
// FADT
table.FadtOffset = offset;
table.Fadt = (struct acpi_20_fadt *)(&buf[offset]);
MemCopy(&Fadt, table.Fadt, sizeof(struct acpi_20_fadt));
offset += sizeof(struct acpi_20_fadt);
// MADT
table.MadtOffset = offset;
table.Madt = (struct acpi_20_madt*)(&buf[offset]);
MemCopy(&Madt, table.Madt, sizeof(struct acpi_20_madt));
offset += sizeof(struct acpi_20_madt);
xsdt = (struct acpi_20_xsdt *)&buf[offset];
memcpy(xsdt, &Xsdt, sizeof(struct acpi_20_xsdt));
inc_offset(sizeof(struct acpi_20_xsdt));
xsdt->entry[0] = (unsigned long)fadt;
xsdt->header.length = sizeof(struct acpi_header) + sizeof(uint64_t);
if ( requires_madt )
{
xsdt->entry[1] = (unsigned long)madt;
xsdt->header.length += sizeof(uint64_t);
}
set_checksum(xsdt,
offsetof(struct acpi_header, checksum),
xsdt->header.length);
// DSDT
table.DsdtOffset = offset;
table.Dsdt = (unsigned char *)(&buf[offset]);
MemCopy(&AmlCode, table.Dsdt, DsdtLen);
offset += DsdtLen;
UpdateTable(&table);
rsdt = (struct acpi_20_rsdt *)&buf[offset];
memcpy(rsdt, &Rsdt, sizeof(struct acpi_20_rsdt));
inc_offset(sizeof(struct acpi_20_rsdt));
rsdt->entry[0] = (unsigned long)fadt;
rsdt->header.length = sizeof(struct acpi_header) + sizeof(uint32_t);
if ( requires_madt )
{
rsdt->entry[1] = (unsigned long)madt;
rsdt->header.length += sizeof(uint32_t);
}
set_checksum(rsdt,
offsetof(struct acpi_header, checksum),
rsdt->header.length);
rsdp = (struct acpi_20_rsdp *)&buf[offset];
memcpy(rsdp, &Rsdp, sizeof(struct acpi_20_rsdp));
inc_offset(sizeof(struct acpi_20_rsdp));
rsdp->rsdt_address = (unsigned long)rsdt;
rsdp->xsdt_address = (unsigned long)xsdt;
set_checksum(rsdp,
offsetof(struct acpi_10_rsdp, checksum),
sizeof(struct acpi_10_rsdp));
set_checksum(rsdp,
offsetof(struct acpi_20_rsdp, extended_checksum),
sizeof(struct acpi_20_rsdp));
#undef inc_offset
return offset;
}
/*
+348 -219
View File
@@ -1,24 +1,21 @@
//**********************************************************************//
//*
//* Copyright (c) 2004, Intel Corporation.
//*
//* This program is free software; you can redistribute it and/or modify it
//* under the terms and conditions of the GNU General Public License,
//* version 2, as published by the Free Software Foundation.
//*
//* This program is distributed in the hope 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., 59 Temple
//* Place - Suite 330, Boston, MA 02111-1307 USA.
//**
//** DSDT for Xen with Qemu device model
//**
//**
/******************************************************************************
* DSDT for Xen with Qemu device model
*
* Copyright (c) 2004, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307 USA.
*/
DefinitionBlock ("DSDT.aml", "DSDT", 1, "INTEL","int-xen", 2006)
{
@@ -36,11 +33,9 @@ DefinitionBlock ("DSDT.aml", "DSDT", 1, "INTEL","int-xen", 2006)
Processor (CPU1, 0x01, 0x00000000, 0x00) {}
Processor (CPU2, 0x02, 0x00000000, 0x00) {}
Processor (CPU3, 0x03, 0x00000000, 0x00) {}
}
/* Poweroff support - ties in with qemu emulation */
/* Poweroff support - ties in with qemu emulation */
Name (\_S5, Package (0x04)
{
0x07,
@@ -49,318 +44,453 @@ DefinitionBlock ("DSDT.aml", "DSDT", 1, "INTEL","int-xen", 2006)
0x00
})
Name(PICD, 0)
Method(_PIC, 1) {
Store(Arg0, PICD)
Method(_PIC, 1)
{
Store(Arg0, PICD)
}
Scope (\_SB)
{
/* Fix HCT test for 0x400 pci memory - need to report low 640 MB mem as motherboard resource */
/* Fix HCT test for 0x400 pci memory:
* - need to report low 640 MB mem as motherboard resource
*/
Device(MEM0) {
Device(MEM0)
{
Name(_HID, EISAID("PNP0C02"))
Name(_CRS, ResourceTemplate() {
QWordMemory (ResourceConsumer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
QWordMemory(
ResourceConsumer, PosDecode, MinFixed,
MaxFixed, Cacheable, ReadWrite,
0x00000000,
0x00000000,
0x0009ffff,
0x00000000,
0x000a0000)
}
)
})
}
Device (PCI0)
{
{
Name (_HID, EisaId ("PNP0A03"))
Name (_UID, 0x00)
Name (_ADR, 0x00)
Name (_BBN, 0x00)
OperationRegion (PIRP, PCI_Config, 0x3c, 0x10)
Field(PIRP, ByteAcc, NoLock, Preserve){
IRQ3,3,
IRQ5,5,
IRQ7,7,
IRQ9,9,
IRQA,10,
IRQB,11
}
Method (_CRS, 0, NotSerialized)
{
Method (_CRS, 0, NotSerialized)
{
Name (PRT0, ResourceTemplate ()
{
/* bus number is from 0 - 255*/
WordBusNumber (ResourceConsumer, MinFixed, MaxFixed, SubDecode,
{
/* bus number is from 0 - 255*/
WordBusNumber(
ResourceConsumer, MinFixed, MaxFixed, SubDecode,
0x0000,
0x0000,
0x00FF,
0x0000,
0x0100)
IO (Decode16, 0x0CF8, 0x0CF8, 0x01, 0x08)
WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
WordIO(
ResourceProducer, MinFixed, MaxFixed, PosDecode,
EntireRange,
0x0000,
0x0000,
0x0CF7,
0x0000,
0x0CF8)
WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
WordIO(
ResourceProducer, MinFixed, MaxFixed, PosDecode,
EntireRange,
0x0000,
0x0D00,
0xFFFF,
0x0000,
0xF300)
/* reserve memory for pci devices */
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
/* reserve memory for pci devices */
DWordMemory(
ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000,
0x000A0000,
0x000BFFFF,
0x00000000,
0x00020000)
DWordMemory (ResourceConsumer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
DWordMemory(
ResourceConsumer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000,
0xF0000000,
0xF4FFFFFF,
0x00000000,
0x05000000)
})
Return (PRT0)
}
Name(BUFA, ResourceTemplate() {
IRQ(Level, ActiveLow, Shared) {
3,4,5,6,7,10,11,12,14,15}
})
Name(BUFB, Buffer(){
0x23, 0x00, 0x00, 0x18,
0x79, 0})
Name(BUFA, ResourceTemplate() {
IRQ(Level, ActiveLow, Shared) { 5, 6, 10, 11 }
})
CreateWordField(BUFB, 0x01, IRQV)
Name(BUFB, Buffer() {
0x23, 0x00, 0x00, 0x18, 0x79, 0
})
Name(BUFC, Buffer(){
5, 7, 10, 11
})
CreateByteField(BUFC, 0x01, PIQA)
CreateByteField(BUFC, 0x01, PIQB)
CreateByteField(BUFC, 0x01, PIQC)
CreateByteField(BUFC, 0x01, PIQD)
Device(LNKA) {
Name(_HID, EISAID("PNP0C0F")) // PCI interrupt link
CreateWordField(BUFB, 0x01, IRQV)
Device(LNKA) {
Name(_HID, EISAID("PNP0C0F")) /* PCI interrupt link */
Name(_UID, 1)
Method(_STA, 0) {
And(PIRA, 0x80, Local0)
If(LEqual(Local0, 0x80)) {
Return(0x09)
}
Else {
Return(0x0B)
}
}
And(PIRA, 0x80, Local0)
If(LEqual(Local0, 0x80)) {
Return(0x09)
} Else {
Return(0x0B)
}
}
Method(_PRS) {
Return(BUFA)
} // Method(_PRS)
Return(BUFA)
}
Method(_DIS) {
Or(PIRA, 0x80, PIRA)
Or(PIRA, 0x80, PIRA)
}
Method(_CRS) {
And(PIRB, 0x0f, Local0)
ShiftLeft(0x1, Local0, IRQV)
Return(BUFB)
}
And(PIRA, 0x0f, Local0)
ShiftLeft(0x1, Local0, IRQV)
Return(BUFB)
}
Method(_SRS, 1) {
CreateWordField(ARG0, 0x01, IRQ1)
FindSetRightBit(IRQ1, Local0)
Decrement(Local0)
Store(Local0, PIRA)
} // Method(_SRS)
}
CreateWordField(ARG0, 0x01, IRQ1)
FindSetRightBit(IRQ1, Local0)
Decrement(Local0)
Store(Local0, PIRA)
}
}
Device(LNKB){
Name(_HID, EISAID("PNP0C0F"))
Device(LNKB) {
Name(_HID, EISAID("PNP0C0F")) /* PCI interrupt link */
Name(_UID, 2)
Method(_STA, 0) {
And(PIRB, 0x80, Local0)
If(LEqual(Local0, 0x80)) {
Return(0x09)
}
Else {
Return(0x0B)
}
}
And(PIRB, 0x80, Local0)
If(LEqual(Local0, 0x80)) {
Return(0x09)
} Else {
Return(0x0B)
}
}
Method(_PRS) {
Return(BUFA)
} // Method(_PRS)
Return(BUFA)
}
Method(_DIS) {
Or(PIRB, 0x80, PIRB)
Or(PIRB, 0x80, PIRB)
}
Method(_CRS) {
And(PIRB, 0x0f, Local0)
ShiftLeft(0x1, Local0, IRQV)
Return(BUFB)
} // Method(_CRS)
And(PIRB, 0x0f, Local0)
ShiftLeft(0x1, Local0, IRQV)
Return(BUFB)
}
Method(_SRS, 1) {
CreateWordField(ARG0, 0x01, IRQ1)
FindSetRightBit(IRQ1, Local0)
Decrement(Local0)
Store(Local0, PIRB)
} // Method(_SRS)
}
CreateWordField(ARG0, 0x01, IRQ1)
FindSetRightBit(IRQ1, Local0)
Decrement(Local0)
Store(Local0, PIRB)
}
}
Device(LNKC){
Name(_HID, EISAID("PNP0C0F")) // PCI interrupt link
Device(LNKC) {
Name(_HID, EISAID("PNP0C0F")) /* PCI interrupt link */
Name(_UID, 3)
Method(_STA, 0) {
And(PIRC, 0x80, Local0)
If(LEqual(Local0, 0x80)) {
Return(0x09)
}
Else {
Return(0x0B)
}
And(PIRC, 0x80, Local0)
If(LEqual(Local0, 0x80)) {
Return(0x09)
} Else {
Return(0x0B)
}
}
Method(_PRS) {
Return(BUFA)
} // Method(_PRS)
Return(BUFA)
}
Method(_DIS) {
Or(PIRC, 0x80, PIRC)
Or(PIRC, 0x80, PIRC)
}
Method(_CRS) {
And(PIRC, 0x0f, Local0)
ShiftLeft(0x1, Local0, IRQV)
Return(BUFB)
} // Method(_CRS)
And(PIRC, 0x0f, Local0)
ShiftLeft(0x1, Local0, IRQV)
Return(BUFB)
}
Method(_SRS, 1) {
CreateWordField(ARG0, 0x01, IRQ1)
FindSetRightBit(IRQ1, Local0)
Decrement(Local0)
Store(Local0, PIRC)
} // Method(_SRS)
}
CreateWordField(ARG0, 0x01, IRQ1)
FindSetRightBit(IRQ1, Local0)
Decrement(Local0)
Store(Local0, PIRC)
}
}
Device(LNKD) {
Name(_HID, EISAID("PNP0C0F"))
Device(LNKD) {
Name(_HID, EISAID("PNP0C0F")) /* PCI interrupt link */
Name(_UID, 4)
Method(_STA, 0) {
And(PIRD, 0x80, Local0)
If(LEqual(Local0, 0x80)) {
Return(0x09)
}
Else {
Return(0x0B)
}
And(PIRD, 0x80, Local0)
If(LEqual(Local0, 0x80)) {
Return(0x09)
} Else {
Return(0x0B)
}
}
Method(_PRS) {
Return(BUFA)
} // Method(_PRS)
Return(BUFA)
}
Method(_DIS) {
Or(PIRD, 0x80, PIRD)
Or(PIRD, 0x80, PIRD)
}
Method(_CRS) {
And(PIRD, 0x0f, Local0)
ShiftLeft(0x1, Local0, IRQV)
Return(BUFB)
} // Method(_CRS)
And(PIRD, 0x0f, Local0)
ShiftLeft(0x1, Local0, IRQV)
Return(BUFB)
}
Method(_SRS, 1) {
CreateWordField(ARG0, 0x01, IRQ1)
FindSetRightBit(IRQ1, Local0)
Decrement(Local0)
Store(Local0, PIRD)
} // Method(_SRS)
}
Method(_PRT,0) {
If(PICD) {Return(PRTA)}
Return (PRTP)
} // end _PRT
CreateWordField(ARG0, 0x01, IRQ1)
FindSetRightBit(IRQ1, Local0)
Decrement(Local0)
Store(Local0, PIRD)
}
}
Name(PRTP, Package() {
// Slot 1, INTA - INTD
Package(){0x0000ffff, 0, \_SB.PCI0.LNKA, 0},
Package(){0x0000ffff, 1, \_SB.PCI0.LNKB, 0},
Package(){0x0000ffff, 2, \_SB.PCI0.LNKC, 0},
Package(){0x0000ffff, 3, \_SB.PCI0.LNKD, 0},
Method(_PRT,0) {
If(PICD) {
Return(PRTA)
}
Return (PRTP)
}
// Slot 2, INTA - INTD
Package(){0x0001ffff, 0, \_SB.PCI0.LNKB, 0},
Package(){0x0001ffff, 1, \_SB.PCI0.LNKC, 0},
Package(){0x0001ffff, 2, \_SB.PCI0.LNKD, 0},
Package(){0x0001ffff, 3, \_SB.PCI0.LNKA, 0},
Name(PRTP, Package() {
/* Device 1, INTA - INTD */
Package(){0x0001ffff, 0, \_SB.PCI0.LNKB, 0},
Package(){0x0001ffff, 1, \_SB.PCI0.LNKC, 0},
Package(){0x0001ffff, 2, \_SB.PCI0.LNKD, 0},
Package(){0x0001ffff, 3, \_SB.PCI0.LNKA, 0},
// Slot 3, INTA - INTD
Package(){0x0002ffff, 0, \_SB.PCI0.LNKC, 0},
Package(){0x0002ffff, 1, \_SB.PCI0.LNKD, 0},
Package(){0x0002ffff, 2, \_SB.PCI0.LNKA, 0},
Package(){0x0002ffff, 3, \_SB.PCI0.LNKB, 0},
/* Device 2, INTA - INTD */
Package(){0x0002ffff, 0, \_SB.PCI0.LNKC, 0},
Package(){0x0002ffff, 1, \_SB.PCI0.LNKD, 0},
Package(){0x0002ffff, 2, \_SB.PCI0.LNKA, 0},
Package(){0x0002ffff, 3, \_SB.PCI0.LNKB, 0},
// Slot 4, INTA - INTD
Package(){0x0003ffff, 0, \_SB.PCI0.LNKD, 0},
Package(){0x0003ffff, 1, \_SB.PCI0.LNKA, 0},
Package(){0x0003ffff, 2, \_SB.PCI0.LNKB, 0},
Package(){0x0003ffff, 3, \_SB.PCI0.LNKC, 0},
/* Device 3, INTA - INTD */
Package(){0x0003ffff, 0, \_SB.PCI0.LNKD, 0},
Package(){0x0003ffff, 1, \_SB.PCI0.LNKA, 0},
Package(){0x0003ffff, 2, \_SB.PCI0.LNKB, 0},
Package(){0x0003ffff, 3, \_SB.PCI0.LNKC, 0},
// Slot 5, INTA - INTD
Package(){0x0004ffff, 0, \_SB.PCI0.LNKA, 0},
Package(){0x0004ffff, 1, \_SB.PCI0.LNKB, 0},
Package(){0x0004ffff, 2, \_SB.PCI0.LNKC, 0},
Package(){0x0004ffff, 3, \_SB.PCI0.LNKD, 0},
}
)
Name(PRTA, Package(){
Package(){0x0001ffff, 0, 0, 5}, // Device 1, INTA
Package(){0x0002ffff, 0, 0, 7}, // Device 2, INTA
Package(){0x0003ffff, 0, 0, 10}, // Device 3, INTA
Package(){0x0004ffff, 0, 0, 11}, // Device 4, INTA
}
)
/* Device 4, INTA - INTD */
Package(){0x0004ffff, 0, \_SB.PCI0.LNKA, 0},
Package(){0x0004ffff, 1, \_SB.PCI0.LNKB, 0},
Package(){0x0004ffff, 2, \_SB.PCI0.LNKC, 0},
Package(){0x0004ffff, 3, \_SB.PCI0.LNKD, 0},
/* Device 5, INTA - INTD */
Package(){0x0005ffff, 0, \_SB.PCI0.LNKB, 0},
Package(){0x0005ffff, 1, \_SB.PCI0.LNKC, 0},
Package(){0x0005ffff, 2, \_SB.PCI0.LNKD, 0},
Package(){0x0005ffff, 3, \_SB.PCI0.LNKA, 0},
/* Device 6, INTA - INTD */
Package(){0x0006ffff, 0, \_SB.PCI0.LNKC, 0},
Package(){0x0006ffff, 1, \_SB.PCI0.LNKD, 0},
Package(){0x0006ffff, 2, \_SB.PCI0.LNKA, 0},
Package(){0x0006ffff, 3, \_SB.PCI0.LNKB, 0},
/* Device 7, INTA - INTD */
Package(){0x0007ffff, 0, \_SB.PCI0.LNKD, 0},
Package(){0x0007ffff, 1, \_SB.PCI0.LNKA, 0},
Package(){0x0007ffff, 2, \_SB.PCI0.LNKB, 0},
Package(){0x0007ffff, 3, \_SB.PCI0.LNKC, 0},
/* Device 8, INTA - INTD */
Package(){0x0008ffff, 0, \_SB.PCI0.LNKA, 0},
Package(){0x0008ffff, 1, \_SB.PCI0.LNKB, 0},
Package(){0x0008ffff, 2, \_SB.PCI0.LNKC, 0},
Package(){0x0008ffff, 3, \_SB.PCI0.LNKD, 0},
/* Device 9, INTA - INTD */
Package(){0x0009ffff, 0, \_SB.PCI0.LNKB, 0},
Package(){0x0009ffff, 1, \_SB.PCI0.LNKC, 0},
Package(){0x0009ffff, 2, \_SB.PCI0.LNKD, 0},
Package(){0x0009ffff, 3, \_SB.PCI0.LNKA, 0},
/* Device 10, INTA - INTD */
Package(){0x000affff, 0, \_SB.PCI0.LNKC, 0},
Package(){0x000affff, 1, \_SB.PCI0.LNKD, 0},
Package(){0x000affff, 2, \_SB.PCI0.LNKA, 0},
Package(){0x000affff, 3, \_SB.PCI0.LNKB, 0},
/* Device 11, INTA - INTD */
Package(){0x000bffff, 0, \_SB.PCI0.LNKD, 0},
Package(){0x000bffff, 1, \_SB.PCI0.LNKA, 0},
Package(){0x000bffff, 2, \_SB.PCI0.LNKB, 0},
Package(){0x000bffff, 3, \_SB.PCI0.LNKC, 0},
/* Device 12, INTA - INTD */
Package(){0x000cffff, 0, \_SB.PCI0.LNKA, 0},
Package(){0x000cffff, 1, \_SB.PCI0.LNKB, 0},
Package(){0x000cffff, 2, \_SB.PCI0.LNKC, 0},
Package(){0x000cffff, 3, \_SB.PCI0.LNKD, 0},
/* Device 13, INTA - INTD */
Package(){0x000dffff, 0, \_SB.PCI0.LNKB, 0},
Package(){0x000dffff, 1, \_SB.PCI0.LNKC, 0},
Package(){0x000dffff, 2, \_SB.PCI0.LNKD, 0},
Package(){0x000dffff, 3, \_SB.PCI0.LNKA, 0},
/* Device 14, INTA - INTD */
Package(){0x000effff, 0, \_SB.PCI0.LNKC, 0},
Package(){0x000effff, 1, \_SB.PCI0.LNKD, 0},
Package(){0x000effff, 2, \_SB.PCI0.LNKA, 0},
Package(){0x000effff, 3, \_SB.PCI0.LNKB, 0},
/* Device 15, INTA - INTD */
Package(){0x000fffff, 0, \_SB.PCI0.LNKD, 0},
Package(){0x000fffff, 1, \_SB.PCI0.LNKA, 0},
Package(){0x000fffff, 2, \_SB.PCI0.LNKB, 0},
Package(){0x000fffff, 3, \_SB.PCI0.LNKC, 0},
})
Name(PRTA, Package() {
/* Device 1, INTA - INTD */
Package(){0x0001ffff, 0, 0, 20},
Package(){0x0001ffff, 1, 0, 21},
Package(){0x0001ffff, 2, 0, 22},
Package(){0x0001ffff, 3, 0, 23},
/* Device 2, INTA - INTD */
Package(){0x0002ffff, 0, 0, 24},
Package(){0x0002ffff, 1, 0, 25},
Package(){0x0002ffff, 2, 0, 26},
Package(){0x0002ffff, 3, 0, 27},
/* Device 3, INTA - INTD */
Package(){0x0003ffff, 0, 0, 28},
Package(){0x0003ffff, 1, 0, 29},
Package(){0x0003ffff, 2, 0, 30},
Package(){0x0003ffff, 3, 0, 31},
/* Device 4, INTA - INTD */
Package(){0x0004ffff, 0, 0, 32},
Package(){0x0004ffff, 1, 0, 33},
Package(){0x0004ffff, 2, 0, 34},
Package(){0x0004ffff, 3, 0, 35},
/* Device 5, INTA - INTD */
Package(){0x0005ffff, 0, 0, 36},
Package(){0x0005ffff, 1, 0, 37},
Package(){0x0005ffff, 2, 0, 38},
Package(){0x0005ffff, 3, 0, 39},
/* Device 6, INTA - INTD */
Package(){0x0006ffff, 0, 0, 40},
Package(){0x0006ffff, 1, 0, 41},
Package(){0x0006ffff, 2, 0, 42},
Package(){0x0006ffff, 3, 0, 43},
/* Device 7, INTA - INTD */
Package(){0x0007ffff, 0, 0, 44},
Package(){0x0007ffff, 1, 0, 45},
Package(){0x0007ffff, 2, 0, 46},
Package(){0x0007ffff, 3, 0, 47},
/* Device 8, INTA - INTD */
Package(){0x0008ffff, 0, 0, 17},
Package(){0x0008ffff, 1, 0, 18},
Package(){0x0008ffff, 2, 0, 19},
Package(){0x0008ffff, 3, 0, 20},
/* Device 9, INTA - INTD */
Package(){0x0009ffff, 0, 0, 21},
Package(){0x0009ffff, 1, 0, 22},
Package(){0x0009ffff, 2, 0, 23},
Package(){0x0009ffff, 3, 0, 24},
/* Device 10, INTA - INTD */
Package(){0x000affff, 0, 0, 25},
Package(){0x000affff, 1, 0, 26},
Package(){0x000affff, 2, 0, 27},
Package(){0x000affff, 3, 0, 28},
/* Device 11, INTA - INTD */
Package(){0x000bffff, 0, 0, 29},
Package(){0x000bffff, 1, 0, 30},
Package(){0x000bffff, 2, 0, 31},
Package(){0x000bffff, 3, 0, 32},
/* Device 12, INTA - INTD */
Package(){0x000cffff, 0, 0, 33},
Package(){0x000cffff, 1, 0, 34},
Package(){0x000cffff, 2, 0, 35},
Package(){0x000cffff, 3, 0, 36},
/* Device 13, INTA - INTD */
Package(){0x000dffff, 0, 0, 37},
Package(){0x000dffff, 1, 0, 38},
Package(){0x000dffff, 2, 0, 39},
Package(){0x000dffff, 3, 0, 40},
/* Device 14, INTA - INTD */
Package(){0x000effff, 0, 0, 41},
Package(){0x000effff, 1, 0, 42},
Package(){0x000effff, 2, 0, 43},
Package(){0x000effff, 3, 0, 44},
/* Device 15, INTA - INTD */
Package(){0x000fffff, 0, 0, 45},
Package(){0x000fffff, 1, 0, 46},
Package(){0x000fffff, 2, 0, 47},
Package(){0x000fffff, 3, 0, 16},
})
Device (ISA)
{
Name (_ADR, 0x00000000) /* device id, PCI bus num, ... */
OperationRegion(PIRQ, PCI_Config, 0x60, 0x4)
Scope(\) {
Field (\_SB.PCI0.ISA.PIRQ, ByteAcc, NoLock, Preserve) {
PIRA, 8,
PIRB, 8,
PIRC, 8,
PIRD, 8
}
}
Name (_ADR, 0x00010000) /* device 1, fn 0 */
OperationRegion(PIRQ, PCI_Config, 0x60, 0x4)
Scope(\) {
Field (\_SB.PCI0.ISA.PIRQ, ByteAcc, NoLock, Preserve) {
PIRA, 8,
PIRB, 8,
PIRC, 8,
PIRD, 8
}
}
Device (SYSR)
{
Name (_HID, EisaId ("PNP0C02"))
Name (_UID, 0x01)
Name (CRS, ResourceTemplate ()
{
/* TODO: list hidden resources */
/* TODO: list hidden resources */
IO (Decode16, 0x0010, 0x0010, 0x00, 0x10)
IO (Decode16, 0x0022, 0x0022, 0x00, 0x0C)
IO (Decode16, 0x0030, 0x0030, 0x00, 0x10)
@@ -525,4 +655,3 @@ DefinitionBlock ("DSDT.aml", "DSDT", 1, "INTEL","int-xen", 2006)
}
}
}
+404 -255
View File
@@ -5,15 +5,15 @@
* Copyright (C) 2000 - 2005 Intel Corporation
* Supports ACPI Specification Revision 3.0
*
* Compilation of "dsdt.asl" - Fri Nov 17 10:00:20 2006
* Compilation of "dsdt.asl" - Wed Nov 22 18:26:19 2006
*
* C source code output
*
*/
unsigned char AmlCode[] =
{
0x44,0x53,0x44,0x54,0xF4,0x08,0x00,0x00, /* 00000000 "DSDT...." */
0x01,0x22,0x49,0x4E,0x54,0x45,0x4C,0x00, /* 00000008 "."INTEL." */
0x44,0x53,0x44,0x54,0x9D,0x0D,0x00,0x00, /* 00000000 "DSDT...." */
0x01,0x83,0x49,0x4E,0x54,0x45,0x4C,0x00, /* 00000008 "..INTEL." */
0x69,0x6E,0x74,0x2D,0x78,0x65,0x6E,0x00, /* 00000010 "int-xen." */
0xD6,0x07,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
0x13,0x05,0x05,0x20,0x08,0x50,0x4D,0x42, /* 00000020 "... .PMB" */
@@ -34,7 +34,7 @@ unsigned char AmlCode[] =
0x12,0x08,0x04,0x0A,0x07,0x0A,0x07,0x00, /* 00000098 "........" */
0x00,0x08,0x50,0x49,0x43,0x44,0x00,0x14, /* 000000A0 "..PICD.." */
0x0C,0x5F,0x50,0x49,0x43,0x01,0x70,0x68, /* 000000A8 "._PIC.ph" */
0x50,0x49,0x43,0x44,0x10,0x4F,0x83,0x5F, /* 000000B0 "PICD.O._" */
0x50,0x49,0x43,0x44,0x10,0x48,0xCE,0x5F, /* 000000B0 "PICD.H._" */
0x53,0x42,0x5F,0x5B,0x82,0x49,0x04,0x4D, /* 000000B8 "SB_[.I.M" */
0x45,0x4D,0x30,0x08,0x5F,0x48,0x49,0x44, /* 000000C0 "EM0._HID" */
0x0C,0x41,0xD0,0x0C,0x02,0x08,0x5F,0x43, /* 000000C8 ".A...._C" */
@@ -45,259 +45,408 @@ unsigned char AmlCode[] =
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000F0 "........" */
0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x00, /* 000000F8 "........" */
0x00,0x00,0x00,0x00,0x79,0x00,0x5B,0x82, /* 00000100 "....y.[." */
0x4C,0x7E,0x50,0x43,0x49,0x30,0x08,0x5F, /* 00000108 "L~PCI0._" */
0x45,0xC9,0x50,0x43,0x49,0x30,0x08,0x5F, /* 00000108 "E.PCI0._" */
0x48,0x49,0x44,0x0C,0x41,0xD0,0x0A,0x03, /* 00000110 "HID.A..." */
0x08,0x5F,0x55,0x49,0x44,0x00,0x08,0x5F, /* 00000118 "._UID.._" */
0x41,0x44,0x52,0x00,0x08,0x5F,0x42,0x42, /* 00000120 "ADR.._BB" */
0x4E,0x00,0x5B,0x80,0x50,0x49,0x52,0x50, /* 00000128 "N.[.PIRP" */
0x02,0x0A,0x3C,0x0A,0x10,0x5B,0x81,0x24, /* 00000130 "..<..[.$" */
0x50,0x49,0x52,0x50,0x01,0x49,0x52,0x51, /* 00000138 "PIRP.IRQ" */
0x33,0x03,0x49,0x52,0x51,0x35,0x05,0x49, /* 00000140 "3.IRQ5.I" */
0x52,0x51,0x37,0x07,0x49,0x52,0x51,0x39, /* 00000148 "RQ7.IRQ9" */
0x09,0x49,0x52,0x51,0x41,0x0A,0x49,0x52, /* 00000150 ".IRQA.IR" */
0x51,0x42,0x0B,0x14,0x44,0x08,0x5F,0x43, /* 00000158 "QB..D._C" */
0x52,0x53,0x00,0x08,0x50,0x52,0x54,0x30, /* 00000160 "RS..PRT0" */
0x11,0x42,0x07,0x0A,0x6E,0x88,0x0D,0x00, /* 00000168 ".B..n..." */
0x02,0x0F,0x00,0x00,0x00,0x00,0x00,0xFF, /* 00000170 "........" */
0x00,0x00,0x00,0x00,0x01,0x47,0x01,0xF8, /* 00000178 ".....G.." */
0x0C,0xF8,0x0C,0x01,0x08,0x88,0x0D,0x00, /* 00000180 "........" */
0x01,0x0C,0x03,0x00,0x00,0x00,0x00,0xF7, /* 00000188 "........" */
0x0C,0x00,0x00,0xF8,0x0C,0x88,0x0D,0x00, /* 00000190 "........" */
0x01,0x0C,0x03,0x00,0x00,0x00,0x0D,0xFF, /* 00000198 "........" */
0xFF,0x00,0x00,0x00,0xF3,0x87,0x17,0x00, /* 000001A0 "........" */
0x00,0x0C,0x03,0x00,0x00,0x00,0x00,0x00, /* 000001A8 "........" */
0x00,0x0A,0x00,0xFF,0xFF,0x0B,0x00,0x00, /* 000001B0 "........" */
0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x87, /* 000001B8 "........" */
0x17,0x00,0x00,0x0D,0x03,0x00,0x00,0x00, /* 000001C0 "........" */
0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF, /* 000001C8 "........" */
0xF4,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000001D0 "........" */
0x05,0x79,0x00,0xA4,0x50,0x52,0x54,0x30, /* 000001D8 ".y..PRT0" */
0x08,0x42,0x55,0x46,0x41,0x11,0x09,0x0A, /* 000001E0 ".BUFA..." */
0x06,0x23,0xF8,0xDC,0x18,0x79,0x00,0x08, /* 000001E8 ".#...y.." */
0x42,0x55,0x46,0x42,0x11,0x09,0x0A,0x06, /* 000001F0 "BUFB...." */
0x23,0x00,0x00,0x18,0x79,0x00,0x8B,0x42, /* 000001F8 "#...y..B" */
0x55,0x46,0x42,0x01,0x49,0x52,0x51,0x56, /* 00000200 "UFB.IRQV" */
0x08,0x42,0x55,0x46,0x43,0x11,0x07,0x0A, /* 00000208 ".BUFC..." */
0x04,0x05,0x07,0x0A,0x0B,0x8C,0x42,0x55, /* 00000210 "......BU" */
0x46,0x43,0x01,0x50,0x49,0x51,0x41,0x8C, /* 00000218 "FC.PIQA." */
0x42,0x55,0x46,0x43,0x01,0x50,0x49,0x51, /* 00000220 "BUFC.PIQ" */
0x42,0x8C,0x42,0x55,0x46,0x43,0x01,0x50, /* 00000228 "B.BUFC.P" */
0x49,0x51,0x43,0x8C,0x42,0x55,0x46,0x43, /* 00000230 "IQC.BUFC" */
0x01,0x50,0x49,0x51,0x44,0x5B,0x82,0x48, /* 00000238 ".PIQD[.H" */
0x08,0x4C,0x4E,0x4B,0x41,0x08,0x5F,0x48, /* 00000240 ".LNKA._H" */
0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08, /* 00000248 "ID.A...." */
0x5F,0x55,0x49,0x44,0x01,0x14,0x1C,0x5F, /* 00000250 "_UID..._" */
0x53,0x54,0x41,0x00,0x7B,0x50,0x49,0x52, /* 00000258 "STA.{PIR" */
0x41,0x0A,0x80,0x60,0xA0,0x08,0x93,0x60, /* 00000260 "A..`...`" */
0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04,0xA4, /* 00000268 "........" */
0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52,0x53, /* 00000270 "...._PRS" */
0x00,0xA4,0x42,0x55,0x46,0x41,0x14,0x11, /* 00000278 "..BUFA.." */
0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,0x49, /* 00000280 "_DIS.}PI" */
0x52,0x41,0x0A,0x80,0x50,0x49,0x52,0x41, /* 00000288 "RA..PIRA" */
0x14,0x1A,0x5F,0x43,0x52,0x53,0x00,0x7B, /* 00000290 ".._CRS.{" */
0x50,0x49,0x52,0x42,0x0A,0x0F,0x60,0x79, /* 00000298 "PIRB..`y" */
0x01,0x60,0x49,0x52,0x51,0x56,0xA4,0x42, /* 000002A0 ".`IRQV.B" */
0x55,0x46,0x42,0x14,0x1B,0x5F,0x53,0x52, /* 000002A8 "UFB.._SR" */
0x53,0x01,0x8B,0x68,0x01,0x49,0x52,0x51, /* 000002B0 "S..h.IRQ" */
0x31,0x82,0x49,0x52,0x51,0x31,0x60,0x76, /* 000002B8 "1.IRQ1`v" */
0x60,0x70,0x60,0x50,0x49,0x52,0x41,0x5B, /* 000002C0 "`p`PIRA[" */
0x82,0x49,0x08,0x4C,0x4E,0x4B,0x42,0x08, /* 000002C8 ".I.LNKB." */
0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C, /* 000002D0 "_HID.A.." */
0x0F,0x08,0x5F,0x55,0x49,0x44,0x0A,0x02, /* 000002D8 ".._UID.." */
0x14,0x1C,0x5F,0x53,0x54,0x41,0x00,0x7B, /* 000002E0 ".._STA.{" */
0x50,0x49,0x52,0x42,0x0A,0x80,0x60,0xA0, /* 000002E8 "PIRB..`." */
0x08,0x93,0x60,0x0A,0x80,0xA4,0x0A,0x09, /* 000002F0 "..`....." */
0xA1,0x04,0xA4,0x0A,0x0B,0x14,0x0B,0x5F, /* 000002F8 "......._" */
0x50,0x52,0x53,0x00,0xA4,0x42,0x55,0x46, /* 00000300 "PRS..BUF" */
0x41,0x14,0x11,0x5F,0x44,0x49,0x53,0x00, /* 00000308 "A.._DIS." */
0x7D,0x50,0x49,0x52,0x42,0x0A,0x80,0x50, /* 00000310 "}PIRB..P" */
0x49,0x52,0x42,0x14,0x1A,0x5F,0x43,0x52, /* 00000318 "IRB.._CR" */
0x53,0x00,0x7B,0x50,0x49,0x52,0x42,0x0A, /* 00000320 "S.{PIRB." */
0x0F,0x60,0x79,0x01,0x60,0x49,0x52,0x51, /* 00000328 ".`y.`IRQ" */
0x56,0xA4,0x42,0x55,0x46,0x42,0x14,0x1B, /* 00000330 "V.BUFB.." */
0x5F,0x53,0x52,0x53,0x01,0x8B,0x68,0x01, /* 00000338 "_SRS..h." */
0x49,0x52,0x51,0x31,0x82,0x49,0x52,0x51, /* 00000340 "IRQ1.IRQ" */
0x31,0x60,0x76,0x60,0x70,0x60,0x50,0x49, /* 00000348 "1`v`p`PI" */
0x52,0x42,0x5B,0x82,0x49,0x08,0x4C,0x4E, /* 00000350 "RB[.I.LN" */
0x4B,0x43,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 00000358 "KC._HID." */
0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55,0x49, /* 00000360 "A...._UI" */
0x44,0x0A,0x03,0x14,0x1C,0x5F,0x53,0x54, /* 00000368 "D...._ST" */
0x41,0x00,0x7B,0x50,0x49,0x52,0x43,0x0A, /* 00000370 "A.{PIRC." */
0x80,0x60,0xA0,0x08,0x93,0x60,0x0A,0x80, /* 00000378 ".`...`.." */
0xA4,0x0A,0x09,0xA1,0x04,0xA4,0x0A,0x0B, /* 00000380 "........" */
0x14,0x0B,0x5F,0x50,0x52,0x53,0x00,0xA4, /* 00000388 ".._PRS.." */
0x42,0x55,0x46,0x41,0x14,0x11,0x5F,0x44, /* 00000390 "BUFA.._D" */
0x49,0x53,0x00,0x7D,0x50,0x49,0x52,0x43, /* 00000398 "IS.}PIRC" */
0x0A,0x80,0x50,0x49,0x52,0x43,0x14,0x1A, /* 000003A0 "..PIRC.." */
0x5F,0x43,0x52,0x53,0x00,0x7B,0x50,0x49, /* 000003A8 "_CRS.{PI" */
0x52,0x43,0x0A,0x0F,0x60,0x79,0x01,0x60, /* 000003B0 "RC..`y.`" */
0x49,0x52,0x51,0x56,0xA4,0x42,0x55,0x46, /* 000003B8 "IRQV.BUF" */
0x42,0x14,0x1B,0x5F,0x53,0x52,0x53,0x01, /* 000003C0 "B.._SRS." */
0x8B,0x68,0x01,0x49,0x52,0x51,0x31,0x82, /* 000003C8 ".h.IRQ1." */
0x49,0x52,0x51,0x31,0x60,0x76,0x60,0x70, /* 000003D0 "IRQ1`v`p" */
0x60,0x50,0x49,0x52,0x43,0x5B,0x82,0x49, /* 000003D8 "`PIRC[.I" */
0x08,0x4C,0x4E,0x4B,0x44,0x08,0x5F,0x48, /* 000003E0 ".LNKD._H" */
0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08, /* 000003E8 "ID.A...." */
0x5F,0x55,0x49,0x44,0x0A,0x04,0x14,0x1C, /* 000003F0 "_UID...." */
0x5F,0x53,0x54,0x41,0x00,0x7B,0x50,0x49, /* 000003F8 "_STA.{PI" */
0x52,0x44,0x0A,0x80,0x60,0xA0,0x08,0x93, /* 00000400 "RD..`..." */
0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04, /* 00000408 "`......." */
0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52, /* 00000410 "....._PR" */
0x53,0x00,0xA4,0x42,0x55,0x46,0x41,0x14, /* 00000418 "S..BUFA." */
0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,0x50, /* 00000420 "._DIS.}P" */
0x49,0x52,0x44,0x0A,0x80,0x50,0x49,0x52, /* 00000428 "IRD..PIR" */
0x44,0x14,0x1A,0x5F,0x43,0x52,0x53,0x00, /* 00000430 "D.._CRS." */
0x7B,0x50,0x49,0x52,0x44,0x0A,0x0F,0x60, /* 00000438 "{PIRD..`" */
0x79,0x01,0x60,0x49,0x52,0x51,0x56,0xA4, /* 00000440 "y.`IRQV." */
0x42,0x55,0x46,0x42,0x14,0x1B,0x5F,0x53, /* 00000448 "BUFB.._S" */
0x52,0x53,0x01,0x8B,0x68,0x01,0x49,0x52, /* 00000450 "RS..h.IR" */
0x51,0x31,0x82,0x49,0x52,0x51,0x31,0x60, /* 00000458 "Q1.IRQ1`" */
0x76,0x60,0x70,0x60,0x50,0x49,0x52,0x44, /* 00000460 "v`p`PIRD" */
0x14,0x16,0x5F,0x50,0x52,0x54,0x00,0xA0, /* 00000468 ".._PRT.." */
0x0A,0x50,0x49,0x43,0x44,0xA4,0x50,0x52, /* 00000470 ".PICD.PR" */
0x54,0x41,0xA4,0x50,0x52,0x54,0x50,0x08, /* 00000478 "TA.PRTP." */
0x50,0x52,0x54,0x50,0x12,0x4D,0x11,0x14, /* 00000480 "PRTP.M.." */
0x12,0x0B,0x04,0x0B,0xFF,0xFF,0x00,0x4C, /* 00000488 ".......L" */
0x4E,0x4B,0x41,0x00,0x12,0x0B,0x04,0x0B, /* 00000490 "NKA....." */
0xFF,0xFF,0x01,0x4C,0x4E,0x4B,0x42,0x00, /* 00000498 "...LNKB." */
0x12,0x0C,0x04,0x0B,0xFF,0xFF,0x0A,0x02, /* 000004A0 "........" */
0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0C,0x04, /* 000004A8 "LNKC...." */
0x0B,0xFF,0xFF,0x0A,0x03,0x4C,0x4E,0x4B, /* 000004B0 ".....LNK" */
0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 000004B8 "D......." */
0x01,0x00,0x00,0x4C,0x4E,0x4B,0x42,0x00, /* 000004C0 "...LNKB." */
0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x01,0x00, /* 000004C8 "........" */
0x01,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E, /* 000004D0 ".LNKC..." */
0x04,0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x02, /* 000004D8 "........" */
0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04, /* 000004E0 "LNKD...." */
0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x03,0x4C, /* 000004E8 ".......L" */
0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C, /* 000004F0 "NKA....." */
0xFF,0xFF,0x02,0x00,0x00,0x4C,0x4E,0x4B, /* 000004F8 ".....LNK" */
0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000500 "C......." */
0x02,0x00,0x01,0x4C,0x4E,0x4B,0x44,0x00, /* 00000508 "...LNKD." */
0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x02,0x00, /* 00000510 "........" */
0x0A,0x02,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 00000518 "..LNKA.." */
0x0E,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x0A, /* 00000520 "........" */
0x03,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D, /* 00000528 ".LNKB..." */
0x04,0x0C,0xFF,0xFF,0x03,0x00,0x00,0x4C, /* 00000530 ".......L" */
0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C, /* 00000538 "NKD....." */
0xFF,0xFF,0x03,0x00,0x01,0x4C,0x4E,0x4B, /* 00000540 ".....LNK" */
0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000548 "A......." */
0x03,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x42, /* 00000550 "....LNKB" */
0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x03, /* 00000558 "........" */
0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x43,0x00, /* 00000560 "...LNKC." */
0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x04,0x00, /* 00000568 "........" */
0x00,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D, /* 00000570 ".LNKA..." */
0x04,0x0C,0xFF,0xFF,0x04,0x00,0x01,0x4C, /* 00000578 ".......L" */
0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C, /* 00000580 "NKB....." */
0xFF,0xFF,0x04,0x00,0x0A,0x02,0x4C,0x4E, /* 00000588 "......LN" */
0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 00000590 "KC......" */
0xFF,0x04,0x00,0x0A,0x03,0x4C,0x4E,0x4B, /* 00000598 ".....LNK" */
0x44,0x00,0x08,0x50,0x52,0x54,0x41,0x12, /* 000005A0 "D..PRTA." */
0x32,0x04,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 000005A8 "2......." */
0x01,0x00,0x00,0x00,0x0A,0x05,0x12,0x0B, /* 000005B0 "........" */
0x04,0x0C,0xFF,0xFF,0x02,0x00,0x00,0x00, /* 000005B8 "........" */
0x0A,0x07,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 000005C0 "........" */
0x03,0x00,0x00,0x00,0x0A,0x0A,0x12,0x0B, /* 000005C8 "........" */
0x04,0x0C,0xFF,0xFF,0x04,0x00,0x00,0x00, /* 000005D0 "........" */
0x0A,0x0B,0x5B,0x82,0x48,0x31,0x49,0x53, /* 000005D8 "..[.H1IS" */
0x41,0x5F,0x08,0x5F,0x41,0x44,0x52,0x00, /* 000005E0 "A_._ADR." */
0x5B,0x80,0x50,0x49,0x52,0x51,0x02,0x0A, /* 000005E8 "[.PIRQ.." */
0x60,0x0A,0x04,0x10,0x2E,0x5C,0x00,0x5B, /* 000005F0 "`....\.[" */
0x81,0x29,0x5C,0x2F,0x04,0x5F,0x53,0x42, /* 000005F8 ".)\/._SB" */
0x5F,0x50,0x43,0x49,0x30,0x49,0x53,0x41, /* 00000600 "_PCI0ISA" */
0x5F,0x50,0x49,0x52,0x51,0x01,0x50,0x49, /* 00000608 "_PIRQ.PI" */
0x52,0x41,0x08,0x50,0x49,0x52,0x42,0x08, /* 00000610 "RA.PIRB." */
0x50,0x49,0x52,0x43,0x08,0x50,0x49,0x52, /* 00000618 "PIRC.PIR" */
0x44,0x08,0x5B,0x82,0x46,0x0B,0x53,0x59, /* 00000620 "D.[.F.SY" */
0x53,0x52,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 00000628 "SR._HID." */
0x41,0xD0,0x0C,0x02,0x08,0x5F,0x55,0x49, /* 00000630 "A...._UI" */
0x44,0x01,0x08,0x43,0x52,0x53,0x5F,0x11, /* 00000638 "D..CRS_." */
0x4E,0x08,0x0A,0x8A,0x47,0x01,0x10,0x00, /* 00000640 "N...G..." */
0x10,0x00,0x00,0x10,0x47,0x01,0x22,0x00, /* 00000648 "....G."." */
0x22,0x00,0x00,0x0C,0x47,0x01,0x30,0x00, /* 00000650 ""...G.0." */
0x30,0x00,0x00,0x10,0x47,0x01,0x44,0x00, /* 00000658 "0...G.D." */
0x44,0x00,0x00,0x1C,0x47,0x01,0x62,0x00, /* 00000660 "D...G.b." */
0x62,0x00,0x00,0x02,0x47,0x01,0x65,0x00, /* 00000668 "b...G.e." */
0x65,0x00,0x00,0x0B,0x47,0x01,0x72,0x00, /* 00000670 "e...G.r." */
0x72,0x00,0x00,0x0E,0x47,0x01,0x80,0x00, /* 00000678 "r...G..." */
0x80,0x00,0x00,0x01,0x47,0x01,0x84,0x00, /* 00000680 "....G..." */
0x84,0x00,0x00,0x03,0x47,0x01,0x88,0x00, /* 00000688 "....G..." */
0x88,0x00,0x00,0x01,0x47,0x01,0x8C,0x00, /* 00000690 "....G..." */
0x8C,0x00,0x00,0x03,0x47,0x01,0x90,0x00, /* 00000698 "....G..." */
0x90,0x00,0x00,0x10,0x47,0x01,0xA2,0x00, /* 000006A0 "....G..." */
0xA2,0x00,0x00,0x1C,0x47,0x01,0xE0,0x00, /* 000006A8 "....G..." */
0xE0,0x00,0x00,0x10,0x47,0x01,0xA0,0x08, /* 000006B0 "....G..." */
0xA0,0x08,0x00,0x04,0x47,0x01,0xC0,0x0C, /* 000006B8 "....G..." */
0xC0,0x0C,0x00,0x10,0x47,0x01,0xD0,0x04, /* 000006C0 "....G..." */
0xD0,0x04,0x00,0x02,0x79,0x00,0x14,0x0B, /* 000006C8 "....y..." */
0x5F,0x43,0x52,0x53,0x00,0xA4,0x43,0x52, /* 000006D0 "_CRS..CR" */
0x53,0x5F,0x5B,0x82,0x2B,0x50,0x49,0x43, /* 000006D8 "S_[.+PIC" */
0x5F,0x08,0x5F,0x48,0x49,0x44,0x0B,0x41, /* 000006E0 "_._HID.A" */
0xD0,0x08,0x5F,0x43,0x52,0x53,0x11,0x18, /* 000006E8 ".._CRS.." */
0x0A,0x15,0x47,0x01,0x20,0x00,0x20,0x00, /* 000006F0 "..G. . ." */
0x01,0x02,0x47,0x01,0xA0,0x00,0xA0,0x00, /* 000006F8 "..G....." */
0x01,0x02,0x22,0x04,0x00,0x79,0x00,0x5B, /* 00000700 ".."..y.[" */
0x82,0x47,0x05,0x44,0x4D,0x41,0x30,0x08, /* 00000708 ".G.DMA0." */
0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x02, /* 00000710 "_HID.A.." */
0x00,0x08,0x5F,0x43,0x52,0x53,0x11,0x41, /* 00000718 ".._CRS.A" */
0x04,0x0A,0x3D,0x2A,0x10,0x04,0x47,0x01, /* 00000720 "..=*..G." */
0x00,0x00,0x00,0x00,0x00,0x10,0x47,0x01, /* 00000728 "......G." */
0x81,0x00,0x81,0x00,0x00,0x03,0x47,0x01, /* 00000730 "......G." */
0x87,0x00,0x87,0x00,0x00,0x01,0x47,0x01, /* 00000738 "......G." */
0x89,0x00,0x89,0x00,0x00,0x03,0x47,0x01, /* 00000740 "......G." */
0x8F,0x00,0x8F,0x00,0x00,0x01,0x47,0x01, /* 00000748 "......G." */
0xC0,0x00,0xC0,0x00,0x00,0x20,0x47,0x01, /* 00000750 "..... G." */
0x80,0x04,0x80,0x04,0x00,0x10,0x79,0x00, /* 00000758 "......y." */
0x5B,0x82,0x25,0x54,0x4D,0x52,0x5F,0x08, /* 00000760 "[.%TMR_." */
0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x01, /* 00000768 "_HID.A.." */
0x00,0x08,0x5F,0x43,0x52,0x53,0x11,0x10, /* 00000770 ".._CRS.." */
0x0A,0x0D,0x47,0x01,0x40,0x00,0x40,0x00, /* 00000778 "..G.@.@." */
0x00,0x04,0x22,0x01,0x00,0x79,0x00,0x5B, /* 00000780 ".."..y.[" */
0x82,0x25,0x52,0x54,0x43,0x5F,0x08,0x5F, /* 00000788 ".%RTC_._" */
0x48,0x49,0x44,0x0C,0x41,0xD0,0x0B,0x00, /* 00000790 "HID.A..." */
0x08,0x5F,0x43,0x52,0x53,0x11,0x10,0x0A, /* 00000798 "._CRS..." */
0x0D,0x47,0x01,0x70,0x00,0x70,0x00,0x00, /* 000007A0 ".G.p.p.." */
0x02,0x22,0x00,0x01,0x79,0x00,0x5B,0x82, /* 000007A8 "."..y.[." */
0x22,0x53,0x50,0x4B,0x52,0x08,0x5F,0x48, /* 000007B0 ""SPKR._H" */
0x49,0x44,0x0C,0x41,0xD0,0x08,0x00,0x08, /* 000007B8 "ID.A...." */
0x5F,0x43,0x52,0x53,0x11,0x0D,0x0A,0x0A, /* 000007C0 "_CRS...." */
0x47,0x01,0x61,0x00,0x61,0x00,0x00,0x01, /* 000007C8 "G.a.a..." */
0x79,0x00,0x5B,0x82,0x31,0x50,0x53,0x32, /* 000007D0 "y.[.1PS2" */
0x4D,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41, /* 000007D8 "M._HID.A" */
0xD0,0x0F,0x13,0x08,0x5F,0x43,0x49,0x44, /* 000007E0 "...._CID" */
0x0C,0x41,0xD0,0x0F,0x13,0x14,0x09,0x5F, /* 000007E8 ".A....._" */
0x53,0x54,0x41,0x00,0xA4,0x0A,0x0F,0x08, /* 000007F0 "STA....." */
0x5F,0x43,0x52,0x53,0x11,0x08,0x0A,0x05, /* 000007F8 "_CRS...." */
0x22,0x00,0x10,0x79,0x00,0x5B,0x82,0x42, /* 00000800 ""..y.[.B" */
0x04,0x50,0x53,0x32,0x4B,0x08,0x5F,0x48, /* 00000808 ".PS2K._H" */
0x49,0x44,0x0C,0x41,0xD0,0x03,0x03,0x08, /* 00000810 "ID.A...." */
0x5F,0x43,0x49,0x44,0x0C,0x41,0xD0,0x03, /* 00000818 "_CID.A.." */
0x0B,0x14,0x09,0x5F,0x53,0x54,0x41,0x00, /* 00000820 "..._STA." */
0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53, /* 00000828 "...._CRS" */
0x11,0x18,0x0A,0x15,0x47,0x01,0x60,0x00, /* 00000830 "....G.`." */
0x60,0x00,0x00,0x01,0x47,0x01,0x64,0x00, /* 00000838 "`...G.d." */
0x64,0x00,0x00,0x01,0x22,0x02,0x00,0x79, /* 00000840 "d..."..y" */
0x00,0x5B,0x82,0x3A,0x46,0x44,0x43,0x30, /* 00000848 ".[.:FDC0" */
0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000850 "._HID.A." */
0x07,0x00,0x14,0x09,0x5F,0x53,0x54,0x41, /* 00000858 "...._STA" */
0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52, /* 00000860 "....._CR" */
0x53,0x11,0x1B,0x0A,0x18,0x47,0x01,0xF0, /* 00000868 "S....G.." */
0x03,0xF0,0x03,0x01,0x06,0x47,0x01,0xF7, /* 00000870 ".....G.." */
0x03,0xF7,0x03,0x01,0x01,0x22,0x40,0x00, /* 00000878 "....."@." */
0x2A,0x04,0x00,0x79,0x00,0x5B,0x82,0x35, /* 00000880 "*..y.[.5" */
0x55,0x41,0x52,0x31,0x08,0x5F,0x48,0x49, /* 00000888 "UAR1._HI" */
0x44,0x0C,0x41,0xD0,0x05,0x01,0x08,0x5F, /* 00000890 "D.A...._" */
0x55,0x49,0x44,0x01,0x14,0x09,0x5F,0x53, /* 00000898 "UID..._S" */
0x54,0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F, /* 000008A0 "TA....._" */
0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,0x47, /* 000008A8 "CRS....G" */
0x01,0xF8,0x03,0xF8,0x03,0x01,0x08,0x22, /* 000008B0 "......."" */
0x10,0x00,0x79,0x00,0x5B,0x82,0x36,0x4C, /* 000008B8 "..y.[.6L" */
0x54,0x50,0x31,0x08,0x5F,0x48,0x49,0x44, /* 000008C0 "TP1._HID" */
0x0C,0x41,0xD0,0x04,0x00,0x08,0x5F,0x55, /* 000008C8 ".A...._U" */
0x49,0x44,0x0A,0x02,0x14,0x09,0x5F,0x53, /* 000008D0 "ID...._S" */
0x54,0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F, /* 000008D8 "TA....._" */
0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,0x47, /* 000008E0 "CRS....G" */
0x01,0x78,0x03,0x78,0x03,0x08,0x08,0x22, /* 000008E8 ".x.x..."" */
0x80,0x00,0x79,0x00,
0x4E,0x00,0x14,0x44,0x08,0x5F,0x43,0x52, /* 00000128 "N..D._CR" */
0x53,0x00,0x08,0x50,0x52,0x54,0x30,0x11, /* 00000130 "S..PRT0." */
0x42,0x07,0x0A,0x6E,0x88,0x0D,0x00,0x02, /* 00000138 "B..n...." */
0x0F,0x00,0x00,0x00,0x00,0x00,0xFF,0x00, /* 00000140 "........" */
0x00,0x00,0x00,0x01,0x47,0x01,0xF8,0x0C, /* 00000148 "....G..." */
0xF8,0x0C,0x01,0x08,0x88,0x0D,0x00,0x01, /* 00000150 "........" */
0x0C,0x03,0x00,0x00,0x00,0x00,0xF7,0x0C, /* 00000158 "........" */
0x00,0x00,0xF8,0x0C,0x88,0x0D,0x00,0x01, /* 00000160 "........" */
0x0C,0x03,0x00,0x00,0x00,0x0D,0xFF,0xFF, /* 00000168 "........" */
0x00,0x00,0x00,0xF3,0x87,0x17,0x00,0x00, /* 00000170 "........" */
0x0C,0x03,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000178 "........" */
0x0A,0x00,0xFF,0xFF,0x0B,0x00,0x00,0x00, /* 00000180 "........" */
0x00,0x00,0x00,0x00,0x02,0x00,0x87,0x17, /* 00000188 "........" */
0x00,0x00,0x0D,0x03,0x00,0x00,0x00,0x00, /* 00000190 "........" */
0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0xF4, /* 00000198 "........" */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05, /* 000001A0 "........" */
0x79,0x00,0xA4,0x50,0x52,0x54,0x30,0x08, /* 000001A8 "y..PRT0." */
0x42,0x55,0x46,0x41,0x11,0x09,0x0A,0x06, /* 000001B0 "BUFA...." */
0x23,0x60,0x0C,0x18,0x79,0x00,0x08,0x42, /* 000001B8 "#`..y..B" */
0x55,0x46,0x42,0x11,0x09,0x0A,0x06,0x23, /* 000001C0 "UFB....#" */
0x00,0x00,0x18,0x79,0x00,0x8B,0x42,0x55, /* 000001C8 "...y..BU" */
0x46,0x42,0x01,0x49,0x52,0x51,0x56,0x5B, /* 000001D0 "FB.IRQV[" */
0x82,0x48,0x08,0x4C,0x4E,0x4B,0x41,0x08, /* 000001D8 ".H.LNKA." */
0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C, /* 000001E0 "_HID.A.." */
0x0F,0x08,0x5F,0x55,0x49,0x44,0x01,0x14, /* 000001E8 ".._UID.." */
0x1C,0x5F,0x53,0x54,0x41,0x00,0x7B,0x50, /* 000001F0 "._STA.{P" */
0x49,0x52,0x41,0x0A,0x80,0x60,0xA0,0x08, /* 000001F8 "IRA..`.." */
0x93,0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1, /* 00000200 ".`......" */
0x04,0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50, /* 00000208 "......_P" */
0x52,0x53,0x00,0xA4,0x42,0x55,0x46,0x41, /* 00000210 "RS..BUFA" */
0x14,0x11,0x5F,0x44,0x49,0x53,0x00,0x7D, /* 00000218 ".._DIS.}" */
0x50,0x49,0x52,0x41,0x0A,0x80,0x50,0x49, /* 00000220 "PIRA..PI" */
0x52,0x41,0x14,0x1A,0x5F,0x43,0x52,0x53, /* 00000228 "RA.._CRS" */
0x00,0x7B,0x50,0x49,0x52,0x41,0x0A,0x0F, /* 00000230 ".{PIRA.." */
0x60,0x79,0x01,0x60,0x49,0x52,0x51,0x56, /* 00000238 "`y.`IRQV" */
0xA4,0x42,0x55,0x46,0x42,0x14,0x1B,0x5F, /* 00000240 ".BUFB.._" */
0x53,0x52,0x53,0x01,0x8B,0x68,0x01,0x49, /* 00000248 "SRS..h.I" */
0x52,0x51,0x31,0x82,0x49,0x52,0x51,0x31, /* 00000250 "RQ1.IRQ1" */
0x60,0x76,0x60,0x70,0x60,0x50,0x49,0x52, /* 00000258 "`v`p`PIR" */
0x41,0x5B,0x82,0x49,0x08,0x4C,0x4E,0x4B, /* 00000260 "A[.I.LNK" */
0x42,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41, /* 00000268 "B._HID.A" */
0xD0,0x0C,0x0F,0x08,0x5F,0x55,0x49,0x44, /* 00000270 "...._UID" */
0x0A,0x02,0x14,0x1C,0x5F,0x53,0x54,0x41, /* 00000278 "...._STA" */
0x00,0x7B,0x50,0x49,0x52,0x42,0x0A,0x80, /* 00000280 ".{PIRB.." */
0x60,0xA0,0x08,0x93,0x60,0x0A,0x80,0xA4, /* 00000288 "`...`..." */
0x0A,0x09,0xA1,0x04,0xA4,0x0A,0x0B,0x14, /* 00000290 "........" */
0x0B,0x5F,0x50,0x52,0x53,0x00,0xA4,0x42, /* 00000298 "._PRS..B" */
0x55,0x46,0x41,0x14,0x11,0x5F,0x44,0x49, /* 000002A0 "UFA.._DI" */
0x53,0x00,0x7D,0x50,0x49,0x52,0x42,0x0A, /* 000002A8 "S.}PIRB." */
0x80,0x50,0x49,0x52,0x42,0x14,0x1A,0x5F, /* 000002B0 ".PIRB.._" */
0x43,0x52,0x53,0x00,0x7B,0x50,0x49,0x52, /* 000002B8 "CRS.{PIR" */
0x42,0x0A,0x0F,0x60,0x79,0x01,0x60,0x49, /* 000002C0 "B..`y.`I" */
0x52,0x51,0x56,0xA4,0x42,0x55,0x46,0x42, /* 000002C8 "RQV.BUFB" */
0x14,0x1B,0x5F,0x53,0x52,0x53,0x01,0x8B, /* 000002D0 ".._SRS.." */
0x68,0x01,0x49,0x52,0x51,0x31,0x82,0x49, /* 000002D8 "h.IRQ1.I" */
0x52,0x51,0x31,0x60,0x76,0x60,0x70,0x60, /* 000002E0 "RQ1`v`p`" */
0x50,0x49,0x52,0x42,0x5B,0x82,0x49,0x08, /* 000002E8 "PIRB[.I." */
0x4C,0x4E,0x4B,0x43,0x08,0x5F,0x48,0x49, /* 000002F0 "LNKC._HI" */
0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08,0x5F, /* 000002F8 "D.A...._" */
0x55,0x49,0x44,0x0A,0x03,0x14,0x1C,0x5F, /* 00000300 "UID...._" */
0x53,0x54,0x41,0x00,0x7B,0x50,0x49,0x52, /* 00000308 "STA.{PIR" */
0x43,0x0A,0x80,0x60,0xA0,0x08,0x93,0x60, /* 00000310 "C..`...`" */
0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04,0xA4, /* 00000318 "........" */
0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52,0x53, /* 00000320 "...._PRS" */
0x00,0xA4,0x42,0x55,0x46,0x41,0x14,0x11, /* 00000328 "..BUFA.." */
0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,0x49, /* 00000330 "_DIS.}PI" */
0x52,0x43,0x0A,0x80,0x50,0x49,0x52,0x43, /* 00000338 "RC..PIRC" */
0x14,0x1A,0x5F,0x43,0x52,0x53,0x00,0x7B, /* 00000340 ".._CRS.{" */
0x50,0x49,0x52,0x43,0x0A,0x0F,0x60,0x79, /* 00000348 "PIRC..`y" */
0x01,0x60,0x49,0x52,0x51,0x56,0xA4,0x42, /* 00000350 ".`IRQV.B" */
0x55,0x46,0x42,0x14,0x1B,0x5F,0x53,0x52, /* 00000358 "UFB.._SR" */
0x53,0x01,0x8B,0x68,0x01,0x49,0x52,0x51, /* 00000360 "S..h.IRQ" */
0x31,0x82,0x49,0x52,0x51,0x31,0x60,0x76, /* 00000368 "1.IRQ1`v" */
0x60,0x70,0x60,0x50,0x49,0x52,0x43,0x5B, /* 00000370 "`p`PIRC[" */
0x82,0x49,0x08,0x4C,0x4E,0x4B,0x44,0x08, /* 00000378 ".I.LNKD." */
0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C, /* 00000380 "_HID.A.." */
0x0F,0x08,0x5F,0x55,0x49,0x44,0x0A,0x04, /* 00000388 ".._UID.." */
0x14,0x1C,0x5F,0x53,0x54,0x41,0x00,0x7B, /* 00000390 ".._STA.{" */
0x50,0x49,0x52,0x44,0x0A,0x80,0x60,0xA0, /* 00000398 "PIRD..`." */
0x08,0x93,0x60,0x0A,0x80,0xA4,0x0A,0x09, /* 000003A0 "..`....." */
0xA1,0x04,0xA4,0x0A,0x0B,0x14,0x0B,0x5F, /* 000003A8 "......._" */
0x50,0x52,0x53,0x00,0xA4,0x42,0x55,0x46, /* 000003B0 "PRS..BUF" */
0x41,0x14,0x11,0x5F,0x44,0x49,0x53,0x00, /* 000003B8 "A.._DIS." */
0x7D,0x50,0x49,0x52,0x44,0x0A,0x80,0x50, /* 000003C0 "}PIRD..P" */
0x49,0x52,0x44,0x14,0x1A,0x5F,0x43,0x52, /* 000003C8 "IRD.._CR" */
0x53,0x00,0x7B,0x50,0x49,0x52,0x44,0x0A, /* 000003D0 "S.{PIRD." */
0x0F,0x60,0x79,0x01,0x60,0x49,0x52,0x51, /* 000003D8 ".`y.`IRQ" */
0x56,0xA4,0x42,0x55,0x46,0x42,0x14,0x1B, /* 000003E0 "V.BUFB.." */
0x5F,0x53,0x52,0x53,0x01,0x8B,0x68,0x01, /* 000003E8 "_SRS..h." */
0x49,0x52,0x51,0x31,0x82,0x49,0x52,0x51, /* 000003F0 "IRQ1.IRQ" */
0x31,0x60,0x76,0x60,0x70,0x60,0x50,0x49, /* 000003F8 "1`v`p`PI" */
0x52,0x44,0x14,0x16,0x5F,0x50,0x52,0x54, /* 00000400 "RD.._PRT" */
0x00,0xA0,0x0A,0x50,0x49,0x43,0x44,0xA4, /* 00000408 "...PICD." */
0x50,0x52,0x54,0x41,0xA4,0x50,0x52,0x54, /* 00000410 "PRTA.PRT" */
0x50,0x08,0x50,0x52,0x54,0x50,0x12,0x49, /* 00000418 "P.PRTP.I" */
0x36,0x3C,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000420 "6<......" */
0x01,0x00,0x00,0x4C,0x4E,0x4B,0x42,0x00, /* 00000428 "...LNKB." */
0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x01,0x00, /* 00000430 "........" */
0x01,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E, /* 00000438 ".LNKC..." */
0x04,0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x02, /* 00000440 "........" */
0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04, /* 00000448 "LNKD...." */
0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x03,0x4C, /* 00000450 ".......L" */
0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C, /* 00000458 "NKA....." */
0xFF,0xFF,0x02,0x00,0x00,0x4C,0x4E,0x4B, /* 00000460 ".....LNK" */
0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000468 "C......." */
0x02,0x00,0x01,0x4C,0x4E,0x4B,0x44,0x00, /* 00000470 "...LNKD." */
0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x02,0x00, /* 00000478 "........" */
0x0A,0x02,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 00000480 "..LNKA.." */
0x0E,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x0A, /* 00000488 "........" */
0x03,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D, /* 00000490 ".LNKB..." */
0x04,0x0C,0xFF,0xFF,0x03,0x00,0x00,0x4C, /* 00000498 ".......L" */
0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C, /* 000004A0 "NKD....." */
0xFF,0xFF,0x03,0x00,0x01,0x4C,0x4E,0x4B, /* 000004A8 ".....LNK" */
0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 000004B0 "A......." */
0x03,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x42, /* 000004B8 "....LNKB" */
0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x03, /* 000004C0 "........" */
0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x43,0x00, /* 000004C8 "...LNKC." */
0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x04,0x00, /* 000004D0 "........" */
0x00,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D, /* 000004D8 ".LNKA..." */
0x04,0x0C,0xFF,0xFF,0x04,0x00,0x01,0x4C, /* 000004E0 ".......L" */
0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C, /* 000004E8 "NKB....." */
0xFF,0xFF,0x04,0x00,0x0A,0x02,0x4C,0x4E, /* 000004F0 "......LN" */
0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 000004F8 "KC......" */
0xFF,0x04,0x00,0x0A,0x03,0x4C,0x4E,0x4B, /* 00000500 ".....LNK" */
0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000508 "D......." */
0x05,0x00,0x00,0x4C,0x4E,0x4B,0x42,0x00, /* 00000510 "...LNKB." */
0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x05,0x00, /* 00000518 "........" */
0x01,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E, /* 00000520 ".LNKC..." */
0x04,0x0C,0xFF,0xFF,0x05,0x00,0x0A,0x02, /* 00000528 "........" */
0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04, /* 00000530 "LNKD...." */
0x0C,0xFF,0xFF,0x05,0x00,0x0A,0x03,0x4C, /* 00000538 ".......L" */
0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C, /* 00000540 "NKA....." */
0xFF,0xFF,0x06,0x00,0x00,0x4C,0x4E,0x4B, /* 00000548 ".....LNK" */
0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000550 "C......." */
0x06,0x00,0x01,0x4C,0x4E,0x4B,0x44,0x00, /* 00000558 "...LNKD." */
0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x06,0x00, /* 00000560 "........" */
0x0A,0x02,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 00000568 "..LNKA.." */
0x0E,0x04,0x0C,0xFF,0xFF,0x06,0x00,0x0A, /* 00000570 "........" */
0x03,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D, /* 00000578 ".LNKB..." */
0x04,0x0C,0xFF,0xFF,0x07,0x00,0x00,0x4C, /* 00000580 ".......L" */
0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C, /* 00000588 "NKD....." */
0xFF,0xFF,0x07,0x00,0x01,0x4C,0x4E,0x4B, /* 00000590 ".....LNK" */
0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000598 "A......." */
0x07,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x42, /* 000005A0 "....LNKB" */
0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x07, /* 000005A8 "........" */
0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x43,0x00, /* 000005B0 "...LNKC." */
0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x08,0x00, /* 000005B8 "........" */
0x00,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D, /* 000005C0 ".LNKA..." */
0x04,0x0C,0xFF,0xFF,0x08,0x00,0x01,0x4C, /* 000005C8 ".......L" */
0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C, /* 000005D0 "NKB....." */
0xFF,0xFF,0x08,0x00,0x0A,0x02,0x4C,0x4E, /* 000005D8 "......LN" */
0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 000005E0 "KC......" */
0xFF,0x08,0x00,0x0A,0x03,0x4C,0x4E,0x4B, /* 000005E8 ".....LNK" */
0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 000005F0 "D......." */
0x09,0x00,0x00,0x4C,0x4E,0x4B,0x42,0x00, /* 000005F8 "...LNKB." */
0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x09,0x00, /* 00000600 "........" */
0x01,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E, /* 00000608 ".LNKC..." */
0x04,0x0C,0xFF,0xFF,0x09,0x00,0x0A,0x02, /* 00000610 "........" */
0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04, /* 00000618 "LNKD...." */
0x0C,0xFF,0xFF,0x09,0x00,0x0A,0x03,0x4C, /* 00000620 ".......L" */
0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C, /* 00000628 "NKA....." */
0xFF,0xFF,0x0A,0x00,0x00,0x4C,0x4E,0x4B, /* 00000630 ".....LNK" */
0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000638 "C......." */
0x0A,0x00,0x01,0x4C,0x4E,0x4B,0x44,0x00, /* 00000640 "...LNKD." */
0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0A,0x00, /* 00000648 "........" */
0x0A,0x02,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 00000650 "..LNKA.." */
0x0E,0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x0A, /* 00000658 "........" */
0x03,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D, /* 00000660 ".LNKB..." */
0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x00,0x4C, /* 00000668 ".......L" */
0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C, /* 00000670 "NKD....." */
0xFF,0xFF,0x0B,0x00,0x01,0x4C,0x4E,0x4B, /* 00000678 ".....LNK" */
0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000680 "A......." */
0x0B,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x42, /* 00000688 "....LNKB" */
0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0B, /* 00000690 "........" */
0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x43,0x00, /* 00000698 "...LNKC." */
0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0C,0x00, /* 000006A0 "........" */
0x00,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D, /* 000006A8 ".LNKA..." */
0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x01,0x4C, /* 000006B0 ".......L" */
0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C, /* 000006B8 "NKB....." */
0xFF,0xFF,0x0C,0x00,0x0A,0x02,0x4C,0x4E, /* 000006C0 "......LN" */
0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 000006C8 "KC......" */
0xFF,0x0C,0x00,0x0A,0x03,0x4C,0x4E,0x4B, /* 000006D0 ".....LNK" */
0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 000006D8 "D......." */
0x0D,0x00,0x00,0x4C,0x4E,0x4B,0x42,0x00, /* 000006E0 "...LNKB." */
0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0D,0x00, /* 000006E8 "........" */
0x01,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E, /* 000006F0 ".LNKC..." */
0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x0A,0x02, /* 000006F8 "........" */
0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04, /* 00000700 "LNKD...." */
0x0C,0xFF,0xFF,0x0D,0x00,0x0A,0x03,0x4C, /* 00000708 ".......L" */
0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C, /* 00000710 "NKA....." */
0xFF,0xFF,0x0E,0x00,0x00,0x4C,0x4E,0x4B, /* 00000718 ".....LNK" */
0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000720 "C......." */
0x0E,0x00,0x01,0x4C,0x4E,0x4B,0x44,0x00, /* 00000728 "...LNKD." */
0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0E,0x00, /* 00000730 "........" */
0x0A,0x02,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 00000738 "..LNKA.." */
0x0E,0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x0A, /* 00000740 "........" */
0x03,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D, /* 00000748 ".LNKB..." */
0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x00,0x4C, /* 00000750 ".......L" */
0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C, /* 00000758 "NKD....." */
0xFF,0xFF,0x0F,0x00,0x01,0x4C,0x4E,0x4B, /* 00000760 ".....LNK" */
0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000768 "A......." */
0x0F,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x42, /* 00000770 "....LNKB" */
0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0F, /* 00000778 "........" */
0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x43,0x00, /* 00000780 "...LNKC." */
0x08,0x50,0x52,0x54,0x41,0x12,0x41,0x2F, /* 00000788 ".PRTA.A/" */
0x3C,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x01, /* 00000790 "<......." */
0x00,0x00,0x00,0x0A,0x14,0x12,0x0B,0x04, /* 00000798 "........" */
0x0C,0xFF,0xFF,0x01,0x00,0x01,0x00,0x0A, /* 000007A0 "........" */
0x15,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x01, /* 000007A8 "........" */
0x00,0x0A,0x02,0x00,0x0A,0x16,0x12,0x0C, /* 000007B0 "........" */
0x04,0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x03, /* 000007B8 "........" */
0x00,0x0A,0x17,0x12,0x0B,0x04,0x0C,0xFF, /* 000007C0 "........" */
0xFF,0x02,0x00,0x00,0x00,0x0A,0x18,0x12, /* 000007C8 "........" */
0x0B,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x01, /* 000007D0 "........" */
0x00,0x0A,0x19,0x12,0x0C,0x04,0x0C,0xFF, /* 000007D8 "........" */
0xFF,0x02,0x00,0x0A,0x02,0x00,0x0A,0x1A, /* 000007E0 "........" */
0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x02,0x00, /* 000007E8 "........" */
0x0A,0x03,0x00,0x0A,0x1B,0x12,0x0B,0x04, /* 000007F0 "........" */
0x0C,0xFF,0xFF,0x03,0x00,0x00,0x00,0x0A, /* 000007F8 "........" */
0x1C,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x03, /* 00000800 "........" */
0x00,0x01,0x00,0x0A,0x1D,0x12,0x0C,0x04, /* 00000808 "........" */
0x0C,0xFF,0xFF,0x03,0x00,0x0A,0x02,0x00, /* 00000810 "........" */
0x0A,0x1E,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000818 "........" */
0x03,0x00,0x0A,0x03,0x00,0x0A,0x1F,0x12, /* 00000820 "........" */
0x0B,0x04,0x0C,0xFF,0xFF,0x04,0x00,0x00, /* 00000828 "........" */
0x00,0x0A,0x20,0x12,0x0B,0x04,0x0C,0xFF, /* 00000830 ".. ....." */
0xFF,0x04,0x00,0x01,0x00,0x0A,0x21,0x12, /* 00000838 "......!." */
0x0C,0x04,0x0C,0xFF,0xFF,0x04,0x00,0x0A, /* 00000840 "........" */
0x02,0x00,0x0A,0x22,0x12,0x0C,0x04,0x0C, /* 00000848 "..."...." */
0xFF,0xFF,0x04,0x00,0x0A,0x03,0x00,0x0A, /* 00000850 "........" */
0x23,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x05, /* 00000858 "#......." */
0x00,0x00,0x00,0x0A,0x24,0x12,0x0B,0x04, /* 00000860 "....$..." */
0x0C,0xFF,0xFF,0x05,0x00,0x01,0x00,0x0A, /* 00000868 "........" */
0x25,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x05, /* 00000870 "%......." */
0x00,0x0A,0x02,0x00,0x0A,0x26,0x12,0x0C, /* 00000878 ".....&.." */
0x04,0x0C,0xFF,0xFF,0x05,0x00,0x0A,0x03, /* 00000880 "........" */
0x00,0x0A,0x27,0x12,0x0B,0x04,0x0C,0xFF, /* 00000888 "..'....." */
0xFF,0x06,0x00,0x00,0x00,0x0A,0x28,0x12, /* 00000890 "......(." */
0x0B,0x04,0x0C,0xFF,0xFF,0x06,0x00,0x01, /* 00000898 "........" */
0x00,0x0A,0x29,0x12,0x0C,0x04,0x0C,0xFF, /* 000008A0 "..)....." */
0xFF,0x06,0x00,0x0A,0x02,0x00,0x0A,0x2A, /* 000008A8 ".......*" */
0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x06,0x00, /* 000008B0 "........" */
0x0A,0x03,0x00,0x0A,0x2B,0x12,0x0B,0x04, /* 000008B8 "....+..." */
0x0C,0xFF,0xFF,0x07,0x00,0x00,0x00,0x0A, /* 000008C0 "........" */
0x2C,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x07, /* 000008C8 ",......." */
0x00,0x01,0x00,0x0A,0x2D,0x12,0x0C,0x04, /* 000008D0 "....-..." */
0x0C,0xFF,0xFF,0x07,0x00,0x0A,0x02,0x00, /* 000008D8 "........" */
0x0A,0x2E,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 000008E0 "........" */
0x07,0x00,0x0A,0x03,0x00,0x0A,0x2F,0x12, /* 000008E8 "....../." */
0x0B,0x04,0x0C,0xFF,0xFF,0x08,0x00,0x00, /* 000008F0 "........" */
0x00,0x0A,0x11,0x12,0x0B,0x04,0x0C,0xFF, /* 000008F8 "........" */
0xFF,0x08,0x00,0x01,0x00,0x0A,0x12,0x12, /* 00000900 "........" */
0x0C,0x04,0x0C,0xFF,0xFF,0x08,0x00,0x0A, /* 00000908 "........" */
0x02,0x00,0x0A,0x13,0x12,0x0C,0x04,0x0C, /* 00000910 "........" */
0xFF,0xFF,0x08,0x00,0x0A,0x03,0x00,0x0A, /* 00000918 "........" */
0x14,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x09, /* 00000920 "........" */
0x00,0x00,0x00,0x0A,0x15,0x12,0x0B,0x04, /* 00000928 "........" */
0x0C,0xFF,0xFF,0x09,0x00,0x01,0x00,0x0A, /* 00000930 "........" */
0x16,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x09, /* 00000938 "........" */
0x00,0x0A,0x02,0x00,0x0A,0x17,0x12,0x0C, /* 00000940 "........" */
0x04,0x0C,0xFF,0xFF,0x09,0x00,0x0A,0x03, /* 00000948 "........" */
0x00,0x0A,0x18,0x12,0x0B,0x04,0x0C,0xFF, /* 00000950 "........" */
0xFF,0x0A,0x00,0x00,0x00,0x0A,0x19,0x12, /* 00000958 "........" */
0x0B,0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x01, /* 00000960 "........" */
0x00,0x0A,0x1A,0x12,0x0C,0x04,0x0C,0xFF, /* 00000968 "........" */
0xFF,0x0A,0x00,0x0A,0x02,0x00,0x0A,0x1B, /* 00000970 "........" */
0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0A,0x00, /* 00000978 "........" */
0x0A,0x03,0x00,0x0A,0x1C,0x12,0x0B,0x04, /* 00000980 "........" */
0x0C,0xFF,0xFF,0x0B,0x00,0x00,0x00,0x0A, /* 00000988 "........" */
0x1D,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0B, /* 00000990 "........" */
0x00,0x01,0x00,0x0A,0x1E,0x12,0x0C,0x04, /* 00000998 "........" */
0x0C,0xFF,0xFF,0x0B,0x00,0x0A,0x02,0x00, /* 000009A0 "........" */
0x0A,0x1F,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 000009A8 "........" */
0x0B,0x00,0x0A,0x03,0x00,0x0A,0x20,0x12, /* 000009B0 "...... ." */
0x0B,0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x00, /* 000009B8 "........" */
0x00,0x0A,0x21,0x12,0x0B,0x04,0x0C,0xFF, /* 000009C0 "..!....." */
0xFF,0x0C,0x00,0x01,0x00,0x0A,0x22,0x12, /* 000009C8 "......"." */
0x0C,0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x0A, /* 000009D0 "........" */
0x02,0x00,0x0A,0x23,0x12,0x0C,0x04,0x0C, /* 000009D8 "...#...." */
0xFF,0xFF,0x0C,0x00,0x0A,0x03,0x00,0x0A, /* 000009E0 "........" */
0x24,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0D, /* 000009E8 "$......." */
0x00,0x00,0x00,0x0A,0x25,0x12,0x0B,0x04, /* 000009F0 "....%..." */
0x0C,0xFF,0xFF,0x0D,0x00,0x01,0x00,0x0A, /* 000009F8 "........" */
0x26,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0D, /* 00000A00 "&......." */
0x00,0x0A,0x02,0x00,0x0A,0x27,0x12,0x0C, /* 00000A08 ".....'.." */
0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x0A,0x03, /* 00000A10 "........" */
0x00,0x0A,0x28,0x12,0x0B,0x04,0x0C,0xFF, /* 00000A18 "..(....." */
0xFF,0x0E,0x00,0x00,0x00,0x0A,0x29,0x12, /* 00000A20 "......)." */
0x0B,0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x01, /* 00000A28 "........" */
0x00,0x0A,0x2A,0x12,0x0C,0x04,0x0C,0xFF, /* 00000A30 "..*....." */
0xFF,0x0E,0x00,0x0A,0x02,0x00,0x0A,0x2B, /* 00000A38 ".......+" */
0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0E,0x00, /* 00000A40 "........" */
0x0A,0x03,0x00,0x0A,0x2C,0x12,0x0B,0x04, /* 00000A48 "....,..." */
0x0C,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x0A, /* 00000A50 "........" */
0x2D,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0F, /* 00000A58 "-......." */
0x00,0x01,0x00,0x0A,0x2E,0x12,0x0C,0x04, /* 00000A60 "........" */
0x0C,0xFF,0xFF,0x0F,0x00,0x0A,0x02,0x00, /* 00000A68 "........" */
0x0A,0x2F,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000A70 "./......" */
0x0F,0x00,0x0A,0x03,0x00,0x0A,0x10,0x5B, /* 00000A78 ".......[" */
0x82,0x4C,0x31,0x49,0x53,0x41,0x5F,0x08, /* 00000A80 ".L1ISA_." */
0x5F,0x41,0x44,0x52,0x0C,0x00,0x00,0x01, /* 00000A88 "_ADR...." */
0x00,0x5B,0x80,0x50,0x49,0x52,0x51,0x02, /* 00000A90 ".[.PIRQ." */
0x0A,0x60,0x0A,0x04,0x10,0x2E,0x5C,0x00, /* 00000A98 ".`....\." */
0x5B,0x81,0x29,0x5C,0x2F,0x04,0x5F,0x53, /* 00000AA0 "[.)\/._S" */
0x42,0x5F,0x50,0x43,0x49,0x30,0x49,0x53, /* 00000AA8 "B_PCI0IS" */
0x41,0x5F,0x50,0x49,0x52,0x51,0x01,0x50, /* 00000AB0 "A_PIRQ.P" */
0x49,0x52,0x41,0x08,0x50,0x49,0x52,0x42, /* 00000AB8 "IRA.PIRB" */
0x08,0x50,0x49,0x52,0x43,0x08,0x50,0x49, /* 00000AC0 ".PIRC.PI" */
0x52,0x44,0x08,0x5B,0x82,0x46,0x0B,0x53, /* 00000AC8 "RD.[.F.S" */
0x59,0x53,0x52,0x08,0x5F,0x48,0x49,0x44, /* 00000AD0 "YSR._HID" */
0x0C,0x41,0xD0,0x0C,0x02,0x08,0x5F,0x55, /* 00000AD8 ".A...._U" */
0x49,0x44,0x01,0x08,0x43,0x52,0x53,0x5F, /* 00000AE0 "ID..CRS_" */
0x11,0x4E,0x08,0x0A,0x8A,0x47,0x01,0x10, /* 00000AE8 ".N...G.." */
0x00,0x10,0x00,0x00,0x10,0x47,0x01,0x22, /* 00000AF0 ".....G."" */
0x00,0x22,0x00,0x00,0x0C,0x47,0x01,0x30, /* 00000AF8 "."...G.0" */
0x00,0x30,0x00,0x00,0x10,0x47,0x01,0x44, /* 00000B00 ".0...G.D" */
0x00,0x44,0x00,0x00,0x1C,0x47,0x01,0x62, /* 00000B08 ".D...G.b" */
0x00,0x62,0x00,0x00,0x02,0x47,0x01,0x65, /* 00000B10 ".b...G.e" */
0x00,0x65,0x00,0x00,0x0B,0x47,0x01,0x72, /* 00000B18 ".e...G.r" */
0x00,0x72,0x00,0x00,0x0E,0x47,0x01,0x80, /* 00000B20 ".r...G.." */
0x00,0x80,0x00,0x00,0x01,0x47,0x01,0x84, /* 00000B28 ".....G.." */
0x00,0x84,0x00,0x00,0x03,0x47,0x01,0x88, /* 00000B30 ".....G.." */
0x00,0x88,0x00,0x00,0x01,0x47,0x01,0x8C, /* 00000B38 ".....G.." */
0x00,0x8C,0x00,0x00,0x03,0x47,0x01,0x90, /* 00000B40 ".....G.." */
0x00,0x90,0x00,0x00,0x10,0x47,0x01,0xA2, /* 00000B48 ".....G.." */
0x00,0xA2,0x00,0x00,0x1C,0x47,0x01,0xE0, /* 00000B50 ".....G.." */
0x00,0xE0,0x00,0x00,0x10,0x47,0x01,0xA0, /* 00000B58 ".....G.." */
0x08,0xA0,0x08,0x00,0x04,0x47,0x01,0xC0, /* 00000B60 ".....G.." */
0x0C,0xC0,0x0C,0x00,0x10,0x47,0x01,0xD0, /* 00000B68 ".....G.." */
0x04,0xD0,0x04,0x00,0x02,0x79,0x00,0x14, /* 00000B70 ".....y.." */
0x0B,0x5F,0x43,0x52,0x53,0x00,0xA4,0x43, /* 00000B78 "._CRS..C" */
0x52,0x53,0x5F,0x5B,0x82,0x2B,0x50,0x49, /* 00000B80 "RS_[.+PI" */
0x43,0x5F,0x08,0x5F,0x48,0x49,0x44,0x0B, /* 00000B88 "C_._HID." */
0x41,0xD0,0x08,0x5F,0x43,0x52,0x53,0x11, /* 00000B90 "A.._CRS." */
0x18,0x0A,0x15,0x47,0x01,0x20,0x00,0x20, /* 00000B98 "...G. . " */
0x00,0x01,0x02,0x47,0x01,0xA0,0x00,0xA0, /* 00000BA0 "...G...." */
0x00,0x01,0x02,0x22,0x04,0x00,0x79,0x00, /* 00000BA8 "..."..y." */
0x5B,0x82,0x47,0x05,0x44,0x4D,0x41,0x30, /* 00000BB0 "[.G.DMA0" */
0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000BB8 "._HID.A." */
0x02,0x00,0x08,0x5F,0x43,0x52,0x53,0x11, /* 00000BC0 "..._CRS." */
0x41,0x04,0x0A,0x3D,0x2A,0x10,0x04,0x47, /* 00000BC8 "A..=*..G" */
0x01,0x00,0x00,0x00,0x00,0x00,0x10,0x47, /* 00000BD0 ".......G" */
0x01,0x81,0x00,0x81,0x00,0x00,0x03,0x47, /* 00000BD8 ".......G" */
0x01,0x87,0x00,0x87,0x00,0x00,0x01,0x47, /* 00000BE0 ".......G" */
0x01,0x89,0x00,0x89,0x00,0x00,0x03,0x47, /* 00000BE8 ".......G" */
0x01,0x8F,0x00,0x8F,0x00,0x00,0x01,0x47, /* 00000BF0 ".......G" */
0x01,0xC0,0x00,0xC0,0x00,0x00,0x20,0x47, /* 00000BF8 "...... G" */
0x01,0x80,0x04,0x80,0x04,0x00,0x10,0x79, /* 00000C00 ".......y" */
0x00,0x5B,0x82,0x25,0x54,0x4D,0x52,0x5F, /* 00000C08 ".[.%TMR_" */
0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000C10 "._HID.A." */
0x01,0x00,0x08,0x5F,0x43,0x52,0x53,0x11, /* 00000C18 "..._CRS." */
0x10,0x0A,0x0D,0x47,0x01,0x40,0x00,0x40, /* 00000C20 "...G.@.@" */
0x00,0x00,0x04,0x22,0x01,0x00,0x79,0x00, /* 00000C28 "..."..y." */
0x5B,0x82,0x25,0x52,0x54,0x43,0x5F,0x08, /* 00000C30 "[.%RTC_." */
0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0B, /* 00000C38 "_HID.A.." */
0x00,0x08,0x5F,0x43,0x52,0x53,0x11,0x10, /* 00000C40 ".._CRS.." */
0x0A,0x0D,0x47,0x01,0x70,0x00,0x70,0x00, /* 00000C48 "..G.p.p." */
0x00,0x02,0x22,0x00,0x01,0x79,0x00,0x5B, /* 00000C50 ".."..y.[" */
0x82,0x22,0x53,0x50,0x4B,0x52,0x08,0x5F, /* 00000C58 "."SPKR._" */
0x48,0x49,0x44,0x0C,0x41,0xD0,0x08,0x00, /* 00000C60 "HID.A..." */
0x08,0x5F,0x43,0x52,0x53,0x11,0x0D,0x0A, /* 00000C68 "._CRS..." */
0x0A,0x47,0x01,0x61,0x00,0x61,0x00,0x00, /* 00000C70 ".G.a.a.." */
0x01,0x79,0x00,0x5B,0x82,0x31,0x50,0x53, /* 00000C78 ".y.[.1PS" */
0x32,0x4D,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 00000C80 "2M._HID." */
0x41,0xD0,0x0F,0x13,0x08,0x5F,0x43,0x49, /* 00000C88 "A...._CI" */
0x44,0x0C,0x41,0xD0,0x0F,0x13,0x14,0x09, /* 00000C90 "D.A....." */
0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,0x0F, /* 00000C98 "_STA...." */
0x08,0x5F,0x43,0x52,0x53,0x11,0x08,0x0A, /* 00000CA0 "._CRS..." */
0x05,0x22,0x00,0x10,0x79,0x00,0x5B,0x82, /* 00000CA8 "."..y.[." */
0x42,0x04,0x50,0x53,0x32,0x4B,0x08,0x5F, /* 00000CB0 "B.PS2K._" */
0x48,0x49,0x44,0x0C,0x41,0xD0,0x03,0x03, /* 00000CB8 "HID.A..." */
0x08,0x5F,0x43,0x49,0x44,0x0C,0x41,0xD0, /* 00000CC0 "._CID.A." */
0x03,0x0B,0x14,0x09,0x5F,0x53,0x54,0x41, /* 00000CC8 "...._STA" */
0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52, /* 00000CD0 "....._CR" */
0x53,0x11,0x18,0x0A,0x15,0x47,0x01,0x60, /* 00000CD8 "S....G.`" */
0x00,0x60,0x00,0x00,0x01,0x47,0x01,0x64, /* 00000CE0 ".`...G.d" */
0x00,0x64,0x00,0x00,0x01,0x22,0x02,0x00, /* 00000CE8 ".d...".." */
0x79,0x00,0x5B,0x82,0x3A,0x46,0x44,0x43, /* 00000CF0 "y.[.:FDC" */
0x30,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41, /* 00000CF8 "0._HID.A" */
0xD0,0x07,0x00,0x14,0x09,0x5F,0x53,0x54, /* 00000D00 "....._ST" */
0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43, /* 00000D08 "A....._C" */
0x52,0x53,0x11,0x1B,0x0A,0x18,0x47,0x01, /* 00000D10 "RS....G." */
0xF0,0x03,0xF0,0x03,0x01,0x06,0x47,0x01, /* 00000D18 "......G." */
0xF7,0x03,0xF7,0x03,0x01,0x01,0x22,0x40, /* 00000D20 "......"@" */
0x00,0x2A,0x04,0x00,0x79,0x00,0x5B,0x82, /* 00000D28 ".*..y.[." */
0x35,0x55,0x41,0x52,0x31,0x08,0x5F,0x48, /* 00000D30 "5UAR1._H" */
0x49,0x44,0x0C,0x41,0xD0,0x05,0x01,0x08, /* 00000D38 "ID.A...." */
0x5F,0x55,0x49,0x44,0x01,0x14,0x09,0x5F, /* 00000D40 "_UID..._" */
0x53,0x54,0x41,0x00,0xA4,0x0A,0x0F,0x08, /* 00000D48 "STA....." */
0x5F,0x43,0x52,0x53,0x11,0x10,0x0A,0x0D, /* 00000D50 "_CRS...." */
0x47,0x01,0xF8,0x03,0xF8,0x03,0x01,0x08, /* 00000D58 "G......." */
0x22,0x10,0x00,0x79,0x00,0x5B,0x82,0x36, /* 00000D60 ""..y.[.6" */
0x4C,0x54,0x50,0x31,0x08,0x5F,0x48,0x49, /* 00000D68 "LTP1._HI" */
0x44,0x0C,0x41,0xD0,0x04,0x00,0x08,0x5F, /* 00000D70 "D.A...._" */
0x55,0x49,0x44,0x0A,0x02,0x14,0x09,0x5F, /* 00000D78 "UID...._" */
0x53,0x54,0x41,0x00,0xA4,0x0A,0x0F,0x08, /* 00000D80 "STA....." */
0x5F,0x43,0x52,0x53,0x11,0x10,0x0A,0x0D, /* 00000D88 "_CRS...." */
0x47,0x01,0x78,0x03,0x78,0x03,0x08,0x08, /* 00000D90 "G.x.x..." */
0x22,0x80,0x00,0x79,0x00,
};
int DsdtLen=sizeof(AmlCode);
-53
View File
@@ -1,53 +0,0 @@
/*
* Copyright (c) 2004, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307 USA.
*
*/
#include "acpi2_0.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define USAGE "Usage: acpi_gen filename \n" \
" generage acpitable and write to the binary \n" \
" filename - the binary name\n"
int main(int argc, char **argv)
{
char *filename;
char buf[ACPI_TABLE_SIZE] = { 0 };
FILE *f;
if (argc < 2) {
fprintf(stderr,"%s",USAGE);
exit(1);
}
filename = argv[1];
if ((f = fopen(filename, "w+")) == NULL) {
fprintf(stderr,"Can not open %s", filename);
exit(1);
}
AcpiBuildTable((uint8_t *)buf);
if (fwrite(buf, ACPI_TABLE_SIZE, 1, f) < 1) {
fprintf(stderr,"Can not write to %s\n", filename);
exit(1);
}
return 0;
}
+1 -40
View File
@@ -17,48 +17,9 @@
*/
#include "acpi2_0.h"
#include "../config.h"
#include <xen/hvm/ioreq.h>
/*
* Multiple APIC Description Table (MADT).
*/
struct acpi_20_madt Madt = {
.header = {
.header = {
.signature = ACPI_2_0_MADT_SIGNATURE,
.length = sizeof(struct acpi_20_madt),
.revision = ACPI_2_0_MADT_REVISION,
.oem_id = ACPI_OEM_ID,
.oem_table_id = ACPI_OEM_TABLE_ID,
.oem_revision = ACPI_OEM_REVISION,
.creator_id = ACPI_CREATOR_ID,
.creator_revision = ACPI_CREATOR_REVISION
},
.lapic_addr = 0xFEE00000,
.flags = ACPI_PCAT_COMPAT
},
/* IO APIC */
.io_apic = {
[0] = {
.type = ACPI_IO_APIC,
.length = sizeof(struct acpi_20_madt_ioapic),
.ioapic_addr = 0xFEC00000
}
},
/* Local APIC entries for up to 32 processors. */
.lapic = {
[0] = {
.type = ACPI_PROCESSOR_LOCAL_APIC,
.length = sizeof(struct acpi_20_madt_lapic),
.flags = 0x00000001
}
}
};
/*
* Firmware ACPI Control Structure (FACS).
*/
-162
View File
@@ -1,162 +0,0 @@
/*
* acpi_madt.c: Update ACPI MADT table for multiple processor guest.
*
* Yu Ke, ke.yu@intel.com
* Copyright (c) 2005, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307 USA.
*/
#include "acpi/acpi2_0.h"
#include "util.h"
#include "acpi_utils.h"
#include <xen/hvm/hvm_info_table.h>
#define NULL ((void*)0)
static struct hvm_info_table *table = NULL;
static int validate_hvm_info(struct hvm_info_table *t)
{
char signature[] = "HVM INFO";
uint8_t *ptr = (uint8_t *)t;
uint8_t sum = 0;
int i;
/* strncmp(t->signature, "HVM INFO", 8) */
for (i = 0; i < 8; i++) {
if (signature[i] != t->signature[i]) {
puts("Bad hvm info signature\n");
return 0;
}
}
for (i = 0; i < t->length; i++)
sum += ptr[i];
return (sum == 0);
}
/* xc_vmx_builder wrote hvm info at 0x9F800. Return it. */
struct hvm_info_table *
get_hvm_info_table(void)
{
struct hvm_info_table *t;
if (table != NULL)
return table;
t = (struct hvm_info_table *)HVM_INFO_PADDR;
if (!validate_hvm_info(t)) {
puts("Bad hvm info table\n");
return NULL;
}
table = t;
return table;
}
int
get_vcpu_nr(void)
{
struct hvm_info_table *t = get_hvm_info_table();
return (t ? t->nr_vcpus : 1); /* default 1 vcpu */
}
int
get_acpi_enabled(void)
{
struct hvm_info_table *t = get_hvm_info_table();
return (t ? t->acpi_enabled : 0); /* default no acpi */
}
static void *
acpi_madt_get_madt(unsigned char *acpi_start)
{
struct acpi_20_rsdt *rsdt;
struct acpi_20_madt *madt;
rsdt = acpi_rsdt_get(acpi_start);
if (rsdt == NULL)
return NULL;
madt = (struct acpi_20_madt *)(acpi_start + rsdt->entry[1] -
ACPI_PHYSICAL_ADDRESS);
if (madt->header.header.signature != ACPI_2_0_MADT_SIGNATURE) {
puts("Bad MADT signature \n");
return NULL;
}
return madt;
}
static int
acpi_madt_set_local_apics(
int nr_vcpu,
struct acpi_20_madt *madt)
{
int i;
if ((nr_vcpu > MAX_VIRT_CPUS) || (nr_vcpu < 0) || !madt)
return -1;
for (i = 0; i < nr_vcpu; i++) {
madt->lapic[i].type = ACPI_PROCESSOR_LOCAL_APIC;
madt->lapic[i].length = sizeof(struct acpi_20_madt_lapic);
madt->lapic[i].acpi_processor_id = i;
madt->lapic[i].apic_id = i;
madt->lapic[i].flags = 1;
}
madt->header.header.length =
sizeof(struct acpi_20_madt) -
(MAX_VIRT_CPUS - nr_vcpu) * sizeof(struct acpi_20_madt_lapic);
return 0;
}
#define FIELD_OFFSET(TYPE,Field) ((unsigned int)(&(((TYPE *) 0)->Field)))
int acpi_madt_update(unsigned char *acpi_start)
{
int rc;
struct acpi_20_madt *madt;
madt = acpi_madt_get_madt(acpi_start);
if (!madt)
return -1;
rc = acpi_madt_set_local_apics(get_vcpu_nr(), madt);
if (rc != 0)
return rc;
set_checksum(
madt, FIELD_OFFSET(struct acpi_header, checksum),
madt->header.header.length);
return 0;
}
/*
* Local variables:
* mode: C
* c-set-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
+52 -18
View File
@@ -78,14 +78,15 @@ static void acpi_tpm_tis_probe(unsigned char *acpi_start,
sizeof(tis_did_vid_rid)) != 0 )
return;
puts("TIS is available\n");
printf("TIS is available\n");
addr = acpi_xsdt_add_entry(acpi_start, freemem, limit,
AmlCode_TPM, sizeof(AmlCode_TPM));
if ( addr == NULL )
return;
/* legacy systems need an RSDT entry */
acpi_rsdt_add_entry_pointer(acpi_start, addr);
if ( acpi_rsdt_add_entry_pointer(acpi_start, addr) != 1 )
return;
/* add ACPI TCPA table */
addr = acpi_xsdt_add_entry(acpi_start, freemem, limit,
@@ -108,7 +109,8 @@ static void acpi_tpm_tis_probe(unsigned char *acpi_start,
tcpa->header.length);
}
acpi_rsdt_add_entry_pointer(acpi_start, addr);
if ( acpi_rsdt_add_entry_pointer(acpi_start, addr) != 1 )
return;
}
@@ -125,23 +127,57 @@ void acpi_update(unsigned char *acpi_start,
}
/*
* Search for the RSDP in memory below the BIOS
*/
struct acpi_20_rsdp *acpi_rsdp_get(unsigned char *acpi_start)
{
int offset = 0;
int found = 0;
static int displayed = 0;
struct acpi_20_rsdp *rsdp;
while ( &acpi_start[offset] < (unsigned char *)0xf0000 )
{
rsdp = (struct acpi_20_rsdp *)&acpi_start[offset];
if ( rsdp->signature == ACPI_2_0_RSDP_SIGNATURE )
{
found = 1;
break;
}
offset += 0x10;
}
if ( !found )
rsdp = NULL;
if ( !displayed )
{
if ( rsdp )
printf("Found RSDP at %lx\n",(long)rsdp);
else
printf("ERROR: RSDP was not found\n");
displayed = 1;
}
return rsdp;
}
struct acpi_20_rsdt *acpi_rsdt_get(unsigned char *acpi_start)
{
struct acpi_20_rsdp *rsdp;
struct acpi_20_rsdt *rsdt;
rsdp = (struct acpi_20_rsdp *)(acpi_start + sizeof(struct acpi_20_facs));
if ( rsdp->signature != ACPI_2_0_RSDP_SIGNATURE )
{
puts("Bad RSDP signature\n");
rsdp = acpi_rsdp_get(acpi_start);
if (!rsdp)
return NULL;
}
rsdt = (struct acpi_20_rsdt *)
(acpi_start + rsdp->rsdt_address - ACPI_PHYSICAL_ADDRESS);
if ( rsdt->header.signature != ACPI_2_0_RSDT_SIGNATURE )
{
puts("Bad RSDT signature\n");
printf("Bad RSDT signature\n");
return NULL;
}
@@ -189,18 +225,15 @@ struct acpi_20_xsdt *acpi_xsdt_get(unsigned char *acpi_start)
struct acpi_20_rsdp *rsdp;
struct acpi_20_xsdt *xsdt;
rsdp = (struct acpi_20_rsdp *)(acpi_start + sizeof(struct acpi_20_facs));
if ( rsdp->signature != ACPI_2_0_RSDP_SIGNATURE )
{
puts("Bad RSDP signature\n");
rsdp = acpi_rsdp_get(acpi_start);
if (!rsdp)
return NULL;
}
xsdt = (struct acpi_20_xsdt *)
(acpi_start + rsdp->xsdt_address - ACPI_PHYSICAL_ADDRESS);
if ( xsdt->header.signature != ACPI_2_0_XSDT_SIGNATURE )
{
puts("Bad XSDT signature\n");
printf("Bad XSDT signature\n");
return NULL;
}
return xsdt;
@@ -270,11 +303,12 @@ static unsigned char *acpi_xsdt_add_entry(unsigned char *acpi_start,
if ( found )
{
/* memory below hard limit ? */
if (*freemem + table_size <= limit) {
puts("Copying SSDT entry!\n");
if ( (*freemem + table_size) <= limit )
{
addr = *freemem;
memcpy(addr, table, table_size);
*freemem += table_size;
printf("Copied dyn. ACPI entry to %lx\n",(long)addr);
*freemem += ((table_size + 0xf) & ~0xf);
acpi_xsdt_add_entry_pointer(acpi_start, addr);
}
+108
View File
@@ -0,0 +1,108 @@
#ifndef __ASM_APICDEF_H
#define __ASM_APICDEF_H
#define APIC_DEFAULT_PHYS_BASE 0xfee00000
#define APIC_ID 0x20
#define APIC_ID_MASK (0xFFu<<24)
#define GET_APIC_ID(x) (((x)>>24)&0xFFu)
#define SET_APIC_ID(x) (((x)<<24))
#define APIC_LVR 0x30
#define APIC_LVR_MASK 0xFF00FF
#define GET_APIC_VERSION(x) ((x)&0xFF)
#define GET_APIC_MAXLVT(x) (((x)>>16)&0xFF)
#define APIC_INTEGRATED(x) ((x)&0xF0)
#define APIC_XAPIC(x) ((x) >= 0x14)
#define APIC_TASKPRI 0x80
#define APIC_TPRI_MASK 0xFF
#define APIC_ARBPRI 0x90
#define APIC_ARBPRI_MASK 0xFF
#define APIC_PROCPRI 0xA0
#define APIC_EOI 0xB0
#define APIC_EIO_ACK 0x0
#define APIC_RRR 0xC0
#define APIC_LDR 0xD0
#define APIC_LDR_MASK (0xFF<<24)
#define GET_APIC_LOGICAL_ID(x) (((x)>>24)&0xFF)
#define SET_APIC_LOGICAL_ID(x) (((x)<<24))
#define APIC_ALL_CPUS 0xFF
#define APIC_DFR 0xE0
#define APIC_DFR_CLUSTER 0x0FFFFFFFul
#define APIC_DFR_FLAT 0xFFFFFFFFul
#define APIC_SPIV 0xF0
#define APIC_SPIV_FOCUS_DISABLED (1<<9)
#define APIC_SPIV_APIC_ENABLED (1<<8)
#define APIC_ISR 0x100
#define APIC_TMR 0x180
#define APIC_IRR 0x200
#define APIC_ESR 0x280
#define APIC_ESR_SEND_CS 0x00001
#define APIC_ESR_RECV_CS 0x00002
#define APIC_ESR_SEND_ACC 0x00004
#define APIC_ESR_RECV_ACC 0x00008
#define APIC_ESR_SENDILL 0x00020
#define APIC_ESR_RECVILL 0x00040
#define APIC_ESR_ILLREGA 0x00080
#define APIC_ICR 0x300
#define APIC_DEST_SELF 0x40000
#define APIC_DEST_ALLINC 0x80000
#define APIC_DEST_ALLBUT 0xC0000
#define APIC_ICR_RR_MASK 0x30000
#define APIC_ICR_RR_INVALID 0x00000
#define APIC_ICR_RR_INPROG 0x10000
#define APIC_ICR_RR_VALID 0x20000
#define APIC_INT_LEVELTRIG 0x08000
#define APIC_INT_ASSERT 0x04000
#define APIC_ICR_BUSY 0x01000
#define APIC_DEST_LOGICAL 0x00800
#define APIC_DEST_PHYSICAL 0x00000
#define APIC_DM_FIXED 0x00000
#define APIC_DM_LOWEST 0x00100
#define APIC_DM_SMI 0x00200
#define APIC_DM_REMRD 0x00300
#define APIC_DM_NMI 0x00400
#define APIC_DM_INIT 0x00500
#define APIC_DM_STARTUP 0x00600
#define APIC_DM_EXTINT 0x00700
#define APIC_VECTOR_MASK 0x000FF
#define APIC_ICR2 0x310
#define GET_APIC_DEST_FIELD(x) (((x)>>24)&0xFF)
#define SET_APIC_DEST_FIELD(x) ((x)<<24)
#define APIC_LVTT 0x320
#define APIC_LVTTHMR 0x330
#define APIC_LVTPC 0x340
#define APIC_LVT0 0x350
#define APIC_LVT_TIMER_BASE_MASK (0x3<<18)
#define GET_APIC_TIMER_BASE(x) (((x)>>18)&0x3)
#define SET_APIC_TIMER_BASE(x) (((x)<<18))
#define APIC_TIMER_BASE_CLKIN 0x0
#define APIC_TIMER_BASE_TMBASE 0x1
#define APIC_TIMER_BASE_DIV 0x2
#define APIC_LVT_TIMER_PERIODIC (1<<17)
#define APIC_LVT_MASKED (1<<16)
#define APIC_LVT_LEVEL_TRIGGER (1<<15)
#define APIC_LVT_REMOTE_IRR (1<<14)
#define APIC_INPUT_POLARITY (1<<13)
#define APIC_SEND_PENDING (1<<12)
#define APIC_MODE_MASK 0x700
#define GET_APIC_DELIVERY_MODE(x) (((x)>>8)&0x7)
#define SET_APIC_DELIVERY_MODE(x,y) (((x)&~0x700)|((y)<<8))
#define APIC_MODE_FIXED 0x0
#define APIC_MODE_NMI 0x4
#define APIC_MODE_EXTINT 0x7
#define APIC_LVT1 0x360
#define APIC_LVTERR 0x370
#define APIC_TMICT 0x380
#define APIC_TMCCT 0x390
#define APIC_TDCR 0x3E0
#define APIC_TDR_DIV_TMBASE (1<<2)
#define APIC_TDR_DIV_1 0xB
#define APIC_TDR_DIV_2 0x0
#define APIC_TDR_DIV_4 0x1
#define APIC_TDR_DIV_8 0x2
#define APIC_TDR_DIV_16 0x3
#define APIC_TDR_DIV_32 0x8
#define APIC_TDR_DIV_64 0x9
#define APIC_TDR_DIV_128 0xA
#endif
+13
View File
@@ -0,0 +1,13 @@
#ifndef __HVMLOADER_CONFIG_H__
#define __HVMLOADER_CONFIG_H__
#define IOAPIC_BASE_ADDRESS 0xfec00000
#define IOAPIC_ID 0x00
#define IOAPIC_VERSION 0x11
#define LAPIC_BASE_ADDRESS 0xfee00000
#define PCI_ISA_DEVFN 0x08 /* dev 1, fn 0 */
#define PCI_ISA_IRQ_MASK 0x0c60U /* ISA IRQs 5,6,10,11 are PCI connected */
#endif /* __HVMLOADER_CONFIG_H__ */
+285 -153
View File
@@ -1,13 +1,11 @@
/*
* hvmloader.c: HVM ROMBIOS/VGABIOS/ACPI/VMXAssist image loader.
*
* A quicky so that we can boot rom images as if they were a Linux kernel.
* This code will copy the rom images (ROMBIOS/VGABIOS/VM86) into their
* respective spaces and transfer control to VM86 to execute the BIOSes.
*
* Leendert van Doorn, leendert@watson.ibm.com
* Copyright (c) 2005, International Business Machines Corporation.
*
* Copyright (c) 2006, Keir Fraser, XenSource Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
@@ -27,202 +25,336 @@
#include "util.h"
#include "acpi_utils.h"
#include "smbios.h"
#include "config.h"
#include "apic_regs.h"
#include "pci_regs.h"
#include <xen/version.h>
#include <xen/hvm/params.h>
#include <xen/hvm/e820.h>
/* memory map */
#define HYPERCALL_PHYSICAL_ADDRESS 0x00080000
#define VGABIOS_PHYSICAL_ADDRESS 0x000C0000
#define VMXASSIST_PHYSICAL_ADDRESS 0x000D0000
#define ROMBIOS_PHYSICAL_ADDRESS 0x000F0000
#define HYPERCALL_PHYSICAL_ADDRESS 0x00080000
#define VGABIOS_PHYSICAL_ADDRESS 0x000C0000
#define VMXASSIST_PHYSICAL_ADDRESS 0x000D0000
#define ROMBIOS_PHYSICAL_ADDRESS 0x000F0000
/* invoke SVM's paged realmode support */
#define SVM_VMMCALL_RESET_TO_REALMODE 0x80000001
#define SVM_VMMCALL_RESET_TO_REALMODE 0x80000001
/*
* C runtime start off
*/
asm(
" .text \n"
" .globl _start \n"
"_start: \n"
" cld \n"
" cli \n"
" lgdt gdt_desr \n"
" movl $stack_top, %esp \n"
" movl %esp, %ebp \n"
" call main \n"
" jmp halt \n"
" \n"
"gdt_desr: \n"
" .word gdt_end - gdt - 1 \n"
" .long gdt \n"
" \n"
" .align 8 \n"
"gdt: \n"
" .quad 0x0000000000000000 \n"
" .quad 0x00CF92000000FFFF \n"
" .quad 0x00CF9A000000FFFF \n"
"gdt_end: \n"
" \n"
"halt: \n"
" sti \n"
" jmp . \n"
" \n"
" .bss \n"
" .align 8 \n"
"stack: \n"
" .skip 0x4000 \n"
"stack_top: \n"
);
" .text \n"
" .globl _start \n"
"_start: \n"
" cld \n"
" cli \n"
" lgdt gdt_desr \n"
" movl $stack_top, %esp \n"
" movl %esp, %ebp \n"
" call main \n"
" ud2 \n"
" \n"
"gdt_desr: \n"
" .word gdt_end - gdt - 1 \n"
" .long gdt \n"
" \n"
" .align 8 \n"
"gdt: \n"
" .quad 0x0000000000000000 \n"
" .quad 0x00CF92000000FFFF \n"
" .quad 0x00CF9A000000FFFF \n"
"gdt_end: \n"
" \n"
" .bss \n"
" .align 8 \n"
"stack: \n"
" .skip 0x4000 \n"
"stack_top: \n"
);
extern int get_acpi_enabled(void);
extern int acpi_madt_update(unsigned char* acpi_start);
extern void create_mp_tables(void);
struct hvm_info_table *get_hvm_info_table(void);
static int
cirrus_check(void)
{
outw(0x3C4, 0x9206);
return inb(0x3C5) == 0x12;
outw(0x3C4, 0x9206);
return inb(0x3C5) == 0x12;
}
static int
vmmcall(int function, int edi, int esi, int edx, int ecx, int ebx)
{
int eax;
int eax;
__asm__ __volatile__(
".byte 0x0F,0x01,0xD9"
: "=a" (eax)
: "a"(function),
"b"(ebx), "c"(ecx), "d"(edx), "D"(edi), "S"(esi)
);
return eax;
__asm__ __volatile__ (
".byte 0x0F,0x01,0xD9"
: "=a" (eax)
: "a"(function),
"b"(ebx), "c"(ecx), "d"(edx), "D"(edi), "S"(esi) );
return eax;
}
static int
check_amd(void)
{
char id[12];
char id[12];
__asm__ __volatile__(
"cpuid"
: "=b" (*(int *)(&id[0])),
"=c" (*(int *)(&id[8])),
"=d" (*(int *)(&id[4]))
: "a" (0)
);
return __builtin_memcmp(id, "AuthenticAMD", 12) == 0;
__asm__ __volatile__ (
"cpuid"
: "=b" (*(int *)(&id[0])),
"=c" (*(int *)(&id[8])),
"=d" (*(int *)(&id[4]))
: "a" (0) );
return __builtin_memcmp(id, "AuthenticAMD", 12) == 0;
}
static void
wrmsr(uint32_t idx, uint64_t v)
{
__asm__ __volatile__(
"wrmsr"
: : "c" (idx), "a" ((uint32_t)v), "d" ((uint32_t)(v>>32)) );
__asm__ __volatile__ (
"wrmsr"
: : "c" (idx), "a" ((uint32_t)v), "d" ((uint32_t)(v>>32)) );
}
static void
init_hypercalls(void)
{
uint32_t eax, ebx, ecx, edx;
unsigned long i;
char signature[13], number[13];
xen_extraversion_t extraversion;
uint32_t eax, ebx, ecx, edx;
unsigned long i;
char signature[13];
xen_extraversion_t extraversion;
cpuid(0x40000000, &eax, &ebx, &ecx, &edx);
cpuid(0x40000000, &eax, &ebx, &ecx, &edx);
*(uint32_t *)(signature + 0) = ebx;
*(uint32_t *)(signature + 4) = ecx;
*(uint32_t *)(signature + 8) = edx;
signature[12] = '\0';
*(uint32_t *)(signature + 0) = ebx;
*(uint32_t *)(signature + 4) = ecx;
*(uint32_t *)(signature + 8) = edx;
signature[12] = '\0';
if (strcmp("XenVMMXenVMM", signature) || (eax < 0x40000002)) {
puts("FATAL: Xen hypervisor not detected\n");
__asm__ __volatile__( "ud2" );
}
if ( strcmp("XenVMMXenVMM", signature) || (eax < 0x40000002) )
{
printf("FATAL: Xen hypervisor not detected\n");
__asm__ __volatile__( "ud2" );
}
cpuid(0x40000001, &eax, &ebx, &ecx, &edx);
/* Fill in hypercall transfer pages. */
cpuid(0x40000002, &eax, &ebx, &ecx, &edx);
for ( i = 0; i < eax; i++ )
wrmsr(ebx, HYPERCALL_PHYSICAL_ADDRESS + (i << 12) + i);
puts("Detected Xen v");
puts(itoa(number, eax >> 16));
puts(".");
puts(itoa(number, eax & 0xffff));
cpuid(0x40000002, &eax, &ebx, &ecx, &edx);
for (i = 0; i < eax; i++)
wrmsr(ebx, HYPERCALL_PHYSICAL_ADDRESS + (i << 12) + i);
hypercall_xen_version(XENVER_extraversion, extraversion);
puts(extraversion);
puts("\n");
/* Print version information. */
cpuid(0x40000001, &eax, &ebx, &ecx, &edx);
hypercall_xen_version(XENVER_extraversion, extraversion);
printf("Detected Xen v%u.%u%s\n", eax >> 16, eax & 0xffff, extraversion);
}
int
main(void)
static void apic_setup(void)
{
puts("HVM Loader\n");
/* Set the IOAPIC ID to tha static value used in the MP/ACPI tables. */
ioapic_write(0x00, IOAPIC_ID);
init_hypercalls();
puts("Writing SMBIOS tables ...\n");
hvm_write_smbios_tables();
puts("Loading ROMBIOS ...\n");
memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, sizeof(rombios));
create_mp_tables();
if (cirrus_check()) {
puts("Loading Cirrus VGABIOS ...\n");
memcpy((void *)VGABIOS_PHYSICAL_ADDRESS,
vgabios_cirrusvga, sizeof(vgabios_cirrusvga));
} else {
puts("Loading Standard VGABIOS ...\n");
memcpy((void *)VGABIOS_PHYSICAL_ADDRESS,
vgabios_stdvga, sizeof(vgabios_stdvga));
}
if (get_acpi_enabled() != 0) {
puts("Loading ACPI ...\n");
acpi_madt_update((unsigned char *) acpi);
if (ACPI_PHYSICAL_ADDRESS+sizeof(acpi) <= 0xF0000) {
unsigned char *freemem = (unsigned char *)
(ACPI_PHYSICAL_ADDRESS + sizeof(acpi));
/*
* Make sure acpi table does not overlap rombios
* currently acpi less than 8K will be OK.
*/
memcpy((void *)ACPI_PHYSICAL_ADDRESS, acpi,
sizeof(acpi));
acpi_update((unsigned char *)ACPI_PHYSICAL_ADDRESS,
sizeof(acpi),
(unsigned char *)0xF0000,
&freemem);
}
}
if (check_amd()) {
/* AMD implies this is SVM */
puts("SVM go ...\n");
vmmcall(SVM_VMMCALL_RESET_TO_REALMODE, 0, 0, 0, 0, 0);
} else {
puts("Loading VMXAssist ...\n");
memcpy((void *)VMXASSIST_PHYSICAL_ADDRESS,
vmxassist, sizeof(vmxassist));
puts("VMX go ...\n");
__asm__ __volatile__(
"jmp *%%eax"
: : "a" (VMXASSIST_PHYSICAL_ADDRESS), "d" (0)
);
}
puts("Failed to invoke ROMBIOS\n");
return 0;
/* Set up Virtual Wire mode. */
lapic_write(APIC_SPIV, APIC_SPIV_APIC_ENABLED | 0xFF);
lapic_write(APIC_LVT0, APIC_MODE_EXTINT << 8);
lapic_write(APIC_LVT1, APIC_MODE_NMI << 8);
}
static void pci_setup(void)
{
uint32_t devfn, bar_reg, bar_data, bar_sz, cmd;
uint32_t *base, io_base = 0xc000, mem_base = HVM_BELOW_4G_MMIO_START;
uint16_t class, vendor_id, device_id;
unsigned int bar, pin, link, isa_irq;
/* Program PCI-ISA bridge with appropriate link routes. */
link = 0;
for ( isa_irq = 0; isa_irq < 15; isa_irq++ )
{
if ( !(PCI_ISA_IRQ_MASK & (1U << isa_irq)) )
continue;
pci_writeb(PCI_ISA_DEVFN, 0x60 + link, isa_irq);
printf("PCI-ISA link %u routed to IRQ%u\n", link, isa_irq);
if ( link++ == 4 )
break;
}
/* Program ELCR to match PCI-wired IRQs. */
outb(0x4d0, (uint8_t)(PCI_ISA_IRQ_MASK >> 0));
outb(0x4d1, (uint8_t)(PCI_ISA_IRQ_MASK >> 8));
/* Scan the PCI bus and map resources. */
for ( devfn = 0; devfn < 128; devfn++ )
{
class = pci_readw(devfn, PCI_CLASS_DEVICE);
vendor_id = pci_readw(devfn, PCI_VENDOR_ID);
device_id = pci_readw(devfn, PCI_DEVICE_ID);
if ( (vendor_id == 0xffff) && (device_id == 0xffff) )
continue;
ASSERT((devfn != PCI_ISA_DEVFN) ||
((vendor_id == 0x8086) && (device_id == 0x7000)));
switch ( class )
{
case 0x0680:
ASSERT((vendor_id == 0x8086) && (device_id == 0x7113));
/*
* PIIX4 ACPI PM. Special device with special PCI config space.
* No ordinary BARs.
*/
pci_writew(devfn, 0x20, 0x0000); /* No smb bus IO enable */
pci_writew(devfn, 0x22, 0x0000);
pci_writew(devfn, 0x3c, 0x0009); /* Hardcoded IRQ9 */
pci_writew(devfn, 0x3d, 0x0001);
break;
case 0x0101:
/* PIIX3 IDE */
ASSERT((vendor_id == 0x8086) && (device_id == 0x7010));
pci_writew(devfn, 0x40, 0x8000); /* enable IDE0 */
pci_writew(devfn, 0x42, 0x8000); /* enable IDE1 */
/* fall through */
default:
/* Default memory mappings. */
for ( bar = 0; bar < 7; bar++ )
{
bar_reg = PCI_BASE_ADDRESS_0 + 4*bar;
if ( bar == 6 )
bar_reg = PCI_ROM_ADDRESS;
bar_data = pci_readl(devfn, bar_reg);
pci_writel(devfn, bar_reg, ~0);
bar_sz = pci_readl(devfn, bar_reg);
if ( bar_sz == 0 )
continue;
if ( (bar_data & PCI_BASE_ADDRESS_SPACE) ==
PCI_BASE_ADDRESS_SPACE_MEMORY )
{
base = &mem_base;
bar_sz &= PCI_BASE_ADDRESS_MEM_MASK;
bar_data &= ~PCI_BASE_ADDRESS_MEM_MASK;
}
else
{
base = &io_base;
bar_sz &= PCI_BASE_ADDRESS_IO_MASK & 0xffff;
bar_data &= ~PCI_BASE_ADDRESS_IO_MASK;
}
bar_sz &= ~(bar_sz - 1);
*base = (*base + bar_sz - 1) & ~(bar_sz - 1);
bar_data |= *base;
*base += bar_sz;
pci_writel(devfn, bar_reg, bar_data);
printf("pci dev %02x:%x bar %02x size %08x: %08x\n",
devfn>>3, devfn&7, bar_reg, bar_sz, bar_data);
/* Now enable the memory or I/O mapping. */
cmd = pci_readw(devfn, PCI_COMMAND);
if ( (bar_reg == PCI_ROM_ADDRESS) ||
((bar_data & PCI_BASE_ADDRESS_SPACE) ==
PCI_BASE_ADDRESS_SPACE_MEMORY) )
cmd |= PCI_COMMAND_MEMORY;
else
cmd |= PCI_COMMAND_IO;
pci_writew(devfn, PCI_COMMAND, cmd);
}
break;
}
/* Map the interrupt. */
pin = pci_readb(devfn, PCI_INTERRUPT_PIN);
if ( pin != 0 )
{
/* This is the barber's pole mapping used by Xen. */
link = ((pin - 1) + (devfn >> 3)) & 3;
isa_irq = pci_readb(PCI_ISA_DEVFN, 0x60 + link);
pci_writeb(devfn, PCI_INTERRUPT_LINE, isa_irq);
printf("pci dev %02x:%x INT%c->IRQ%u\n",
devfn>>3, devfn&7, 'A'+pin-1, isa_irq);
}
}
}
int main(void)
{
int acpi_sz;
uint8_t *freemem;
printf("HVM Loader\n");
init_hypercalls();
printf("Writing SMBIOS tables ...\n");
hvm_write_smbios_tables();
printf("Loading ROMBIOS ...\n");
memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, sizeof(rombios));
apic_setup();
pci_setup();
if ( (get_vcpu_nr() > 1) || get_apic_mode() )
create_mp_tables();
if ( cirrus_check() )
{
printf("Loading Cirrus VGABIOS ...\n");
memcpy((void *)VGABIOS_PHYSICAL_ADDRESS,
vgabios_cirrusvga, sizeof(vgabios_cirrusvga));
}
else
{
printf("Loading Standard VGABIOS ...\n");
memcpy((void *)VGABIOS_PHYSICAL_ADDRESS,
vgabios_stdvga, sizeof(vgabios_stdvga));
}
if ( get_acpi_enabled() != 0 )
{
printf("Loading ACPI ...\n");
acpi_sz = acpi_build_tables((uint8_t *)ACPI_PHYSICAL_ADDRESS);
freemem = (uint8_t *)ACPI_PHYSICAL_ADDRESS + acpi_sz;
ASSERT(freemem <= (uint8_t *)0xF0000);
acpi_update((unsigned char *)ACPI_PHYSICAL_ADDRESS,
freemem - (uint8_t *)ACPI_PHYSICAL_ADDRESS,
(unsigned char *)0xF0000,
&freemem);
}
if ( check_amd() )
{
/* AMD implies this is SVM */
printf("SVM go ...\n");
vmmcall(SVM_VMMCALL_RESET_TO_REALMODE, 0, 0, 0, 0, 0);
}
else
{
printf("Loading VMXAssist ...\n");
memcpy((void *)VMXASSIST_PHYSICAL_ADDRESS,
vmxassist, sizeof(vmxassist));
printf("VMX go ...\n");
__asm__ __volatile__(
"jmp *%%eax"
: : "a" (VMXASSIST_PHYSICAL_ADDRESS), "d" (0)
);
}
printf("Failed to invoke ROMBIOS\n");
return 0;
}
/*
* Local variables:
* mode: C
* c-set-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
+193 -228
View File
@@ -28,6 +28,8 @@
* Place - Suite 330, Boston, MA 02111-1307 USA.
*/
#include <acpi_utils.h>
#include "config.h"
/* FIXME find a header that already has types defined!!! */
typedef unsigned char uint8_t;
@@ -44,11 +46,11 @@ typedef unsigned long uint64_t;
typedef signed long int64_t;
#endif
#define ROMBIOS_SEG 0xF000
#define ROMBIOS_BEGIN 0x000F0000
#define ROMBIOS_SIZE 0x00010000
#define ROMBIOS_MAXOFFSET 0x0000FFFF
#define ROMBIOS_END (ROMBIOS_BEGIN + ROMBIOS_SIZE)
#define ROMBIOS_SEG 0xF000
#define ROMBIOS_BEGIN 0x000F0000
#define ROMBIOS_SIZE 0x00010000
#define ROMBIOS_MAXOFFSET 0x0000FFFF
#define ROMBIOS_END (ROMBIOS_BEGIN + ROMBIOS_SIZE)
/* number of non-processor MP table entries */
#define NR_NONPROC_ENTRIES 18
@@ -77,20 +79,13 @@ typedef signed long int64_t;
#define BUS_TYPE_LENGTH 6
#define BUS_TYPE_STR_ISA "ISA "
#define LAPIC_BASE_ADDR 0xFEE00000
#define IOAPIC_VERSION 0x11
#define IOAPIC_BASE_ADDR 0xFEC00000
#define IOAPIC_FLAG_ENABLED (1U << 0)
#define BUS_ID_ISA 0
#define INTR_TYPE_INT 0
#define INTR_TYPE_NMI 1
#define INTR_TYPE_SMI 2
#define INTR_TYPE_EXTINT 3
#define INTR_FLAGS 0
#define INTR_MAX_NR 16
#include "util.h"
@@ -103,232 +98,203 @@ extern int get_vcpu_nr(void); /* for the guest's VCPU count */
/* MP Floating Pointer Structure */
struct mp_floating_pointer_struct {
uint8_t signature[4];
uint32_t mp_table;
uint8_t length;
uint8_t revision;
uint8_t checksum;
uint8_t feature[5];
uint8_t signature[4];
uint32_t mp_table;
uint8_t length;
uint8_t revision;
uint8_t checksum;
uint8_t feature[5];
};
/* MP Configuration Table */
struct mp_config_table {
uint8_t signature[4];
uint16_t length;
uint8_t revision;
uint8_t checksum;
uint8_t oem_id[8];
uint8_t vendor_id[12];
uint32_t oem_table;
uint16_t oem_table_sz;
uint16_t nr_entries;
uint32_t lapic;
uint16_t extended_length;
uint8_t extended_checksum;
uint8_t reserved;
uint8_t signature[4];
uint16_t length;
uint8_t revision;
uint8_t checksum;
uint8_t oem_id[8];
uint8_t vendor_id[12];
uint32_t oem_table;
uint16_t oem_table_sz;
uint16_t nr_entries;
uint32_t lapic;
uint16_t extended_length;
uint8_t extended_checksum;
uint8_t reserved;
};
/* MP Processor Entry */
struct mp_proc_entry {
uint8_t type;
uint8_t lapic_id;
uint8_t lapic_version;
uint8_t cpu_flags;
uint32_t cpu_signature;
uint32_t feature_flags;
uint8_t reserved[8];
uint8_t type;
uint8_t lapic_id;
uint8_t lapic_version;
uint8_t cpu_flags;
uint32_t cpu_signature;
uint32_t feature_flags;
uint8_t reserved[8];
};
/* MP Bus Entry */
struct mp_bus_entry {
uint8_t type;
uint8_t bus_id;
uint8_t bus_type_str[6];
uint8_t type;
uint8_t bus_id;
uint8_t bus_type_str[6];
};
/* MP IOAPIC Entry */
struct mp_ioapic_entry {
uint8_t type;
uint8_t ioapic_id;
uint8_t ioapic_version;
uint8_t ioapic_flags;
uint32_t ioapic_addr;
uint8_t type;
uint8_t ioapic_id;
uint8_t ioapic_version;
uint8_t ioapic_flags;
uint32_t ioapic_addr;
};
/* MP IO Interrupt Entry */
struct mp_io_intr_entry {
uint8_t type;
uint8_t intr_type;
uint16_t io_intr_flags;
uint8_t src_bus_id;
uint8_t src_bus_irq;
uint8_t dst_ioapic_id;
uint8_t dst_ioapic_intin;
uint8_t type;
uint8_t intr_type;
uint16_t io_intr_flags;
uint8_t src_bus_id;
uint8_t src_bus_irq;
uint8_t dst_ioapic_id;
uint8_t dst_ioapic_intin;
};
/* MP Local Interrupt Entry */
struct mp_local_intr_entry {
uint8_t type;
uint8_t intr_type;
uint16_t local_intr_flags;
uint8_t src_bus_id;
uint8_t src_bus_irq;
uint8_t dst_lapic_id;
uint8_t dst_lapic_lintin;
uint8_t type;
uint8_t intr_type;
uint16_t local_intr_flags;
uint8_t src_bus_id;
uint8_t src_bus_irq;
uint8_t dst_lapic_id;
uint8_t dst_lapic_lintin;
};
/*
* fill_mp_config_table - fills in the information for the MP config table
*
* When calculating the length and nr_entries fields, keep in mind that there
* are always 18 non-processor entries and N processor entries
*
* N vcpu entries
* 1 bus entry
* 1 IOAPIC entry
* + 16 IO intr. entries
* ----------------------
* 18 + N total entries
*/
void fill_mp_config_table(struct mp_config_table *mpct)
void fill_mp_config_table(struct mp_config_table *mpct, int length)
{
int vcpu_nr;
int vcpu_nr, i;
uint8_t checksum;
vcpu_nr = get_vcpu_nr();
vcpu_nr = get_vcpu_nr();
/* fill in the MP configuration table signature, "PCMP" */
mpct->signature[0] = 'P';
mpct->signature[1] = 'C';
mpct->signature[2] = 'M';
mpct->signature[3] = 'P';
/* fill in the MP configuration table signature, "PCMP" */
mpct->signature[0] = 'P';
mpct->signature[1] = 'C';
mpct->signature[2] = 'M';
mpct->signature[3] = 'P';
mpct->length = sizeof(struct mp_config_table)
+ vcpu_nr * sizeof(struct mp_proc_entry)
+ sizeof(struct mp_ioapic_entry)
+ sizeof(struct mp_bus_entry)
+ 16 * sizeof(struct mp_local_intr_entry);
mpct->length = length;
mpct->revision = 4;
mpct->revision = 4;
/*
* We'll fill in the checksum later after all of the
* entries have been created
*/
mpct->checksum = 0;
/* fill in the OEM ID string, "_HVMCPU_" */
mpct->oem_id[0] = '_'; mpct->oem_id[3] = 'M'; mpct->oem_id[6] = 'U';
mpct->oem_id[1] = 'H'; mpct->oem_id[4] = 'C'; mpct->oem_id[7] = '_';
mpct->oem_id[2] = 'V'; mpct->oem_id[5] = 'P';
/* fill in the OEM ID string, "_HVMCPU_" */
mpct->oem_id[0] = '_'; mpct->oem_id[3] = 'M'; mpct->oem_id[6] = 'U';
mpct->oem_id[1] = 'H'; mpct->oem_id[4] = 'C'; mpct->oem_id[7] = '_';
mpct->oem_id[2] = 'V'; mpct->oem_id[5] = 'P';
/* fill in the Vendor ID string, "XEN " */
mpct->vendor_id[0] = 'X'; mpct->vendor_id[6] = ' ';
mpct->vendor_id[1] = 'E'; mpct->vendor_id[7] = ' ';
mpct->vendor_id[2] = 'N'; mpct->vendor_id[8] = ' ';
mpct->vendor_id[3] = ' '; mpct->vendor_id[9] = ' ';
mpct->vendor_id[4] = ' '; mpct->vendor_id[10] = ' ';
mpct->vendor_id[5] = ' '; mpct->vendor_id[11] = ' ';
/* fill in the Vendor ID string, "XEN " */
mpct->vendor_id[0] = 'X'; mpct->vendor_id[6] = ' ';
mpct->vendor_id[1] = 'E'; mpct->vendor_id[7] = ' ';
mpct->vendor_id[2] = 'N'; mpct->vendor_id[8] = ' ';
mpct->vendor_id[3] = ' '; mpct->vendor_id[9] = ' ';
mpct->vendor_id[4] = ' '; mpct->vendor_id[10] = ' ';
mpct->vendor_id[5] = ' '; mpct->vendor_id[11] = ' ';
mpct->oem_table = 0;
mpct->oem_table_sz = 0;
mpct->oem_table = 0;
mpct->oem_table_sz = 0;
mpct->nr_entries = vcpu_nr + NR_NONPROC_ENTRIES;
mpct->nr_entries = vcpu_nr + NR_NONPROC_ENTRIES;
mpct->lapic = LAPIC_BASE_ADDRESS;
mpct->extended_length = 0;
mpct->extended_checksum = 0;
mpct->lapic = LAPIC_BASE_ADDR;
mpct->extended_length = 0;
mpct->extended_checksum = 0;
/* Finally, fill in the checksum. */
mpct->checksum = checksum = 0;
for ( i = 0; i < length; i++ )
checksum += ((uint8_t *)(mpct))[i];
mpct->checksum = -checksum;
}
/* calculates the checksum for the MP configuration table */
void fill_mp_config_table_checksum(struct mp_config_table *mpct)
{
int i;
uint8_t checksum;
checksum = 0;
for (i = 0; i < mpct->length; ++i)
checksum += ((uint8_t *)(mpct))[i];
mpct->checksum = -checksum;
}
/* fills in an MP processor entry for VCPU 'vcpu_id' */
void fill_mp_proc_entry(struct mp_proc_entry *mppe, int vcpu_id)
{
mppe->type = ENTRY_TYPE_PROCESSOR;
mppe->lapic_id = vcpu_id;
mppe->lapic_version = 0x11;
mppe->cpu_flags = CPU_FLAG_ENABLED;
if (vcpu_id == 0)
mppe->cpu_flags |= CPU_FLAG_BSP;
mppe->cpu_signature = CPU_SIGNATURE;
mppe->feature_flags = CPU_FEATURES;
mppe->type = ENTRY_TYPE_PROCESSOR;
mppe->lapic_id = vcpu_id + 1;
mppe->lapic_version = 0x11;
mppe->cpu_flags = CPU_FLAG_ENABLED;
if ( vcpu_id == 0 )
mppe->cpu_flags |= CPU_FLAG_BSP;
mppe->cpu_signature = CPU_SIGNATURE;
mppe->feature_flags = CPU_FEATURES;
}
/* fills in an MP bus entry of type 'type' and bus ID 'bus_id' */
void fill_mp_bus_entry(struct mp_bus_entry *mpbe, int bus_id, const char *type)
{
int i;
int i;
mpbe->type = ENTRY_TYPE_BUS;
mpbe->bus_id = bus_id;
for (i = 0; i < BUS_TYPE_LENGTH; ++i)
mpbe->bus_type_str[i] = type[i]; /* FIXME length check? */
mpbe->type = ENTRY_TYPE_BUS;
mpbe->bus_id = bus_id;
for ( i = 0; i < BUS_TYPE_LENGTH; i++ )
mpbe->bus_type_str[i] = type[i]; /* FIXME length check? */
}
/* fills in an MP IOAPIC entry for IOAPIC 'ioapic_id' */
void fill_mp_ioapic_entry(struct mp_ioapic_entry *mpie, int ioapic_id)
void fill_mp_ioapic_entry(struct mp_ioapic_entry *mpie)
{
mpie->type = ENTRY_TYPE_IOAPIC;
mpie->ioapic_id = ioapic_id;
mpie->ioapic_version = IOAPIC_VERSION;
mpie->ioapic_flags = IOAPIC_FLAG_ENABLED;
mpie->ioapic_addr = IOAPIC_BASE_ADDR;
mpie->type = ENTRY_TYPE_IOAPIC;
mpie->ioapic_id = IOAPIC_ID;
mpie->ioapic_version = IOAPIC_VERSION;
mpie->ioapic_flags = 1; /* enabled */
mpie->ioapic_addr = IOAPIC_BASE_ADDRESS;
}
/* fills in an IO interrupt entry for IOAPIC 'ioapic_id' */
void fill_mp_io_intr_entry(struct mp_io_intr_entry *mpiie,
int src_bus_irq, int ioapic_id, int dst_ioapic_intin)
void fill_mp_io_intr_entry(
struct mp_io_intr_entry *mpiie,
int src_bus_id, int src_bus_irq, int ioapic_id, int dst_ioapic_intin)
{
mpiie->type = ENTRY_TYPE_IO_INTR;
mpiie->intr_type = INTR_TYPE_INT;
mpiie->io_intr_flags = INTR_FLAGS;
mpiie->src_bus_id = 0;
mpiie->src_bus_irq = src_bus_irq;
mpiie->dst_ioapic_id = ioapic_id;
mpiie->dst_ioapic_intin = dst_ioapic_intin;
mpiie->type = ENTRY_TYPE_IO_INTR;
mpiie->intr_type = INTR_TYPE_INT;
mpiie->io_intr_flags = (PCI_ISA_IRQ_MASK & (1U<<src_bus_irq)) ? 0xf : 0x0;
mpiie->src_bus_id = src_bus_id;
mpiie->src_bus_irq = src_bus_irq;
mpiie->dst_ioapic_id = ioapic_id;
mpiie->dst_ioapic_intin = dst_ioapic_intin;
}
/* fill in the mp floating processor structure */
void fill_mpfps(struct mp_floating_pointer_struct *mpfps, uint32_t mpct)
{
int i;
uint8_t checksum;
int i;
uint8_t checksum;
mpfps->signature[0] = '_';
mpfps->signature[1] = 'M';
mpfps->signature[2] = 'P';
mpfps->signature[3] = '_';
mpfps->signature[0] = '_';
mpfps->signature[1] = 'M';
mpfps->signature[2] = 'P';
mpfps->signature[3] = '_';
mpfps->mp_table = mpct;
mpfps->length = 1;
mpfps->revision = 4;
mpfps->checksum = 0;
for (i = 0; i < 5; ++i)
mpfps->feature[i] = 0;
mpfps->mp_table = mpct;
mpfps->length = 1;
mpfps->revision = 4;
mpfps->checksum = 0;
for (i = 0; i < 5; ++i)
mpfps->feature[i] = 0;
/* compute the checksum for our new table */
checksum = 0;
for (i = 0; i < sizeof(struct mp_floating_pointer_struct); ++i)
checksum += ((uint8_t *)(mpfps))[i];
mpfps->checksum = -checksum;
/* compute the checksum for our new table */
checksum = 0;
for ( i = 0; i < sizeof(struct mp_floating_pointer_struct); i++ )
checksum += ((uint8_t *)(mpfps))[i];
mpfps->checksum = -checksum;
}
@@ -340,88 +306,87 @@ void fill_mpfps(struct mp_floating_pointer_struct *mpfps, uint32_t mpct)
*/
void* get_mp_table_start(void)
{
char *bios_mem;
for (bios_mem = (char *)ROMBIOS_BEGIN;
bios_mem != (char *)ROMBIOS_END;
++bios_mem)
if (bios_mem[0] == '_' && bios_mem[1] == '_' &&
bios_mem[2] == '_' && bios_mem[3] == 'H' &&
bios_mem[4] == 'V' && bios_mem[5] == 'M' &&
bios_mem[6] == 'M' && bios_mem[7] == 'P')
return bios_mem;
char *bios_mem;
return (void *)-1;
for ( bios_mem = (char *)ROMBIOS_BEGIN;
bios_mem != (char *)ROMBIOS_END;
bios_mem++ )
{
if ( bios_mem[0] == '_' && bios_mem[1] == '_' &&
bios_mem[2] == '_' && bios_mem[3] == 'H' &&
bios_mem[4] == 'V' && bios_mem[5] == 'M' &&
bios_mem[6] == 'M' && bios_mem[7] == 'P' )
return bios_mem;
}
return NULL;
}
/* recalculate the new ROMBIOS checksum after adding MP tables */
void reset_bios_checksum(void)
{
uint32_t i;
uint8_t checksum;
uint32_t i;
uint8_t checksum;
checksum = 0;
for (i = 0; i < ROMBIOS_MAXOFFSET; ++i)
checksum += ((uint8_t *)(ROMBIOS_BEGIN))[i];
*((uint8_t *)(ROMBIOS_BEGIN + ROMBIOS_MAXOFFSET)) = -checksum;
checksum = 0;
for (i = 0; i < ROMBIOS_MAXOFFSET; ++i)
checksum += ((uint8_t *)(ROMBIOS_BEGIN))[i];
*((uint8_t *)(ROMBIOS_BEGIN + ROMBIOS_MAXOFFSET)) = -checksum;
}
/* create_mp_tables - creates MP tables for the guest based upon config data */
void create_mp_tables(void)
{
void *mp_table_base;
char *p;
struct mp_config_table *mp_config_table;
int vcpu_nr;
int i;
void *mp_table_base;
char *p;
int vcpu_nr, i, length;
vcpu_nr = get_vcpu_nr();
puts("Creating MP tables ...\n");
vcpu_nr = get_vcpu_nr();
/* find the 'safe' place in ROMBIOS for the MP tables */
mp_table_base = get_mp_table_start();
if (mp_table_base == (void *)-1) {
puts("Couldn't find start point for MP tables\n");
return;
}
p = mp_table_base;
printf("Creating MP tables ...\n");
fill_mp_config_table((struct mp_config_table *)p);
/* Find the 'safe' place in ROMBIOS for the MP tables. */
mp_table_base = get_mp_table_start();
if ( mp_table_base == NULL )
{
printf("Couldn't find start point for MP tables\n");
return;
}
/* save the location of the MP config table for a little later*/
mp_config_table = (struct mp_config_table *)p;
p += sizeof(struct mp_config_table);
p = mp_table_base + sizeof(struct mp_config_table);
for (i = 0; i < vcpu_nr; ++i) {
fill_mp_proc_entry((struct mp_proc_entry *)p, i);
p += sizeof(struct mp_proc_entry);
}
for ( i = 0; i < vcpu_nr; i++ )
{
fill_mp_proc_entry((struct mp_proc_entry *)p, i);
p += sizeof(struct mp_proc_entry);
}
fill_mp_bus_entry((struct mp_bus_entry *)p, 0, BUS_TYPE_STR_ISA);
p += sizeof(struct mp_bus_entry);
fill_mp_bus_entry((struct mp_bus_entry *)p, BUS_ID_ISA, BUS_TYPE_STR_ISA);
p += sizeof(struct mp_bus_entry);
fill_mp_ioapic_entry((struct mp_ioapic_entry *)p, vcpu_nr);
p += sizeof(struct mp_ioapic_entry);
fill_mp_ioapic_entry((struct mp_ioapic_entry *)p);
p += sizeof(struct mp_ioapic_entry);
for (i = 0; i < INTR_MAX_NR; ++i) {
fill_mp_io_intr_entry((struct mp_io_intr_entry *)p,
i, vcpu_nr, i);
p += sizeof(struct mp_io_intr_entry);
}
for ( i = 0; i < 16; i++ )
{
if ( i == 2 ) continue; /* skip the slave PIC connection */
fill_mp_io_intr_entry((struct mp_io_intr_entry *)p,
BUS_ID_ISA, i, IOAPIC_ID, i);
p += sizeof(struct mp_io_intr_entry);
}
/* find the next 16-byte boundary to place the mp floating pointer */
while ((unsigned long)p & 0xF)
++p;
fill_mpfps((struct mp_floating_pointer_struct *)p,
(uint32_t)mp_table_base);
length = p - (char *)mp_table_base;
/* calculate the MP configuration table's checksum */
fill_mp_config_table_checksum(mp_config_table);
/* find the next 16-byte boundary to place the mp floating pointer */
while ( (unsigned long)p & 0xF )
p++;
/* finally, recalculate the ROMBIOS checksum */
reset_bios_checksum();
fill_mpfps((struct mp_floating_pointer_struct *)p,
(uint32_t)mp_table_base);
fill_mp_config_table((struct mp_config_table *)mp_table_base, length);
reset_bios_checksum();
}
+108
View File
@@ -0,0 +1,108 @@
/*
* pci_regs.h
*
* PCI standard defines
* Copyright 1994, Drew Eckhardt
* Copyright 1997--1999 Martin Mares <mj@ucw.cz>
*
* For more information, please consult the following manuals (look at
* http://www.pcisig.com/ for how to get them):
*
* PCI BIOS Specification
* PCI Local Bus Specification
* PCI to PCI Bridge Specification
* PCI System Design Guide
*/
#ifndef __HVMLOADER_PCI_REGS_H__
#define __HVMLOADER_PCI_REGS_H__
#define PCI_VENDOR_ID 0x00 /* 16 bits */
#define PCI_DEVICE_ID 0x02 /* 16 bits */
#define PCI_COMMAND 0x04 /* 16 bits */
#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
#define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */
#define PCI_COMMAND_SPECIAL 0x8 /* Enable response to special cycles */
#define PCI_COMMAND_INVALIDATE 0x10 /* Use memory write and invalidate */
#define PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */
#define PCI_COMMAND_PARITY 0x40 /* Enable parity checking */
#define PCI_COMMAND_WAIT 0x80 /* Enable address/data stepping */
#define PCI_COMMAND_SERR 0x100 /* Enable SERR */
#define PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */
#define PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */
#define PCI_STATUS 0x06 /* 16 bits */
#define PCI_STATUS_CAP_LIST 0x10 /* Support Capability List */
#define PCI_STATUS_66MHZ 0x20 /* Support 66 Mhz PCI 2.1 bus */
#define PCI_STATUS_UDF 0x40 /* Support User Definable Features [obsolete] */
#define PCI_STATUS_FAST_BACK 0x80 /* Accept fast-back to back */
#define PCI_STATUS_PARITY 0x100 /* Detected parity error */
#define PCI_STATUS_DEVSEL_MASK 0x600 /* DEVSEL timing */
#define PCI_STATUS_DEVSEL_FAST 0x000
#define PCI_STATUS_DEVSEL_MEDIUM 0x200
#define PCI_STATUS_DEVSEL_SLOW 0x400
#define PCI_STATUS_SIG_TARGET_ABORT 0x800 /* Set on target abort */
#define PCI_STATUS_REC_TARGET_ABORT 0x1000 /* Master ack of " */
#define PCI_STATUS_REC_MASTER_ABORT 0x2000 /* Set on master abort */
#define PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 /* Set when we drive SERR */
#define PCI_STATUS_DETECTED_PARITY 0x8000 /* Set on parity error */
#define PCI_CLASS_REVISION 0x08 /* High 24 bits are class, low 8 revision */
#define PCI_REVISION_ID 0x08 /* Revision ID */
#define PCI_CLASS_PROG 0x09 /* Reg. Level Programming Interface */
#define PCI_CLASS_DEVICE 0x0a /* Device class */
#define PCI_CACHE_LINE_SIZE 0x0c /* 8 bits */
#define PCI_LATENCY_TIMER 0x0d /* 8 bits */
#define PCI_HEADER_TYPE 0x0e /* 8 bits */
#define PCI_HEADER_TYPE_NORMAL 0
#define PCI_HEADER_TYPE_BRIDGE 1
#define PCI_HEADER_TYPE_CARDBUS 2
#define PCI_BIST 0x0f /* 8 bits */
#define PCI_BIST_CODE_MASK 0x0f /* Return result */
#define PCI_BIST_START 0x40 /* 1 to start BIST, 2 secs or less */
#define PCI_BIST_CAPABLE 0x80 /* 1 if BIST capable */
/*
* Base addresses specify locations in memory or I/O space.
* Decoded size can be determined by writing a value of
* 0xffffffff to the register, and reading it back. Only
* 1 bits are decoded.
*/
#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */
#define PCI_BASE_ADDRESS_1 0x14 /* 32 bits [htype 0,1 only] */
#define PCI_BASE_ADDRESS_2 0x18 /* 32 bits [htype 0 only] */
#define PCI_BASE_ADDRESS_3 0x1c /* 32 bits */
#define PCI_BASE_ADDRESS_4 0x20 /* 32 bits */
#define PCI_BASE_ADDRESS_5 0x24 /* 32 bits */
#define PCI_BASE_ADDRESS_SPACE 0x01 /* 0 = memory, 1 = I/O */
#define PCI_BASE_ADDRESS_SPACE_IO 0x01
#define PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
#define PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06
#define PCI_BASE_ADDRESS_MEM_TYPE_32 0x00 /* 32 bit address */
#define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 /* Below 1M [obsolete] */
#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */
#define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */
#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL)
#define PCI_BASE_ADDRESS_IO_MASK (~0x03UL)
/* bit 1 is reserved if address_space = 1 */
/* Header type 0 (normal devices) */
#define PCI_CARDBUS_CIS 0x28
#define PCI_SUBSYSTEM_VENDOR_ID 0x2c
#define PCI_SUBSYSTEM_ID 0x2e
#define PCI_ROM_ADDRESS 0x30 /* Bits 31..11 are address, 10..1 reserved */
#define PCI_ROM_ADDRESS_ENABLE 0x01
#define PCI_ROM_ADDRESS_MASK (~0x7ffUL)
#define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */
/* 0x35-0x3b are reserved */
#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */
#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
#define PCI_MIN_GNT 0x3e /* 8 bits */
#define PCI_MAX_LAT 0x3f /* 8 bits */
#endif /* __HVMLOADER_PCI_REGS_H__ */
+347 -336
View File
@@ -30,29 +30,29 @@
static size_t
write_smbios_tables(void *start,
uint32_t vcpus, uint64_t memsize,
uint8_t uuid[16], char *xen_version,
uint32_t xen_major_version, uint32_t xen_minor_version);
uint32_t vcpus, uint64_t memsize,
uint8_t uuid[16], char *xen_version,
uint32_t xen_major_version, uint32_t xen_minor_version);
static void
get_cpu_manufacturer(char *buf, int len);
static void
smbios_entry_point_init(void *start,
uint16_t max_structure_size,
uint16_t structure_table_length,
uint32_t structure_table_address,
uint16_t number_of_structures);
uint16_t max_structure_size,
uint16_t structure_table_length,
uint32_t structure_table_address,
uint16_t number_of_structures);
static void *
smbios_type_0_init(void *start, const char *xen_version,
uint32_t xen_major_version, uint32_t xen_minor_version);
uint32_t xen_major_version, uint32_t xen_minor_version);
static void *
smbios_type_1_init(void *start, const char *xen_version,
uint8_t uuid[16]);
uint8_t uuid[16]);
static void *
smbios_type_3_init(void *start);
static void *
smbios_type_4_init(void *start, unsigned int cpu_number,
char *cpu_manufacturer);
char *cpu_manufacturer);
static void *
smbios_type_16_init(void *start, uint32_t memory_size_mb);
static void *
@@ -69,64 +69,64 @@ smbios_type_127_init(void *start);
static void
get_cpu_manufacturer(char *buf, int len)
{
char id[12];
uint32_t eax = 0;
char id[12];
uint32_t eax = 0;
cpuid(0, &eax, (uint32_t *)&id[0], (uint32_t *)&id[8],
(uint32_t *)&id[4]);
cpuid(0, &eax, (uint32_t *)&id[0], (uint32_t *)&id[8],
(uint32_t *)&id[4]);
if (memcmp(id, "GenuineIntel", 12) == 0)
strncpy(buf, "Intel", len);
else if (memcmp(id, "AuthenticAMD", 12) == 0)
strncpy(buf, "AMD", len);
else
strncpy(buf, "unknown", len);
if (memcmp(id, "GenuineIntel", 12) == 0)
strncpy(buf, "Intel", len);
else if (memcmp(id, "AuthenticAMD", 12) == 0)
strncpy(buf, "AMD", len);
else
strncpy(buf, "unknown", len);
}
static size_t
write_smbios_tables(void *start,
uint32_t vcpus, uint64_t memsize,
uint8_t uuid[16], char *xen_version,
uint32_t xen_major_version, uint32_t xen_minor_version)
uint32_t vcpus, uint64_t memsize,
uint8_t uuid[16], char *xen_version,
uint32_t xen_major_version, uint32_t xen_minor_version)
{
unsigned cpu_num, nr_structs = 0, max_struct_size = 0;
char *p, *q;
char cpu_manufacturer[15];
unsigned cpu_num, nr_structs = 0, max_struct_size = 0;
char *p, *q;
char cpu_manufacturer[15];
get_cpu_manufacturer(cpu_manufacturer, 15);
get_cpu_manufacturer(cpu_manufacturer, 15);
p = (char *)start + sizeof(struct smbios_entry_point);
p = (char *)start + sizeof(struct smbios_entry_point);
#define do_struct(fn) do { \
q = (fn); \
nr_structs++; \
if ((q - p) > max_struct_size) \
max_struct_size = q - p; \
p = q; \
#define do_struct(fn) do { \
q = (fn); \
nr_structs++; \
if ( (q - p) > max_struct_size ) \
max_struct_size = q - p; \
p = q; \
} while (0)
do_struct(smbios_type_0_init(p, xen_version, xen_major_version,
xen_minor_version));
do_struct(smbios_type_1_init(p, xen_version, uuid));
do_struct(smbios_type_3_init(p));
for (cpu_num = 1; cpu_num <= vcpus; cpu_num++)
do_struct(smbios_type_4_init(p, cpu_num, cpu_manufacturer));
do_struct(smbios_type_16_init(p, memsize));
do_struct(smbios_type_17_init(p, memsize));
do_struct(smbios_type_19_init(p, memsize));
do_struct(smbios_type_20_init(p, memsize));
do_struct(smbios_type_32_init(p));
do_struct(smbios_type_127_init(p));
do_struct(smbios_type_0_init(p, xen_version, xen_major_version,
xen_minor_version));
do_struct(smbios_type_1_init(p, xen_version, uuid));
do_struct(smbios_type_3_init(p));
for ( cpu_num = 1; cpu_num <= vcpus; cpu_num++ )
do_struct(smbios_type_4_init(p, cpu_num, cpu_manufacturer));
do_struct(smbios_type_16_init(p, memsize));
do_struct(smbios_type_17_init(p, memsize));
do_struct(smbios_type_19_init(p, memsize));
do_struct(smbios_type_20_init(p, memsize));
do_struct(smbios_type_32_init(p));
do_struct(smbios_type_127_init(p));
#undef do_struct
smbios_entry_point_init(
start, max_struct_size,
(p - (char *)start) - sizeof(struct smbios_entry_point),
SMBIOS_PHYSICAL_ADDRESS + sizeof(struct smbios_entry_point),
nr_structs);
smbios_entry_point_init(
start, max_struct_size,
(p - (char *)start) - sizeof(struct smbios_entry_point),
SMBIOS_PHYSICAL_ADDRESS + sizeof(struct smbios_entry_point),
nr_structs);
return (size_t)((char *)p - (char *)start);
return (size_t)((char *)p - (char *)start);
}
/* This tries to figure out how much pseudo-physical memory (in MB)
@@ -142,428 +142,439 @@ write_smbios_tables(void *start,
static uint64_t
get_memsize(void)
{
struct e820entry *map = NULL;
uint8_t num_entries = 0;
uint64_t memsize = 0;
uint8_t i;
struct e820entry *map = NULL;
uint8_t num_entries = 0;
uint64_t memsize = 0;
uint8_t i;
map = (struct e820entry *) (E820_MAP_PAGE + E820_MAP_OFFSET);
num_entries = *((uint8_t *) (E820_MAP_PAGE + E820_MAP_NR_OFFSET));
map = (struct e820entry *) (E820_MAP_PAGE + E820_MAP_OFFSET);
num_entries = *((uint8_t *) (E820_MAP_PAGE + E820_MAP_NR_OFFSET));
/* walk through e820map, ignoring any entries that aren't marked
as usable or reserved. */
/* walk through e820map, ignoring any entries that aren't marked
as usable or reserved. */
for (i = 0; i < num_entries; i++) {
if (map->type == E820_RAM || map->type == E820_RESERVED)
memsize += map->size;
map++;
}
for ( i = 0; i < num_entries; i++ )
{
if (map->type == E820_RAM || map->type == E820_RESERVED)
memsize += map->size;
map++;
}
/* Round up to the nearest MB. The user specifies domU
pseudo-physical memory in megabytes, so not doing this
could easily lead to reporting one less MB than the user
specified. */
if (memsize & ((1<<20)-1))
memsize = (memsize >> 20) + 1;
else
memsize = (memsize >> 20);
/* Round up to the nearest MB. The user specifies domU
pseudo-physical memory in megabytes, so not doing this
could easily lead to reporting one less MB than the user
specified. */
if ( memsize & ((1<<20)-1) )
memsize = (memsize >> 20) + 1;
else
memsize = (memsize >> 20);
return memsize;
return memsize;
}
void
hvm_write_smbios_tables(void)
{
uint8_t uuid[16]; /* ** This will break if xen_domain_handle_t is
not uint8_t[16]. ** */
uint16_t xen_major_version, xen_minor_version;
uint32_t xen_version;
char xen_extra_version[XEN_EXTRAVERSION_LEN];
/* guess conservatively on buffer length for Xen version string */
char xen_version_str[80];
/* temporary variables used to build up Xen version string */
char *p = NULL; /* points to next point of insertion */
unsigned len = 0; /* length of string already composed */
char *tmp = NULL; /* holds result of itoa() */
unsigned tmp_len; /* length of next string to add */
uint8_t uuid[16]; /* ** This will break if xen_domain_handle_t is
not uint8_t[16]. ** */
uint16_t xen_major_version, xen_minor_version;
uint32_t xen_version;
char xen_extra_version[XEN_EXTRAVERSION_LEN];
/* guess conservatively on buffer length for Xen version string */
char xen_version_str[80];
/* temporary variables used to build up Xen version string */
char *p = NULL; /* points to next point of insertion */
unsigned len = 0; /* length of string already composed */
char *tmp = NULL; /* holds result of itoa() */
unsigned tmp_len; /* length of next string to add */
hypercall_xen_version(XENVER_guest_handle, uuid);
hypercall_xen_version(XENVER_guest_handle, uuid);
/* xen_version major and minor */
xen_version = hypercall_xen_version(XENVER_version, NULL);
xen_major_version = (uint16_t) (xen_version >> 16);
xen_minor_version = (uint16_t) xen_version;
/* xen_version major and minor */
xen_version = hypercall_xen_version(XENVER_version, NULL);
xen_major_version = (uint16_t) (xen_version >> 16);
xen_minor_version = (uint16_t) xen_version;
hypercall_xen_version(XENVER_extraversion, xen_extra_version);
hypercall_xen_version(XENVER_extraversion, xen_extra_version);
/* build up human-readable Xen version string */
p = xen_version_str;
len = 0;
/* build up human-readable Xen version string */
p = xen_version_str;
len = 0;
itoa(tmp, xen_major_version);
tmp_len = strlen(tmp);
len += tmp_len;
if (len >= sizeof(xen_version_str))
goto error_out;
strcpy(p, tmp);
p += tmp_len;
itoa(tmp, xen_major_version);
tmp_len = strlen(tmp);
len += tmp_len;
if ( len >= sizeof(xen_version_str) )
goto error_out;
strcpy(p, tmp);
p += tmp_len;
len++;
if (len >= sizeof(xen_version_str))
goto error_out;
*p = '.';
p++;
len++;
if ( len >= sizeof(xen_version_str) )
goto error_out;
*p = '.';
p++;
itoa(tmp, xen_minor_version);
tmp_len = strlen(tmp);
len += tmp_len;
if (len >= sizeof(xen_version_str))
goto error_out;
strcpy(p, tmp);
p += tmp_len;
itoa(tmp, xen_minor_version);
tmp_len = strlen(tmp);
len += tmp_len;
if ( len >= sizeof(xen_version_str) )
goto error_out;
strcpy(p, tmp);
p += tmp_len;
tmp_len = strlen(xen_extra_version);
len += tmp_len;
if (len >= sizeof(xen_version_str))
goto error_out;
strcpy(p, xen_extra_version);
p += tmp_len;
tmp_len = strlen(xen_extra_version);
len += tmp_len;
if ( len >= sizeof(xen_version_str) )
goto error_out;
strcpy(p, xen_extra_version);
p += tmp_len;
xen_version_str[sizeof(xen_version_str)-1] = '\0';
xen_version_str[sizeof(xen_version_str)-1] = '\0';
/* NB. 0xC0000 is a safe large memory area for scratch. */
len = write_smbios_tables((void *)0xC0000,
get_vcpu_nr(), get_memsize(),
uuid, xen_version_str,
xen_major_version, xen_minor_version);
if (len > SMBIOS_SIZE_LIMIT)
goto error_out;
/* Okay, not too large: copy out of scratch to final location. */
memcpy((void *)SMBIOS_PHYSICAL_ADDRESS, (void *)0xC0000, len);
/* NB. 0xC0000 is a safe large memory area for scratch. */
len = write_smbios_tables((void *)0xC0000,
get_vcpu_nr(), get_memsize(),
uuid, xen_version_str,
xen_major_version, xen_minor_version);
if ( len > SMBIOS_SIZE_LIMIT )
goto error_out;
/* Okay, not too large: copy out of scratch to final location. */
memcpy((void *)SMBIOS_PHYSICAL_ADDRESS, (void *)0xC0000, len);
return;
return;
error_out:
puts("Could not write SMBIOS tables, error in hvmloader.c:"
"hvm_write_smbios_tables()\n");
printf("Could not write SMBIOS tables, error in hvmloader.c:"
"hvm_write_smbios_tables()\n");
}
static void
smbios_entry_point_init(void *start,
uint16_t max_structure_size,
uint16_t structure_table_length,
uint32_t structure_table_address,
uint16_t number_of_structures)
uint16_t max_structure_size,
uint16_t structure_table_length,
uint32_t structure_table_address,
uint16_t number_of_structures)
{
uint8_t sum;
int i;
struct smbios_entry_point *ep = (struct smbios_entry_point *)start;
uint8_t sum;
int i;
struct smbios_entry_point *ep = (struct smbios_entry_point *)start;
strncpy(ep->anchor_string, "_SM_", 4);
ep->length = 0x1f;
ep->smbios_major_version = 2;
ep->smbios_minor_version = 4;
ep->max_structure_size = max_structure_size;
ep->entry_point_revision = 0;
memset(ep->formatted_area, 0, 5);
strncpy(ep->intermediate_anchor_string, "_DMI_", 5);
strncpy(ep->anchor_string, "_SM_", 4);
ep->length = 0x1f;
ep->smbios_major_version = 2;
ep->smbios_minor_version = 4;
ep->max_structure_size = max_structure_size;
ep->entry_point_revision = 0;
memset(ep->formatted_area, 0, 5);
strncpy(ep->intermediate_anchor_string, "_DMI_", 5);
ep->structure_table_length = structure_table_length;
ep->structure_table_address = structure_table_address;
ep->number_of_structures = number_of_structures;
ep->smbios_bcd_revision = 0x24;
ep->structure_table_length = structure_table_length;
ep->structure_table_address = structure_table_address;
ep->number_of_structures = number_of_structures;
ep->smbios_bcd_revision = 0x24;
ep->checksum = 0;
ep->intermediate_checksum = 0;
ep->checksum = 0;
ep->intermediate_checksum = 0;
sum = 0;
for (i = 0; i < 0x10; ++i)
sum += ((int8_t *)start)[i];
ep->checksum = -sum;
sum = 0;
for ( i = 0; i < 0x10; i++ )
sum += ((int8_t *)start)[i];
ep->checksum = -sum;
sum = 0;
for (i = 0x10; i < ep->length; ++i)
sum += ((int8_t *)start)[i];
ep->intermediate_checksum = -sum;
sum = 0;
for ( i = 0x10; i < ep->length; i++ )
sum += ((int8_t *)start)[i];
ep->intermediate_checksum = -sum;
}
/* Type 0 -- BIOS Information */
static void *
smbios_type_0_init(void *start, const char *xen_version,
uint32_t xen_major_version, uint32_t xen_minor_version)
uint32_t xen_major_version, uint32_t xen_minor_version)
{
struct smbios_type_0 *p = (struct smbios_type_0 *)start;
struct smbios_type_0 *p = (struct smbios_type_0 *)start;
p->header.type = 0;
p->header.length = sizeof(struct smbios_type_0);
p->header.handle = 0;
p->header.type = 0;
p->header.length = sizeof(struct smbios_type_0);
p->header.handle = 0;
p->vendor_str = 1;
p->version_str = 2;
p->starting_address_segment = 0xe800;
p->release_date_str = 0;
p->rom_size = 0;
p->vendor_str = 1;
p->version_str = 2;
p->starting_address_segment = 0xe800;
p->release_date_str = 0;
p->rom_size = 0;
memset(p->characteristics, 0, 8);
p->characteristics[7] = 0x08; /* BIOS characteristics not supported */
p->characteristics_extension_bytes[0] = 0;
p->characteristics_extension_bytes[1] = 0;
memset(p->characteristics, 0, 8);
p->characteristics[7] = 0x08; /* BIOS characteristics not supported */
p->characteristics_extension_bytes[0] = 0;
p->characteristics_extension_bytes[1] = 0;
p->major_release = (uint8_t) xen_major_version;
p->minor_release = (uint8_t) xen_minor_version;
p->embedded_controller_major = 0xff;
p->embedded_controller_minor = 0xff;
p->major_release = (uint8_t) xen_major_version;
p->minor_release = (uint8_t) xen_minor_version;
p->embedded_controller_major = 0xff;
p->embedded_controller_minor = 0xff;
start += sizeof(struct smbios_type_0);
strcpy((char *)start, "Xen");
start += strlen("Xen") + 1;
strcpy((char *)start, xen_version);
start += strlen(xen_version) + 1;
start += sizeof(struct smbios_type_0);
strcpy((char *)start, "Xen");
start += strlen("Xen") + 1;
strcpy((char *)start, xen_version);
start += strlen(xen_version) + 1;
*((uint8_t *)start) = 0;
return start + 1;
*((uint8_t *)start) = 0;
return start + 1;
}
/* Type 1 -- System Information */
static void *
smbios_type_1_init(void *start, const char *xen_version,
uint8_t uuid[16])
uint8_t uuid[16])
{
char uuid_str[37];
struct smbios_type_1 *p = (struct smbios_type_1 *)start;
p->header.type = 1;
p->header.length = sizeof(struct smbios_type_1);
p->header.handle = 0x100;
char uuid_str[37];
struct smbios_type_1 *p = (struct smbios_type_1 *)start;
p->header.type = 1;
p->header.length = sizeof(struct smbios_type_1);
p->header.handle = 0x100;
p->manufacturer_str = 1;
p->product_name_str = 2;
p->version_str = 3;
p->serial_number_str = 4;
p->manufacturer_str = 1;
p->product_name_str = 2;
p->version_str = 3;
p->serial_number_str = 4;
memcpy(p->uuid, uuid, 16);
memcpy(p->uuid, uuid, 16);
p->wake_up_type = 0x06; /* power switch */
p->sku_str = 0;
p->family_str = 0;
p->wake_up_type = 0x06; /* power switch */
p->sku_str = 0;
p->family_str = 0;
start += sizeof(struct smbios_type_1);
start += sizeof(struct smbios_type_1);
strcpy((char *)start, "Xen");
start += strlen("Xen") + 1;
strcpy((char *)start, "HVM domU");
start += strlen("HVM domU") + 1;
strcpy((char *)start, xen_version);
start += strlen(xen_version) + 1;
uuid_to_string(uuid_str, uuid);
strcpy((char *)start, uuid_str);
start += strlen(uuid_str) + 1;
*((uint8_t *)start) = 0;
strcpy((char *)start, "Xen");
start += strlen("Xen") + 1;
strcpy((char *)start, "HVM domU");
start += strlen("HVM domU") + 1;
strcpy((char *)start, xen_version);
start += strlen(xen_version) + 1;
uuid_to_string(uuid_str, uuid);
strcpy((char *)start, uuid_str);
start += strlen(uuid_str) + 1;
*((uint8_t *)start) = 0;
return start+1;
return start+1;
}
/* Type 3 -- System Enclosure */
static void *
smbios_type_3_init(void *start)
{
struct smbios_type_3 *p = (struct smbios_type_3 *)start;
struct smbios_type_3 *p = (struct smbios_type_3 *)start;
p->header.type = 3;
p->header.length = sizeof(struct smbios_type_3);
p->header.handle = 0x300;
p->header.type = 3;
p->header.length = sizeof(struct smbios_type_3);
p->header.handle = 0x300;
p->manufacturer_str = 1;
p->type = 0x01; /* other */
p->version_str = 0;
p->serial_number_str = 0;
p->asset_tag_str = 0;
p->boot_up_state = 0x03; /* safe */
p->power_supply_state = 0x03; /* safe */
p->thermal_state = 0x03; /* safe */
p->security_status = 0x02; /* unknown */
p->manufacturer_str = 1;
p->type = 0x01; /* other */
p->version_str = 0;
p->serial_number_str = 0;
p->asset_tag_str = 0;
p->boot_up_state = 0x03; /* safe */
p->power_supply_state = 0x03; /* safe */
p->thermal_state = 0x03; /* safe */
p->security_status = 0x02; /* unknown */
start += sizeof(struct smbios_type_3);
start += sizeof(struct smbios_type_3);
strcpy((char *)start, "Xen");
start += strlen("Xen") + 1;
*((uint8_t *)start) = 0;
return start+1;
strcpy((char *)start, "Xen");
start += strlen("Xen") + 1;
*((uint8_t *)start) = 0;
return start+1;
}
/* Type 4 -- Processor Information */
static void *
smbios_type_4_init(void *start, unsigned int cpu_number, char *cpu_manufacturer)
{
char buf[80];
struct smbios_type_4 *p = (struct smbios_type_4 *)start;
uint32_t eax, ebx, ecx, edx;
char buf[80];
struct smbios_type_4 *p = (struct smbios_type_4 *)start;
uint32_t eax, ebx, ecx, edx;
p->header.type = 4;
p->header.length = sizeof(struct smbios_type_4);
p->header.handle = 0x400 + cpu_number;
p->header.type = 4;
p->header.length = sizeof(struct smbios_type_4);
p->header.handle = 0x400 + cpu_number;
p->socket_designation_str = 1;
p->processor_type = 0x03; /* CPU */
p->processor_family = 0x01; /* other */
p->manufacturer_str = 2;
p->socket_designation_str = 1;
p->processor_type = 0x03; /* CPU */
p->processor_family = 0x01; /* other */
p->manufacturer_str = 2;
cpuid(1, &eax, &ebx, &ecx, &edx);
cpuid(1, &eax, &ebx, &ecx, &edx);
p->cpuid[0] = eax;
p->cpuid[1] = edx;
p->cpuid[0] = eax;
p->cpuid[1] = edx;
p->version_str = 0;
p->voltage = 0;
p->external_clock = 0;
p->version_str = 0;
p->voltage = 0;
p->external_clock = 0;
p->max_speed = 0; /* unknown */
p->current_speed = 0; /* unknown */
p->max_speed = 0; /* unknown */
p->current_speed = 0; /* unknown */
p->status = 0x41; /* socket populated, CPU enabled */
p->upgrade = 0x01; /* other */
p->status = 0x41; /* socket populated, CPU enabled */
p->upgrade = 0x01; /* other */
start += sizeof(struct smbios_type_4);
start += sizeof(struct smbios_type_4);
strncpy(buf, "CPU ", sizeof(buf));
if ((sizeof(buf) - strlen("CPU ")) >= 3)
itoa(buf + strlen("CPU "), cpu_number);
strncpy(buf, "CPU ", sizeof(buf));
if ( (sizeof(buf) - strlen("CPU ")) >= 3 )
itoa(buf + strlen("CPU "), cpu_number);
strcpy((char *)start, buf);
start += strlen(buf) + 1;
strcpy((char *)start, buf);
start += strlen(buf) + 1;
strcpy((char *)start, cpu_manufacturer);
start += strlen(cpu_manufacturer) + 1;
strcpy((char *)start, cpu_manufacturer);
start += strlen(cpu_manufacturer) + 1;
*((uint8_t *)start) = 0;
return start+1;
*((uint8_t *)start) = 0;
return start+1;
}
/* Type 16 -- Physical Memory Array */
static void *
smbios_type_16_init(void *start, uint32_t memsize)
{
struct smbios_type_16 *p = (struct smbios_type_16*)start;
struct smbios_type_16 *p = (struct smbios_type_16*)start;
p->header.type = 16;
p->header.handle = 0x1000;
p->header.length = sizeof(struct smbios_type_16);
p->header.type = 16;
p->header.handle = 0x1000;
p->header.length = sizeof(struct smbios_type_16);
p->location = 0x01; /* other */
p->use = 0x03; /* system memory */
p->error_correction = 0x01; /* other */
p->maximum_capacity = memsize * 1024;
p->memory_error_information_handle = 0xfffe; /* none provided */
p->number_of_memory_devices = 1;
p->location = 0x01; /* other */
p->use = 0x03; /* system memory */
p->error_correction = 0x01; /* other */
p->maximum_capacity = memsize * 1024;
p->memory_error_information_handle = 0xfffe; /* none provided */
p->number_of_memory_devices = 1;
start += sizeof(struct smbios_type_16);
*((uint16_t *)start) = 0;
return start + 2;
start += sizeof(struct smbios_type_16);
*((uint16_t *)start) = 0;
return start + 2;
}
/* Type 17 -- Memory Device */
static void *
smbios_type_17_init(void *start, uint32_t memory_size_mb)
{
struct smbios_type_17 *p = (struct smbios_type_17 *)start;
struct smbios_type_17 *p = (struct smbios_type_17 *)start;
p->header.type = 17;
p->header.length = sizeof(struct smbios_type_17);
p->header.handle = 0x1100;
p->header.type = 17;
p->header.length = sizeof(struct smbios_type_17);
p->header.handle = 0x1100;
p->physical_memory_array_handle = 0x1000;
p->total_width = 64;
p->data_width = 64;
/* truncate memory_size_mb to 16 bits and clear most significant
bit [indicates size in MB] */
p->size = (uint16_t) memory_size_mb & 0x7fff;
p->form_factor = 0x09; /* DIMM */
p->device_set = 0;
p->device_locator_str = 1;
p->bank_locator_str = 0;
p->memory_type = 0x07; /* RAM */
p->type_detail = 0;
p->physical_memory_array_handle = 0x1000;
p->total_width = 64;
p->data_width = 64;
/* truncate memory_size_mb to 16 bits and clear most significant
bit [indicates size in MB] */
p->size = (uint16_t) memory_size_mb & 0x7fff;
p->form_factor = 0x09; /* DIMM */
p->device_set = 0;
p->device_locator_str = 1;
p->bank_locator_str = 0;
p->memory_type = 0x07; /* RAM */
p->type_detail = 0;
start += sizeof(struct smbios_type_17);
strcpy((char *)start, "DIMM 1");
start += strlen("DIMM 1") + 1;
*((uint8_t *)start) = 0;
start += sizeof(struct smbios_type_17);
strcpy((char *)start, "DIMM 1");
start += strlen("DIMM 1") + 1;
*((uint8_t *)start) = 0;
return start+1;
return start+1;
}
/* Type 19 -- Memory Array Mapped Address */
static void *
smbios_type_19_init(void *start, uint32_t memory_size_mb)
{
struct smbios_type_19 *p = (struct smbios_type_19 *)start;
struct smbios_type_19 *p = (struct smbios_type_19 *)start;
p->header.type = 19;
p->header.length = sizeof(struct smbios_type_19);
p->header.handle = 0x1300;
p->header.type = 19;
p->header.length = sizeof(struct smbios_type_19);
p->header.handle = 0x1300;
p->starting_address = 0;
p->ending_address = (memory_size_mb-1) * 1024;
p->memory_array_handle = 0x1000;
p->partition_width = 1;
p->starting_address = 0;
p->ending_address = (memory_size_mb-1) * 1024;
p->memory_array_handle = 0x1000;
p->partition_width = 1;
start += sizeof(struct smbios_type_19);
*((uint16_t *)start) = 0;
return start + 2;
start += sizeof(struct smbios_type_19);
*((uint16_t *)start) = 0;
return start + 2;
}
/* Type 20 -- Memory Device Mapped Address */
static void *
smbios_type_20_init(void *start, uint32_t memory_size_mb)
{
struct smbios_type_20 *p = (struct smbios_type_20 *)start;
struct smbios_type_20 *p = (struct smbios_type_20 *)start;
p->header.type = 20;
p->header.length = sizeof(struct smbios_type_20);
p->header.handle = 0x1400;
p->header.type = 20;
p->header.length = sizeof(struct smbios_type_20);
p->header.handle = 0x1400;
p->starting_address = 0;
p->ending_address = (memory_size_mb-1)*1024;
p->memory_device_handle = 0x1100;
p->memory_array_mapped_address_handle = 0x1300;
p->partition_row_position = 1;
p->interleave_position = 0;
p->interleaved_data_depth = 0;
p->starting_address = 0;
p->ending_address = (memory_size_mb-1)*1024;
p->memory_device_handle = 0x1100;
p->memory_array_mapped_address_handle = 0x1300;
p->partition_row_position = 1;
p->interleave_position = 0;
p->interleaved_data_depth = 0;
start += sizeof(struct smbios_type_20);
start += sizeof(struct smbios_type_20);
*((uint16_t *)start) = 0;
return start+2;
*((uint16_t *)start) = 0;
return start+2;
}
/* Type 32 -- System Boot Information */
static void *
smbios_type_32_init(void *start)
{
struct smbios_type_32 *p = (struct smbios_type_32 *)start;
struct smbios_type_32 *p = (struct smbios_type_32 *)start;
p->header.type = 32;
p->header.length = sizeof(struct smbios_type_32);
p->header.handle = 0x2000;
memset(p->reserved, 0, 6);
p->boot_status = 0; /* no errors detected */
p->header.type = 32;
p->header.length = sizeof(struct smbios_type_32);
p->header.handle = 0x2000;
memset(p->reserved, 0, 6);
p->boot_status = 0; /* no errors detected */
start += sizeof(struct smbios_type_32);
*((uint16_t *)start) = 0;
return start+2;
start += sizeof(struct smbios_type_32);
*((uint16_t *)start) = 0;
return start+2;
}
/* Type 127 -- End of Table */
static void *
smbios_type_127_init(void *start)
{
struct smbios_type_127 *p = (struct smbios_type_127 *)start;
struct smbios_type_127 *p = (struct smbios_type_127 *)start;
p->header.type = 127;
p->header.length = sizeof(struct smbios_type_127);
p->header.handle = 0x7f00;
p->header.type = 127;
p->header.length = sizeof(struct smbios_type_127);
p->header.handle = 0x7f00;
start += sizeof(struct smbios_type_127);
*((uint16_t *)start) = 0;
return start + 2;
start += sizeof(struct smbios_type_127);
*((uint16_t *)start) = 0;
return start + 2;
}
/*
* Local variables:
* mode: C
* c-set-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
+445 -166
View File
@@ -20,175 +20,194 @@
#include "acpi/acpi2_0.h" /* for ACPI_PHYSICAL_ADDRESS */
#include "util.h"
#include "config.h"
#include <stdint.h>
void outw(uint16_t addr, uint16_t val)
{
__asm__ __volatile__ ("outw %%ax, %%dx" :: "d"(addr), "a"(val));
}
#include <xenctrl.h>
#include <xen/hvm/hvm_info_table.h>
void outb(uint16_t addr, uint8_t val)
{
__asm__ __volatile__ ("outb %%al, %%dx" :: "d"(addr), "a"(val));
__asm__ __volatile__ ( "outb %%al, %%dx" :: "d"(addr), "a"(val) );
}
void outw(uint16_t addr, uint16_t val)
{
__asm__ __volatile__ ( "outw %%ax, %%dx" :: "d"(addr), "a"(val) );
}
void outl(uint16_t addr, uint32_t val)
{
__asm__ __volatile__ ( "outl %%eax, %%dx" :: "d"(addr), "a"(val) );
}
uint8_t inb(uint16_t addr)
{
uint8_t val;
__asm__ __volatile__ ("inb %w1,%0" : "=a" (val) : "Nd" (addr));
return val;
uint8_t val;
__asm__ __volatile__ ( "inb %%dx,%%al" : "=a" (val) : "d" (addr) );
return val;
}
uint16_t inw(uint16_t addr)
{
uint16_t val;
__asm__ __volatile__ ( "inw %%dx,%%ax" : "=a" (val) : "d" (addr) );
return val;
}
uint32_t inl(uint16_t addr)
{
uint32_t val;
__asm__ __volatile__ ( "inl %%dx,%%eax" : "=a" (val) : "d" (addr) );
return val;
}
char *itoa(char *a, unsigned int i)
{
unsigned int _i = i, x = 0;
unsigned int _i = i, x = 0;
do {
x++;
_i /= 10;
} while (_i != 0);
do {
x++;
_i /= 10;
} while ( _i != 0 );
a += x;
*a-- = '\0';
a += x;
*a-- = '\0';
do {
*a-- = (i % 10) + '0';
i /= 10;
} while (i != 0);
do {
*a-- = (i % 10) + '0';
i /= 10;
} while ( i != 0 );
return a + 1;
return a + 1;
}
int strcmp(const char *cs, const char *ct)
{
signed char res;
signed char res;
while (((res = *cs - *ct++) == 0) && (*cs++ != '\0'))
continue;
while ( ((res = *cs - *ct++) == 0) && (*cs++ != '\0') )
continue;
return res;
return res;
}
void *memcpy(void *dest, const void *src, unsigned n)
{
int t0, t1, t2;
int t0, t1, t2;
__asm__ __volatile__(
"cld\n"
"rep; movsl\n"
"testb $2,%b4\n"
"je 1f\n"
"movsw\n"
"1: testb $1,%b4\n"
"je 2f\n"
"movsb\n"
"2:"
: "=&c" (t0), "=&D" (t1), "=&S" (t2)
: "0" (n/4), "q" (n), "1" ((long) dest), "2" ((long) src)
: "memory"
);
return dest;
__asm__ __volatile__ (
"cld\n"
"rep; movsl\n"
"testb $2,%b4\n"
"je 1f\n"
"movsw\n"
"1: testb $1,%b4\n"
"je 2f\n"
"movsb\n"
"2:"
: "=&c" (t0), "=&D" (t1), "=&S" (t2)
: "0" (n/4), "q" (n), "1" ((long) dest), "2" ((long) src)
: "memory" );
return dest;
}
void *memmove(void *dest, const void *src, unsigned n)
{
if ((long)dest > (long)src) {
n--;
while (n > 0) {
((char *)dest)[n] = ((char *)src)[n];
n--;
}
} else {
memcpy(dest, src, n);
}
return dest;
}
void puts(const char *s)
{
while (*s)
outb(0xE9, *s++);
if ( (long)dest > (long)src )
{
n--;
while ( n > 0 )
{
((char *)dest)[n] = ((char *)src)[n];
n--;
}
}
else
{
memcpy(dest, src, n);
}
return dest;
}
char *
strcpy(char *dest, const char *src)
{
char *p = dest;
while (*src)
*p++ = *src++;
*p = 0;
return dest;
char *p = dest;
while ( *src )
*p++ = *src++;
*p = 0;
return dest;
}
char *
strncpy(char *dest, const char *src, unsigned n)
{
int i = 0;
char *p = dest;
int i = 0;
char *p = dest;
/* write non-NUL characters from src into dest until we run
out of room in dest or encounter a NUL in src */
while (i < n && *src) {
*p++ = *src++;
++i;
}
/* write non-NUL characters from src into dest until we run
out of room in dest or encounter a NUL in src */
while ( (i < n) && *src )
{
*p++ = *src++;
i++;
}
/* pad remaining bytes of dest with NUL bytes */
while (i < n) {
*p++ = 0;
++i;
}
/* pad remaining bytes of dest with NUL bytes */
while ( i < n )
{
*p++ = 0;
i++;
}
return dest;
return dest;
}
unsigned
strlen(const char *s)
{
int i = 0;
while (*s++)
++i;
return i;
int i = 0;
while ( *s++ )
i++;
return i;
}
void *
memset(void *s, int c, unsigned n)
{
uint8_t b = (uint8_t) c;
uint8_t *p = (uint8_t *)s;
int i;
for (i = 0; i < n; ++i)
*p++ = b;
return s;
uint8_t b = (uint8_t) c;
uint8_t *p = (uint8_t *)s;
int i;
for ( i = 0; i < n; i++ )
*p++ = b;
return s;
}
int
memcmp(const void *s1, const void *s2, unsigned n)
{
unsigned i;
uint8_t *p1 = (uint8_t *) s1;
uint8_t *p2 = (uint8_t *) s2;
unsigned i;
uint8_t *p1 = (uint8_t *) s1;
uint8_t *p2 = (uint8_t *) s2;
for (i = 0; i < n; ++i) {
if (p1[i] < p2[i])
return -1;
else if (p1[i] > p2[i])
return 1;
}
for ( i = 0; i < n; i++ )
{
if ( p1[i] < p2[i] )
return -1;
else if ( p1[i] > p2[i] )
return 1;
}
return 0;
return 0;
}
void
cpuid(uint32_t idx, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
{
__asm__ __volatile__(
"cpuid"
: "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
: "0" (idx) );
__asm__ __volatile__ (
"cpuid"
: "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
: "0" (idx) );
}
/* Write a two-character hex representation of 'byte' to digits[].
@@ -196,18 +215,18 @@ cpuid(uint32_t idx, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
void
byte_to_hex(char *digits, uint8_t byte)
{
uint8_t nybbel = byte >> 4;
uint8_t nybbel = byte >> 4;
if (nybbel > 9)
digits[0] = 'a' + nybbel-10;
else
digits[0] = '0' + nybbel;
if ( nybbel > 9 )
digits[0] = 'a' + nybbel-10;
else
digits[0] = '0' + nybbel;
nybbel = byte & 0x0f;
if (nybbel > 9)
digits[1] = 'a' + nybbel-10;
else
digits[1] = '0' + nybbel;
nybbel = byte & 0x0f;
if ( nybbel > 9 )
digits[1] = 'a' + nybbel-10;
else
digits[1] = '0' + nybbel;
}
/* Convert an array of 16 unsigned bytes to a DCE/OSF formatted UUID
@@ -217,34 +236,39 @@ byte_to_hex(char *digits, uint8_t byte)
void
uuid_to_string(char *dest, uint8_t *uuid)
{
int i = 0;
char *p = dest;
int i = 0;
char *p = dest;
for (i = 0; i < 4; ++i) {
byte_to_hex(p, uuid[i]);
p += 2;
}
*p++ = '-';
for (i = 4; i < 6; ++i) {
byte_to_hex(p, uuid[i]);
p += 2;
}
*p++ = '-';
for (i = 6; i < 8; ++i) {
byte_to_hex(p, uuid[i]);
p += 2;
}
*p++ = '-';
for (i = 8; i < 10; ++i) {
byte_to_hex(p, uuid[i]);
p += 2;
}
*p++ = '-';
for (i = 10; i < 16; ++i) {
byte_to_hex(p, uuid[i]);
p += 2;
}
*p = 0;
for ( i = 0; i < 4; i++ )
{
byte_to_hex(p, uuid[i]);
p += 2;
}
*p++ = '-';
for ( i = 4; i < 6; i++ )
{
byte_to_hex(p, uuid[i]);
p += 2;
}
*p++ = '-';
for ( i = 6; i < 8; i++ )
{
byte_to_hex(p, uuid[i]);
p += 2;
}
*p++ = '-';
for ( i = 8; i < 10; i++ )
{
byte_to_hex(p, uuid[i]);
p += 2;
}
*p++ = '-';
for ( i = 10; i < 16; i++ )
{
byte_to_hex(p, uuid[i]);
p += 2;
}
*p = '\0';
}
#include <xen/hvm/e820.h>
@@ -252,31 +276,286 @@ uuid_to_string(char *dest, uint8_t *uuid)
#define E820_MAP ((struct e820entry *)(E820_MAP_PAGE + E820_MAP_OFFSET))
uint64_t e820_malloc(uint64_t size, uint32_t type, uint64_t mask)
{
uint64_t addr = 0;
int c = *E820_MAP_NR - 1;
struct e820entry *e820entry = (struct e820entry *)E820_MAP;
uint64_t addr = 0;
int c = *E820_MAP_NR - 1;
struct e820entry *e820entry = (struct e820entry *)E820_MAP;
while (c >= 0) {
if (e820entry[c].type == E820_RAM &&
(e820entry[c].addr & (~mask)) == 0 &&
e820entry[c].size >= size) {
addr = e820entry[c].addr;
if (e820entry[c].size != size) {
(*E820_MAP_NR)++;
memmove(&e820entry[c+1],
&e820entry[c],
(*E820_MAP_NR - c) *
sizeof(struct e820entry));
e820entry[c].size -= size;
addr += e820entry[c].size;
c++;
}
e820entry[c].addr = addr;
e820entry[c].size = size;
e820entry[c].type = type;
break;
}
c--;
}
return addr;
while ( c >= 0 )
{
if ( (e820entry[c].type == E820_RAM) &&
((e820entry[c].addr & (~mask)) == 0) &&
(e820entry[c].size >= size) )
{
addr = e820entry[c].addr;
if ( e820entry[c].size != size )
{
(*E820_MAP_NR)++;
memmove(&e820entry[c+1],
&e820entry[c],
(*E820_MAP_NR - c) *
sizeof(struct e820entry));
e820entry[c].size -= size;
addr += e820entry[c].size;
c++;
}
e820entry[c].addr = addr;
e820entry[c].size = size;
e820entry[c].type = type;
break;
}
c--;
}
return addr;
}
uint32_t ioapic_read(uint32_t reg)
{
*(volatile uint32_t *)(IOAPIC_BASE_ADDRESS + 0x00) = reg;
return *(volatile uint32_t *)(IOAPIC_BASE_ADDRESS + 0x10);
}
void ioapic_write(uint32_t reg, uint32_t val)
{
*(volatile uint32_t *)(IOAPIC_BASE_ADDRESS + 0x00) = reg;
*(volatile uint32_t *)(IOAPIC_BASE_ADDRESS + 0x10) = val;
}
uint32_t lapic_read(uint32_t reg)
{
return *(volatile uint32_t *)(LAPIC_BASE_ADDRESS + reg);
}
void lapic_write(uint32_t reg, uint32_t val)
{
*(volatile uint32_t *)(LAPIC_BASE_ADDRESS + reg) = val;
}
#define PCI_CONF1_ADDRESS(bus, devfn, reg) \
(0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3))
uint32_t pci_read(uint32_t devfn, uint32_t reg, uint32_t len)
{
outl(0xcf8, PCI_CONF1_ADDRESS(0, devfn, reg));
switch ( len )
{
case 1: return inb(0xcfc + (reg & 3));
case 2: return inw(0xcfc + (reg & 2));
}
return inl(0xcfc);
}
void pci_write(uint32_t devfn, uint32_t reg, uint32_t len, uint32_t val)
{
outl(0xcf8, PCI_CONF1_ADDRESS(0, devfn, reg));
switch ( len )
{
case 1: outb(0xcfc + (reg & 3), val); break;
case 2: outw(0xcfc + (reg & 2), val); break;
case 4: outl(0xcfc, val); break;
}
}
static char *printnum(char *p, unsigned long num, int base)
{
unsigned long n;
if ( (n = num/base) > 0 )
p = printnum(p, n, base);
*p++ = "0123456789abcdef"[(int)(num % base)];
*p = '\0';
return p;
}
static void _doprint(void (*put)(char), char const *fmt, va_list ap)
{
register char *str, c;
int lflag, zflag, nflag;
char buffer[17];
unsigned value;
int i, slen, pad;
for ( ; *fmt != '\0'; fmt++ )
{
if ( *fmt != '%' )
{
put(*fmt);
continue;
}
pad = zflag = nflag = lflag = 0;
c = *++fmt;
if ( (c == '-') || isdigit(c) )
{
if ( c == '-' )
{
nflag = 1;
c = *++fmt;
}
zflag = c == '0';
for ( pad = 0; isdigit(c); c = *++fmt )
pad = (pad * 10) + c - '0';
}
if ( c == 'l' ) /* long extension */
{
lflag = 1;
c = *++fmt;
}
if ( (c == 'd') || (c == 'u') || (c == 'o') || (c == 'x') )
{
if ( lflag )
value = va_arg(ap, unsigned);
else
value = (unsigned) va_arg(ap, unsigned int);
str = buffer;
printnum(str, value,
c == 'o' ? 8 : (c == 'x' ? 16 : 10));
goto printn;
}
else if ( (c == 'O') || (c == 'D') || (c == 'X') )
{
value = va_arg(ap, unsigned);
str = buffer;
printnum(str, value,
c == 'O' ? 8 : (c == 'X' ? 16 : 10));
printn:
slen = strlen(str);
for ( i = pad - slen; i > 0; i-- )
put(zflag ? '0' : ' ');
while ( *str )
put(*str++);
}
else if ( c == 's' )
{
str = va_arg(ap, char *);
slen = strlen(str);
if ( nflag == 0 )
for ( i = pad - slen; i > 0; i-- )
put(' ');
while ( *str )
put(*str++);
if ( nflag )
for ( i = pad - slen; i > 0; i-- )
put(' ');
}
else if ( c == 'c' )
{
put(va_arg(ap, int));
}
else
{
put(*fmt);
}
}
}
static void putchar(char c)
{
outb(0xe9, c);
}
int printf(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
_doprint(putchar, fmt, ap);
va_end(ap);
return 0;
}
int vprintf(const char *fmt, va_list ap)
{
_doprint(putchar, fmt, ap);
return 0;
}
void __assert_failed(char *assertion, char *file, int line)
{
printf("HVMLoader assertion '%s' failed at %s:%d\n",
assertion, file, line);
for ( ; ; )
__asm__ __volatile__ ( "ud2" );
}
void __bug(char *file, int line)
{
printf("HVMLoader bug at %s:%d\n", file, line);
for ( ; ; )
__asm__ __volatile__ ( "ud2" );
}
static int validate_hvm_info(struct hvm_info_table *t)
{
char signature[] = "HVM INFO";
uint8_t *ptr = (uint8_t *)t;
uint8_t sum = 0;
int i;
/* strncmp(t->signature, "HVM INFO", 8) */
for ( i = 0; i < 8; i++ )
{
if ( signature[i] != t->signature[i] )
{
printf("Bad hvm info signature\n");
return 0;
}
}
for ( i = 0; i < t->length; i++ )
sum += ptr[i];
return (sum == 0);
}
static struct hvm_info_table *get_hvm_info_table(void)
{
static struct hvm_info_table *table;
struct hvm_info_table *t;
if ( table != NULL )
return table;
t = (struct hvm_info_table *)HVM_INFO_PADDR;
if ( !validate_hvm_info(t) )
{
printf("Bad hvm info table\n");
return NULL;
}
table = t;
return table;
}
int get_vcpu_nr(void)
{
struct hvm_info_table *t = get_hvm_info_table();
return (t ? t->nr_vcpus : 1);
}
int get_acpi_enabled(void)
{
struct hvm_info_table *t = get_hvm_info_table();
return (t ? t->acpi_enabled : 1);
}
int get_apic_mode(void)
{
struct hvm_info_table *t = get_hvm_info_table();
return (t ? t->apic_mode : 1);
}
/*
* Local variables:
* mode: C
* c-set-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
Loaded 100 of 197 files, more files were not shown because too many files have changed in this diff. Show more
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.