1
1
/******************************************************************************
4
* This file should contain architecture-independent bootstrap and low-level
5
* help routines. It's a bit x86/PC specific right now!
7
* Copyright (c) 2002-2003 K A Fraser
4
* Copyright (c) 2002-2005 K A Fraser
12
#include <xeno/errno.h>
13
#include <xeno/spinlock.h>
14
#include <xeno/multiboot.h>
15
#include <xeno/sched.h>
17
#include <xeno/delay.h>
18
#include <xeno/skbuff.h>
19
#include <xeno/interrupt.h>
20
#include <xeno/compile.h>
21
#include <xeno/version.h>
22
#include <xeno/netdevice.h>
25
#include <asm/uaccess.h>
26
#include <hypervisor-ifs/dom0_ops.h>
27
#include <asm/byteorder.h>
28
#include <linux/if_ether.h>
29
#include <asm/domain_page.h>
30
#include <xeno/console.h>
31
#include <xeno/net_headers.h>
33
kmem_cache_t *task_struct_cachep;
35
static int xpos, ypos;
36
static volatile unsigned char *video;
38
spinlock_t console_lock = SPIN_LOCK_UNLOCKED;
41
unsigned long addr_lo, addr_hi; /* start of memory segment */
42
unsigned long size_lo, size_hi; /* size of memory segment */
43
unsigned long type; /* type of memory segment */
47
void init_serial(void);
48
void start_of_day(void);
50
/* opt_console: If true, Xen sends logging to the VGA console. */
52
/* opt_ser_baud: Baud rate at which logging is sent to COM1. */
53
/* NB. Default (0) means that serial I/O is disabled. */
54
unsigned int opt_ser_baud = 0;
55
/* opt_dom0_mem: Kilobytes of memory allocated to domain 0. */
56
unsigned int opt_dom0_mem = 16000;
57
/* opt_ifname: Name of physical network interface to use. */
58
unsigned char opt_ifname[10] = "eth0";
59
/* opt_noht: If true, Hyperthreading is ignored. */
61
/* opt_noacpi: If true, ACPI tables are not parsed. */
63
/* opt_nosmp: If true, secondary processors are ignored. */
65
/* opt_noreboot: If true, machine will need manual reset on error. */
67
/* opt_ignorebiostables: If true, ACPI and MP tables are ignored. */
68
/* NB. This flag implies 'nosmp' and 'noacpi'. */
69
int opt_ignorebiostables=0;
70
/* opt_watchdog: If true, run a watchdog NMI on each processor. */
75
enum { OPT_IP, OPT_STR, OPT_UINT, OPT_BOOL } type;
78
{ "console", OPT_UINT, &opt_console },
79
{ "ser_baud", OPT_UINT, &opt_ser_baud },
80
{ "dom0_mem", OPT_UINT, &opt_dom0_mem },
81
{ "ifname", OPT_STR, &opt_ifname },
82
{ "noht", OPT_BOOL, &opt_noht },
83
{ "noacpi", OPT_BOOL, &opt_noacpi },
84
{ "nosmp", OPT_BOOL, &opt_nosmp },
85
{ "noreboot", OPT_BOOL, &opt_noreboot },
86
{ "ignorebiostables", OPT_BOOL, &opt_ignorebiostables },
87
{ "watchdog", OPT_BOOL, &opt_watchdog },
92
void cmain (unsigned long magic, multiboot_info_t *mbi)
7
#include <xen/config.h>
10
#include <xen/errno.h>
11
#include <xen/version.h>
12
#include <xen/sched.h>
13
#include <xen/paging.h>
15
#include <xen/guest_access.h>
16
#include <asm/current.h>
17
#include <public/nmi.h>
18
#include <public/version.h>
20
#include <asm/shared.h>
27
xen_commandline_t saved_cmdline;
29
void cmdline_parse(char *cmdline)
94
struct task_struct *new_dom;
95
dom0_createdomain_t dom0_params;
96
unsigned long max_page;
97
unsigned char *cmdline;
102
* Note that serial output cannot be done properly until after
103
* command-line arguments have been parsed, and the required baud rate is
104
* known. Any messages before that will be output using the settings of
105
* the bootloader, for example.
108
if ( magic != MULTIBOOT_BOOTLOADER_MAGIC )
112
printk("Invalid magic number: 0x%x\n", (unsigned)magic);
116
/* Parse the command line. */
117
cmdline = (unsigned char *)(mbi->cmdline ? __va(mbi->cmdline) : NULL);
118
if ( cmdline != NULL )
120
unsigned char *opt_end, *opt;
121
while ( *cmdline == ' ' ) cmdline++;
122
cmdline = strchr(cmdline, ' ');
123
while ( cmdline != NULL )
125
while ( *cmdline == ' ' ) cmdline++;
126
if ( *cmdline == '\0' ) break;
127
opt_end = strchr(cmdline, ' ');
128
if ( opt_end != NULL ) *opt_end++ = '\0';
129
opt = strchr(cmdline, '=');
130
if ( opt != NULL ) *opt++ = '\0';
131
for ( i = 0; opts[i].name != NULL; i++ )
31
char opt[100], *optval, *optkey, *q;
32
const char *p = cmdline;
33
struct kernel_param *param;
36
safe_strcpy(saved_cmdline, cmdline);
43
/* Skip whitespace. */
49
/* Grab the next whitespace-delimited option. */
51
while ( (*p != ' ') && (*p != '\0') )
53
if ( (q-opt) < (sizeof(opt)-1) ) /* avoid overflow */
59
/* Search for value part of a key=value option. */
60
optval = strchr(opt, '=');
62
*optval++ = '\0'; /* nul-terminate the option value */
64
optval = q; /* default option value is empty string */
66
/* Boolean parameters can be inverted with 'no-' prefix. */
67
bool_assert = !!strncmp("no-", optkey, 3);
71
for ( param = &__setup_start; param <= &__setup_end; param++ )
73
if ( strcmp(param->name, optkey) )
76
switch ( param->type )
133
if ( strcmp(opts[i].name, cmdline ) != 0 ) continue;
134
switch ( opts[i].type )
79
strlcpy(param->var, optval, param->len);
82
*(unsigned int *)param->var = simple_strtol(optval, NULL, 0);
86
if ( !strcmp("no", optval) ||
87
!strcmp("off", optval) ||
88
!strcmp("false", optval) ||
89
!strcmp("0", optval) )
90
bool_assert = !bool_assert;
91
if ( param->type == OPT_INVBOOL )
92
bool_assert = !bool_assert;
93
*(int *)param->var = bool_assert;
96
uint64_t sz = parse_size_and_unit(optval, NULL);
138
*(unsigned long *)opts[i].var = str_to_quad(opt);
142
strcpy(opts[i].var, opt);
146
*(unsigned int *)opts[i].var =
147
simple_strtol(opt, (char **)&opt, 0);
150
*(int *)opts[i].var = 1;
99
case sizeof(uint32_t):
100
*(uint32_t *)param->var = sz;
102
case sizeof(uint64_t):
103
*(uint64_t *)param->var = sz;
111
((void (*)(const char *))param->var)(optval);
163
printk(" http://www.cl.cam.ac.uk/netos/xen\n");
164
printk(" University of Cambridge Computer Laboratory\n\n");
165
printk(" Xen version %d.%d%s (%s@%s) (%s) %s\n\n",
166
XEN_VERSION, XEN_SUBVERSION, XEN_EXTRAVERSION,
167
XEN_COMPILE_BY, XEN_COMPILE_DOMAIN,
168
XEN_COMPILER, XEN_COMPILE_DATE);
170
/* We require memory and module information. */
171
if ( (mbi->flags & 9) != 9 )
173
printk("FATAL ERROR: Bad flags passed by bootloader: 0x%x\n",
174
(unsigned)mbi->flags);
178
if ( mbi->mods_count == 0 )
180
printk("Require at least one Multiboot module!\n");
184
set_current(&idle0_task);
186
max_page = (mbi->mem_upper+1024) >> (PAGE_SHIFT - 10);
187
init_frametable(max_page);
188
printk("Initialised all memory on a %luMB machine\n",
189
max_page >> (20-PAGE_SHIFT));
191
init_page_allocator(__pa(&_end), MAX_MONITOR_ADDRESS);
193
/* These things will get done by do_createdomain() for all other tasks. */
194
current->shared_info = (void *)get_free_page(GFP_KERNEL);
195
memset(current->shared_info, 0, sizeof(shared_info_t));
198
/* Initialise the slab allocator. */
200
kmem_cache_sizes_init(max_page);
202
task_struct_cachep = kmem_cache_create(
203
"task_struct_cache", sizeof(struct task_struct),
204
0, SLAB_HWCACHE_ALIGN, NULL, NULL);
205
if ( task_struct_cachep == NULL )
206
panic("No slab cache for task structs.");
210
/* Create initial domain 0. */
211
dom0_params.memory_kb = opt_dom0_mem;
212
new_dom = do_createdomain(0, 0);
213
if ( new_dom == NULL ) panic("Error creating domain 0\n");
216
* We're going to setup domain0 using the module(s) that we stashed safely
217
* above our MAX_DIRECTMAP_ADDRESS in boot/Boot.S The second module, if
218
* present, is an initrd ramdisk
220
mod = (module_t *)__va(mbi->mods_addr);
221
if ( setup_guestos(new_dom,
223
(char *)MAX_DIRECTMAP_ADDRESS,
224
mod[mbi->mods_count-1].mod_end - mod[0].mod_start,
226
(mbi->mods_count == 2) ?
227
(mod[1].mod_end - mod[1].mod_start):0)
228
!= 0 ) panic("Could not set up DOM0 guest OS\n");
232
startup_cpu_idle_loop();
236
#define SERIAL_BASE 0x3f8
241
#define DATA_FORMAT 3
243
#define LINE_STATUS 5
248
void init_serial(void)
250
if ( !SERIAL_ENABLED )
253
/* 'opt_ser_baud' baud, no parity, 1 stop bit, 8 data bits. */
254
outb(0x83, SERIAL_BASE+DATA_FORMAT);
255
outb(115200/opt_ser_baud, SERIAL_BASE+DIVISOR_LO);
256
outb(0, SERIAL_BASE+DIVISOR_HI);
257
outb(0x03, SERIAL_BASE+DATA_FORMAT);
259
/* DTR and RTS should both be high, to keep other end happy. */
260
outb(0x02, SERIAL_BASE+LINE_CTL);
263
outb(0x00, SERIAL_BASE+INT_ENABLE);
267
#ifdef CONFIG_OUTPUT_SERIAL
268
void putchar_serial(unsigned char c)
270
if ( !SERIAL_ENABLED )
272
if ( c == '\n' ) putchar_serial('\r');
273
while ( !(inb(SERIAL_BASE+LINE_STATUS)&(1<<5)) ) barrier();
274
outb(c, SERIAL_BASE+TX_HOLD);
277
void putchar_serial(unsigned char c) {}
281
#ifdef CONFIG_OUTPUT_CONSOLE
283
/* VGA text (mode 3) definitions. */
287
#define VIDEO __va(0xB8000)
289
int detect_video(void *video_base)
291
volatile u16 *p = (volatile u16 *)video_base;
292
u16 saved1 = p[0], saved2 = p[1];
297
if ( (p[0] != 0xAA55) || (p[1] != 0x55AA) )
302
if ( (p[0] != 0x55AA) || (p[1] != 0xAA55) )
314
* Look at a number of well-known locations. Even if video is not at
315
* 0xB8000 right now, it will appear there when we set up text mode 3.
317
* We assume if there is any sign of a video adaptor then it is at least
318
* VGA-compatible (surely noone runs CGA, EGA, .... these days?).
320
* These checks are basically to detect headless server boxes.
322
return (detect_video(__va(0xA0000)) ||
323
detect_video(__va(0xB0000)) ||
324
detect_video(__va(0xB8000)));
327
/* This is actually code from vgaHWRestore in an old version of XFree86 :-) */
330
/* The following VGA state was saved from a chip in text mode 3. */
331
static unsigned char regs[] = {
332
/* Sequencer registers */
333
0x03, 0x00, 0x03, 0x00, 0x02,
335
0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, 0x00, 0x4f, 0x20,
336
0x0e, 0x00, 0x00, 0x01, 0xe0, 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96,
338
/* Graphic registers */
339
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, 0xff,
340
/* Attribute registers */
341
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3a,
342
0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x0c, 0x00, 0x0f, 0x08, 0x00
346
volatile unsigned char tmp;
353
printk("No VGA adaptor detected!\n");
361
for ( i = 0; i < 5; i++ )
362
outw((regs[j++] << 8) | i, 0x3c4);
364
/* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17]. */
365
outw(((regs[5+17] & 0x7F) << 8) | 17, 0x3d4);
367
for ( i = 0; i < 25; i++ )
368
outw((regs[j++] << 8) | i, 0x3d4);
370
for ( i = 0; i < 9; i++ )
371
outw((regs[j++] << 8) | i, 0x3ce);
373
for ( i = 0; i < 21; i++ )
377
outb(regs[j++], 0x3c0);
385
/* Clear the screen and initialize VIDEO, XPOS and YPOS. */
393
video = (unsigned char *) VIDEO;
395
for (i = 0; i < COLUMNS * LINES * 2; i++)
401
outw(10+(1<<(5+8)), 0x3d4); /* cursor off */
405
static void put_newline(void)
412
static char zeroarr[2*COLUMNS] = { 0 };
415
(char*)video + 2*COLUMNS, (LINES-1)*2*COLUMNS);
416
memcpy((char*)video + (LINES-1)*2*COLUMNS,
422
void putchar_console(int c)
119
* print_tainted - return a string to represent the kernel taint state.
121
* 'S' - SMP with CPUs not designed for SMP.
122
* 'M' - Machine had a machine check experience.
123
* 'B' - System has hit bad_page.
125
* The string is overwritten by the next call to print_taint().
127
char *print_tainted(char *str)
131
snprintf(str, TAINT_STRING_MAX_LEN, "Tainted: %c%c%c%c",
132
tainted & TAINT_UNSAFE_SMP ? 'S' : ' ',
133
tainted & TAINT_MACHINE_CHECK ? 'M' : ' ',
134
tainted & TAINT_BAD_PAGE ? 'B' : ' ',
135
tainted & TAINT_SYNC_CONSOLE ? 'C' : ' ');
433
*(video + (xpos + ypos * COLUMNS) * 2) = c & 0xFF;
434
*(video + (xpos + ypos * COLUMNS) * 2 + 1) = ATTRIBUTE;
444
void init_vga(void) {}
446
void putchar_console(int c) {}
450
#ifdef CONFIG_OUTPUT_CONSOLE_RING
452
void putchar_console_ring(int c)
454
if (console_ring.len < CONSOLE_RING_SIZE)
455
console_ring.buf[console_ring.len++] = (char)c;
460
void putchar_console_ring(int c) {}
465
static void putchar(int c)
467
if ( (c != '\n') && ((c < 32) || (c > 126)) ) return;
470
putchar_console_ring(c);
474
static inline void __putstr(const char *str)
476
while ( *str ) putchar(*str++);
480
void printf (const char *fmt, ...)
488
* If the format string contains '%' descriptors then we have to parse it
489
* before printing it. We parse it into a fixed-length buffer. Long
490
* strings should therefore _not_ contain '%' characters!
492
if ( strchr(fmt, '%') != NULL )
495
(void)vsnprintf(buf, sizeof(buf), fmt, args);
500
spin_lock_irqsave(&console_lock, flags);
501
while ( *p ) putchar(*p++);
502
spin_unlock_irqrestore(&console_lock, flags);
506
void panic(const char *fmt, ...)
511
extern void machine_restart(char *);
514
(void)vsnprintf(buf, sizeof(buf), fmt, args);
517
/* Spit out multiline message in one go. */
518
spin_lock_irqsave(&console_lock, flags);
519
__putstr("\n****************************************\n");
521
__putstr("Aieee! CPU");
522
sprintf(buf, "%d", smp_processor_id());
524
__putstr(" is toast...\n");
525
__putstr("****************************************\n\n");
526
__putstr("Reboot in five seconds...\n");
527
spin_unlock_irqrestore(&console_lock, flags);
535
asmlinkage long sys_ni_syscall(void)
541
unsigned short compute_cksum(unsigned short *buf, int count)
543
unsigned long sum = 0;
547
sum = (sum & 0xffff) + (sum >> 16);
548
return (unsigned short) ~sum;
553
* Function written by ek247. Exports console output from all domains upwards
554
* to domain0, by stuffing it into a fake network packet.
556
int console_export(char *str, int len)
559
struct iphdr *iph = NULL;
560
struct udphdr *udph = NULL;
561
struct ethhdr *ethh = NULL;
562
int hdr_size = sizeof(struct iphdr) + sizeof(struct udphdr);
565
skb = dev_alloc_skb(sizeof(struct ethhdr) +
566
hdr_size + len + 20);
567
if ( skb == NULL ) return 0;
570
skb_data = (u8 *)map_domain_mem((skb->pf - frame_table) << PAGE_SHIFT);
573
/* Get a pointer to each header. */
574
ethh = (struct ethhdr *)
575
(skb_data + (skb->data - skb->head));
576
iph = (struct iphdr *)(ethh + 1);
577
udph = (struct udphdr *)(iph + 1);
579
skb_reserve(skb, sizeof(struct ethhdr));
580
skb_put(skb, hdr_size + len);
582
/* Build IP header. */
586
iph->tot_len = htons(hdr_size + len);
591
iph->daddr = htonl(0xa9fe0100); /* 169.254.1.0 */
592
iph->saddr = htonl(0xa9fefeff); /* 169.254.254.255 */
594
iph->check = compute_cksum((__u16 *)iph, sizeof(struct iphdr)/2);
596
/* Build UDP header. */
597
udph->source = htons(current->domain);
598
udph->dest = htons(666);
599
udph->len = htons(sizeof(struct udphdr) + len);
602
/* Build the UDP payload. */
603
memcpy((char *)(udph + 1), str, len);
605
/* Fix Ethernet header. */
606
memset(ethh->h_source, 0, ETH_ALEN);
607
memset(ethh->h_dest, 0, ETH_ALEN);
608
ethh->h_proto = htons(ETH_P_IP);
609
skb->mac.ethernet= (struct ethhdr *)ethh;
611
unmap_domain_mem(skb_data);
613
skb->dst_vif = find_vif_by_id(0);
620
long do_console_write(char *str, unsigned int count)
622
#define SIZEOF_BUF 256
623
unsigned char safe_str[SIZEOF_BUF+1];
624
unsigned char exported_str[SIZEOF_BUF+2];
625
unsigned char dom_id[5];
633
if ( count > SIZEOF_BUF )
636
if ( copy_from_user(safe_str, str, count) )
638
safe_str[count] = '\0';
645
spin_lock_irqsave(&console_lock, flags);
648
sprintf(dom_id, "%d", current->domain);
652
while ( (*p != '\0') && (*p != '\n') )
654
exported_str[j++] = *p;
664
spin_unlock_irqrestore(&console_lock, flags);
666
if ( current->domain != 0 )
668
exported_str[j++] = '\n';
669
exported_str[j++] = '\0';
670
console_export(exported_str, j);
678
void __out_of_line_bug(int line)
680
printk("kernel BUG in header file at line %d\n", line);
682
for ( ; ; ) continue;
690
if ( (mbi->flags & (1<<6)) )
692
memory_map_t *mmap = (memory_map_t *)mbi->mmap_addr;
693
struct e820entry *e820 = E820_MAP;
695
while ( (unsigned long)mmap < (mbi->mmap_addr + mbi->mmap_length) )
697
e820->addr_lo = mmap->base_addr_low;
698
e820->addr_hi = mmap->base_addr_high;
699
e820->size_lo = mmap->length_low;
700
e820->size_hi = mmap->length_high;
701
e820->type = mmap->type;
703
mmap = (memory_map_t *)
704
((unsigned long)mmap + mmap->size + sizeof (mmap->size));
139
snprintf(str, TAINT_STRING_MAX_LEN, "Not tainted");
145
void add_taint(unsigned flag)
150
# define DO(fn) long do_##fn
158
DO(xen_version)(int cmd, XEN_GUEST_HANDLE(void) arg)
164
return (xen_major_version() << 16) | xen_minor_version();
167
case XENVER_extraversion:
169
xen_extraversion_t extraversion;
170
safe_strcpy(extraversion, xen_extra_version());
171
if ( copy_to_guest(arg, extraversion, ARRAY_SIZE(extraversion)) )
176
case XENVER_compile_info:
178
struct xen_compile_info info;
179
safe_strcpy(info.compiler, xen_compiler());
180
safe_strcpy(info.compile_by, xen_compile_by());
181
safe_strcpy(info.compile_domain, xen_compile_domain());
182
safe_strcpy(info.compile_date, xen_compile_date());
183
if ( copy_to_guest(arg, &info, 1) )
188
case XENVER_capabilities:
190
xen_capabilities_info_t info;
191
extern void arch_get_xen_caps(xen_capabilities_info_t *info);
193
memset(info, 0, sizeof(info));
194
arch_get_xen_caps(&info);
196
if ( copy_to_guest(arg, info, ARRAY_SIZE(info)) )
201
case XENVER_platform_parameters:
203
xen_platform_parameters_t params = {
204
.virt_start = HYPERVISOR_VIRT_START
206
if ( copy_to_guest(arg, ¶ms, 1) )
212
case XENVER_changeset:
214
xen_changeset_info_t chgset;
215
safe_strcpy(chgset, xen_changeset());
216
if ( copy_to_guest(arg, chgset, ARRAY_SIZE(chgset)) )
221
case XENVER_get_features:
223
xen_feature_info_t fi;
224
struct domain *d = current->domain;
226
if ( copy_from_guest(&fi, arg, 1) )
229
switch ( fi.submap_idx )
233
if ( VM_ASSIST(d, VMASST_TYPE_pae_extended_cr3) )
234
fi.submap |= (1U << XENFEAT_pae_pgdir_above_4gb);
235
if ( paging_mode_translate(current->domain) )
237
(1U << XENFEAT_writable_page_tables) |
238
(1U << XENFEAT_auto_translated_physmap);
239
if ( supervisor_mode_kernel )
240
fi.submap |= 1U << XENFEAT_supervisor_mode_kernel;
242
if ( !is_hvm_vcpu(current) )
243
fi.submap |= (1U << XENFEAT_mmu_pt_update_preserve_ad) |
244
(1U << XENFEAT_highmem_assist) |
245
(1U << XENFEAT_gnttab_map_avail_bits);
252
if ( copy_to_guest(arg, &fi, 1) )
257
case XENVER_pagesize:
259
return (!guest_handle_is_null(arg) ? -EINVAL : PAGE_SIZE);
262
case XENVER_guest_handle:
264
if ( copy_to_guest(arg, current->domain->handle,
265
ARRAY_SIZE(current->domain->handle)) )
270
case XENVER_commandline:
272
if ( copy_to_guest(arg, saved_cmdline, ARRAY_SIZE(saved_cmdline)) )
281
DO(nmi_op)(unsigned int cmd, XEN_GUEST_HANDLE(void) arg)
283
struct xennmi_callback cb;
288
case XENNMI_register_callback:
290
if ( copy_from_guest(&cb, arg, 1) )
292
rc = register_guest_nmi_callback(cb.handler_address);
294
case XENNMI_unregister_callback:
295
rc = unregister_guest_nmi_callback();
305
DO(vm_assist)(unsigned int cmd, unsigned int type)
307
return vm_assist(current->domain, cmd, type);
310
DO(ni_hypercall)(void)
312
/* No-op hypercall. */
322
* indent-tabs-mode: nil