ia64/xen-unstable

changeset 16747:bf828db8d017

hvm: Extboot support for Xen

This patch adds extboot to Xen. It should be pretty harmless as the
moment because it's never enabled. extboot allows arbitrary block
devices to be used to boot guests including SCSI and PV disks. I've
tested it with both Windows and Linux guests in QEMU.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Jan 17 16:39:14 2008 +0000 (2008-01-17)
parents 95558b4a6714
children 09cd682ac68e 764d6741de07
files tools/firmware/Makefile tools/firmware/extboot/Makefile tools/firmware/extboot/STATUS tools/firmware/extboot/extboot.S tools/firmware/extboot/extboot.img tools/firmware/extboot/signrom tools/firmware/extboot/signrom.c tools/firmware/hvmloader/Makefile tools/firmware/hvmloader/config.h tools/firmware/hvmloader/hvmloader.c tools/ioemu/Makefile.target tools/ioemu/hw/extboot.c tools/ioemu/vl.h
line diff
     1.1 --- a/tools/firmware/Makefile	Thu Jan 17 15:50:48 2008 +0000
     1.2 +++ b/tools/firmware/Makefile	Thu Jan 17 16:39:14 2008 +0000
     1.3 @@ -10,6 +10,7 @@ SUBDIRS :=
     1.4  SUBDIRS += rombios rombios/32bit
     1.5  SUBDIRS += vgabios
     1.6  SUBDIRS += vmxassist
     1.7 +SUBDIRS += extboot
     1.8  SUBDIRS += hvmloader
     1.9  
    1.10  .PHONY: all
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/tools/firmware/extboot/Makefile	Thu Jan 17 16:39:14 2008 +0000
     2.3 @@ -0,0 +1,30 @@
     2.4 +
     2.5 +override XEN_TARGET_ARCH = x86_32
     2.6 +XEN_ROOT = ../../..
     2.7 +CFLAGS := -I$(XEN_ROOT)/tools/libxc -I.
     2.8 +include $(XEN_ROOT)/tools/Rules.mk
     2.9 +
    2.10 +# Disable PIE/SSP if GCC supports them. They can break us.
    2.11 +CFLAGS  += $(call cc-option,$(CC),-nopie,)
    2.12 +CFLAGS  += $(call cc-option,$(CC),-fno-stack-protector,)
    2.13 +CFLAGS  += $(call cc-option,$(CC),-fno-stack-protector-all,)
    2.14 +
    2.15 +CFLAGS  += -fno-builtin -O2 -msoft-float
    2.16 +
    2.17 +.PHONY: all
    2.18 +all: extboot.bin
    2.19 +
    2.20 +%.o: %.S
    2.21 +	$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -c $<
    2.22 +
    2.23 +extboot.img: extboot.o
    2.24 +	$(LD) $(LDFLAGS_DIRECT) --oformat binary -Ttext 0 -o $@ $<
    2.25 +
    2.26 +extboot.bin: extboot.img signrom
    2.27 +	./signrom extboot.img extboot.bin
    2.28 +
    2.29 +signrom: signrom.c
    2.30 +	$(HOSTCC) $(HOSTCFLAGS) -o $@ $^
    2.31 +
    2.32 +clean:
    2.33 +	$(RM) -f *.o *.img *.bin signrom *~
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/tools/firmware/extboot/STATUS	Thu Jan 17 16:39:14 2008 +0000
     3.3 @@ -0,0 +1,6 @@
     3.4 +Working
     3.5 +-------
     3.6 +
     3.7 +Ubuntu Server 7.04 (i386)
     3.8 +Windows 2000 Professional (i386)
     3.9 +Windows XP SP2 (i386)
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/tools/firmware/extboot/extboot.S	Thu Jan 17 16:39:14 2008 +0000
     4.3 @@ -0,0 +1,633 @@
     4.4 +/*
     4.5 + * Extended Boot Option ROM
     4.6 + *
     4.7 + * This program is free software; you can redistribute it and/or modify
     4.8 + * it under the terms of the GNU General Public License as published by
     4.9 + * the Free Software Foundation; either version 2 of the License, or
    4.10 + * (at your option) any later version.
    4.11 + *
    4.12 + * This program is distributed in the hope that it will be useful,
    4.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    4.15 + * GNU General Public License for more details.
    4.16 + *
    4.17 + * You should have received a copy of the GNU General Public License
    4.18 + * along with this program; if not, write to the Free Software
    4.19 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
    4.20 + *
    4.21 + * Copyright IBM Corporation, 2007
    4.22 + *   Authors: Anthony Liguori <aliguori@us.ibm.com>
    4.23 + */
    4.24 +
    4.25 +.code16
    4.26 +.text
    4.27 +	.global _start
    4.28 +_start:
    4.29 +	.short 0xaa55
    4.30 +	.byte (_end - _start) / 512
    4.31 +
    4.32 +	push %ax
    4.33 +	push %bx
    4.34 +	push %cx
    4.35 +	push %dx
    4.36 +	push %ds
    4.37 +
    4.38 +	/* setup ds so we can access the IVT */
    4.39 +	xor %ax, %ax
    4.40 +	mov %ax, %ds
    4.41 +
    4.42 +	/* save old int 19 at int 2b */
    4.43 +	mov $(0x19 * 4), %bx
    4.44 +	mov 0(%bx), %ax
    4.45 +	mov 2(%bx), %cx
    4.46 +
    4.47 +	mov $(0x2b * 4), %bx
    4.48 +	mov %ax, 0(%bx)
    4.49 +	mov %cx, 2(%bx)
    4.50 +
    4.51 +	/* install our int 19 handler */
    4.52 +	mov $(0x19 * 4), %bx
    4.53 +	mov $int19_handler, %ax
    4.54 +	mov %ax, 0(%bx)
    4.55 +	mov %cs, 2(%bx)
    4.56 +
    4.57 +	pop %ds
    4.58 +	pop %dx
    4.59 +	pop %cx
    4.60 +	pop %bx
    4.61 +	pop %ax
    4.62 +	lret
    4.63 +
    4.64 +int19_handler:
    4.65 +	push %ax
    4.66 +	push %bx
    4.67 +	push %cx
    4.68 +	push %dx
    4.69 +	push %ds
    4.70 +
    4.71 +	movw $0x404, %dx
    4.72 +	inb %dx, %al
    4.73 +	cmp $1, %al
    4.74 +	jne 1f
    4.75 +
    4.76 +	/* hook int13 */
    4.77 +	/* setup ds to access IVT */
    4.78 +	xor %ax, %ax
    4.79 +	mov %ax, %ds
    4.80 +
    4.81 +	/* save old int 13 to int 2c */
    4.82 +	mov $(0x13 * 4), %bx
    4.83 +	mov 0(%bx), %ax
    4.84 +	mov 2(%bx), %cx
    4.85 +
    4.86 +	mov $(0x2c * 4), %bx
    4.87 +	mov %ax, 0(%bx)
    4.88 +	mov %cx, 2(%bx)
    4.89 +
    4.90 +	/* install our int 13 handler */
    4.91 +	mov $(0x13 * 4), %bx
    4.92 +	mov $int13_handler, %ax
    4.93 +
    4.94 +	mov %ax, 0(%bx)
    4.95 +	mov %cs, 2(%bx)
    4.96 +
    4.97 +1:	pop %ds
    4.98 +	pop %dx
    4.99 +	pop %cx
   4.100 +	pop %bx
   4.101 +	pop %ax
   4.102 +	int $0x2b
   4.103 +
   4.104 +#define FLAGS_CF	0x01
   4.105 +
   4.106 +.macro clc
   4.107 +	push %ax
   4.108 +	pushf
   4.109 +	pop %ax
   4.110 +	and $(~FLAGS_CF), %ax
   4.111 +	push %ax
   4.112 +	popf
   4.113 +	pop %ax
   4.114 +.endm
   4.115 +
   4.116 +.macro stc
   4.117 +	push %ax
   4.118 +	pushf
   4.119 +	pop %ax
   4.120 +	or $(FLAGS_CF), %ax
   4.121 +	push %ax
   4.122 +	popf
   4.123 +	pop %ax
   4.124 +.endm
   4.125 +
   4.126 +/* we clobber %bx */
   4.127 +.macro alloca size
   4.128 +	push %ds
   4.129 +	push %bp
   4.130 +	mov %sp, %bp  /* remember the current stack position */
   4.131 +
   4.132 +	mov %ss, %bx
   4.133 +	mov %bx, %ds
   4.134 +
   4.135 +	sub \size, %sp
   4.136 +	and $(~0x0F), %sp
   4.137 +	mov %sp, %bx
   4.138 +
   4.139 +	push %bp
   4.140 +	mov 0(%bp), %bp
   4.141 +.endm
   4.142 +
   4.143 +/* we clobber %bp */
   4.144 +.macro allocbpa size
   4.145 +	mov %sp, %bp  /* remember the current stack position */
   4.146 +	sub \size, %sp
   4.147 +	and $(~0x0F), %sp
   4.148 +	push %bp
   4.149 +	mov %sp, %bp
   4.150 +	add $2, %bp
   4.151 +.endm
   4.152 +
   4.153 +.macro freea
   4.154 +	pop %sp
   4.155 +	add $2, %sp
   4.156 +	pop %ds
   4.157 +.endm
   4.158 +
   4.159 +.macro freebpa
   4.160 +	pop %sp
   4.161 +.endm
   4.162 +
   4.163 +.macro dump reg
   4.164 +	push %ax
   4.165 +	push %dx
   4.166 +
   4.167 +	mov \reg, %ax
   4.168 +	mov $0x406, %dx
   4.169 +	outw %ax, %dx
   4.170 +
   4.171 +	pop %dx
   4.172 +	pop %ax
   4.173 +.endm
   4.174 +
   4.175 +.macro callout value
   4.176 +	push %bp
   4.177 +	push %bx
   4.178 +	mov %sp, %bp
   4.179 +	alloca $16
   4.180 +	push %ax
   4.181 +	push %dx
   4.182 +
   4.183 +	mov %ax, 0(%bx)     /* ax */
   4.184 +	mov 0(%bp), %ax     /* bx */
   4.185 +	mov %ax, 2(%bx)
   4.186 +	mov %cx, 4(%bx)     /* cx */
   4.187 +	mov %dx, 6(%bx)     /* dx */
   4.188 +	mov %si, 8(%bx)     /* si */
   4.189 +	mov %ds, 10(%bx)    /* ds */
   4.190 +	mov %es, 12(%bx)    /* ds */
   4.191 +	movw \value, 14(%bx) /* value */
   4.192 +
   4.193 +	mov %bx, %ax
   4.194 +	shr $4, %ax
   4.195 +	mov %ds, %dx
   4.196 +	add %dx, %ax
   4.197 +
   4.198 +	mov $0x407, %dx
   4.199 +	outw %ax, %dx
   4.200 +
   4.201 +	pop %dx
   4.202 +	pop %ax
   4.203 +	freea
   4.204 +	pop %bx
   4.205 +	pop %bp
   4.206 +.endm
   4.207 +
   4.208 +send_command:
   4.209 +	push %bp
   4.210 +	mov %sp, %bp
   4.211 +	push %ax
   4.212 +	push %bx
   4.213 +	push %dx
   4.214 +
   4.215 +	mov 4(%bp), %ax
   4.216 +	shr $4, %ax
   4.217 +	and $0x0FFF, %ax
   4.218 +	mov %ss, %bx
   4.219 +	add %bx, %ax
   4.220 +
   4.221 +	mov $0x405, %dx
   4.222 +	outw %ax, %dx
   4.223 +
   4.224 +	pop %dx
   4.225 +	pop %bx
   4.226 +	pop %ax
   4.227 +	pop %bp
   4.228 +
   4.229 +	push %ax
   4.230 +	mov 2(%bx), %ax
   4.231 +	pop %ax
   4.232 +
   4.233 +	ret
   4.234 +
   4.235 +add32:  /* lo, hi, lo, hi */
   4.236 +	push %bp
   4.237 +	mov %sp, %bp
   4.238 +
   4.239 +	movw 4(%bp), %cx  /* hi */
   4.240 +	movw 6(%bp), %dx  /* lo */
   4.241 +
   4.242 +	add  10(%bp), %dx
   4.243 +	jnc 1f
   4.244 +	add $1, %cx
   4.245 +1:	add 8(%bp), %cx
   4.246 +
   4.247 +	pop %bp
   4.248 +	ret
   4.249 +
   4.250 +mul32:  /* lo,      hi,     lo,     hi */
   4.251 +	/* 10(%bp), 8(%bp), 6(%bp), 4(%bp) */
   4.252 +	push %bp
   4.253 +	mov %sp, %bp
   4.254 +	push %ax
   4.255 +	push %bx
   4.256 +
   4.257 +	xor %cx, %cx
   4.258 +	xor %dx, %dx
   4.259 +
   4.260 +	/* for (i = 0; i < 16;) */
   4.261 +	xor %bx, %bx
   4.262 +0:
   4.263 +	cmp $16, %bx
   4.264 +	jge 2f
   4.265 +
   4.266 +	mov 6(%bp), %ax
   4.267 +	and $1, %ax
   4.268 +	cmp $1, %ax
   4.269 +	jne 1f
   4.270 +	push 10(%bp)
   4.271 +	push 8(%bp)
   4.272 +	push %dx
   4.273 +	push %cx
   4.274 +	call add32
   4.275 +	add $8, %sp
   4.276 +1:
   4.277 +	shlw $1, 8(%bp)
   4.278 +	movw 10(%bp), %ax
   4.279 +	and $0x8000, %ax
   4.280 +	cmp $0x8000, %ax
   4.281 +	jne 1f
   4.282 +	orw $1, 8(%bp)
   4.283 +1:
   4.284 +	shlw $1, 10(%bp)
   4.285 +	shrw $1, 6(%bp)
   4.286 +
   4.287 +	/* i++) { */
   4.288 +	add $1, %bx
   4.289 +	jmp 0b
   4.290 +
   4.291 +2:
   4.292 +	pop %bx
   4.293 +	pop %ax
   4.294 +	pop %bp
   4.295 +	ret
   4.296 +
   4.297 +disk_reset:
   4.298 +	movb $0, %ah
   4.299 +	clc
   4.300 +	ret
   4.301 +
   4.302 +/* this really should be a function, not a macro but i'm lazy */
   4.303 +.macro read_write_disk_sectors cmd
   4.304 +	push %ax
   4.305 +	push %bx
   4.306 +	push %cx
   4.307 +	push %dx
   4.308 +	push %si
   4.309 +
   4.310 +	push %bp
   4.311 +	sub $10, %sp
   4.312 +	mov %sp, %bp
   4.313 +
   4.314 +	/* save nb_sectors */
   4.315 +	mov %al, 6(%bp)
   4.316 +	movb $0, 7(%bp)
   4.317 +
   4.318 +	/* save buffer */
   4.319 +	mov %bx, 8(%bp)
   4.320 +
   4.321 +	/* cylinders */
   4.322 +	xor %ax, %ax
   4.323 +	mov %cl, %al
   4.324 +	shl $2, %ax
   4.325 +	and $0x300, %ax
   4.326 +	mov %ch, %al
   4.327 +	mov %ax, 0(%bp)
   4.328 +
   4.329 +	/* heads */
   4.330 +	xor %ax, %ax
   4.331 +	mov %dh, %al
   4.332 +	mov %ax, 2(%bp)
   4.333 +
   4.334 +	/* sectors - 1 */
   4.335 +	xor %ax, %ax
   4.336 +	mov %cl, %al
   4.337 +	and $0x3F, %al
   4.338 +	sub $1, %ax
   4.339 +	mov %ax, 4(%bp)
   4.340 +
   4.341 +	alloca $8
   4.342 +
   4.343 +	movw $0, 0(%bx) /* read c,h,s */
   4.344 +	push %bx
   4.345 +	call send_command
   4.346 +	add $2, %sp
   4.347 +
   4.348 +	mov 6(%bx), %ax /* total_sectors */
   4.349 +	mov 2(%bp), %si /* *= heads */
   4.350 +	mul %si
   4.351 +	add 4(%bp), %ax /* += sectors - 1 */
   4.352 +
   4.353 +	push 4(%bx) /* total_heads */
   4.354 +	push $0
   4.355 +	push 6(%bx) /* total_sectors */
   4.356 +	push $0
   4.357 +	call mul32
   4.358 +	add $8, %sp
   4.359 +
   4.360 +	push 0(%bp) /* cylinders */
   4.361 +	push $0
   4.362 +	push %dx
   4.363 +	push %cx
   4.364 +	call mul32
   4.365 +	add $8, %sp
   4.366 +
   4.367 +	add %ax, %dx
   4.368 +	jnc 1f
   4.369 +	add $1, %cx
   4.370 +1:
   4.371 +	freea
   4.372 +
   4.373 +	alloca $16
   4.374 +
   4.375 +	movw \cmd, 0(%bx) /* read */
   4.376 +	movw 6(%bp), %ax /* nb_sectors */
   4.377 +	movw %ax, 2(%bx)
   4.378 +	movw %es, 4(%bx) /* segment */
   4.379 +	movw 8(%bp), %ax /* offset */
   4.380 +	mov %ax, 6(%bx)
   4.381 +	movw %dx, 8(%bx) /* sector */
   4.382 +	movw %cx, 10(%bx)
   4.383 +	movw $0, 12(%bx)
   4.384 +	movw $0, 14(%bx)
   4.385 +
   4.386 +	push %bx
   4.387 +	call send_command
   4.388 +	add $2, %sp
   4.389 +
   4.390 +	freea
   4.391 +
   4.392 +	add $10, %sp
   4.393 +	pop %bp
   4.394 +
   4.395 +	pop %si
   4.396 +	pop %dx
   4.397 +	pop %cx
   4.398 +	pop %bx
   4.399 +	pop %ax
   4.400 +
   4.401 +	mov $0, %ah
   4.402 +	clc
   4.403 +	ret
   4.404 +.endm
   4.405 +
   4.406 +read_disk_sectors:
   4.407 +	read_write_disk_sectors $0x01
   4.408 +
   4.409 +write_disk_sectors:
   4.410 +	read_write_disk_sectors $0x02
   4.411 +
   4.412 +read_disk_drive_parameters:
   4.413 +	push %bx
   4.414 +
   4.415 +	/* allocate memory for packet, pointer gets returned in bx */
   4.416 +	alloca $8
   4.417 +
   4.418 +	/* issue command */
   4.419 +	movw $0, 0(%bx) /* cmd = 0, read c,h,s */
   4.420 +	push %bx
   4.421 +	call send_command
   4.422 +	add $2, %sp
   4.423 +
   4.424 +	/* normalize sector value */
   4.425 +	movb 6(%bx), %cl
   4.426 +	andb $0x3F, %cl
   4.427 +	movb %cl, 6(%bx)
   4.428 +
   4.429 +	/* normalize cylinders */
   4.430 +	subw $2, 2(%bx)
   4.431 +
   4.432 +	/* normalize heads */
   4.433 +	subw $1, 4(%bx)
   4.434 +
   4.435 +	/* return code */
   4.436 +	mov $0, %ah
   4.437 +
   4.438 +	/* cylinders */
   4.439 +	movb 2(%bx), %ch
   4.440 +	movb 3(%bx), %cl
   4.441 +	shlb $6, %cl
   4.442 +	andb $0xC0, %cl
   4.443 +
   4.444 +	/* sectors */
   4.445 +	orb 6(%bx), %cl
   4.446 +
   4.447 +	/* heads */
   4.448 +	movb 4(%bx), %dh
   4.449 +
   4.450 +	/* drives */
   4.451 +	movb $1, %dl
   4.452 +
   4.453 +	/* status */
   4.454 +	mov $0, %ah
   4.455 +
   4.456 +	freea
   4.457 +
   4.458 +	pop %bx
   4.459 +
   4.460 +	/* do this last since it's the most sensitive */
   4.461 +	clc
   4.462 +	ret
   4.463 +
   4.464 +alternate_disk_reset:
   4.465 +	movb $0, %ah
   4.466 +	clc
   4.467 +	ret
   4.468 +
   4.469 +read_disk_drive_size:
   4.470 +	push %bx
   4.471 +	alloca $8
   4.472 +
   4.473 +	movw $0, 0(%bx) /* cmd = 0, read c,h,s */
   4.474 +	push %bx
   4.475 +	call send_command
   4.476 +	add $2, %sp
   4.477 +
   4.478 +	/* cylinders - 1 to cx:dx */
   4.479 +	mov 2(%bx), %dx
   4.480 +	xor %cx, %cx
   4.481 +	sub $1, %dx
   4.482 +
   4.483 +	/* heads */
   4.484 +	push 4(%bx)
   4.485 +	push $0
   4.486 +	push %dx
   4.487 +	push %cx
   4.488 +	call mul32
   4.489 +	add $8, %sp
   4.490 +
   4.491 +	/* sectors */
   4.492 +	push 6(%bx)
   4.493 +	push $0
   4.494 +	push %dx
   4.495 +	push %cx
   4.496 +	call mul32
   4.497 +	add $8, %sp
   4.498 +
   4.499 +	/* status */
   4.500 +	mov $3, %ah
   4.501 +
   4.502 +	freea
   4.503 +	pop %bx
   4.504 +
   4.505 +	clc
   4.506 +	ret
   4.507 +
   4.508 +check_if_extensions_present:
   4.509 +	mov $0x30, %ah
   4.510 +	mov $0xAA55, %bx
   4.511 +	mov $0x07, %cx
   4.512 +	clc
   4.513 +	ret
   4.514 +
   4.515 +.macro extended_read_write_sectors cmd
   4.516 +	cmpb $10, 0(%si)
   4.517 +	jg 1f
   4.518 +	mov $1, %ah
   4.519 +	stc
   4.520 +	ret
   4.521 +1:
   4.522 +	push %ax
   4.523 +	push %bp
   4.524 +	allocbpa $16
   4.525 +
   4.526 +	movw \cmd, 0(%bp) /* read */
   4.527 +	movw 2(%si), %ax   /* nb_sectors */
   4.528 +	movw %ax, 2(%bp)
   4.529 +	movw 4(%si), %ax   /* offset */
   4.530 +	movw %ax, 6(%bp)
   4.531 +	movw 6(%si), %ax   /* segment */
   4.532 +	movw %ax, 4(%bp)
   4.533 +	movw 8(%si), %ax   /* block */
   4.534 +	movw %ax, 8(%bp)
   4.535 +	movw 10(%si), %ax
   4.536 +	movw %ax, 10(%bp)
   4.537 +	movw 12(%si), %ax
   4.538 +	movw %ax, 12(%bp)
   4.539 +	movw 14(%si), %ax
   4.540 +	movw %ax, 14(%bp)
   4.541 +
   4.542 +	push %bp
   4.543 +	call send_command
   4.544 +	add $2, %sp
   4.545 +
   4.546 +	freebpa
   4.547 +	pop %bp
   4.548 +	pop %ax
   4.549 +
   4.550 +	mov $0, %ah
   4.551 +	clc
   4.552 +	ret
   4.553 +.endm
   4.554 +
   4.555 +extended_read_sectors:
   4.556 +	extended_read_write_sectors $0x01
   4.557 +
   4.558 +extended_write_sectors:
   4.559 +	extended_read_write_sectors $0x02
   4.560 +
   4.561 +get_extended_drive_parameters:
   4.562 +	mov $1, %ah
   4.563 +	stc
   4.564 +	ret
   4.565 +
   4.566 +terminate_disk_emulation:
   4.567 +	mov $1, %ah
   4.568 +	stc
   4.569 +	ret
   4.570 +
   4.571 +int13_handler:
   4.572 +	cmp $0x80, %dl
   4.573 +	je 1f
   4.574 +	int $0x2c
   4.575 +	iret
   4.576 +1:
   4.577 +	cmp $0x0, %ah
   4.578 +	jne 1f
   4.579 +	call disk_reset
   4.580 +	iret
   4.581 +1:
   4.582 +	cmp $0x2, %ah
   4.583 +	jne 1f
   4.584 +	call read_disk_sectors
   4.585 +	iret
   4.586 +1:
   4.587 +	cmp $0x8, %ah
   4.588 +	jne 1f
   4.589 +	call read_disk_drive_parameters
   4.590 +	iret
   4.591 +1:
   4.592 +	cmp $0x15, %ah
   4.593 +	jne 1f
   4.594 +	call read_disk_drive_size
   4.595 +	iret
   4.596 +1:
   4.597 +	cmp $0x41, %ah
   4.598 +	jne 1f
   4.599 +	call check_if_extensions_present
   4.600 +	iret
   4.601 +1:
   4.602 +	cmp $0x42, %ah
   4.603 +	jne 1f
   4.604 +	call extended_read_sectors
   4.605 +	iret
   4.606 +1:
   4.607 +	cmp $0x48, %ah
   4.608 +	jne 1f
   4.609 +	call get_extended_drive_parameters
   4.610 +	iret
   4.611 +1:
   4.612 +	cmp $0x4b, %ah
   4.613 +	jne 1f
   4.614 +	call terminate_disk_emulation
   4.615 +	iret
   4.616 +1:
   4.617 +	cmp $0x0d, %ah
   4.618 +	jne 1f
   4.619 +	call alternate_disk_reset
   4.620 +	iret
   4.621 +1:
   4.622 +	cmp $0x03, %ah
   4.623 +	jne 1f
   4.624 +	call write_disk_sectors
   4.625 +	iret
   4.626 +1:
   4.627 +	cmp $0x43, %ah
   4.628 +	jne 1f
   4.629 +	call extended_write_sectors
   4.630 +	iret
   4.631 +1:
   4.632 +	int $0x18  /* boot failed */
   4.633 +	iret
   4.634 +
   4.635 +.align 512, 0
   4.636 +_end:
     5.1 Binary file tools/firmware/extboot/extboot.img has changed
     6.1 Binary file tools/firmware/extboot/signrom has changed
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/tools/firmware/extboot/signrom.c	Thu Jan 17 16:39:14 2008 +0000
     7.3 @@ -0,0 +1,79 @@
     7.4 +/*
     7.5 + * Extended Boot Option ROM
     7.6 + *
     7.7 + * This program is free software; you can redistribute it and/or modify
     7.8 + * it under the terms of the GNU General Public License as published by
     7.9 + * the Free Software Foundation; either version 2 of the License, or
    7.10 + * (at your option) any later version.
    7.11 + *
    7.12 + * This program is distributed in the hope that it will be useful,
    7.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    7.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    7.15 + * GNU General Public License for more details.
    7.16 + *
    7.17 + * You should have received a copy of the GNU General Public License
    7.18 + * along with this program; if not, write to the Free Software
    7.19 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
    7.20 + *
    7.21 + * Copyright IBM Corporation, 2007
    7.22 + *   Authors: Anthony Liguori <aliguori@us.ibm.com>
    7.23 + */
    7.24 +
    7.25 +#include <stdio.h>
    7.26 +#include <stdint.h>
    7.27 +#include <string.h>
    7.28 +
    7.29 +int main(int argc, char **argv)
    7.30 +{
    7.31 +	FILE *fin, *fout;
    7.32 +	char buffer[512], oldbuffer[512];
    7.33 +	int i, size, lag = 0;
    7.34 +	uint8_t sum = 0;
    7.35 +
    7.36 +	if (argc != 3) {
    7.37 +		printf("Usage: %s ROM OUTPUT\n", argv[0]);
    7.38 +		return 1;
    7.39 +	}
    7.40 +
    7.41 +	fin = fopen(argv[1], "rb");
    7.42 +	fout = fopen(argv[2], "wb");
    7.43 +
    7.44 +	if (fin == NULL || fout == NULL) {
    7.45 +		fprintf(stderr, "Could not open input/output files\n");
    7.46 +		return 1;
    7.47 +	}
    7.48 +
    7.49 +	do {
    7.50 +		size = fread(buffer, 512, 1, fin);
    7.51 +		if (size == 1) {
    7.52 +			for (i = 0; i < 512; i++)
    7.53 +				sum += buffer[i];
    7.54 +
    7.55 +			if (lag) {
    7.56 +				if (fwrite(oldbuffer, 512, 1, fout) != 1) {
    7.57 +					fprintf(stderr, "Write failed\n");
    7.58 +					return 1;
    7.59 +				}
    7.60 +			}
    7.61 +			lag = 1;
    7.62 +			memcpy(oldbuffer, buffer, 512);
    7.63 +		}
    7.64 +	} while (size == 1);
    7.65 +
    7.66 +	if (size != 0) {
    7.67 +		fprintf(stderr, "Failed to read from input file\n");
    7.68 +		return 1;
    7.69 +	}
    7.70 +
    7.71 +	oldbuffer[511] = -sum;
    7.72 +
    7.73 +	if (fwrite(oldbuffer, 512, 1, fout) != 1) {
    7.74 +		fprintf(stderr, "Failed to write to output file\n");
    7.75 +		return 1;
    7.76 +	}
    7.77 +
    7.78 +	fclose(fin);
    7.79 +	fclose(fout);
    7.80 +
    7.81 +	return 0;
    7.82 +}
     8.1 --- a/tools/firmware/hvmloader/Makefile	Thu Jan 17 15:50:48 2008 +0000
     8.2 +++ b/tools/firmware/hvmloader/Makefile	Thu Jan 17 16:39:14 2008 +0000
     8.3 @@ -55,6 +55,7 @@ roms.h:	../rombios/BIOS-bochs-latest ../
     8.4  	sh ./mkhex vgabios_cirrusvga ../vgabios/VGABIOS-lgpl-latest.cirrus.bin >> roms.h
     8.5  	sh ./mkhex vmxassist ../vmxassist/vmxassist.bin >> roms.h
     8.6  	cat ../etherboot/eb-rtl8139.zrom.h >> roms.h
     8.7 +	sh ./mkhex extboot ../extboot/extboot.bin >> roms.h
     8.8  
     8.9  .PHONY: clean
    8.10  clean:
     9.1 --- a/tools/firmware/hvmloader/config.h	Thu Jan 17 15:50:48 2008 +0000
     9.2 +++ b/tools/firmware/hvmloader/config.h	Thu Jan 17 16:39:14 2008 +0000
     9.3 @@ -22,6 +22,7 @@
     9.4  #define VGABIOS_PHYSICAL_ADDRESS      0x000C0000
     9.5  #define ETHERBOOT_PHYSICAL_ADDRESS    0x000C8000
     9.6  #define VMXASSIST_PHYSICAL_ADDRESS    0x000D0000
     9.7 +#define EXTBOOT_PHYSICAL_ADDRESS      0x000DF800
     9.8  #define SMBIOS_PHYSICAL_ADDRESS       0x000E9000
     9.9  #define SMBIOS_MAXIMUM_SIZE           0x00001000
    9.10  #define ACPI_PHYSICAL_ADDRESS         0x000EA000
    10.1 --- a/tools/firmware/hvmloader/hvmloader.c	Thu Jan 17 15:50:48 2008 +0000
    10.2 +++ b/tools/firmware/hvmloader/hvmloader.c	Thu Jan 17 16:39:14 2008 +0000
    10.3 @@ -316,6 +316,11 @@ static int must_load_nic(void)
    10.4      return ((boot_order & 0xf0) == 0x40);
    10.5  }
    10.6  
    10.7 +static int must_load_extboot(void)
    10.8 +{
    10.9 +    return (inb(0x404) == 1);
   10.10 +}
   10.11 +
   10.12  /* Replace possibly erroneous memory-size CMOS fields with correct values. */
   10.13  static void cmos_write_memory_size(void)
   10.14  {
   10.15 @@ -354,6 +359,7 @@ static void cmos_write_memory_size(void)
   10.16  int main(void)
   10.17  {
   10.18      int acpi_sz = 0, vgabios_sz = 0, etherboot_sz = 0, rombios_sz, smbios_sz;
   10.19 +    int extboot_sz = 0;
   10.20  
   10.21      printf("HVM Loader\n");
   10.22  
   10.23 @@ -398,6 +404,14 @@ int main(void)
   10.24          etherboot_sz = sizeof(etherboot);
   10.25      }
   10.26  
   10.27 +    if ( must_load_extboot() )
   10.28 +    {
   10.29 +        printf("Loading EXTBOOT ...\n");
   10.30 +        memcpy((void *)EXTBOOT_PHYSICAL_ADDRESS,
   10.31 +               extboot, sizeof(extboot));
   10.32 +        extboot_sz = sizeof(extboot);
   10.33 +    }
   10.34 +
   10.35      if ( get_acpi_enabled() )
   10.36      {
   10.37          printf("Loading ACPI ...\n");
   10.38 @@ -416,6 +430,10 @@ int main(void)
   10.39          printf(" %05x-%05x: Etherboot ROM\n",
   10.40                 ETHERBOOT_PHYSICAL_ADDRESS,
   10.41                 ETHERBOOT_PHYSICAL_ADDRESS + etherboot_sz - 1);
   10.42 +    if ( extboot_sz )
   10.43 +        printf(" %05x-%05x: Extboot ROM\n",
   10.44 +               EXTBOOT_PHYSICAL_ADDRESS,
   10.45 +               EXTBOOT_PHYSICAL_ADDRESS + extboot_sz - 1);
   10.46      if ( use_vmxassist() )
   10.47          printf(" %05x-%05x: VMXAssist\n",
   10.48                 VMXASSIST_PHYSICAL_ADDRESS,
    11.1 --- a/tools/ioemu/Makefile.target	Thu Jan 17 15:50:48 2008 +0000
    11.2 +++ b/tools/ioemu/Makefile.target	Thu Jan 17 16:39:14 2008 +0000
    11.3 @@ -403,7 +403,7 @@ VL_OBJS+= ne2000.o rtl8139.o pcnet.o e10
    11.4  
    11.5  ifeq ($(TARGET_BASE_ARCH), i386)
    11.6  # Hardware support
    11.7 -VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
    11.8 +VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV) extboot.o
    11.9  ifeq ($(ARCH),ia64)
   11.10  VL_OBJS+= fdc.o mc146818rtc.o serial.o pc.o
   11.11  else
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/tools/ioemu/hw/extboot.c	Thu Jan 17 16:39:14 2008 +0000
    12.3 @@ -0,0 +1,125 @@
    12.4 +/*
    12.5 + * Extended boot option ROM support.
    12.6 + *
    12.7 + * Copyright IBM, Corp. 2007
    12.8 + *
    12.9 + * Authors:
   12.10 + *  Anthony Liguori   <aliguori@us.ibm.com>
   12.11 + *
   12.12 + * This work is licensed under the terms of the GNU GPL, version 2.  See
   12.13 + * the COPYING file in the top-level directory.
   12.14 + *
   12.15 + */
   12.16 +
   12.17 +#include "vl.h"
   12.18 +
   12.19 +/* Extended Boot ROM suport */
   12.20 +
   12.21 +union extboot_cmd
   12.22 +{
   12.23 +    uint16_t type;
   12.24 +    struct {
   12.25 +	uint16_t type;
   12.26 +	uint16_t cylinders;
   12.27 +	uint16_t heads;
   12.28 +	uint16_t sectors;
   12.29 +    } query_geometry;
   12.30 +    struct {
   12.31 +	uint16_t type;
   12.32 +	uint16_t nb_sectors;
   12.33 +	uint16_t segment;
   12.34 +	uint16_t offset;
   12.35 +	uint64_t sector;
   12.36 +    } xfer;
   12.37 +};
   12.38 +
   12.39 +static void get_translated_chs(BlockDriverState *bs, int *c, int *h, int *s)
   12.40 +{
   12.41 +    bdrv_get_geometry_hint(bs, c, h, s);
   12.42 +
   12.43 +    if (*c <= 1024) {
   12.44 +	*c >>= 0;
   12.45 +	*h <<= 0;
   12.46 +    } else if (*c <= 2048) {
   12.47 +	*c >>= 1;
   12.48 +	*h <<= 1;
   12.49 +    } else if (*c <= 4096) {
   12.50 +	*c >>= 2;
   12.51 +	*h <<= 2;
   12.52 +    } else if (*c <= 8192) {
   12.53 +	*c >>= 3;
   12.54 +	*h <<= 3;
   12.55 +    } else {
   12.56 +	*c >>= 4;
   12.57 +	*h <<= 4;
   12.58 +    }
   12.59 +
   12.60 +    /* what is the correct algorithm for this?? */
   12.61 +    if (*h == 256) {
   12.62 +	*h = 255;
   12.63 +	*c = *c + 1;
   12.64 +    }
   12.65 +}
   12.66 +
   12.67 +static uint32_t extboot_read(void *opaque, uint32_t addr)
   12.68 +{
   12.69 +    int *pcmd = opaque;
   12.70 +    return *pcmd;
   12.71 +}
   12.72 +
   12.73 +static void extboot_write_cmd(void *opaque, uint32_t addr, uint32_t value)
   12.74 +{
   12.75 +    union extboot_cmd *cmd = (void *)(phys_ram_base + ((value & 0xFFFF) << 4));
   12.76 +    BlockDriverState *bs = opaque;
   12.77 +    int cylinders, heads, sectors, err;
   12.78 +
   12.79 +    get_translated_chs(bs, &cylinders, &heads, &sectors);
   12.80 +
   12.81 +    if (cmd->type == 0x01 || cmd->type == 0x02) {
   12.82 +	target_ulong pa = cmd->xfer.segment * 16 + cmd->xfer.segment;
   12.83 +
   12.84 +	/* possible buffer overflow */
   12.85 +	if ((pa + cmd->xfer.nb_sectors * 512) > phys_ram_size)
   12.86 +	    return;
   12.87 +    }
   12.88 +
   12.89 +    switch (cmd->type) {
   12.90 +    case 0x00:
   12.91 +	cmd->query_geometry.cylinders = cylinders;
   12.92 +	cmd->query_geometry.heads = heads;
   12.93 +	cmd->query_geometry.sectors = sectors;
   12.94 +	cpu_physical_memory_set_dirty((value & 0xFFFF) << 4);
   12.95 +	break;
   12.96 +    case 0x01:
   12.97 +	err = bdrv_read(bs, cmd->xfer.sector, phys_ram_base +
   12.98 +			cmd->xfer.segment * 16 + cmd->xfer.offset,
   12.99 +			cmd->xfer.nb_sectors);
  12.100 +	if (err)
  12.101 +	    printf("Read failed\n");
  12.102 +	break;
  12.103 +    case 0x02:
  12.104 +	err = bdrv_write(bs, cmd->xfer.sector, phys_ram_base +
  12.105 +			 cmd->xfer.segment * 16 + cmd->xfer.offset,
  12.106 +			 cmd->xfer.nb_sectors);
  12.107 +	if (err)
  12.108 +	    printf("Write failed\n");
  12.109 +
  12.110 +	cpu_physical_memory_set_dirty(cmd->xfer.segment * 16 + cmd->xfer.offset);
  12.111 +	break;
  12.112 +    }
  12.113 +}
  12.114 +
  12.115 +void extboot_init(BlockDriverState *bs, int cmd)
  12.116 +{
  12.117 +    int *pcmd;
  12.118 +
  12.119 +    pcmd = qemu_mallocz(sizeof(int));
  12.120 +    if (!pcmd) {
  12.121 +	fprintf(stderr, "Error allocating memory\n");
  12.122 +	exit(1);
  12.123 +    }
  12.124 +
  12.125 +    *pcmd = cmd;
  12.126 +    register_ioport_read(0x404, 1, 1, extboot_read, pcmd);
  12.127 +    register_ioport_write(0x405, 1, 2, extboot_write_cmd, bs);
  12.128 +}
    13.1 --- a/tools/ioemu/vl.h	Thu Jan 17 15:50:48 2008 +0000
    13.2 +++ b/tools/ioemu/vl.h	Thu Jan 17 16:39:14 2008 +0000
    13.3 @@ -971,6 +971,9 @@ void pci_piix3_ide_init(PCIBus *bus, Blo
    13.4  int pmac_ide_init (BlockDriverState **hd_table,
    13.5                     SetIRQFunc *set_irq, void *irq_opaque, int irq);
    13.6  
    13.7 +/* extboot.c */
    13.8 +void extboot_init(BlockDriverState *bs, int cmd);
    13.9 +
   13.10  /* cdrom.c */
   13.11  int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track);
   13.12  int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num);