Commit d4afc623ae3ca529ff16cc2cf5de9293310de3e6

Authored by bellard
1 parent 80b3ada7

moved PCI, MP and ACPI init to bios


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2167 c046a42c-6fe2-441c-8c8c-71466251a162
pc-bios/bios.bin
No preview for this file type
pc-bios/bios.diff
1   -Index: apmbios.S
2   -===================================================================
3   -RCS file: /cvsroot/bochs/bochs/bios/apmbios.S,v
4   -retrieving revision 1.4
5   -diff -u -w -r1.4 apmbios.S
6   ---- apmbios.S 26 Dec 2005 10:35:51 -0000 1.4
7   -+++ apmbios.S 3 May 2006 21:22:46 -0000
8   -@@ -225,6 +225,7 @@
9   - APMSYM(05):
10   - cmp al, #0x05
11   - jne APMSYM(07)
12   -+ sti
13   - hlt
14   - jmp APMSYM(ok)
  1 +diff -ruN --exclude Makefile bios/acpi-dsdt.dsl bios.new/acpi-dsdt.dsl
  2 +--- bios/acpi-dsdt.dsl 1970-01-01 01:00:00.000000000 +0100
  3 ++++ bios.new/acpi-dsdt.dsl 2006-09-24 20:27:54.000000000 +0200
  4 +@@ -0,0 +1,559 @@
  5 ++/*
  6 ++ * QEMU ACPI DSDT ASL definition
  7 ++ *
  8 ++ * Copyright (c) 2006 Fabrice Bellard
  9 ++ *
  10 ++ * This library is free software; you can redistribute it and/or
  11 ++ * modify it under the terms of the GNU Lesser General Public
  12 ++ * License version 2 as published by the Free Software Foundation.
  13 ++ *
  14 ++ * This library is distributed in the hope that it will be useful,
  15 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17 ++ * Lesser General Public License for more details.
  18 ++ *
  19 ++ * You should have received a copy of the GNU Lesser General Public
  20 ++ * License along with this library; if not, write to the Free Software
  21 ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22 ++ */
  23 ++DefinitionBlock (
  24 ++ "acpi-dsdt.aml", // Output Filename
  25 ++ "DSDT", // Signature
  26 ++ 0x01, // DSDT Compliance Revision
  27 ++ "QEMU", // OEMID
  28 ++ "QEMUDSDT", // TABLE ID
  29 ++ 0x1 // OEM Revision
  30 ++ )
  31 ++{
  32 ++ Scope (\)
  33 ++ {
  34 ++ /* CMOS memory access */
  35 ++ OperationRegion (CMS, SystemIO, 0x70, 0x02)
  36 ++ Field (CMS, ByteAcc, NoLock, Preserve)
  37 ++ {
  38 ++ CMSI, 8,
  39 ++ CMSD, 8
  40 ++ }
  41 ++ Method (CMRD, 1, NotSerialized)
  42 ++ {
  43 ++ Store (Arg0, CMSI)
  44 ++ Store (CMSD, Local0)
  45 ++ Return (Local0)
  46 ++ }
  47 ++
  48 ++ /* Debug Output */
  49 ++ OperationRegion (DBG, SystemIO, 0xb044, 0x04)
  50 ++ Field (DBG, DWordAcc, NoLock, Preserve)
  51 ++ {
  52 ++ DBGL, 32,
  53 ++ }
  54 ++ }
  55 ++
  56 ++
  57 ++ /* PCI Bus definition */
  58 ++ Scope(\_SB) {
  59 ++ Device(PCI0) {
  60 ++ Name (_HID, EisaId ("PNP0A03"))
  61 ++ Name (_ADR, 0x00)
  62 ++ Name (_UID, 1)
  63 ++ Name(_PRT, Package() {
  64 ++ /* PCI IRQ routing table, example from ACPI 2.0a specification,
  65 ++ section 6.2.8.1 */
  66 ++ /* Note: we provide the same info as the PCI routing
  67 ++ table of the Bochs BIOS */
  68 ++
  69 ++ // PCI Slot 0
  70 ++ Package() {0x0000ffff, 0, LNKD, 0},
  71 ++ Package() {0x0000ffff, 1, LNKA, 0},
  72 ++ Package() {0x0000ffff, 2, LNKB, 0},
  73 ++ Package() {0x0000ffff, 3, LNKC, 0},
  74 ++
  75 ++ // PCI Slot 1
  76 ++ Package() {0x0001ffff, 0, LNKA, 0},
  77 ++ Package() {0x0001ffff, 1, LNKB, 0},
  78 ++ Package() {0x0001ffff, 2, LNKC, 0},
  79 ++ Package() {0x0001ffff, 3, LNKD, 0},
  80 ++
  81 ++ // PCI Slot 2
  82 ++ Package() {0x0002ffff, 0, LNKB, 0},
  83 ++ Package() {0x0002ffff, 1, LNKC, 0},
  84 ++ Package() {0x0002ffff, 2, LNKD, 0},
  85 ++ Package() {0x0002ffff, 3, LNKA, 0},
  86 ++
  87 ++ // PCI Slot 3
  88 ++ Package() {0x0003ffff, 0, LNKC, 0},
  89 ++ Package() {0x0003ffff, 1, LNKD, 0},
  90 ++ Package() {0x0003ffff, 2, LNKA, 0},
  91 ++ Package() {0x0003ffff, 3, LNKB, 0},
  92 ++
  93 ++ // PCI Slot 4
  94 ++ Package() {0x0004ffff, 0, LNKD, 0},
  95 ++ Package() {0x0004ffff, 1, LNKA, 0},
  96 ++ Package() {0x0004ffff, 2, LNKB, 0},
  97 ++ Package() {0x0004ffff, 3, LNKC, 0},
  98 ++
  99 ++ // PCI Slot 5
  100 ++ Package() {0x0005ffff, 0, LNKA, 0},
  101 ++ Package() {0x0005ffff, 1, LNKB, 0},
  102 ++ Package() {0x0005ffff, 2, LNKC, 0},
  103 ++ Package() {0x0005ffff, 3, LNKD, 0},
  104 ++ })
  105 ++
  106 ++ Method (_CRS, 0, NotSerialized)
  107 ++ {
  108 ++ Name (MEMP, ResourceTemplate ()
  109 ++ {
  110 ++ WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
  111 ++ 0x0000, // Address Space Granularity
  112 ++ 0x0000, // Address Range Minimum
  113 ++ 0x00FF, // Address Range Maximum
  114 ++ 0x0000, // Address Translation Offset
  115 ++ 0x0100, // Address Length
  116 ++ ,, )
  117 ++ IO (Decode16,
  118 ++ 0x0CF8, // Address Range Minimum
  119 ++ 0x0CF8, // Address Range Maximum
  120 ++ 0x01, // Address Alignment
  121 ++ 0x08, // Address Length
  122 ++ )
  123 ++ WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
  124 ++ 0x0000, // Address Space Granularity
  125 ++ 0x0000, // Address Range Minimum
  126 ++ 0x0CF7, // Address Range Maximum
  127 ++ 0x0000, // Address Translation Offset
  128 ++ 0x0CF8, // Address Length
  129 ++ ,, , TypeStatic)
  130 ++ WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
  131 ++ 0x0000, // Address Space Granularity
  132 ++ 0x0D00, // Address Range Minimum
  133 ++ 0xFFFF, // Address Range Maximum
  134 ++ 0x0000, // Address Translation Offset
  135 ++ 0xF300, // Address Length
  136 ++ ,, , TypeStatic)
  137 ++ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
  138 ++ 0x00000000, // Address Space Granularity
  139 ++ 0x000A0000, // Address Range Minimum
  140 ++ 0x000BFFFF, // Address Range Maximum
  141 ++ 0x00000000, // Address Translation Offset
  142 ++ 0x00020000, // Address Length
  143 ++ ,, , AddressRangeMemory, TypeStatic)
  144 ++ DWordMemory (ResourceProducer, PosDecode, MinNotFixed, MaxFixed, NonCacheable, ReadWrite,
  145 ++ 0x00000000, // Address Space Granularity
  146 ++ 0x00000000, // Address Range Minimum
  147 ++ 0xFEBFFFFF, // Address Range Maximum
  148 ++ 0x00000000, // Address Translation Offset
  149 ++ 0x00000000, // Address Length
  150 ++ ,, MEMF, AddressRangeMemory, TypeStatic)
  151 ++ })
  152 ++ CreateDWordField (MEMP, \_SB.PCI0._CRS.MEMF._MIN, PMIN)
  153 ++ CreateDWordField (MEMP, \_SB.PCI0._CRS.MEMF._MAX, PMAX)
  154 ++ CreateDWordField (MEMP, \_SB.PCI0._CRS.MEMF._LEN, PLEN)
  155 ++ /* compute available RAM */
  156 ++ Add(CMRD(0x34), ShiftLeft(CMRD(0x35), 8), Local0)
  157 ++ ShiftLeft(Local0, 16, Local0)
  158 ++ Add(Local0, 0x1000000, Local0)
  159 ++ /* update field of last region */
  160 ++ Store(Local0, PMIN)
  161 ++ Subtract (PMAX, PMIN, PLEN)
  162 ++ Increment (PLEN)
  163 ++ Return (MEMP)
  164 ++ }
  165 ++ }
  166 ++ }
  167 ++
  168 ++ Scope(\_SB.PCI0) {
  169 ++
  170 ++ /* PIIX3 ISA bridge */
  171 ++ Device (ISA) {
  172 ++ Name (_ADR, 0x00010000)
  173 ++
  174 ++ /* PIIX PCI to ISA irq remapping */
  175 ++ OperationRegion (P40C, PCI_Config, 0x60, 0x04)
  176 ++
  177 ++
  178 ++ /* Keyboard seems to be important for WinXP install */
  179 ++ Device (KBD)
  180 ++ {
  181 ++ Name (_HID, EisaId ("PNP0303"))
  182 ++ Method (_STA, 0, NotSerialized)
  183 ++ {
  184 ++ Return (0x0f)
  185 ++ }
  186 ++
  187 ++ Method (_CRS, 0, NotSerialized)
  188 ++ {
  189 ++ Name (TMP, ResourceTemplate ()
  190 ++ {
  191 ++ IO (Decode16,
  192 ++ 0x0060, // Address Range Minimum
  193 ++ 0x0060, // Address Range Maximum
  194 ++ 0x01, // Address Alignment
  195 ++ 0x01, // Address Length
  196 ++ )
  197 ++ IO (Decode16,
  198 ++ 0x0064, // Address Range Minimum
  199 ++ 0x0064, // Address Range Maximum
  200 ++ 0x01, // Address Alignment
  201 ++ 0x01, // Address Length
  202 ++ )
  203 ++ IRQNoFlags ()
  204 ++ {1}
  205 ++ })
  206 ++ Return (TMP)
  207 ++ }
  208 ++ }
  209 ++
  210 ++ /* PS/2 mouse */
  211 ++ Device (MOU)
  212 ++ {
  213 ++ Name (_HID, EisaId ("PNP0F13"))
  214 ++ Method (_STA, 0, NotSerialized)
  215 ++ {
  216 ++ Return (0x0f)
  217 ++ }
  218 ++
  219 ++ Method (_CRS, 0, NotSerialized)
  220 ++ {
  221 ++ Name (TMP, ResourceTemplate ()
  222 ++ {
  223 ++ IRQNoFlags () {12}
  224 ++ })
  225 ++ Return (TMP)
  226 ++ }
  227 ++ }
  228 ++
  229 ++ /* PS/2 floppy controller */
  230 ++ Device (FDC0)
  231 ++ {
  232 ++ Name (_HID, EisaId ("PNP0700"))
  233 ++ Method (_STA, 0, NotSerialized)
  234 ++ {
  235 ++ Return (0x0F)
  236 ++ }
  237 ++ Method (_CRS, 0, NotSerialized)
  238 ++ {
  239 ++ Name (BUF0, ResourceTemplate ()
  240 ++ {
  241 ++ IO (Decode16, 0x03F2, 0x03F2, 0x00, 0x04)
  242 ++ IO (Decode16, 0x03F7, 0x03F7, 0x00, 0x01)
  243 ++ IRQNoFlags () {6}
  244 ++ DMA (Compatibility, NotBusMaster, Transfer8) {2}
  245 ++ })
  246 ++ Return (BUF0)
  247 ++ }
  248 ++ }
  249 ++
  250 ++ /* Parallel port */
  251 ++ Device (LPT)
  252 ++ {
  253 ++ Name (_HID, EisaId ("PNP0400"))
  254 ++ Method (_STA, 0, NotSerialized)
  255 ++ {
  256 ++ Store (\_SB.PCI0.PX13.DRSA, Local0)
  257 ++ And (Local0, 0x80000000, Local0)
  258 ++ If (LEqual (Local0, 0))
  259 ++ {
  260 ++ Return (0x00)
  261 ++ }
  262 ++ Else
  263 ++ {
  264 ++ Return (0x0F)
  265 ++ }
  266 ++ }
  267 ++ Method (_CRS, 0, NotSerialized)
  268 ++ {
  269 ++ Name (BUF0, ResourceTemplate ()
  270 ++ {
  271 ++ IO (Decode16, 0x0378, 0x0378, 0x08, 0x08)
  272 ++ IRQNoFlags () {7}
  273 ++ })
  274 ++ Return (BUF0)
  275 ++ }
  276 ++ }
  277 ++
  278 ++ /* Serial Ports */
  279 ++ Device (COM1)
  280 ++ {
  281 ++ Name (_HID, EisaId ("PNP0501"))
  282 ++ Name (_UID, 0x01)
  283 ++ Method (_STA, 0, NotSerialized)
  284 ++ {
  285 ++ Store (\_SB.PCI0.PX13.DRSC, Local0)
  286 ++ And (Local0, 0x08000000, Local0)
  287 ++ If (LEqual (Local0, 0))
  288 ++ {
  289 ++ Return (0x00)
  290 ++ }
  291 ++ Else
  292 ++ {
  293 ++ Return (0x0F)
  294 ++ }
  295 ++ }
  296 ++ Method (_CRS, 0, NotSerialized)
  297 ++ {
  298 ++ Name (BUF0, ResourceTemplate ()
  299 ++ {
  300 ++ IO (Decode16, 0x03F8, 0x03F8, 0x00, 0x08)
  301 ++ IRQNoFlags () {4}
  302 ++ })
  303 ++ Return (BUF0)
  304 ++ }
  305 ++ }
  306 ++
  307 ++ Device (COM2)
  308 ++ {
  309 ++ Name (_HID, EisaId ("PNP0501"))
  310 ++ Name (_UID, 0x02)
  311 ++ Method (_STA, 0, NotSerialized)
  312 ++ {
  313 ++ Store (\_SB.PCI0.PX13.DRSC, Local0)
  314 ++ And (Local0, 0x80000000, Local0)
  315 ++ If (LEqual (Local0, 0))
  316 ++ {
  317 ++ Return (0x00)
  318 ++ }
  319 ++ Else
  320 ++ {
  321 ++ Return (0x0F)
  322 ++ }
  323 ++ }
  324 ++ Method (_CRS, 0, NotSerialized)
  325 ++ {
  326 ++ Name (BUF0, ResourceTemplate ()
  327 ++ {
  328 ++ IO (Decode16, 0x02F8, 0x02F8, 0x00, 0x08)
  329 ++ IRQNoFlags () {3}
  330 ++ })
  331 ++ Return (BUF0)
  332 ++ }
  333 ++ }
  334 ++ }
  335 ++
  336 ++ /* PIIX4 PM */
  337 ++ Device (PX13) {
  338 ++ Name (_ADR, 0x00010003)
  339 ++
  340 ++ OperationRegion (P13C, PCI_Config, 0x5c, 0x24)
  341 ++ Field (P13C, DWordAcc, NoLock, Preserve)
  342 ++ {
  343 ++ DRSA, 32,
  344 ++ DRSB, 32,
  345 ++ DRSC, 32,
  346 ++ DRSE, 32,
  347 ++ DRSF, 32,
  348 ++ DRSG, 32,
  349 ++ DRSH, 32,
  350 ++ DRSI, 32,
  351 ++ DRSJ, 32
  352 ++ }
  353 ++ }
  354 ++ }
  355 ++
  356 ++ /* PCI IRQs */
  357 ++ Scope(\_SB) {
  358 ++ Field (\_SB.PCI0.ISA.P40C, ByteAcc, NoLock, Preserve)
  359 ++ {
  360 ++ PRQ0, 8,
  361 ++ PRQ1, 8,
  362 ++ PRQ2, 8,
  363 ++ PRQ3, 8
  364 ++ }
  365 ++
  366 ++ Device(LNKA){
  367 ++ Name(_HID, EISAID("PNP0C0F")) // PCI interrupt link
  368 ++ Name(_UID, 1)
  369 ++ Name(_PRS, ResourceTemplate(){
  370 ++ IRQ (Level, ActiveLow, Shared)
  371 ++ {3,4,5,6,7,9,10,11,12}
  372 ++ })
  373 ++ Method (_STA, 0, NotSerialized)
  374 ++ {
  375 ++ Store (0x0B, Local0)
  376 ++ If (And (0x80, PRQ0, Local1))
  377 ++ {
  378 ++ Store (0x09, Local0)
  379 ++ }
  380 ++ Return (Local0)
  381 ++ }
  382 ++ Method (_DIS, 0, NotSerialized)
  383 ++ {
  384 ++ Or (PRQ0, 0x80, PRQ0)
  385 ++ }
  386 ++ Method (_CRS, 0, NotSerialized)
  387 ++ {
  388 ++ Name (PRR0, ResourceTemplate ()
  389 ++ {
  390 ++ IRQ (Level, ActiveLow, Shared)
  391 ++ {1}
  392 ++ })
  393 ++ CreateWordField (PRR0, 0x01, TMP)
  394 ++ Store (PRQ0, Local0)
  395 ++ If (LLess (Local0, 0x80))
  396 ++ {
  397 ++ ShiftLeft (One, Local0, TMP)
  398 ++ }
  399 ++ Else
  400 ++ {
  401 ++ Store (Zero, TMP)
  402 ++ }
  403 ++ Return (PRR0)
  404 ++ }
  405 ++ Method (_SRS, 1, NotSerialized)
  406 ++ {
  407 ++ CreateWordField (Arg0, 0x01, TMP)
  408 ++ FindSetRightBit (TMP, Local0)
  409 ++ Decrement (Local0)
  410 ++ Store (Local0, PRQ0)
  411 ++ }
  412 ++ }
  413 ++ Device(LNKB){
  414 ++ Name(_HID, EISAID("PNP0C0F")) // PCI interrupt link
  415 ++ Name(_UID, 2)
  416 ++ Name(_PRS, ResourceTemplate(){
  417 ++ IRQ (Level, ActiveLow, Shared)
  418 ++ {3,4,5,6,7,9,10,11,12}
  419 ++ })
  420 ++ Method (_STA, 0, NotSerialized)
  421 ++ {
  422 ++ Store (0x0B, Local0)
  423 ++ If (And (0x80, PRQ1, Local1))
  424 ++ {
  425 ++ Store (0x09, Local0)
  426 ++ }
  427 ++ Return (Local0)
  428 ++ }
  429 ++ Method (_DIS, 0, NotSerialized)
  430 ++ {
  431 ++ Or (PRQ1, 0x80, PRQ1)
  432 ++ }
  433 ++ Method (_CRS, 0, NotSerialized)
  434 ++ {
  435 ++ Name (PRR0, ResourceTemplate ()
  436 ++ {
  437 ++ IRQ (Level, ActiveLow, Shared)
  438 ++ {1}
  439 ++ })
  440 ++ CreateWordField (PRR0, 0x01, TMP)
  441 ++ Store (PRQ1, Local0)
  442 ++ If (LLess (Local0, 0x80))
  443 ++ {
  444 ++ ShiftLeft (One, Local0, TMP)
  445 ++ }
  446 ++ Else
  447 ++ {
  448 ++ Store (Zero, TMP)
  449 ++ }
  450 ++ Return (PRR0)
  451 ++ }
  452 ++ Method (_SRS, 1, NotSerialized)
  453 ++ {
  454 ++ CreateWordField (Arg0, 0x01, TMP)
  455 ++ FindSetRightBit (TMP, Local0)
  456 ++ Decrement (Local0)
  457 ++ Store (Local0, PRQ1)
  458 ++ }
  459 ++ }
  460 ++ Device(LNKC){
  461 ++ Name(_HID, EISAID("PNP0C0F")) // PCI interrupt link
  462 ++ Name(_UID, 3)
  463 ++ Name(_PRS, ResourceTemplate(){
  464 ++ IRQ (Level, ActiveLow, Shared)
  465 ++ {3,4,5,6,7,9,10,11,12}
  466 ++ })
  467 ++ Method (_STA, 0, NotSerialized)
  468 ++ {
  469 ++ Store (0x0B, Local0)
  470 ++ If (And (0x80, PRQ2, Local1))
  471 ++ {
  472 ++ Store (0x09, Local0)
  473 ++ }
  474 ++ Return (Local0)
  475 ++ }
  476 ++ Method (_DIS, 0, NotSerialized)
  477 ++ {
  478 ++ Or (PRQ2, 0x80, PRQ2)
  479 ++ }
  480 ++ Method (_CRS, 0, NotSerialized)
  481 ++ {
  482 ++ Name (PRR0, ResourceTemplate ()
  483 ++ {
  484 ++ IRQ (Level, ActiveLow, Shared)
  485 ++ {1}
  486 ++ })
  487 ++ CreateWordField (PRR0, 0x01, TMP)
  488 ++ Store (PRQ2, Local0)
  489 ++ If (LLess (Local0, 0x80))
  490 ++ {
  491 ++ ShiftLeft (One, Local0, TMP)
  492 ++ }
  493 ++ Else
  494 ++ {
  495 ++ Store (Zero, TMP)
  496 ++ }
  497 ++ Return (PRR0)
  498 ++ }
  499 ++ Method (_SRS, 1, NotSerialized)
  500 ++ {
  501 ++ CreateWordField (Arg0, 0x01, TMP)
  502 ++ FindSetRightBit (TMP, Local0)
  503 ++ Decrement (Local0)
  504 ++ Store (Local0, PRQ2)
  505 ++ }
  506 ++ }
  507 ++ Device(LNKD){
  508 ++ Name(_HID, EISAID("PNP0C0F")) // PCI interrupt link
  509 ++ Name(_UID, 4)
  510 ++ Name(_PRS, ResourceTemplate(){
  511 ++ IRQ (Level, ActiveLow, Shared)
  512 ++ {3,4,5,6,7,9,10,11,12}
  513 ++ })
  514 ++ Method (_STA, 0, NotSerialized)
  515 ++ {
  516 ++ Store (0x0B, Local0)
  517 ++ If (And (0x80, PRQ3, Local1))
  518 ++ {
  519 ++ Store (0x09, Local0)
  520 ++ }
  521 ++ Return (Local0)
  522 ++ }
  523 ++ Method (_DIS, 0, NotSerialized)
  524 ++ {
  525 ++ Or (PRQ3, 0x80, PRQ3)
  526 ++ }
  527 ++ Method (_CRS, 0, NotSerialized)
  528 ++ {
  529 ++ Name (PRR0, ResourceTemplate ()
  530 ++ {
  531 ++ IRQ (Level, ActiveLow, Shared)
  532 ++ {1}
  533 ++ })
  534 ++ CreateWordField (PRR0, 0x01, TMP)
  535 ++ Store (PRQ3, Local0)
  536 ++ If (LLess (Local0, 0x80))
  537 ++ {
  538 ++ ShiftLeft (One, Local0, TMP)
  539 ++ }
  540 ++ Else
  541 ++ {
  542 ++ Store (Zero, TMP)
  543 ++ }
  544 ++ Return (PRR0)
  545 ++ }
  546 ++ Method (_SRS, 1, NotSerialized)
  547 ++ {
  548 ++ CreateWordField (Arg0, 0x01, TMP)
  549 ++ FindSetRightBit (TMP, Local0)
  550 ++ Decrement (Local0)
  551 ++ Store (Local0, PRQ3)
  552 ++ }
  553 ++ }
  554 ++ }
  555 ++
  556 ++ /* S5 = power off state */
  557 ++ Name (_S5, Package (4) {
  558 ++ 0x00, // PM1a_CNT.SLP_TYP
  559 ++ 0x00, // PM2a_CNT.SLP_TYP
  560 ++ 0x00, // reserved
  561 ++ 0x00, // reserved
  562 ++ })
  563 ++}
  564 +diff -ruN --exclude Makefile bios/acpi-dsdt.hex bios.new/acpi-dsdt.hex
  565 +--- bios/acpi-dsdt.hex 1970-01-01 01:00:00.000000000 +0100
  566 ++++ bios.new/acpi-dsdt.hex 2006-09-24 20:27:54.000000000 +0200
  567 +@@ -0,0 +1,278 @@
  568 ++/*
  569 ++ *
  570 ++ * Intel ACPI Component Architecture
  571 ++ * ASL Optimizing Compiler version 20060421 [Apr 29 2006]
  572 ++ * Copyright (C) 2000 - 2006 Intel Corporation
  573 ++ * Supports ACPI Specification Revision 3.0a
  574 ++ *
  575 ++ * Compilation of "/usr/local/home/bellard/qemu-current/hw/acpi-dsdt.dsl" - Wed Jun 14 20:09:53 2006
  576 ++ *
  577 ++ * C source code output
  578 ++ *
  579 ++ */
  580 ++unsigned char AmlCode[] =
  581 ++{
  582 ++ 0x44,0x53,0x44,0x54,0x32,0x08,0x00,0x00, /* 00000000 "DSDT2..." */
  583 ++ 0x01,0x5B,0x51,0x45,0x4D,0x55,0x00,0x00, /* 00000008 ".[QEMU.." */
  584 ++ 0x51,0x45,0x4D,0x55,0x44,0x53,0x44,0x54, /* 00000010 "QEMUDSDT" */
  585 ++ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
  586 ++ 0x21,0x04,0x06,0x20,0x10,0x4F,0x04,0x5C, /* 00000020 "!.. .O.\" */
  587 ++ 0x00,0x5B,0x80,0x43,0x4D,0x53,0x5F,0x01, /* 00000028 ".[.CMS_." */
  588 ++ 0x0A,0x70,0x0A,0x02,0x5B,0x81,0x10,0x43, /* 00000030 ".p..[..C" */
  589 ++ 0x4D,0x53,0x5F,0x01,0x43,0x4D,0x53,0x49, /* 00000038 "MS_.CMSI" */
  590 ++ 0x08,0x43,0x4D,0x53,0x44,0x08,0x14,0x14, /* 00000040 ".CMSD..." */
  591 ++ 0x43,0x4D,0x52,0x44,0x01,0x70,0x68,0x43, /* 00000048 "CMRD.phC" */
  592 ++ 0x4D,0x53,0x49,0x70,0x43,0x4D,0x53,0x44, /* 00000050 "MSIpCMSD" */
  593 ++ 0x60,0xA4,0x60,0x5B,0x80,0x44,0x42,0x47, /* 00000058 "`.`[.DBG" */
  594 ++ 0x5F,0x01,0x0B,0x44,0xB0,0x0A,0x04,0x5B, /* 00000060 "_..D...[" */
  595 ++ 0x81,0x0B,0x44,0x42,0x47,0x5F,0x03,0x44, /* 00000068 "..DBG_.D" */
  596 ++ 0x42,0x47,0x4C,0x20,0x10,0x4E,0x25,0x5F, /* 00000070 "BGL .N%_" */
  597 ++ 0x53,0x42,0x5F,0x5B,0x82,0x46,0x25,0x50, /* 00000078 "SB_[.F%P" */
  598 ++ 0x43,0x49,0x30,0x08,0x5F,0x48,0x49,0x44, /* 00000080 "CI0._HID" */
  599 ++ 0x0C,0x41,0xD0,0x0A,0x03,0x08,0x5F,0x41, /* 00000088 ".A...._A" */
  600 ++ 0x44,0x52,0x00,0x08,0x5F,0x55,0x49,0x44, /* 00000090 "DR.._UID" */
  601 ++ 0x01,0x08,0x5F,0x50,0x52,0x54,0x12,0x47, /* 00000098 ".._PRT.G" */
  602 ++ 0x15,0x18,0x12,0x0B,0x04,0x0B,0xFF,0xFF, /* 000000A0 "........" */
  603 ++ 0x00,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0B, /* 000000A8 ".LNKD..." */
  604 ++ 0x04,0x0B,0xFF,0xFF,0x01,0x4C,0x4E,0x4B, /* 000000B0 ".....LNK" */
  605 ++ 0x41,0x00,0x12,0x0C,0x04,0x0B,0xFF,0xFF, /* 000000B8 "A......." */
  606 ++ 0x0A,0x02,0x4C,0x4E,0x4B,0x42,0x00,0x12, /* 000000C0 "..LNKB.." */
  607 ++ 0x0C,0x04,0x0B,0xFF,0xFF,0x0A,0x03,0x4C, /* 000000C8 ".......L" */
  608 ++ 0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C, /* 000000D0 "NKC....." */
  609 ++ 0xFF,0xFF,0x01,0x00,0x00,0x4C,0x4E,0x4B, /* 000000D8 ".....LNK" */
  610 ++ 0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 000000E0 "A......." */
  611 ++ 0x01,0x00,0x01,0x4C,0x4E,0x4B,0x42,0x00, /* 000000E8 "...LNKB." */
  612 ++ 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x01,0x00, /* 000000F0 "........" */
  613 ++ 0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 000000F8 "..LNKC.." */
  614 ++ 0x0E,0x04,0x0C,0xFF,0xFF,0x01,0x00,0x0A, /* 00000100 "........" */
  615 ++ 0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D, /* 00000108 ".LNKD..." */
  616 ++ 0x04,0x0C,0xFF,0xFF,0x02,0x00,0x00,0x4C, /* 00000110 ".......L" */
  617 ++ 0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C, /* 00000118 "NKB....." */
  618 ++ 0xFF,0xFF,0x02,0x00,0x01,0x4C,0x4E,0x4B, /* 00000120 ".....LNK" */
  619 ++ 0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000128 "C......." */
  620 ++ 0x02,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x44, /* 00000130 "....LNKD" */
  621 ++ 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x02, /* 00000138 "........" */
  622 ++ 0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,0x00, /* 00000140 "...LNKA." */
  623 ++ 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x03,0x00, /* 00000148 "........" */
  624 ++ 0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D, /* 00000150 ".LNKC..." */
  625 ++ 0x04,0x0C,0xFF,0xFF,0x03,0x00,0x01,0x4C, /* 00000158 ".......L" */
  626 ++ 0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C, /* 00000160 "NKD....." */
  627 ++ 0xFF,0xFF,0x03,0x00,0x0A,0x02,0x4C,0x4E, /* 00000168 "......LN" */
  628 ++ 0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 00000170 "KA......" */
  629 ++ 0xFF,0x03,0x00,0x0A,0x03,0x4C,0x4E,0x4B, /* 00000178 ".....LNK" */
  630 ++ 0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000180 "B......." */
  631 ++ 0x04,0x00,0x00,0x4C,0x4E,0x4B,0x44,0x00, /* 00000188 "...LNKD." */
  632 ++ 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x04,0x00, /* 00000190 "........" */
  633 ++ 0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E, /* 00000198 ".LNKA..." */
  634 ++ 0x04,0x0C,0xFF,0xFF,0x04,0x00,0x0A,0x02, /* 000001A0 "........" */
  635 ++ 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04, /* 000001A8 "LNKB...." */
  636 ++ 0x0C,0xFF,0xFF,0x04,0x00,0x0A,0x03,0x4C, /* 000001B0 ".......L" */
  637 ++ 0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C, /* 000001B8 "NKC....." */
  638 ++ 0xFF,0xFF,0x05,0x00,0x00,0x4C,0x4E,0x4B, /* 000001C0 ".....LNK" */
  639 ++ 0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 000001C8 "A......." */
  640 ++ 0x05,0x00,0x01,0x4C,0x4E,0x4B,0x42,0x00, /* 000001D0 "...LNKB." */
  641 ++ 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x05,0x00, /* 000001D8 "........" */
  642 ++ 0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 000001E0 "..LNKC.." */
  643 ++ 0x0E,0x04,0x0C,0xFF,0xFF,0x05,0x00,0x0A, /* 000001E8 "........" */
  644 ++ 0x03,0x4C,0x4E,0x4B,0x44,0x00,0x14,0x4C, /* 000001F0 ".LNKD..L" */
  645 ++ 0x0D,0x5F,0x43,0x52,0x53,0x00,0x08,0x4D, /* 000001F8 "._CRS..M" */
  646 ++ 0x45,0x4D,0x50,0x11,0x42,0x07,0x0A,0x6E, /* 00000200 "EMP.B..n" */
  647 ++ 0x88,0x0D,0x00,0x02,0x0C,0x00,0x00,0x00, /* 00000208 "........" */
  648 ++ 0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x01, /* 00000210 "........" */
  649 ++ 0x47,0x01,0xF8,0x0C,0xF8,0x0C,0x01,0x08, /* 00000218 "G......." */
  650 ++ 0x88,0x0D,0x00,0x01,0x0C,0x03,0x00,0x00, /* 00000220 "........" */
  651 ++ 0x00,0x00,0xF7,0x0C,0x00,0x00,0xF8,0x0C, /* 00000228 "........" */
  652 ++ 0x88,0x0D,0x00,0x01,0x0C,0x03,0x00,0x00, /* 00000230 "........" */
  653 ++ 0x00,0x0D,0xFF,0xFF,0x00,0x00,0x00,0xF3, /* 00000238 "........" */
  654 ++ 0x87,0x17,0x00,0x00,0x0C,0x03,0x00,0x00, /* 00000240 "........" */
  655 ++ 0x00,0x00,0x00,0x00,0x0A,0x00,0xFF,0xFF, /* 00000248 "........" */
  656 ++ 0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000250 "........" */
  657 ++ 0x02,0x00,0x87,0x17,0x00,0x00,0x08,0x01, /* 00000258 "........" */
  658 ++ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000260 "........" */
  659 ++ 0xFF,0xFF,0xBF,0xFE,0x00,0x00,0x00,0x00, /* 00000268 "........" */
  660 ++ 0x00,0x00,0x00,0x00,0x79,0x00,0x8A,0x4D, /* 00000270 "....y..M" */
  661 ++ 0x45,0x4D,0x50,0x0A,0x5C,0x50,0x4D,0x49, /* 00000278 "EMP.\PMI" */
  662 ++ 0x4E,0x8A,0x4D,0x45,0x4D,0x50,0x0A,0x60, /* 00000280 "N.MEMP.`" */
  663 ++ 0x50,0x4D,0x41,0x58,0x8A,0x4D,0x45,0x4D, /* 00000288 "PMAX.MEM" */
  664 ++ 0x50,0x0A,0x68,0x50,0x4C,0x45,0x4E,0x72, /* 00000290 "P.hPLENr" */
  665 ++ 0x43,0x4D,0x52,0x44,0x0A,0x34,0x79,0x43, /* 00000298 "CMRD.4yC" */
  666 ++ 0x4D,0x52,0x44,0x0A,0x35,0x0A,0x08,0x00, /* 000002A0 "MRD.5..." */
  667 ++ 0x60,0x79,0x60,0x0A,0x10,0x60,0x72,0x60, /* 000002A8 "`y`..`r`" */
  668 ++ 0x0C,0x00,0x00,0x00,0x01,0x60,0x70,0x60, /* 000002B0 ".....`p`" */
  669 ++ 0x50,0x4D,0x49,0x4E,0x74,0x50,0x4D,0x41, /* 000002B8 "PMINtPMA" */
  670 ++ 0x58,0x50,0x4D,0x49,0x4E,0x50,0x4C,0x45, /* 000002C0 "XPMINPLE" */
  671 ++ 0x4E,0x75,0x50,0x4C,0x45,0x4E,0xA4,0x4D, /* 000002C8 "NuPLEN.M" */
  672 ++ 0x45,0x4D,0x50,0x10,0x42,0x26,0x2E,0x5F, /* 000002D0 "EMP.B&._" */
  673 ++ 0x53,0x42,0x5F,0x50,0x43,0x49,0x30,0x5B, /* 000002D8 "SB_PCI0[" */
  674 ++ 0x82,0x43,0x20,0x49,0x53,0x41,0x5F,0x08, /* 000002E0 ".C ISA_." */
  675 ++ 0x5F,0x41,0x44,0x52,0x0C,0x00,0x00,0x01, /* 000002E8 "_ADR...." */
  676 ++ 0x00,0x5B,0x80,0x50,0x34,0x30,0x43,0x02, /* 000002F0 ".[.P40C." */
  677 ++ 0x0A,0x60,0x0A,0x04,0x5B,0x82,0x44,0x04, /* 000002F8 ".`..[.D." */
  678 ++ 0x4B,0x42,0x44,0x5F,0x08,0x5F,0x48,0x49, /* 00000300 "KBD_._HI" */
  679 ++ 0x44,0x0C,0x41,0xD0,0x03,0x03,0x14,0x09, /* 00000308 "D.A....." */
  680 ++ 0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,0x0F, /* 00000310 "_STA...." */
  681 ++ 0x14,0x29,0x5F,0x43,0x52,0x53,0x00,0x08, /* 00000318 ".)_CRS.." */
  682 ++ 0x54,0x4D,0x50,0x5F,0x11,0x18,0x0A,0x15, /* 00000320 "TMP_...." */
  683 ++ 0x47,0x01,0x60,0x00,0x60,0x00,0x01,0x01, /* 00000328 "G.`.`..." */
  684 ++ 0x47,0x01,0x64,0x00,0x64,0x00,0x01,0x01, /* 00000330 "G.d.d..." */
  685 ++ 0x22,0x02,0x00,0x79,0x00,0xA4,0x54,0x4D, /* 00000338 ""..y..TM" */
  686 ++ 0x50,0x5F,0x5B,0x82,0x33,0x4D,0x4F,0x55, /* 00000340 "P_[.3MOU" */
  687 ++ 0x5F,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41, /* 00000348 "_._HID.A" */
  688 ++ 0xD0,0x0F,0x13,0x14,0x09,0x5F,0x53,0x54, /* 00000350 "....._ST" */
  689 ++ 0x41,0x00,0xA4,0x0A,0x0F,0x14,0x19,0x5F, /* 00000358 "A......_" */
  690 ++ 0x43,0x52,0x53,0x00,0x08,0x54,0x4D,0x50, /* 00000360 "CRS..TMP" */
  691 ++ 0x5F,0x11,0x08,0x0A,0x05,0x22,0x00,0x10, /* 00000368 "_....".." */
  692 ++ 0x79,0x00,0xA4,0x54,0x4D,0x50,0x5F,0x5B, /* 00000370 "y..TMP_[" */
  693 ++ 0x82,0x47,0x04,0x46,0x44,0x43,0x30,0x08, /* 00000378 ".G.FDC0." */
  694 ++ 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x07, /* 00000380 "_HID.A.." */
  695 ++ 0x00,0x14,0x09,0x5F,0x53,0x54,0x41,0x00, /* 00000388 "..._STA." */
  696 ++ 0xA4,0x0A,0x0F,0x14,0x2C,0x5F,0x43,0x52, /* 00000390 "....,_CR" */
  697 ++ 0x53,0x00,0x08,0x42,0x55,0x46,0x30,0x11, /* 00000398 "S..BUF0." */
  698 ++ 0x1B,0x0A,0x18,0x47,0x01,0xF2,0x03,0xF2, /* 000003A0 "...G...." */
  699 ++ 0x03,0x00,0x04,0x47,0x01,0xF7,0x03,0xF7, /* 000003A8 "...G...." */
  700 ++ 0x03,0x00,0x01,0x22,0x40,0x00,0x2A,0x04, /* 000003B0 "..."@.*." */
  701 ++ 0x00,0x79,0x00,0xA4,0x42,0x55,0x46,0x30, /* 000003B8 ".y..BUF0" */
  702 ++ 0x5B,0x82,0x4B,0x05,0x4C,0x50,0x54,0x5F, /* 000003C0 "[.K.LPT_" */
  703 ++ 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 000003C8 "._HID.A." */
  704 ++ 0x04,0x00,0x14,0x28,0x5F,0x53,0x54,0x41, /* 000003D0 "...(_STA" */
  705 ++ 0x00,0x70,0x5E,0x5E,0x5E,0x2E,0x50,0x58, /* 000003D8 ".p^^^.PX" */
  706 ++ 0x31,0x33,0x44,0x52,0x53,0x41,0x60,0x7B, /* 000003E0 "13DRSA`{" */
  707 ++ 0x60,0x0C,0x00,0x00,0x00,0x80,0x60,0xA0, /* 000003E8 "`.....`." */
  708 ++ 0x06,0x93,0x60,0x00,0xA4,0x00,0xA1,0x04, /* 000003F0 "..`....." */
  709 ++ 0xA4,0x0A,0x0F,0x14,0x21,0x5F,0x43,0x52, /* 000003F8 "....!_CR" */
  710 ++ 0x53,0x00,0x08,0x42,0x55,0x46,0x30,0x11, /* 00000400 "S..BUF0." */
  711 ++ 0x10,0x0A,0x0D,0x47,0x01,0x78,0x03,0x78, /* 00000408 "...G.x.x" */
  712 ++ 0x03,0x08,0x08,0x22,0x80,0x00,0x79,0x00, /* 00000410 "..."..y." */
  713 ++ 0xA4,0x42,0x55,0x46,0x30,0x5B,0x82,0x41, /* 00000418 ".BUF0[.A" */
  714 ++ 0x06,0x43,0x4F,0x4D,0x31,0x08,0x5F,0x48, /* 00000420 ".COM1._H" */
  715 ++ 0x49,0x44,0x0C,0x41,0xD0,0x05,0x01,0x08, /* 00000428 "ID.A...." */
  716 ++ 0x5F,0x55,0x49,0x44,0x01,0x14,0x28,0x5F, /* 00000430 "_UID..(_" */
  717 ++ 0x53,0x54,0x41,0x00,0x70,0x5E,0x5E,0x5E, /* 00000438 "STA.p^^^" */
  718 ++ 0x2E,0x50,0x58,0x31,0x33,0x44,0x52,0x53, /* 00000440 ".PX13DRS" */
  719 ++ 0x43,0x60,0x7B,0x60,0x0C,0x00,0x00,0x00, /* 00000448 "C`{`...." */
  720 ++ 0x08,0x60,0xA0,0x06,0x93,0x60,0x00,0xA4, /* 00000450 ".`...`.." */
  721 ++ 0x00,0xA1,0x04,0xA4,0x0A,0x0F,0x14,0x21, /* 00000458 ".......!" */
  722 ++ 0x5F,0x43,0x52,0x53,0x00,0x08,0x42,0x55, /* 00000460 "_CRS..BU" */
  723 ++ 0x46,0x30,0x11,0x10,0x0A,0x0D,0x47,0x01, /* 00000468 "F0....G." */
  724 ++ 0xF8,0x03,0xF8,0x03,0x00,0x08,0x22,0x10, /* 00000470 "......"." */
  725 ++ 0x00,0x79,0x00,0xA4,0x42,0x55,0x46,0x30, /* 00000478 ".y..BUF0" */
  726 ++ 0x5B,0x82,0x42,0x06,0x43,0x4F,0x4D,0x32, /* 00000480 "[.B.COM2" */
  727 ++ 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000488 "._HID.A." */
  728 ++ 0x05,0x01,0x08,0x5F,0x55,0x49,0x44,0x0A, /* 00000490 "..._UID." */
  729 ++ 0x02,0x14,0x28,0x5F,0x53,0x54,0x41,0x00, /* 00000498 "..(_STA." */
  730 ++ 0x70,0x5E,0x5E,0x5E,0x2E,0x50,0x58,0x31, /* 000004A0 "p^^^.PX1" */
  731 ++ 0x33,0x44,0x52,0x53,0x43,0x60,0x7B,0x60, /* 000004A8 "3DRSC`{`" */
  732 ++ 0x0C,0x00,0x00,0x00,0x80,0x60,0xA0,0x06, /* 000004B0 ".....`.." */
  733 ++ 0x93,0x60,0x00,0xA4,0x00,0xA1,0x04,0xA4, /* 000004B8 ".`......" */
  734 ++ 0x0A,0x0F,0x14,0x21,0x5F,0x43,0x52,0x53, /* 000004C0 "...!_CRS" */
  735 ++ 0x00,0x08,0x42,0x55,0x46,0x30,0x11,0x10, /* 000004C8 "..BUF0.." */
  736 ++ 0x0A,0x0D,0x47,0x01,0xF8,0x02,0xF8,0x02, /* 000004D0 "..G....." */
  737 ++ 0x00,0x08,0x22,0x08,0x00,0x79,0x00,0xA4, /* 000004D8 ".."..y.." */
  738 ++ 0x42,0x55,0x46,0x30,0x5B,0x82,0x40,0x05, /* 000004E0 "BUF0[.@." */
  739 ++ 0x50,0x58,0x31,0x33,0x08,0x5F,0x41,0x44, /* 000004E8 "PX13._AD" */
  740 ++ 0x52,0x0C,0x03,0x00,0x01,0x00,0x5B,0x80, /* 000004F0 "R.....[." */
  741 ++ 0x50,0x31,0x33,0x43,0x02,0x0A,0x5C,0x0A, /* 000004F8 "P13C..\." */
  742 ++ 0x24,0x5B,0x81,0x33,0x50,0x31,0x33,0x43, /* 00000500 "$[.3P13C" */
  743 ++ 0x03,0x44,0x52,0x53,0x41,0x20,0x44,0x52, /* 00000508 ".DRSA DR" */
  744 ++ 0x53,0x42,0x20,0x44,0x52,0x53,0x43,0x20, /* 00000510 "SB DRSC " */
  745 ++ 0x44,0x52,0x53,0x45,0x20,0x44,0x52,0x53, /* 00000518 "DRSE DRS" */
  746 ++ 0x46,0x20,0x44,0x52,0x53,0x47,0x20,0x44, /* 00000520 "F DRSG D" */
  747 ++ 0x52,0x53,0x48,0x20,0x44,0x52,0x53,0x49, /* 00000528 "RSH DRSI" */
  748 ++ 0x20,0x44,0x52,0x53,0x4A,0x20,0x10,0x4F, /* 00000530 " DRSJ .O" */
  749 ++ 0x2E,0x5F,0x53,0x42,0x5F,0x5B,0x81,0x24, /* 00000538 "._SB_[.$" */
  750 ++ 0x2F,0x03,0x50,0x43,0x49,0x30,0x49,0x53, /* 00000540 "/.PCI0IS" */
  751 ++ 0x41,0x5F,0x50,0x34,0x30,0x43,0x01,0x50, /* 00000548 "A_P40C.P" */
  752 ++ 0x52,0x51,0x30,0x08,0x50,0x52,0x51,0x31, /* 00000550 "RQ0.PRQ1" */
  753 ++ 0x08,0x50,0x52,0x51,0x32,0x08,0x50,0x52, /* 00000558 ".PRQ2.PR" */
  754 ++ 0x51,0x33,0x08,0x5B,0x82,0x4E,0x0A,0x4C, /* 00000560 "Q3.[.N.L" */
  755 ++ 0x4E,0x4B,0x41,0x08,0x5F,0x48,0x49,0x44, /* 00000568 "NKA._HID" */
  756 ++ 0x0C,0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55, /* 00000570 ".A...._U" */
  757 ++ 0x49,0x44,0x01,0x08,0x5F,0x50,0x52,0x53, /* 00000578 "ID.._PRS" */
  758 ++ 0x11,0x09,0x0A,0x06,0x23,0xF8,0x1E,0x18, /* 00000580 "....#..." */
  759 ++ 0x79,0x00,0x14,0x1A,0x5F,0x53,0x54,0x41, /* 00000588 "y..._STA" */
  760 ++ 0x00,0x70,0x0A,0x0B,0x60,0xA0,0x0D,0x7B, /* 00000590 ".p..`..{" */
  761 ++ 0x0A,0x80,0x50,0x52,0x51,0x30,0x61,0x70, /* 00000598 "..PRQ0ap" */
  762 ++ 0x0A,0x09,0x60,0xA4,0x60,0x14,0x11,0x5F, /* 000005A0 "..`.`.._" */
  763 ++ 0x44,0x49,0x53,0x00,0x7D,0x50,0x52,0x51, /* 000005A8 "DIS.}PRQ" */
  764 ++ 0x30,0x0A,0x80,0x50,0x52,0x51,0x30,0x14, /* 000005B0 "0..PRQ0." */
  765 ++ 0x3F,0x5F,0x43,0x52,0x53,0x00,0x08,0x50, /* 000005B8 "?_CRS..P" */
  766 ++ 0x52,0x52,0x30,0x11,0x09,0x0A,0x06,0x23, /* 000005C0 "RR0....#" */
  767 ++ 0x02,0x00,0x18,0x79,0x00,0x8B,0x50,0x52, /* 000005C8 "...y..PR" */
  768 ++ 0x52,0x30,0x01,0x54,0x4D,0x50,0x5F,0x70, /* 000005D0 "R0.TMP_p" */
  769 ++ 0x50,0x52,0x51,0x30,0x60,0xA0,0x0C,0x95, /* 000005D8 "PRQ0`..." */
  770 ++ 0x60,0x0A,0x80,0x79,0x01,0x60,0x54,0x4D, /* 000005E0 "`..y.`TM" */
  771 ++ 0x50,0x5F,0xA1,0x07,0x70,0x00,0x54,0x4D, /* 000005E8 "P_..p.TM" */
  772 ++ 0x50,0x5F,0xA4,0x50,0x52,0x52,0x30,0x14, /* 000005F0 "P_.PRR0." */
  773 ++ 0x1B,0x5F,0x53,0x52,0x53,0x01,0x8B,0x68, /* 000005F8 "._SRS..h" */
  774 ++ 0x01,0x54,0x4D,0x50,0x5F,0x82,0x54,0x4D, /* 00000600 ".TMP_.TM" */
  775 ++ 0x50,0x5F,0x60,0x76,0x60,0x70,0x60,0x50, /* 00000608 "P_`v`p`P" */
  776 ++ 0x52,0x51,0x30,0x5B,0x82,0x4F,0x0A,0x4C, /* 00000610 "RQ0[.O.L" */
  777 ++ 0x4E,0x4B,0x42,0x08,0x5F,0x48,0x49,0x44, /* 00000618 "NKB._HID" */
  778 ++ 0x0C,0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55, /* 00000620 ".A...._U" */
  779 ++ 0x49,0x44,0x0A,0x02,0x08,0x5F,0x50,0x52, /* 00000628 "ID..._PR" */
  780 ++ 0x53,0x11,0x09,0x0A,0x06,0x23,0xF8,0x1E, /* 00000630 "S....#.." */
  781 ++ 0x18,0x79,0x00,0x14,0x1A,0x5F,0x53,0x54, /* 00000638 ".y..._ST" */
  782 ++ 0x41,0x00,0x70,0x0A,0x0B,0x60,0xA0,0x0D, /* 00000640 "A.p..`.." */
  783 ++ 0x7B,0x0A,0x80,0x50,0x52,0x51,0x31,0x61, /* 00000648 "{..PRQ1a" */
  784 ++ 0x70,0x0A,0x09,0x60,0xA4,0x60,0x14,0x11, /* 00000650 "p..`.`.." */
  785 ++ 0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,0x52, /* 00000658 "_DIS.}PR" */
  786 ++ 0x51,0x31,0x0A,0x80,0x50,0x52,0x51,0x31, /* 00000660 "Q1..PRQ1" */
  787 ++ 0x14,0x3F,0x5F,0x43,0x52,0x53,0x00,0x08, /* 00000668 ".?_CRS.." */
  788 ++ 0x50,0x52,0x52,0x30,0x11,0x09,0x0A,0x06, /* 00000670 "PRR0...." */
  789 ++ 0x23,0x02,0x00,0x18,0x79,0x00,0x8B,0x50, /* 00000678 "#...y..P" */
  790 ++ 0x52,0x52,0x30,0x01,0x54,0x4D,0x50,0x5F, /* 00000680 "RR0.TMP_" */
  791 ++ 0x70,0x50,0x52,0x51,0x31,0x60,0xA0,0x0C, /* 00000688 "pPRQ1`.." */
  792 ++ 0x95,0x60,0x0A,0x80,0x79,0x01,0x60,0x54, /* 00000690 ".`..y.`T" */
  793 ++ 0x4D,0x50,0x5F,0xA1,0x07,0x70,0x00,0x54, /* 00000698 "MP_..p.T" */
  794 ++ 0x4D,0x50,0x5F,0xA4,0x50,0x52,0x52,0x30, /* 000006A0 "MP_.PRR0" */
  795 ++ 0x14,0x1B,0x5F,0x53,0x52,0x53,0x01,0x8B, /* 000006A8 ".._SRS.." */
  796 ++ 0x68,0x01,0x54,0x4D,0x50,0x5F,0x82,0x54, /* 000006B0 "h.TMP_.T" */
  797 ++ 0x4D,0x50,0x5F,0x60,0x76,0x60,0x70,0x60, /* 000006B8 "MP_`v`p`" */
  798 ++ 0x50,0x52,0x51,0x31,0x5B,0x82,0x4F,0x0A, /* 000006C0 "PRQ1[.O." */
  799 ++ 0x4C,0x4E,0x4B,0x43,0x08,0x5F,0x48,0x49, /* 000006C8 "LNKC._HI" */
  800 ++ 0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08,0x5F, /* 000006D0 "D.A...._" */
  801 ++ 0x55,0x49,0x44,0x0A,0x03,0x08,0x5F,0x50, /* 000006D8 "UID..._P" */
  802 ++ 0x52,0x53,0x11,0x09,0x0A,0x06,0x23,0xF8, /* 000006E0 "RS....#." */
  803 ++ 0x1E,0x18,0x79,0x00,0x14,0x1A,0x5F,0x53, /* 000006E8 "..y..._S" */
  804 ++ 0x54,0x41,0x00,0x70,0x0A,0x0B,0x60,0xA0, /* 000006F0 "TA.p..`." */
  805 ++ 0x0D,0x7B,0x0A,0x80,0x50,0x52,0x51,0x32, /* 000006F8 ".{..PRQ2" */
  806 ++ 0x61,0x70,0x0A,0x09,0x60,0xA4,0x60,0x14, /* 00000700 "ap..`.`." */
  807 ++ 0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,0x50, /* 00000708 "._DIS.}P" */
  808 ++ 0x52,0x51,0x32,0x0A,0x80,0x50,0x52,0x51, /* 00000710 "RQ2..PRQ" */
  809 ++ 0x32,0x14,0x3F,0x5F,0x43,0x52,0x53,0x00, /* 00000718 "2.?_CRS." */
  810 ++ 0x08,0x50,0x52,0x52,0x30,0x11,0x09,0x0A, /* 00000720 ".PRR0..." */
  811 ++ 0x06,0x23,0x02,0x00,0x18,0x79,0x00,0x8B, /* 00000728 ".#...y.." */
  812 ++ 0x50,0x52,0x52,0x30,0x01,0x54,0x4D,0x50, /* 00000730 "PRR0.TMP" */
  813 ++ 0x5F,0x70,0x50,0x52,0x51,0x32,0x60,0xA0, /* 00000738 "_pPRQ2`." */
  814 ++ 0x0C,0x95,0x60,0x0A,0x80,0x79,0x01,0x60, /* 00000740 "..`..y.`" */
  815 ++ 0x54,0x4D,0x50,0x5F,0xA1,0x07,0x70,0x00, /* 00000748 "TMP_..p." */
  816 ++ 0x54,0x4D,0x50,0x5F,0xA4,0x50,0x52,0x52, /* 00000750 "TMP_.PRR" */
  817 ++ 0x30,0x14,0x1B,0x5F,0x53,0x52,0x53,0x01, /* 00000758 "0.._SRS." */
  818 ++ 0x8B,0x68,0x01,0x54,0x4D,0x50,0x5F,0x82, /* 00000760 ".h.TMP_." */
  819 ++ 0x54,0x4D,0x50,0x5F,0x60,0x76,0x60,0x70, /* 00000768 "TMP_`v`p" */
  820 ++ 0x60,0x50,0x52,0x51,0x32,0x5B,0x82,0x4F, /* 00000770 "`PRQ2[.O" */
  821 ++ 0x0A,0x4C,0x4E,0x4B,0x44,0x08,0x5F,0x48, /* 00000778 ".LNKD._H" */
  822 ++ 0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08, /* 00000780 "ID.A...." */
  823 ++ 0x5F,0x55,0x49,0x44,0x0A,0x04,0x08,0x5F, /* 00000788 "_UID..._" */
  824 ++ 0x50,0x52,0x53,0x11,0x09,0x0A,0x06,0x23, /* 00000790 "PRS....#" */
  825 ++ 0xF8,0x1E,0x18,0x79,0x00,0x14,0x1A,0x5F, /* 00000798 "...y..._" */
  826 ++ 0x53,0x54,0x41,0x00,0x70,0x0A,0x0B,0x60, /* 000007A0 "STA.p..`" */
  827 ++ 0xA0,0x0D,0x7B,0x0A,0x80,0x50,0x52,0x51, /* 000007A8 "..{..PRQ" */
  828 ++ 0x33,0x61,0x70,0x0A,0x09,0x60,0xA4,0x60, /* 000007B0 "3ap..`.`" */
  829 ++ 0x14,0x11,0x5F,0x44,0x49,0x53,0x00,0x7D, /* 000007B8 ".._DIS.}" */
  830 ++ 0x50,0x52,0x51,0x33,0x0A,0x80,0x50,0x52, /* 000007C0 "PRQ3..PR" */
  831 ++ 0x51,0x33,0x14,0x3F,0x5F,0x43,0x52,0x53, /* 000007C8 "Q3.?_CRS" */
  832 ++ 0x00,0x08,0x50,0x52,0x52,0x30,0x11,0x09, /* 000007D0 "..PRR0.." */
  833 ++ 0x0A,0x06,0x23,0x02,0x00,0x18,0x79,0x00, /* 000007D8 "..#...y." */
  834 ++ 0x8B,0x50,0x52,0x52,0x30,0x01,0x54,0x4D, /* 000007E0 ".PRR0.TM" */
  835 ++ 0x50,0x5F,0x70,0x50,0x52,0x51,0x33,0x60, /* 000007E8 "P_pPRQ3`" */
  836 ++ 0xA0,0x0C,0x95,0x60,0x0A,0x80,0x79,0x01, /* 000007F0 "...`..y." */
  837 ++ 0x60,0x54,0x4D,0x50,0x5F,0xA1,0x07,0x70, /* 000007F8 "`TMP_..p" */
  838 ++ 0x00,0x54,0x4D,0x50,0x5F,0xA4,0x50,0x52, /* 00000800 ".TMP_.PR" */
  839 ++ 0x52,0x30,0x14,0x1B,0x5F,0x53,0x52,0x53, /* 00000808 "R0.._SRS" */
  840 ++ 0x01,0x8B,0x68,0x01,0x54,0x4D,0x50,0x5F, /* 00000810 "..h.TMP_" */
  841 ++ 0x82,0x54,0x4D,0x50,0x5F,0x60,0x76,0x60, /* 00000818 ".TMP_`v`" */
  842 ++ 0x70,0x60,0x50,0x52,0x51,0x33,0x08,0x5F, /* 00000820 "p`PRQ3._" */
  843 ++ 0x53,0x35,0x5F,0x12,0x06,0x04,0x00,0x00, /* 00000828 "S5_....." */
  844 ++ 0x00,0x00,
  845 ++};
  846 +Binary files bios/BIOS-bochs-latest and bios.new/BIOS-bochs-latest differ
  847 +diff -ruN --exclude Makefile bios/Makefile.in bios.new/Makefile.in
  848 +--- bios/Makefile.in 2006-01-13 18:36:27.000000000 +0100
  849 ++++ bios.new/Makefile.in 2006-09-24 20:26:39.000000000 +0200
  850 +@@ -61,7 +61,8 @@
15 851  
16   -Index: rombios.c
17   -===================================================================
18   -RCS file: /cvsroot/bochs/bochs/bios/rombios.c,v
19   -retrieving revision 1.160
20   -diff -u -w -r1.160 rombios.c
21   ---- rombios.c 25 Jan 2006 17:51:49 -0000 1.160
22   -+++ rombios.c 3 May 2006 21:22:48 -0000
23   -@@ -1816,6 +1816,7 @@
24   - {
25   - printf(BX_APPNAME" BIOS - build: %s\n%s\nOptions: ",
26   - BIOS_BUILD_DATE, bios_cvs_version_string);
  852 + clean:
  853 + @RMCOMMAND@ *.o *.a *.s _rombios*_.c rombios*.txt rombios*.sym
  854 +- @RMCOMMAND@ usage biossums
  855 ++ @RMCOMMAND@ usage biossums rombios16.bin
  856 ++ @RMCOMMAND@ rombios32.bin rombios32.out pad tmp32.bin
  857 +
  858 + dist-clean: clean
  859 + @RMCOMMAND@ Makefile
  860 +@@ -69,15 +70,35 @@
  861 + bios-clean:
  862 + @RMCOMMAND@ BIOS-bochs-*
  863 +
  864 +-BIOS-bochs-latest: rombios.c apmbios.S biossums
  865 ++rombios16.bin: rombios.c apmbios.S biossums
  866 + $(GCC) $(BIOS_BUILD_DATE) -E -P $< > _rombios_.c
  867 + $(BCC) -o rombios.s -C-c -D__i86__ -0 -S _rombios_.c
  868 + sed -e 's/^\.text//' -e 's/^\.data//' rombios.s > _rombios_.s
  869 + $(AS86) _rombios_.s -b tmp.bin -u- -w- -g -0 -j -O -l rombios.txt
  870 + -perl ${srcdir}/makesym.perl < rombios.txt > rombios.sym
  871 +- mv tmp.bin BIOS-bochs-latest
  872 +- ./biossums BIOS-bochs-latest
  873 ++ mv tmp.bin rombios16.bin
  874 ++ ./biossums rombios16.bin
  875 + rm -f _rombios_.s
  876 +
  877 ++
  878 ++rombios32.bin: rombios32.out pad
  879 ++ objcopy -O binary $< tmp32.bin
  880 ++ ./pad < tmp32.bin > $@ 65536 0xff
  881 ++
  882 ++rombios32.out: rombios32start.o rombios32.o rombios32.ld
  883 ++ ld -o $@ -T rombios32.ld rombios32start.o rombios32.o
  884 ++
  885 ++rombios32.o: rombios32.c
  886 ++ $(GCC) -O2 -Wall -c -o $@ $<
  887 ++
  888 ++rombios32start.o: rombios32start.S
  889 ++ $(GCC) -c -o $@ $<
  890 ++
  891 ++BIOS-bochs-latest: rombios16.bin rombios32.bin
  892 ++ cat rombios32.bin rombios16.bin > $@
  893 ++
  894 ++pad: pad.c
  895 ++ $(GCC) -o $@ $<
  896 ++
  897 + biossums: biossums.c
  898 + $(GCC) -o biossums biossums.c
  899 +diff -ruN --exclude Makefile bios/pad.c bios.new/pad.c
  900 +--- bios/pad.c 1970-01-01 01:00:00.000000000 +0100
  901 ++++ bios.new/pad.c 2006-09-24 20:22:58.000000000 +0200
  902 +@@ -0,0 +1,20 @@
  903 ++#include <stdlib.h>
  904 ++#include <stdio.h>
  905 ++
  906 ++int main(int argc, char **argv)
  907 ++{
  908 ++ int len, val, i, c;
  909 ++
  910 ++ len = strtol(argv[1], NULL, 0);
  911 ++ val = strtol(argv[2], NULL, 0);
  912 ++ for(i = 0 ; i < len; i++) {
  913 ++ c = getchar();
  914 ++ if (c == EOF)
  915 ++ break;
  916 ++ putchar(c);
  917 ++ }
  918 ++ for( ; i < len; i++) {
  919 ++ putchar(val);
  920 ++ }
  921 ++ return 0;
  922 ++}
  923 +diff -ruN --exclude Makefile bios/rombios32.c bios.new/rombios32.c
  924 +--- bios/rombios32.c 1970-01-01 01:00:00.000000000 +0100
  925 ++++ bios.new/rombios32.c 2006-09-24 20:22:58.000000000 +0200
  926 +@@ -0,0 +1,1324 @@
  927 ++// 32 bit Bochs BIOS init code
  928 ++// Copyright (C) 2006 Fabrice Bellard
  929 ++//
  930 ++// This library is free software; you can redistribute it and/or
  931 ++// modify it under the terms of the GNU Lesser General Public
  932 ++// License as published by the Free Software Foundation; either
  933 ++// version 2 of the License, or (at your option) any later version.
  934 ++//
  935 ++// This library is distributed in the hope that it will be useful,
  936 ++// but WITHOUT ANY WARRANTY; without even the implied warranty of
  937 ++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  938 ++// Lesser General Public License for more details.
  939 ++//
  940 ++// You should have received a copy of the GNU Lesser General Public
  941 ++// License along with this library; if not, write to the Free Software
  942 ++// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  943 ++#include <stdarg.h>
  944 ++#include <stddef.h>
  945 ++
  946 ++typedef signed char int8_t;
  947 ++typedef short int16_t;
  948 ++typedef int int32_t;
  949 ++typedef long long int64_t;
  950 ++typedef unsigned char uint8_t;
  951 ++typedef unsigned short uint16_t;
  952 ++typedef unsigned int uint32_t;
  953 ++typedef unsigned long long uint64_t;
  954 ++
  955 ++/* if true, put the MP float table and ACPI RSDT in EBDA and the MP
  956 ++ table in RAM. Unfortunately, Linux has bugs with that, so we prefer
  957 ++ to modify the BIOS in shadow RAM */
  958 ++//#define BX_USE_EBDA_TABLES
  959 ++
  960 ++/* define it if the (emulated) hardware supports SMM mode */
  961 ++#define BX_USE_SMM
  962 ++
  963 ++#define BX_INFO(fmt, args...) bios_printf(0, fmt, ## args);
  964 ++
  965 ++#define INFO_PORT 0x402
  966 ++
  967 ++#define cpuid(index, eax, ebx, ecx, edx) \
  968 ++ asm volatile ("cpuid" \
  969 ++ : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) \
  970 ++ : "0" (index))
  971 ++
  972 ++#define CPUID_APIC (1 << 9)
  973 ++
  974 ++#define APIC_BASE ((uint8_t *)0xfee00000)
  975 ++#define APIC_ICR_LOW 0x300
  976 ++#define APIC_SVR 0x0F0
  977 ++#define APIC_ID 0x020
  978 ++#define APIC_LVT3 0x370
  979 ++
  980 ++#define APIC_ENABLED 0x0100
  981 ++
  982 ++#define CPU_COUNT_ADDR 0xf000
  983 ++#define AP_BOOT_ADDR 0x10000
  984 ++
  985 ++#define MPTABLE_MAX_SIZE 0x00002000
  986 ++#define ACPI_DATA_SIZE 0x00010000
  987 ++#define SMI_CMD_IO_ADDR 0xb2
  988 ++#define PM_IO_BASE 0xb000
  989 ++
  990 ++#define BIOS_TMP_STORAGE 0x00030000 /* 64 KB used to copy the BIOS to shadow RAM */
  991 ++
  992 ++static inline void outl(int addr, int val)
  993 ++{
  994 ++ asm volatile ("outl %1, %w0" : : "d" (addr), "a" (val));
  995 ++}
  996 ++
  997 ++static inline void outw(int addr, int val)
  998 ++{
  999 ++ asm volatile ("outw %w1, %w0" : : "d" (addr), "a" (val));
  1000 ++}
  1001 ++
  1002 ++static inline void outb(int addr, int val)
  1003 ++{
  1004 ++ asm volatile ("outb %b1, %w0" : : "d" (addr), "a" (val));
  1005 ++}
  1006 ++
  1007 ++static inline uint32_t inl(int addr)
  1008 ++{
  1009 ++ uint32_t val;
  1010 ++ asm volatile ("inl %w1, %0" : "=a" (val) : "d" (addr));
  1011 ++ return val;
  1012 ++}
  1013 ++
  1014 ++static inline uint16_t inw(int addr)
  1015 ++{
  1016 ++ uint16_t val;
  1017 ++ asm volatile ("inw %w1, %w0" : "=a" (val) : "d" (addr));
  1018 ++ return val;
  1019 ++}
  1020 ++
  1021 ++static inline uint8_t inb(int addr)
  1022 ++{
  1023 ++ uint8_t val;
  1024 ++ asm volatile ("inb %w1, %b0" : "=a" (val) : "d" (addr));
  1025 ++ return val;
  1026 ++}
  1027 ++
  1028 ++static inline void writel(void *addr, uint32_t val)
  1029 ++{
  1030 ++ *(volatile uint32_t *)addr = val;
  1031 ++}
  1032 ++
  1033 ++static inline void writew(void *addr, uint16_t val)
  1034 ++{
  1035 ++ *(volatile uint16_t *)addr = val;
  1036 ++}
  1037 ++
  1038 ++static inline void writeb(void *addr, uint8_t val)
  1039 ++{
  1040 ++ *(volatile uint8_t *)addr = val;
  1041 ++}
  1042 ++
  1043 ++static inline uint32_t readl(const void *addr)
  1044 ++{
  1045 ++ return *(volatile const uint32_t *)addr;
  1046 ++}
  1047 ++
  1048 ++static inline uint16_t readw(const void *addr)
  1049 ++{
  1050 ++ return *(volatile const uint16_t *)addr;
  1051 ++}
  1052 ++
  1053 ++static inline uint8_t readb(const void *addr)
  1054 ++{
  1055 ++ return *(volatile const uint8_t *)addr;
  1056 ++}
  1057 ++
  1058 ++static inline void putc(int c)
  1059 ++{
  1060 ++ outb(INFO_PORT, c);
  1061 ++}
  1062 ++
  1063 ++static inline int isdigit(int c)
  1064 ++{
  1065 ++ return c >= '0' && c <= '9';
  1066 ++}
  1067 ++
  1068 ++void *memset(void *d1, int val, size_t len)
  1069 ++{
  1070 ++ uint8_t *d = d1;
  1071 ++
  1072 ++ while (len--) {
  1073 ++ *d++ = val;
  1074 ++ }
  1075 ++ return d1;
  1076 ++}
  1077 ++
  1078 ++void *memcpy(void *d1, const void *s1, size_t len)
  1079 ++{
  1080 ++ uint8_t *d = d1;
  1081 ++ const uint8_t *s = s1;
  1082 ++
  1083 ++ while (len--) {
  1084 ++ *d++ = *s++;
  1085 ++ }
  1086 ++ return d1;
  1087 ++}
  1088 ++
  1089 ++void *memmove(void *d1, const void *s1, size_t len)
  1090 ++{
  1091 ++ uint8_t *d = d1;
  1092 ++ const uint8_t *s = s1;
  1093 ++
  1094 ++ if (d <= s) {
  1095 ++ while (len--) {
  1096 ++ *d++ = *s++;
  1097 ++ }
  1098 ++ } else {
  1099 ++ d += len;
  1100 ++ s += len;
  1101 ++ while (len--) {
  1102 ++ *--d = *--s;
  1103 ++ }
  1104 ++ }
  1105 ++ return d1;
  1106 ++}
  1107 ++
  1108 ++size_t strlen(const char *s)
  1109 ++{
  1110 ++ const char *s1;
  1111 ++ for(s1 = s; *s1 != '\0'; s1++);
  1112 ++ return s1 - s;
  1113 ++}
  1114 ++
  1115 ++/* from BSD ppp sources */
  1116 ++int vsnprintf(char *buf, int buflen, const char *fmt, va_list args)
  1117 ++{
  1118 ++ int c, i, n;
  1119 ++ int width, prec, fillch;
  1120 ++ int base, len, neg;
  1121 ++ unsigned long val = 0;
  1122 ++ const char *f;
  1123 ++ char *str, *buf0;
  1124 ++ char num[32];
  1125 ++ static const char hexchars[] = "0123456789abcdef";
  1126 ++
  1127 ++ buf0 = buf;
  1128 ++ --buflen;
  1129 ++ while (buflen > 0) {
  1130 ++ for (f = fmt; *f != '%' && *f != 0; ++f)
  1131 ++ ;
  1132 ++ if (f > fmt) {
  1133 ++ len = f - fmt;
  1134 ++ if (len > buflen)
  1135 ++ len = buflen;
  1136 ++ memcpy(buf, fmt, len);
  1137 ++ buf += len;
  1138 ++ buflen -= len;
  1139 ++ fmt = f;
  1140 ++ }
  1141 ++ if (*fmt == 0)
  1142 ++ break;
  1143 ++ c = *++fmt;
  1144 ++ width = prec = 0;
  1145 ++ fillch = ' ';
  1146 ++ if (c == '0') {
  1147 ++ fillch = '0';
  1148 ++ c = *++fmt;
  1149 ++ }
  1150 ++ if (c == '*') {
  1151 ++ width = va_arg(args, int);
  1152 ++ c = *++fmt;
  1153 ++ } else {
  1154 ++ while (isdigit(c)) {
  1155 ++ width = width * 10 + c - '0';
  1156 ++ c = *++fmt;
  1157 ++ }
  1158 ++ }
  1159 ++ if (c == '.') {
  1160 ++ c = *++fmt;
  1161 ++ if (c == '*') {
  1162 ++ prec = va_arg(args, int);
  1163 ++ c = *++fmt;
  1164 ++ } else {
  1165 ++ while (isdigit(c)) {
  1166 ++ prec = prec * 10 + c - '0';
  1167 ++ c = *++fmt;
  1168 ++ }
  1169 ++ }
  1170 ++ }
  1171 ++ /* modifiers */
  1172 ++ switch(c) {
  1173 ++ case 'l':
  1174 ++ c = *++fmt;
  1175 ++ break;
  1176 ++ default:
  1177 ++ break;
  1178 ++ }
  1179 ++ str = 0;
  1180 ++ base = 0;
  1181 ++ neg = 0;
  1182 ++ ++fmt;
  1183 ++ switch (c) {
  1184 ++ case 'd':
  1185 ++ i = va_arg(args, int);
  1186 ++ if (i < 0) {
  1187 ++ neg = 1;
  1188 ++ val = -i;
  1189 ++ } else
  1190 ++ val = i;
  1191 ++ base = 10;
  1192 ++ break;
  1193 ++ case 'o':
  1194 ++ val = va_arg(args, unsigned int);
  1195 ++ base = 8;
  1196 ++ break;
  1197 ++ case 'x':
  1198 ++ case 'X':
  1199 ++ val = va_arg(args, unsigned int);
  1200 ++ base = 16;
  1201 ++ break;
  1202 ++ case 'p':
  1203 ++ val = (unsigned long) va_arg(args, void *);
  1204 ++ base = 16;
  1205 ++ neg = 2;
  1206 ++ break;
  1207 ++ case 's':
  1208 ++ str = va_arg(args, char *);
  1209 ++ break;
  1210 ++ case 'c':
  1211 ++ num[0] = va_arg(args, int);
  1212 ++ num[1] = 0;
  1213 ++ str = num;
  1214 ++ break;
  1215 ++ default:
  1216 ++ *buf++ = '%';
  1217 ++ if (c != '%')
  1218 ++ --fmt; /* so %z outputs %z etc. */
  1219 ++ --buflen;
  1220 ++ continue;
  1221 ++ }
  1222 ++ if (base != 0) {
  1223 ++ str = num + sizeof(num);
  1224 ++ *--str = 0;
  1225 ++ while (str > num + neg) {
  1226 ++ *--str = hexchars[val % base];
  1227 ++ val = val / base;
  1228 ++ if (--prec <= 0 && val == 0)
  1229 ++ break;
  1230 ++ }
  1231 ++ switch (neg) {
  1232 ++ case 1:
  1233 ++ *--str = '-';
  1234 ++ break;
  1235 ++ case 2:
  1236 ++ *--str = 'x';
  1237 ++ *--str = '0';
  1238 ++ break;
  1239 ++ }
  1240 ++ len = num + sizeof(num) - 1 - str;
  1241 ++ } else {
  1242 ++ len = strlen(str);
  1243 ++ if (prec > 0 && len > prec)
  1244 ++ len = prec;
  1245 ++ }
  1246 ++ if (width > 0) {
  1247 ++ if (width > buflen)
  1248 ++ width = buflen;
  1249 ++ if ((n = width - len) > 0) {
  1250 ++ buflen -= n;
  1251 ++ for (; n > 0; --n)
  1252 ++ *buf++ = fillch;
  1253 ++ }
  1254 ++ }
  1255 ++ if (len > buflen)
  1256 ++ len = buflen;
  1257 ++ memcpy(buf, str, len);
  1258 ++ buf += len;
  1259 ++ buflen -= len;
  1260 ++ }
  1261 ++ *buf = 0;
  1262 ++ return buf - buf0;
  1263 ++}
  1264 ++
  1265 ++void bios_printf(int flags, const char *fmt, ...)
  1266 ++{
  1267 ++ va_list ap;
  1268 ++ char buf[1024];
  1269 ++ const char *s;
  1270 ++
  1271 ++ va_start(ap, fmt);
  1272 ++ vsnprintf(buf, sizeof(buf), fmt, ap);
  1273 ++ s = buf;
  1274 ++ while (*s)
  1275 ++ putc(*s++);
  1276 ++ va_end(ap);
  1277 ++}
  1278 ++
  1279 ++/* approximative ! */
  1280 ++void delay_ms(int n)
  1281 ++{
  1282 ++ int i, j;
  1283 ++ for(i = 0; i < n; i++) {
  1284 ++ for(j = 0; j < 1000000; j++);
  1285 ++ }
  1286 ++}
  1287 ++
  1288 ++int smp_cpus;
  1289 ++uint32_t cpuid_features;
  1290 ++uint32_t cpuid_ext_features;
  1291 ++unsigned long ram_size;
  1292 ++#ifdef BX_USE_EBDA_TABLES
  1293 ++unsigned long ebda_cur_addr;
  1294 ++#endif
  1295 ++int acpi_enabled;
  1296 ++uint32_t pm_io_base;
  1297 ++int pm_sci_int;
  1298 ++unsigned long bios_table_cur_addr;
  1299 ++unsigned long bios_table_end_addr;
  1300 ++
  1301 ++void cpu_probe(void)
  1302 ++{
  1303 ++ uint32_t eax, ebx, ecx, edx;
  1304 ++ cpuid(1, eax, ebx, ecx, edx);
  1305 ++ cpuid_features = edx;
  1306 ++ cpuid_ext_features = ecx;
  1307 ++}
  1308 ++
  1309 ++static int cmos_readb(int addr)
  1310 ++{
  1311 ++ outb(0x70, addr);
  1312 ++ return inb(0x71);
  1313 ++}
  1314 ++
  1315 ++void ram_probe(void)
  1316 ++{
  1317 ++ ram_size = (cmos_readb(0x34) | (cmos_readb(0x35) << 8)) * 65536 +
  1318 ++ 16 * 1024 * 1024;
  1319 ++#ifdef BX_USE_EBDA_TABLES
  1320 ++ ebda_cur_addr = ((*(uint16_t *)(0x40e)) << 4) + 0x380;
  1321 ++#endif
  1322 ++ BX_INFO("ram_size=0x%08lx\n");
  1323 ++}
  1324 ++
  1325 ++/****************************************************/
  1326 ++/* SMP probe */
  1327 ++
  1328 ++extern uint8_t smp_ap_boot_code_start;
  1329 ++extern uint8_t smp_ap_boot_code_end;
  1330 ++
  1331 ++/* find the number of CPUs by launching a SIPI to them */
  1332 ++void smp_probe(void)
  1333 ++{
  1334 ++ uint32_t val, sipi_vector;
  1335 ++
  1336 ++ smp_cpus = 1;
  1337 ++ if (cpuid_features & CPUID_APIC) {
  1338 ++
  1339 ++ /* enable local APIC */
  1340 ++ val = readl(APIC_BASE + APIC_SVR);
  1341 ++ val |= APIC_ENABLED;
  1342 ++ writel(APIC_BASE + APIC_SVR, val);
  1343 ++
  1344 ++ writew((void *)CPU_COUNT_ADDR, 1);
  1345 ++ /* copy AP boot code */
  1346 ++ memcpy((void *)AP_BOOT_ADDR, &smp_ap_boot_code_start,
  1347 ++ &smp_ap_boot_code_end - &smp_ap_boot_code_start);
  1348 ++
  1349 ++ /* broadcast SIPI */
  1350 ++ writel(APIC_BASE + APIC_ICR_LOW, 0x000C4500);
  1351 ++ sipi_vector = AP_BOOT_ADDR >> 12;
  1352 ++ writel(APIC_BASE + APIC_ICR_LOW, 0x000C4600 | sipi_vector);
  1353 ++
  1354 ++ delay_ms(10);
  1355 ++
  1356 ++ smp_cpus = readw((void *)CPU_COUNT_ADDR);
  1357 ++ }
  1358 ++ BX_INFO("Found %d cpus\n", smp_cpus);
  1359 ++}
  1360 ++
  1361 ++/****************************************************/
  1362 ++/* PCI init */
  1363 ++
  1364 ++#define PCI_ADDRESS_SPACE_MEM 0x00
  1365 ++#define PCI_ADDRESS_SPACE_IO 0x01
  1366 ++#define PCI_ADDRESS_SPACE_MEM_PREFETCH 0x08
  1367 ++
  1368 ++#define PCI_ROM_SLOT 6
  1369 ++#define PCI_NUM_REGIONS 7
  1370 ++
  1371 ++#define PCI_DEVICES_MAX 64
  1372 ++
  1373 ++#define PCI_VENDOR_ID 0x00 /* 16 bits */
  1374 ++#define PCI_DEVICE_ID 0x02 /* 16 bits */
  1375 ++#define PCI_COMMAND 0x04 /* 16 bits */
  1376 ++#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
  1377 ++#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
  1378 ++#define PCI_CLASS_DEVICE 0x0a /* Device class */
  1379 ++#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */
  1380 ++#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
  1381 ++#define PCI_MIN_GNT 0x3e /* 8 bits */
  1382 ++#define PCI_MAX_LAT 0x3f /* 8 bits */
  1383 ++
  1384 ++typedef struct PCIDevice {
  1385 ++ int bus;
  1386 ++ int devfn;
  1387 ++} PCIDevice;
  1388 ++
  1389 ++static uint32_t pci_bios_io_addr;
  1390 ++static uint32_t pci_bios_mem_addr;
  1391 ++/* host irqs corresponding to PCI irqs A-D */
  1392 ++static uint8_t pci_irqs[4] = { 11, 9, 11, 9 };
  1393 ++static PCIDevice i440_pcidev;
  1394 ++
  1395 ++static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val)
  1396 ++{
  1397 ++ outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
  1398 ++ outl(0xcfc, val);
  1399 ++}
  1400 ++
  1401 ++static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val)
  1402 ++{
  1403 ++ outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
  1404 ++ outw(0xcfc + (addr & 2), val);
  1405 ++}
  1406 ++
  1407 ++static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val)
  1408 ++{
  1409 ++ outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
  1410 ++ outb(0xcfc + (addr & 3), val);
  1411 ++}
  1412 ++
  1413 ++static uint32_t pci_config_readl(PCIDevice *d, uint32_t addr)
  1414 ++{
  1415 ++ outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
  1416 ++ return inl(0xcfc);
  1417 ++}
  1418 ++
  1419 ++static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr)
  1420 ++{
  1421 ++ outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
  1422 ++ return inw(0xcfc + (addr & 2));
  1423 ++}
  1424 ++
  1425 ++static uint32_t pci_config_readb(PCIDevice *d, uint32_t addr)
  1426 ++{
  1427 ++ outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
  1428 ++ return inb(0xcfc + (addr & 3));
  1429 ++}
  1430 ++
  1431 ++static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t addr)
  1432 ++{
  1433 ++ uint16_t cmd;
  1434 ++ uint32_t ofs, old_addr;
  1435 ++
  1436 ++ if ( region_num == PCI_ROM_SLOT ) {
  1437 ++ ofs = 0x30;
  1438 ++ }else{
  1439 ++ ofs = 0x10 + region_num * 4;
  1440 ++ }
  1441 ++
  1442 ++ old_addr = pci_config_readl(d, ofs);
  1443 ++
  1444 ++ pci_config_writel(d, ofs, addr);
  1445 ++ BX_INFO("region %d: 0x%08x\n", region_num, addr);
  1446 ++
  1447 ++ /* enable memory mappings */
  1448 ++ cmd = pci_config_readw(d, PCI_COMMAND);
  1449 ++ if ( region_num == PCI_ROM_SLOT )
  1450 ++ cmd |= 2;
  1451 ++ else if (old_addr & PCI_ADDRESS_SPACE_IO)
  1452 ++ cmd |= 1;
  1453 ++ else
  1454 ++ cmd |= 2;
  1455 ++ pci_config_writew(d, PCI_COMMAND, cmd);
  1456 ++}
  1457 ++
  1458 ++/* return the global irq number corresponding to a given device irq
  1459 ++ pin. We could also use the bus number to have a more precise
  1460 ++ mapping. */
  1461 ++static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
  1462 ++{
  1463 ++ int slot_addend;
  1464 ++ slot_addend = (pci_dev->devfn >> 3) - 1;
  1465 ++ return (irq_num + slot_addend) & 3;
  1466 ++}
  1467 ++
  1468 ++static int find_bios_table_area(void)
  1469 ++{
  1470 ++ unsigned long addr;
  1471 ++ for(addr = 0xf0000; addr < 0x100000; addr += 16) {
  1472 ++ if (*(uint32_t *)addr == 0xaafb4442) {
  1473 ++ bios_table_cur_addr = addr + 8;
  1474 ++ bios_table_end_addr = bios_table_cur_addr + *(uint32_t *)(addr + 4);
  1475 ++ BX_INFO("bios_table_addr: 0x%08lx end=0x%08lx\n",
  1476 ++ bios_table_cur_addr, bios_table_end_addr);
  1477 ++ return 0;
  1478 ++ }
  1479 ++ }
  1480 ++ return -1;
  1481 ++}
  1482 ++
  1483 ++static void bios_shadow_init(PCIDevice *d)
  1484 ++{
  1485 ++ int v;
  1486 ++
  1487 ++ if (find_bios_table_area() < 0)
  1488 ++ return;
  1489 ++
  1490 ++ /* remap the BIOS to shadow RAM an keep it read/write while we
  1491 ++ are writing tables */
  1492 ++ memcpy((void *)BIOS_TMP_STORAGE, (void *)0x000f0000, 0x10000);
  1493 ++ v = pci_config_readb(d, 0x67);
  1494 ++ v = (v & 0x0f) | (0x30);
  1495 ++ pci_config_writeb(d, 0x67, v);
  1496 ++ memcpy((void *)0x000f0000, (void *)BIOS_TMP_STORAGE, 0x10000);
  1497 ++
  1498 ++ i440_pcidev = *d;
  1499 ++}
  1500 ++
  1501 ++static void bios_lock_shadow_ram(void)
  1502 ++{
  1503 ++ PCIDevice *d = &i440_pcidev;
  1504 ++ int v;
  1505 ++
  1506 ++ v = pci_config_readb(d, 0x67);
  1507 ++ v = (v & 0x0f) | (0x20);
  1508 ++ pci_config_writeb(d, 0x67, v);
  1509 ++}
  1510 ++
  1511 ++static void pci_bios_init_bridges(PCIDevice *d)
  1512 ++{
  1513 ++ uint16_t vendor_id, device_id;
  1514 ++
  1515 ++ vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
  1516 ++ device_id = pci_config_readw(d, PCI_DEVICE_ID);
  1517 ++
  1518 ++ if (vendor_id == 0x8086 && device_id == 0x7000) {
  1519 ++ int i, irq;
  1520 ++ uint8_t elcr[2];
  1521 ++
  1522 ++ /* PIIX3 bridge */
  1523 ++
  1524 ++ elcr[0] = 0x00;
  1525 ++ elcr[1] = 0x00;
  1526 ++ for(i = 0; i < 4; i++) {
  1527 ++ irq = pci_irqs[i];
  1528 ++ /* set to trigger level */
  1529 ++ elcr[irq >> 3] |= (1 << (irq & 7));
  1530 ++ /* activate irq remapping in PIIX */
  1531 ++ pci_config_writeb(d, 0x60 + i, irq);
  1532 ++ }
  1533 ++ outb(0x4d0, elcr[0]);
  1534 ++ outb(0x4d1, elcr[1]);
  1535 ++ BX_INFO("PIIX3 init: elcr=%02x %02x\n",
  1536 ++ elcr[0], elcr[1]);
  1537 ++ } else if (vendor_id == 0x8086 && device_id == 0x1237) {
  1538 ++ /* i440 PCI bridge */
  1539 ++ bios_shadow_init(d);
  1540 ++ }
  1541 ++}
  1542 ++
  1543 ++extern uint8_t smm_relocation_start, smm_relocation_end;
  1544 ++extern uint8_t smm_code_start, smm_code_end;
  1545 ++
  1546 ++#ifdef BX_USE_SMM
  1547 ++static void smm_init(void)
  1548 ++{
  1549 ++ /* copy the SMM relocation code */
  1550 ++ memcpy((void *)0x38000, &smm_relocation_start,
  1551 ++ &smm_relocation_end - &smm_relocation_start);
  1552 ++ /* raise an SMI interrupt */
  1553 ++ outb(0xb2, 00);
  1554 ++
  1555 ++ /* enable the SMM memory window */
  1556 ++ pci_config_writel(&i440_pcidev, 0x6c, (1 << 26) | 0x000a);
  1557 ++
  1558 ++ /* copy the SMM code */
  1559 ++ memcpy((void *)0xa8000, &smm_code_start,
  1560 ++ &smm_code_end - &smm_code_start);
  1561 ++
  1562 ++ /* close the SMM memory window and enable normal SMM */
  1563 ++ pci_config_writel(&i440_pcidev, 0x6c, (1 << 31) | 0x000a);
  1564 ++}
  1565 ++#endif
  1566 ++
  1567 ++static void pci_bios_init_device(PCIDevice *d)
  1568 ++{
  1569 ++ int class;
  1570 ++ uint32_t *paddr;
  1571 ++ int i, pin, pic_irq, vendor_id, device_id;
  1572 ++
  1573 ++ class = pci_config_readw(d, PCI_CLASS_DEVICE);
  1574 ++ vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
  1575 ++ device_id = pci_config_readw(d, PCI_DEVICE_ID);
  1576 ++ BX_INFO("PCI: bus=%d devfn=0x%02x: vendor_id=0x%04x device_id=0x%04x\n",
  1577 ++ d->bus, d->devfn, vendor_id, device_id);
  1578 ++ switch(class) {
  1579 ++ case 0x0101:
  1580 ++ if (vendor_id == 0x8086 && device_id == 0x7010) {
  1581 ++ /* PIIX3 IDE */
  1582 ++ pci_config_writew(d, 0x40, 0x8000); // enable IDE0
  1583 ++ pci_config_writew(d, 0x42, 0x8000); // enable IDE1
  1584 ++ goto default_map;
  1585 ++ } else {
  1586 ++ /* IDE: we map it as in ISA mode */
  1587 ++ pci_set_io_region_addr(d, 0, 0x1f0);
  1588 ++ pci_set_io_region_addr(d, 1, 0x3f4);
  1589 ++ pci_set_io_region_addr(d, 2, 0x170);
  1590 ++ pci_set_io_region_addr(d, 3, 0x374);
  1591 ++ }
  1592 ++ break;
  1593 ++ case 0x0300:
  1594 ++ if (vendor_id != 0x1234)
  1595 ++ goto default_map;
  1596 ++ /* VGA: map frame buffer to default Bochs VBE address */
  1597 ++ pci_set_io_region_addr(d, 0, 0xE0000000);
  1598 ++ break;
  1599 ++ case 0x0800:
  1600 ++ /* PIC */
  1601 ++ if (vendor_id == 0x1014) {
  1602 ++ /* IBM */
  1603 ++ if (device_id == 0x0046 || device_id == 0xFFFF) {
  1604 ++ /* MPIC & MPIC2 */
  1605 ++ pci_set_io_region_addr(d, 0, 0x80800000 + 0x00040000);
  1606 ++ }
  1607 ++ }
  1608 ++ break;
  1609 ++ case 0xff00:
  1610 ++ if (vendor_id == 0x0106b &&
  1611 ++ (device_id == 0x0017 || device_id == 0x0022)) {
  1612 ++ /* macio bridge */
  1613 ++ pci_set_io_region_addr(d, 0, 0x80800000);
  1614 ++ }
  1615 ++ break;
  1616 ++ default:
  1617 ++ default_map:
  1618 ++ /* default memory mappings */
  1619 ++ for(i = 0; i < PCI_NUM_REGIONS; i++) {
  1620 ++ int ofs;
  1621 ++ uint32_t val, size ;
  1622 ++
  1623 ++ if (i == PCI_ROM_SLOT)
  1624 ++ ofs = 0x30;
  1625 ++ else
  1626 ++ ofs = 0x10 + i * 4;
  1627 ++ pci_config_writel(d, ofs, 0xffffffff);
  1628 ++ val = pci_config_readl(d, ofs);
  1629 ++ if (val != 0) {
  1630 ++ size = (~(val & ~0xf)) + 1;
  1631 ++ if (val & PCI_ADDRESS_SPACE_IO)
  1632 ++ paddr = &pci_bios_io_addr;
  1633 ++ else
  1634 ++ paddr = &pci_bios_mem_addr;
  1635 ++ *paddr = (*paddr + size - 1) & ~(size - 1);
  1636 ++ pci_set_io_region_addr(d, i, *paddr);
  1637 ++ *paddr += size;
  1638 ++ }
  1639 ++ }
  1640 ++ break;
  1641 ++ }
  1642 ++
  1643 ++ /* map the interrupt */
  1644 ++ pin = pci_config_readb(d, PCI_INTERRUPT_PIN);
  1645 ++ if (pin != 0) {
  1646 ++ pin = pci_slot_get_pirq(d, pin - 1);
  1647 ++ pic_irq = pci_irqs[pin];
  1648 ++ pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq);
  1649 ++ }
  1650 ++
  1651 ++ if (vendor_id == 0x8086 && device_id == 0x7113) {
  1652 ++ /* PIIX4 Power Management device (for ACPI) */
  1653 ++ pm_io_base = PM_IO_BASE;
  1654 ++ pci_config_writel(d, 0x40, pm_io_base | 1);
  1655 ++ pci_config_writeb(d, 0x80, 0x01); /* enable PM io space */
  1656 ++ pm_sci_int = pci_config_readb(d, PCI_INTERRUPT_LINE);
  1657 ++#ifdef BX_USE_SMM
  1658 ++ smm_init();
  1659 ++#endif
  1660 ++ acpi_enabled = 1;
  1661 ++ }
  1662 ++}
  1663 ++
  1664 ++void pci_for_each_device(void (*init_func)(PCIDevice *d))
  1665 ++{
  1666 ++ PCIDevice d1, *d = &d1;
  1667 ++ int bus, devfn;
  1668 ++ uint16_t vendor_id, device_id;
  1669 ++
  1670 ++ for(bus = 0; bus < 1; bus++) {
  1671 ++ for(devfn = 0; devfn < 256; devfn++) {
  1672 ++ d->bus = bus;
  1673 ++ d->devfn = devfn;
  1674 ++ vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
  1675 ++ device_id = pci_config_readw(d, PCI_DEVICE_ID);
  1676 ++ if (vendor_id != 0xffff || device_id != 0xffff) {
  1677 ++ init_func(d);
  1678 ++ }
  1679 ++ }
  1680 ++ }
  1681 ++}
  1682 ++
  1683 ++void pci_bios_init(void)
  1684 ++{
  1685 ++ pci_bios_io_addr = 0xc000;
  1686 ++ pci_bios_mem_addr = 0xf0000000;
  1687 ++
  1688 ++ pci_for_each_device(pci_bios_init_bridges);
  1689 ++
  1690 ++ pci_for_each_device(pci_bios_init_device);
  1691 ++}
  1692 ++
  1693 ++/****************************************************/
  1694 ++/* Multi Processor table init */
  1695 ++
  1696 ++static void putb(uint8_t **pp, int val)
  1697 ++{
  1698 ++ uint8_t *q;
  1699 ++ q = *pp;
  1700 ++ *q++ = val;
  1701 ++ *pp = q;
  1702 ++}
  1703 ++
  1704 ++static void putstr(uint8_t **pp, const char *str)
  1705 ++{
  1706 ++ uint8_t *q;
  1707 ++ q = *pp;
  1708 ++ while (*str)
  1709 ++ *q++ = *str++;
  1710 ++ *pp = q;
  1711 ++}
  1712 ++
  1713 ++static void putle16(uint8_t **pp, int val)
  1714 ++{
  1715 ++ uint8_t *q;
  1716 ++ q = *pp;
  1717 ++ *q++ = val;
  1718 ++ *q++ = val >> 8;
  1719 ++ *pp = q;
  1720 ++}
  1721 ++
  1722 ++static void putle32(uint8_t **pp, int val)
  1723 ++{
  1724 ++ uint8_t *q;
  1725 ++ q = *pp;
  1726 ++ *q++ = val;
  1727 ++ *q++ = val >> 8;
  1728 ++ *q++ = val >> 16;
  1729 ++ *q++ = val >> 24;
  1730 ++ *pp = q;
  1731 ++}
  1732 ++
  1733 ++static int mpf_checksum(const uint8_t *data, int len)
  1734 ++{
  1735 ++ int sum, i;
  1736 ++ sum = 0;
  1737 ++ for(i = 0; i < len; i++)
  1738 ++ sum += data[i];
  1739 ++ return sum & 0xff;
  1740 ++}
  1741 ++
  1742 ++static unsigned long align(unsigned long addr, unsigned long v)
  1743 ++{
  1744 ++ return (addr + v - 1) & ~(v - 1);
  1745 ++}
  1746 ++
  1747 ++static void mptable_init(void)
  1748 ++{
  1749 ++ uint8_t *mp_config_table, *q, *float_pointer_struct;
  1750 ++ int ioapic_id, i, len;
  1751 ++ int mp_config_table_size;
  1752 ++
  1753 ++ if (smp_cpus <= 1)
  1754 ++ return;
  1755 ++
  1756 ++#ifdef BX_USE_EBDA_TABLES
  1757 ++ mp_config_table = (uint8_t *)(ram_size - ACPI_DATA_SIZE - MPTABLE_MAX_SIZE);
  1758 ++#else
  1759 ++ bios_table_cur_addr = align(bios_table_cur_addr, 16);
  1760 ++ mp_config_table = (uint8_t *)bios_table_cur_addr;
  1761 ++#endif
  1762 ++ q = mp_config_table;
  1763 ++ putstr(&q, "PCMP"); /* "PCMP signature */
  1764 ++ putle16(&q, 0); /* table length (patched later) */
  1765 ++ putb(&q, 4); /* spec rev */
  1766 ++ putb(&q, 0); /* checksum (patched later) */
  1767 ++ putstr(&q, "QEMUCPU "); /* OEM id */
  1768 ++ putstr(&q, "0.1 "); /* vendor id */
  1769 ++ putle32(&q, 0); /* OEM table ptr */
  1770 ++ putle16(&q, 0); /* OEM table size */
  1771 ++ putle16(&q, 20); /* entry count */
  1772 ++ putle32(&q, 0xfee00000); /* local APIC addr */
  1773 ++ putle16(&q, 0); /* ext table length */
  1774 ++ putb(&q, 0); /* ext table checksum */
  1775 ++ putb(&q, 0); /* reserved */
  1776 ++
  1777 ++ for(i = 0; i < smp_cpus; i++) {
  1778 ++ putb(&q, 0); /* entry type = processor */
  1779 ++ putb(&q, i); /* APIC id */
  1780 ++ putb(&q, 0x11); /* local APIC version number */
  1781 ++ if (i == 0)
  1782 ++ putb(&q, 3); /* cpu flags: enabled, bootstrap cpu */
  1783 ++ else
  1784 ++ putb(&q, 1); /* cpu flags: enabled */
  1785 ++ putb(&q, 0); /* cpu signature */
  1786 ++ putb(&q, 6);
  1787 ++ putb(&q, 0);
  1788 ++ putb(&q, 0);
  1789 ++ putle16(&q, 0x201); /* feature flags */
  1790 ++ putle16(&q, 0);
  1791 ++
  1792 ++ putle16(&q, 0); /* reserved */
  1793 ++ putle16(&q, 0);
  1794 ++ putle16(&q, 0);
  1795 ++ putle16(&q, 0);
  1796 ++ }
  1797 ++
  1798 ++ /* isa bus */
  1799 ++ putb(&q, 1); /* entry type = bus */
  1800 ++ putb(&q, 0); /* bus ID */
  1801 ++ putstr(&q, "ISA ");
  1802 ++
  1803 ++ /* ioapic */
  1804 ++ ioapic_id = smp_cpus;
  1805 ++ putb(&q, 2); /* entry type = I/O APIC */
  1806 ++ putb(&q, ioapic_id); /* apic ID */
  1807 ++ putb(&q, 0x11); /* I/O APIC version number */
  1808 ++ putb(&q, 1); /* enable */
  1809 ++ putle32(&q, 0xfec00000); /* I/O APIC addr */
  1810 ++
  1811 ++ /* irqs */
  1812 ++ for(i = 0; i < 16; i++) {
  1813 ++ putb(&q, 3); /* entry type = I/O interrupt */
  1814 ++ putb(&q, 0); /* interrupt type = vectored interrupt */
  1815 ++ putb(&q, 0); /* flags: po=0, el=0 */
  1816 ++ putb(&q, 0);
  1817 ++ putb(&q, 0); /* source bus ID = ISA */
  1818 ++ putb(&q, i); /* source bus IRQ */
  1819 ++ putb(&q, ioapic_id); /* dest I/O APIC ID */
  1820 ++ putb(&q, i); /* dest I/O APIC interrupt in */
  1821 ++ }
  1822 ++ /* patch length */
  1823 ++ len = q - mp_config_table;
  1824 ++ mp_config_table[4] = len;
  1825 ++ mp_config_table[5] = len >> 8;
  1826 ++
  1827 ++ mp_config_table[7] = -mpf_checksum(mp_config_table, q - mp_config_table);
  1828 ++
  1829 ++ mp_config_table_size = q - mp_config_table;
  1830 ++
  1831 ++#ifndef BX_USE_EBDA_TABLES
  1832 ++ bios_table_cur_addr += mp_config_table_size;
  1833 ++#endif
  1834 ++
  1835 ++ /* floating pointer structure */
  1836 ++#ifdef BX_USE_EBDA_TABLES
  1837 ++ ebda_cur_addr = align(ebda_cur_addr, 16);
  1838 ++ float_pointer_struct = (uint8_t *)ebda_cur_addr;
  1839 ++#else
  1840 ++ bios_table_cur_addr = align(bios_table_cur_addr, 16);
  1841 ++ float_pointer_struct = (uint8_t *)bios_table_cur_addr;
  1842 ++#endif
  1843 ++ q = float_pointer_struct;
  1844 ++ putstr(&q, "_MP_");
  1845 ++ /* pointer to MP config table */
  1846 ++ putle32(&q, (unsigned long)mp_config_table);
  1847 ++
  1848 ++ putb(&q, 1); /* length in 16 byte units */
  1849 ++ putb(&q, 4); /* MP spec revision */
  1850 ++ putb(&q, 0); /* checksum (patched later) */
  1851 ++ putb(&q, 0); /* MP feature byte 1 */
  1852 ++
  1853 ++ putb(&q, 0);
  1854 ++ putb(&q, 0);
  1855 ++ putb(&q, 0);
  1856 ++ putb(&q, 0);
  1857 ++ float_pointer_struct[10] =
  1858 ++ -mpf_checksum(float_pointer_struct, q - float_pointer_struct);
  1859 ++#ifdef BX_USE_EBDA_TABLES
  1860 ++ ebda_cur_addr += (q - float_pointer_struct);
  1861 ++#else
  1862 ++ bios_table_cur_addr += (q - float_pointer_struct);
  1863 ++#endif
  1864 ++ BX_INFO("MP table addr=0x%08lx MPC table addr=0x%08lx size=0x%x\n",
  1865 ++ (unsigned long)float_pointer_struct,
  1866 ++ (unsigned long)mp_config_table,
  1867 ++ mp_config_table_size);
  1868 ++}
  1869 ++
  1870 ++/****************************************************/
  1871 ++/* ACPI tables init */
  1872 ++
  1873 ++/* Table structure from Linux kernel (the ACPI tables are under the
  1874 ++ BSD license) */
  1875 ++
  1876 ++#define ACPI_TABLE_HEADER_DEF /* ACPI common table header */ \
  1877 ++ uint8_t signature [4]; /* ACPI signature (4 ASCII characters) */\
  1878 ++ uint32_t length; /* Length of table, in bytes, including header */\
  1879 ++ uint8_t revision; /* ACPI Specification minor version # */\
  1880 ++ uint8_t checksum; /* To make sum of entire table == 0 */\
  1881 ++ uint8_t oem_id [6]; /* OEM identification */\
  1882 ++ uint8_t oem_table_id [8]; /* OEM table identification */\
  1883 ++ uint32_t oem_revision; /* OEM revision number */\
  1884 ++ uint8_t asl_compiler_id [4]; /* ASL compiler vendor ID */\
  1885 ++ uint32_t asl_compiler_revision; /* ASL compiler revision number */
  1886 ++
  1887 ++
  1888 ++struct acpi_table_header /* ACPI common table header */
  1889 ++{
  1890 ++ ACPI_TABLE_HEADER_DEF
  1891 ++};
  1892 ++
  1893 ++struct rsdp_descriptor /* Root System Descriptor Pointer */
  1894 ++{
  1895 ++ uint8_t signature [8]; /* ACPI signature, contains "RSD PTR " */
  1896 ++ uint8_t checksum; /* To make sum of struct == 0 */
  1897 ++ uint8_t oem_id [6]; /* OEM identification */
  1898 ++ uint8_t revision; /* Must be 0 for 1.0, 2 for 2.0 */
  1899 ++ uint32_t rsdt_physical_address; /* 32-bit physical address of RSDT */
  1900 ++ uint32_t length; /* XSDT Length in bytes including hdr */
  1901 ++ uint64_t xsdt_physical_address; /* 64-bit physical address of XSDT */
  1902 ++ uint8_t extended_checksum; /* Checksum of entire table */
  1903 ++ uint8_t reserved [3]; /* Reserved field must be 0 */
  1904 ++};
  1905 ++
  1906 ++/*
  1907 ++ * ACPI 1.0 Root System Description Table (RSDT)
  1908 ++ */
  1909 ++struct rsdt_descriptor_rev1
  1910 ++{
  1911 ++ ACPI_TABLE_HEADER_DEF /* ACPI common table header */
  1912 ++ uint32_t table_offset_entry [2]; /* Array of pointers to other */
  1913 ++ /* ACPI tables */
  1914 ++};
  1915 ++
  1916 ++/*
  1917 ++ * ACPI 1.0 Firmware ACPI Control Structure (FACS)
  1918 ++ */
  1919 ++struct facs_descriptor_rev1
  1920 ++{
  1921 ++ uint8_t signature[4]; /* ACPI Signature */
  1922 ++ uint32_t length; /* Length of structure, in bytes */
  1923 ++ uint32_t hardware_signature; /* Hardware configuration signature */
  1924 ++ uint32_t firmware_waking_vector; /* ACPI OS waking vector */
  1925 ++ uint32_t global_lock; /* Global Lock */
  1926 ++ uint32_t S4bios_f : 1; /* Indicates if S4BIOS support is present */
  1927 ++ uint32_t reserved1 : 31; /* Must be 0 */
  1928 ++ uint8_t resverved3 [40]; /* Reserved - must be zero */
  1929 ++};
  1930 ++
  1931 ++
  1932 ++/*
  1933 ++ * ACPI 1.0 Fixed ACPI Description Table (FADT)
  1934 ++ */
  1935 ++struct fadt_descriptor_rev1
  1936 ++{
  1937 ++ ACPI_TABLE_HEADER_DEF /* ACPI common table header */
  1938 ++ uint32_t firmware_ctrl; /* Physical address of FACS */
  1939 ++ uint32_t dsdt; /* Physical address of DSDT */
  1940 ++ uint8_t model; /* System Interrupt Model */
  1941 ++ uint8_t reserved1; /* Reserved */
  1942 ++ uint16_t sci_int; /* System vector of SCI interrupt */
  1943 ++ uint32_t smi_cmd; /* Port address of SMI command port */
  1944 ++ uint8_t acpi_enable; /* Value to write to smi_cmd to enable ACPI */
  1945 ++ uint8_t acpi_disable; /* Value to write to smi_cmd to disable ACPI */
  1946 ++ uint8_t S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */
  1947 ++ uint8_t reserved2; /* Reserved - must be zero */
  1948 ++ uint32_t pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */
  1949 ++ uint32_t pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */
  1950 ++ uint32_t pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */
  1951 ++ uint32_t pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */
  1952 ++ uint32_t pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */
  1953 ++ uint32_t pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */
  1954 ++ uint32_t gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */
  1955 ++ uint32_t gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */
  1956 ++ uint8_t pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */
  1957 ++ uint8_t pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */
  1958 ++ uint8_t pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */
  1959 ++ uint8_t pm_tmr_len; /* Byte Length of ports at pm_tm_blk */
  1960 ++ uint8_t gpe0_blk_len; /* Byte Length of ports at gpe0_blk */
  1961 ++ uint8_t gpe1_blk_len; /* Byte Length of ports at gpe1_blk */
  1962 ++ uint8_t gpe1_base; /* Offset in gpe model where gpe1 events start */
  1963 ++ uint8_t reserved3; /* Reserved */
  1964 ++ uint16_t plvl2_lat; /* Worst case HW latency to enter/exit C2 state */
  1965 ++ uint16_t plvl3_lat; /* Worst case HW latency to enter/exit C3 state */
  1966 ++ uint16_t flush_size; /* Size of area read to flush caches */
  1967 ++ uint16_t flush_stride; /* Stride used in flushing caches */
  1968 ++ uint8_t duty_offset; /* Bit location of duty cycle field in p_cnt reg */
  1969 ++ uint8_t duty_width; /* Bit width of duty cycle field in p_cnt reg */
  1970 ++ uint8_t day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */
  1971 ++ uint8_t mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */
  1972 ++ uint8_t century; /* Index to century in RTC CMOS RAM */
  1973 ++ uint8_t reserved4; /* Reserved */
  1974 ++ uint8_t reserved4a; /* Reserved */
  1975 ++ uint8_t reserved4b; /* Reserved */
27 1976 +#if 0
28   - printf(
29   - #ifdef BX_APM
30   - "apmbios "
31   -@@ -1827,6 +1828,9 @@
32   - "eltorito "
33   - #endif
34   - "\n\n");
  1977 ++ uint32_t wb_invd : 1; /* The wbinvd instruction works properly */
  1978 ++ uint32_t wb_invd_flush : 1; /* The wbinvd flushes but does not invalidate */
  1979 ++ uint32_t proc_c1 : 1; /* All processors support C1 state */
  1980 ++ uint32_t plvl2_up : 1; /* C2 state works on MP system */
  1981 ++ uint32_t pwr_button : 1; /* Power button is handled as a generic feature */
  1982 ++ uint32_t sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */
  1983 ++ uint32_t fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */
  1984 ++ uint32_t rtcs4 : 1; /* RTC wakeup stat not possible from S4 */
  1985 ++ uint32_t tmr_val_ext : 1; /* The tmr_val width is 32 bits (0 = 24 bits) */
  1986 ++ uint32_t reserved5 : 23; /* Reserved - must be zero */
35 1987 +#else
36   -+ printf("apmbios pcibios eltorito \n\n");
  1988 ++ uint32_t flags;
37 1989 +#endif
38   - }
39   -
40   - //--------------------------------------------------------------------------
41   -@@ -3999,6 +4003,29 @@
42   - }
43   - #endif
44   -
  1990 ++};
  1991 ++
  1992 ++/*
  1993 ++ * MADT values and structures
  1994 ++ */
  1995 ++
  1996 ++/* Values for MADT PCATCompat */
  1997 ++
  1998 ++#define DUAL_PIC 0
  1999 ++#define MULTIPLE_APIC 1
  2000 ++
  2001 ++
  2002 ++/* Master MADT */
  2003 ++
  2004 ++struct multiple_apic_table
  2005 ++{
  2006 ++ ACPI_TABLE_HEADER_DEF /* ACPI common table header */
  2007 ++ uint32_t local_apic_address; /* Physical address of local APIC */
  2008 ++#if 0
  2009 ++ uint32_t PCATcompat : 1; /* A one indicates system also has dual 8259s */
  2010 ++ uint32_t reserved1 : 31;
  2011 ++#else
  2012 ++ uint32_t flags;
  2013 ++#endif
  2014 ++};
  2015 ++
  2016 ++
  2017 ++/* Values for Type in APIC_HEADER_DEF */
  2018 ++
  2019 ++#define APIC_PROCESSOR 0
  2020 ++#define APIC_IO 1
  2021 ++#define APIC_XRUPT_OVERRIDE 2
  2022 ++#define APIC_NMI 3
  2023 ++#define APIC_LOCAL_NMI 4
  2024 ++#define APIC_ADDRESS_OVERRIDE 5
  2025 ++#define APIC_IO_SAPIC 6
  2026 ++#define APIC_LOCAL_SAPIC 7
  2027 ++#define APIC_XRUPT_SOURCE 8
  2028 ++#define APIC_RESERVED 9 /* 9 and greater are reserved */
  2029 ++
  2030 ++/*
  2031 ++ * MADT sub-structures (Follow MULTIPLE_APIC_DESCRIPTION_TABLE)
  2032 ++ */
  2033 ++#define APIC_HEADER_DEF /* Common APIC sub-structure header */\
  2034 ++ uint8_t type; \
  2035 ++ uint8_t length;
  2036 ++
  2037 ++/* Sub-structures for MADT */
  2038 ++
  2039 ++struct madt_processor_apic
  2040 ++{
  2041 ++ APIC_HEADER_DEF
  2042 ++ uint8_t processor_id; /* ACPI processor id */
  2043 ++ uint8_t local_apic_id; /* Processor's local APIC id */
  2044 ++#if 0
  2045 ++ uint32_t processor_enabled: 1; /* Processor is usable if set */
  2046 ++ uint32_t reserved2 : 31; /* Reserved, must be zero */
  2047 ++#else
  2048 ++ uint32_t flags;
  2049 ++#endif
  2050 ++};
  2051 ++
  2052 ++struct madt_io_apic
  2053 ++{
  2054 ++ APIC_HEADER_DEF
  2055 ++ uint8_t io_apic_id; /* I/O APIC ID */
  2056 ++ uint8_t reserved; /* Reserved - must be zero */
  2057 ++ uint32_t address; /* APIC physical address */
  2058 ++ uint32_t interrupt; /* Global system interrupt where INTI
  2059 ++ * lines start */
  2060 ++};
  2061 ++
  2062 ++#include "acpi-dsdt.hex"
45 2063 +
46   -+void set_e820_range(ES, DI, start, end, type)
47   -+ Bit16u ES;
48   -+ Bit16u DI;
49   -+ Bit32u start;
50   -+ Bit32u end;
51   -+ Bit16u type;
52   -+{
53   -+ write_word(ES, DI, start);
54   -+ write_word(ES, DI+2, start >> 16);
55   -+ write_word(ES, DI+4, 0x00);
56   -+ write_word(ES, DI+6, 0x00);
  2064 ++static inline uint16_t cpu_to_le16(uint16_t x)
  2065 ++{
  2066 ++ return x;
  2067 ++}
  2068 ++
  2069 ++static inline uint32_t cpu_to_le32(uint32_t x)
  2070 ++{
  2071 ++ return x;
  2072 ++}
  2073 ++
  2074 ++static int acpi_checksum(const uint8_t *data, int len)
  2075 ++{
  2076 ++ int sum, i;
  2077 ++ sum = 0;
  2078 ++ for(i = 0; i < len; i++)
  2079 ++ sum += data[i];
  2080 ++ return (-sum) & 0xff;
  2081 ++}
  2082 ++
  2083 ++static void acpi_build_table_header(struct acpi_table_header *h,
  2084 ++ char *sig, int len)
  2085 ++{
  2086 ++ memcpy(h->signature, sig, 4);
  2087 ++ h->length = cpu_to_le32(len);
  2088 ++ h->revision = 0;
  2089 ++ memcpy(h->oem_id, "QEMU ", 6);
  2090 ++ memcpy(h->oem_table_id, "QEMU", 4);
  2091 ++ memcpy(h->oem_table_id + 4, sig, 4);
  2092 ++ h->oem_revision = cpu_to_le32(1);
  2093 ++ memcpy(h->asl_compiler_id, "QEMU", 4);
  2094 ++ h->asl_compiler_revision = cpu_to_le32(1);
  2095 ++ h->checksum = acpi_checksum((void *)h, len);
  2096 ++}
  2097 ++
  2098 ++/* base_addr must be a multiple of 4KB */
  2099 ++void acpi_bios_init(void)
  2100 ++{
  2101 ++ struct rsdp_descriptor *rsdp;
  2102 ++ struct rsdt_descriptor_rev1 *rsdt;
  2103 ++ struct fadt_descriptor_rev1 *fadt;
  2104 ++ struct facs_descriptor_rev1 *facs;
  2105 ++ struct multiple_apic_table *madt;
  2106 ++ uint8_t *dsdt;
  2107 ++ uint32_t base_addr, rsdt_addr, fadt_addr, addr, facs_addr, dsdt_addr;
  2108 ++ uint32_t acpi_tables_size, madt_addr, madt_size;
  2109 ++ int i;
  2110 ++
  2111 ++ /* reserve memory space for tables */
  2112 ++#ifdef BX_USE_EBDA_TABLES
  2113 ++ ebda_cur_addr = align(ebda_cur_addr, 16);
  2114 ++ rsdp = (void *)(ebda_cur_addr);
  2115 ++ ebda_cur_addr += sizeof(*rsdp);
  2116 ++#else
  2117 ++ bios_table_cur_addr = align(bios_table_cur_addr, 16);
  2118 ++ rsdp = (void *)(bios_table_cur_addr);
  2119 ++ bios_table_cur_addr += sizeof(*rsdp);
  2120 ++#endif
  2121 ++
  2122 ++ addr = base_addr = ram_size - ACPI_DATA_SIZE;
  2123 ++ rsdt_addr = addr;
  2124 ++ rsdt = (void *)(addr);
  2125 ++ addr += sizeof(*rsdt);
  2126 ++
  2127 ++ fadt_addr = addr;
  2128 ++ fadt = (void *)(addr);
  2129 ++ addr += sizeof(*fadt);
  2130 ++
  2131 ++ /* XXX: FACS should be in RAM */
  2132 ++ addr = (addr + 63) & ~63; /* 64 byte alignment for FACS */
  2133 ++ facs_addr = addr;
  2134 ++ facs = (void *)(addr);
  2135 ++ addr += sizeof(*facs);
  2136 ++
  2137 ++ dsdt_addr = addr;
  2138 ++ dsdt = (void *)(addr);
  2139 ++ addr += sizeof(AmlCode);
  2140 ++
  2141 ++ addr = (addr + 7) & ~7;
  2142 ++ madt_addr = addr;
  2143 ++ madt_size = sizeof(*madt) +
  2144 ++ sizeof(struct madt_processor_apic) * smp_cpus +
  2145 ++ sizeof(struct madt_io_apic);
  2146 ++ madt = (void *)(addr);
  2147 ++ addr += madt_size;
  2148 ++
  2149 ++ acpi_tables_size = addr - base_addr;
  2150 ++
  2151 ++ BX_INFO("ACPI tables: RSDP addr=0x%08lx ACPI DATA addr=0x%08lx size=0x%x\n",
  2152 ++ (unsigned long)rsdp,
  2153 ++ (unsigned long)rsdt, acpi_tables_size);
  2154 ++
  2155 ++ /* RSDP */
  2156 ++ memset(rsdp, 0, sizeof(*rsdp));
  2157 ++ memcpy(rsdp->signature, "RSD PTR ", 8);
  2158 ++ memcpy(rsdp->oem_id, "QEMU ", 6);
  2159 ++ rsdp->rsdt_physical_address = cpu_to_le32(rsdt_addr);
  2160 ++ rsdp->checksum = acpi_checksum((void *)rsdp, 20);
57 2161 +
58   -+ end -= start;
59   -+ write_word(ES, DI+8, end);
60   -+ write_word(ES, DI+10, end >> 16);
61   -+ write_word(ES, DI+12, 0x0000);
62   -+ write_word(ES, DI+14, 0x0000);
  2162 ++ /* RSDT */
  2163 ++ rsdt->table_offset_entry[0] = cpu_to_le32(fadt_addr);
  2164 ++ rsdt->table_offset_entry[1] = cpu_to_le32(madt_addr);
  2165 ++ acpi_build_table_header((struct acpi_table_header *)rsdt,
  2166 ++ "RSDT", sizeof(*rsdt));
63 2167 +
64   -+ write_word(ES, DI+16, type);
65   -+ write_word(ES, DI+18, 0x0);
  2168 ++ /* FADT */
  2169 ++ memset(fadt, 0, sizeof(*fadt));
  2170 ++ fadt->firmware_ctrl = cpu_to_le32(facs_addr);
  2171 ++ fadt->dsdt = cpu_to_le32(dsdt_addr);
  2172 ++ fadt->model = 1;
  2173 ++ fadt->reserved1 = 0;
  2174 ++ fadt->sci_int = cpu_to_le16(pm_sci_int);
  2175 ++ fadt->smi_cmd = cpu_to_le32(SMI_CMD_IO_ADDR);
  2176 ++ fadt->acpi_enable = 0xf1;
  2177 ++ fadt->acpi_disable = 0xf0;
  2178 ++ fadt->pm1a_evt_blk = cpu_to_le32(pm_io_base);
  2179 ++ fadt->pm1a_cnt_blk = cpu_to_le32(pm_io_base + 0x04);
  2180 ++ fadt->pm_tmr_blk = cpu_to_le32(pm_io_base + 0x08);
  2181 ++ fadt->pm1_evt_len = 4;
  2182 ++ fadt->pm1_cnt_len = 2;
  2183 ++ fadt->pm_tmr_len = 4;
  2184 ++ fadt->plvl2_lat = cpu_to_le16(50);
  2185 ++ fadt->plvl3_lat = cpu_to_le16(50);
  2186 ++ fadt->plvl3_lat = cpu_to_le16(50);
  2187 ++ /* WBINVD + PROC_C1 + PWR_BUTTON + SLP_BUTTON + FIX_RTC */
  2188 ++ fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 4) | (1 << 5) | (1 << 6));
  2189 ++ acpi_build_table_header((struct acpi_table_header *)fadt, "FACP",
  2190 ++ sizeof(*fadt));
  2191 ++
  2192 ++ /* FACS */
  2193 ++ memset(facs, 0, sizeof(*facs));
  2194 ++ memcpy(facs->signature, "FACS", 4);
  2195 ++ facs->length = cpu_to_le32(sizeof(*facs));
  2196 ++
  2197 ++ /* DSDT */
  2198 ++ memcpy(dsdt, AmlCode, sizeof(AmlCode));
  2199 ++
  2200 ++ /* MADT */
  2201 ++ {
  2202 ++ struct madt_processor_apic *apic;
  2203 ++ struct madt_io_apic *io_apic;
  2204 ++
  2205 ++ memset(madt, 0, madt_size);
  2206 ++ madt->local_apic_address = cpu_to_le32(0xfee00000);
  2207 ++ madt->flags = cpu_to_le32(1);
  2208 ++ apic = (void *)(madt + 1);
  2209 ++ for(i=0;i<smp_cpus;i++) {
  2210 ++ apic->type = APIC_PROCESSOR;
  2211 ++ apic->length = sizeof(*apic);
  2212 ++ apic->processor_id = i;
  2213 ++ apic->local_apic_id = i;
  2214 ++ apic->flags = cpu_to_le32(1);
  2215 ++ apic++;
  2216 ++ }
  2217 ++ io_apic = (void *)apic;
  2218 ++ io_apic->type = APIC_IO;
  2219 ++ io_apic->length = sizeof(*io_apic);
  2220 ++ io_apic->io_apic_id = smp_cpus;
  2221 ++ io_apic->address = cpu_to_le32(0xfec00000);
  2222 ++ io_apic->interrupt = cpu_to_le32(0);
  2223 ++
  2224 ++ acpi_build_table_header((struct acpi_table_header *)madt,
  2225 ++ "APIC", madt_size);
  2226 ++ }
  2227 ++}
  2228 ++
  2229 ++void rombios32_init(void)
  2230 ++{
  2231 ++ BX_INFO("Starting rombios32\n");
  2232 ++
  2233 ++ ram_probe();
  2234 ++
  2235 ++ cpu_probe();
  2236 ++
  2237 ++ smp_probe();
  2238 ++
  2239 ++ pci_bios_init();
  2240 ++
  2241 ++ if (bios_table_cur_addr != 0) {
  2242 ++
  2243 ++ mptable_init();
  2244 ++
  2245 ++ if (acpi_enabled)
  2246 ++ acpi_bios_init();
  2247 ++
  2248 ++ bios_lock_shadow_ram();
  2249 ++ }
  2250 ++}
  2251 +diff -ruN --exclude Makefile bios/rombios32.ld bios.new/rombios32.ld
  2252 +--- bios/rombios32.ld 1970-01-01 01:00:00.000000000 +0100
  2253 ++++ bios.new/rombios32.ld 2006-09-24 20:28:05.000000000 +0200
  2254 +@@ -0,0 +1,19 @@
  2255 ++OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
  2256 ++OUTPUT_ARCH(i386)
  2257 ++ENTRY(_start);
  2258 ++SECTIONS
  2259 ++{
  2260 ++ . = 0x00040000;
  2261 ++ .text : { *(.text) }
  2262 ++ .rodata : { *(.rodata) }
  2263 ++ . = ALIGN(4096);
  2264 ++ .data : { *(.data) }
  2265 ++ __bss_start = . ;
  2266 ++ .bss : { *(.bss) *(COMMON) }
  2267 ++ _end = . ;
  2268 ++ /DISCARD/ : { *(.stab)
  2269 ++ *(.stabstr)
  2270 ++ *(.comment)
  2271 ++ *(.note)
  2272 ++ }
66 2273 +}
  2274 +diff -ruN --exclude Makefile bios/rombios32start.S bios.new/rombios32start.S
  2275 +--- bios/rombios32start.S 1970-01-01 01:00:00.000000000 +0100
  2276 ++++ bios.new/rombios32start.S 2006-09-24 20:22:58.000000000 +0200
  2277 +@@ -0,0 +1,76 @@
  2278 ++.globl _start
  2279 ++.globl smp_ap_boot_code_start
  2280 ++.globl smp_ap_boot_code_end
  2281 ++.global smm_relocation_start
  2282 ++.global smm_relocation_end
  2283 ++.global smm_code_start
  2284 ++.global smm_code_end
  2285 ++
  2286 ++#define PM_IO_BASE 0xb000
  2287 ++
  2288 ++_start:
  2289 ++ /* clear bss section */
  2290 ++ xor %eax, %eax
  2291 ++ mov $__bss_start, %edi
  2292 ++ mov $_end, %ecx
  2293 ++ sub %edi, %ecx
  2294 ++ rep stosb
  2295 ++
  2296 ++ jmp rombios32_init
  2297 ++
  2298 ++#define CPU_COUNT 0xf000
  2299 ++
  2300 ++ .code16
  2301 ++smp_ap_boot_code_start:
  2302 ++ xor %ax, %ax
  2303 ++ mov %ax, %ds
  2304 ++ incw CPU_COUNT
  2305 ++1:
  2306 ++ hlt
  2307 ++ jmp 1b
  2308 ++smp_ap_boot_code_end:
  2309 ++
  2310 ++/* code to relocate SMBASE to 0xa0000 */
  2311 ++smm_relocation_start:
  2312 ++ mov $0x38000 + 0x7efc, %ebx
  2313 ++ mov (%ebx), %al /* revision ID to see if x86_64 or x86 */
  2314 ++ cmp $0x64, %al
  2315 ++ je 1f
  2316 ++ mov $0x38000 + 0x7ef8, %ebx
  2317 ++ jmp 2f
  2318 ++1:
  2319 ++ mov $0x38000 + 0x7f00, %ebx
  2320 ++2:
  2321 ++ movl $0xa0000, %eax
  2322 ++ movl %eax, (%ebx)
  2323 ++ rsm
  2324 ++smm_relocation_end:
  2325 ++
  2326 ++/* minimal SMM code to enable or disable ACPI */
  2327 ++smm_code_start:
  2328 ++ movw $0xb2, %dx
  2329 ++ inb %dx, %al
  2330 ++ cmp $0xf0, %al
  2331 ++ jne 1f
  2332 ++
  2333 ++ /* ACPI disable */
  2334 ++ mov $PM_IO_BASE + 0x04, %dx /* PMCNTRL */
  2335 ++ inw %dx, %ax
  2336 ++ andw $~1, %ax
  2337 ++ outw %ax, %dx
  2338 ++
  2339 ++ jmp 2f
  2340 ++
  2341 ++1:
  2342 ++ cmp $0xf1, %al
  2343 ++ jne 2f
  2344 ++
  2345 ++ /* ACPI enable */
  2346 ++ mov $PM_IO_BASE + 0x04, %dx /* PMCNTRL */
  2347 ++ inw %dx, %ax
  2348 ++ orw $1, %ax
  2349 ++ outw %ax, %dx
  2350 ++
  2351 ++2:
  2352 ++ rsm
  2353 ++smm_code_end:
  2354 +diff -ruN --exclude Makefile bios/rombios.c bios.new/rombios.c
  2355 +--- bios/rombios.c 2006-08-11 19:34:12.000000000 +0200
  2356 ++++ bios.new/rombios.c 2006-09-24 20:35:47.000000000 +0200
  2357 +@@ -24,7 +24,7 @@
  2358 + // License along with this library; if not, write to the Free Software
  2359 + // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  2360 +
  2361 +-// ROM BIOS for use with Bochs/Plex x86 emulation environment
  2362 ++// ROM BIOS for use with Bochs/Plex x86/QEMU emulation environment
  2363 +
  2364 +
  2365 + // ROM BIOS compatability entry points:
  2366 +@@ -143,6 +143,7 @@
  2367 + #define BX_FLOPPY_ON_CNT 37 /* 2 seconds */
  2368 + #define BX_PCIBIOS 1
  2369 + #define BX_APM 1
  2370 ++#define BX_ROMBIOS32 1
  2371 +
  2372 + #define BX_USE_ATADRV 1
  2373 + #define BX_ELTORITO_BOOT 1
  2374 +@@ -159,6 +160,9 @@
  2375 + #define BIOS_REVISION 1
  2376 + #define BIOS_CONFIG_TABLE 0xe6f5
  2377 +
  2378 ++/* define it to include QEMU specific code */
  2379 ++#define BX_QEMU
  2380 ++
  2381 + #ifndef BIOS_BUILD_DATE
  2382 + # define BIOS_BUILD_DATE "06/23/99"
  2383 + #endif
  2384 +@@ -170,7 +174,9 @@
  2385 + #define BASE_MEM_IN_K (640 - EBDA_SIZE)
  2386 +
  2387 + // Define the application NAME
  2388 +-#ifdef PLEX86
  2389 ++#if defined(BX_QEMU)
  2390 ++# define BX_APPNAME "QEMU"
  2391 ++#elif defined(PLEX86)
  2392 + # define BX_APPNAME "Plex86"
  2393 + #else
  2394 + # define BX_APPNAME "Bochs"
  2395 +@@ -1826,6 +1832,9 @@
  2396 + #ifdef BX_ELTORITO_BOOT
  2397 + "eltorito "
  2398 + #endif
  2399 ++#ifdef BX_ROMBIOS32
  2400 ++ "rombios32 "
  2401 ++#endif
  2402 + "\n\n");
  2403 + }
  2404 +
  2405 +@@ -4085,6 +4094,24 @@
  2406 + case 0x20: // coded by osmaker aka K.J.
  2407 + if(regs.u.r32.edx == 0x534D4150)
  2408 + {
  2409 ++ extended_memory_size = inb_cmos(0x35);
  2410 ++ extended_memory_size <<= 8;
  2411 ++ extended_memory_size |= inb_cmos(0x34);
  2412 ++ extended_memory_size *= 64;
  2413 ++ // greater than EFF00000???
  2414 ++ if(extended_memory_size > 0x3bc000) {
  2415 ++ extended_memory_size = 0x3bc000; // everything after this is reserved memory until we get to 0x100000000
  2416 ++ }
  2417 ++ extended_memory_size *= 1024;
  2418 ++ extended_memory_size += (16L * 1024 * 1024);
  2419 ++
  2420 ++ if(extended_memory_size <= (16L * 1024 * 1024)) {
  2421 ++ extended_memory_size = inb_cmos(0x31);
  2422 ++ extended_memory_size <<= 8;
  2423 ++ extended_memory_size |= inb_cmos(0x30);
  2424 ++ extended_memory_size *= 1024;
  2425 ++ }
67 2426 +
68   - void
69   - int15_function32(regs, ES, DS, FLAGS)
70   - pushad_regs_t regs; // REGS pushed via pushad
71   -@@ -4063,19 +4090,8 @@
72 2427 switch(regs.u.r16.bx)
73 2428 {
74 2429 case 0:
75   -- write_word(ES, regs.u.r16.di, 0x00);
76   -- write_word(ES, regs.u.r16.di+2, 0x00);
77   -- write_word(ES, regs.u.r16.di+4, 0x00);
78   -- write_word(ES, regs.u.r16.di+6, 0x00);
79   --
80   -- write_word(ES, regs.u.r16.di+8, 0xFC00);
81   -- write_word(ES, regs.u.r16.di+10, 0x0009);
82   -- write_word(ES, regs.u.r16.di+12, 0x0000);
83   -- write_word(ES, regs.u.r16.di+14, 0x0000);
84   --
85   -- write_word(ES, regs.u.r16.di+16, 0x1);
86   -- write_word(ES, regs.u.r16.di+18, 0x0);
87   --
88   -+ set_e820_range(ES, regs.u.r16.di,
89   -+ 0x0000000L, 0x0009fc00L, 1);
90   - regs.u.r32.ebx = 1;
91   - regs.u.r32.eax = 0x534D4150;
92   - regs.u.r32.ecx = 0x14;
93   -@@ -4083,6 +4099,24 @@
  2430 +@@ -4115,27 +4142,9 @@
94 2431 return;
95 2432 break;
96   - case 1:
97   -+ set_e820_range(ES, regs.u.r16.di,
98   -+ 0x0009fc00L, 0x000a0000L, 2);
99   -+ regs.u.r32.ebx = 2;
100   -+ regs.u.r32.eax = 0x534D4150;
101   -+ regs.u.r32.ecx = 0x14;
102   -+ CLEAR_CF();
103   -+ return;
104   -+ break;
105   -+ case 2:
106   -+ set_e820_range(ES, regs.u.r16.di,
107   -+ 0x000e8000L, 0x00100000L, 2);
108   -+ regs.u.r32.ebx = 3;
109   -+ regs.u.r32.eax = 0x534D4150;
110   -+ regs.u.r32.ecx = 0x14;
111   -+ CLEAR_CF();
112   -+ return;
113   -+ break;
114   -+ case 3:
115   - extended_memory_size = inb_cmos(0x35);
116   - extended_memory_size <<= 8;
117   - extended_memory_size |= inb_cmos(0x34);
118   -@@ -4092,9 +4126,9 @@
119   - extended_memory_size = 0x3bc000; // everything after this is reserved memory until we get to 0x100000000
120   - }
121   - extended_memory_size *= 1024;
122   -- extended_memory_size += 15728640; // make up for the 16mb of memory that is chopped off
123   -+ extended_memory_size += (16L * 1024 * 1024);
124   -
125   -- if(extended_memory_size <= 15728640)
126   -+ if(extended_memory_size <= (16L * 1024 * 1024))
127   - {
128   - extended_memory_size = inb_cmos(0x31);
129   - extended_memory_size <<= 8;
130   -@@ -4102,28 +4136,23 @@
131   - extended_memory_size *= 1024;
132   - }
133   -
134   -- write_word(ES, regs.u.r16.di, 0x0000);
135   -- write_word(ES, regs.u.r16.di+2, 0x0010);
136   -- write_word(ES, regs.u.r16.di+4, 0x0000);
137   -- write_word(ES, regs.u.r16.di+6, 0x0000);
138   --
139   -- write_word(ES, regs.u.r16.di+8, extended_memory_size);
140   -- extended_memory_size >>= 16;
141   -- write_word(ES, regs.u.r16.di+10, extended_memory_size);
142   -- extended_memory_size >>= 16;
143   -- write_word(ES, regs.u.r16.di+12, extended_memory_size);
144   -- extended_memory_size >>= 16;
145   -- write_word(ES, regs.u.r16.di+14, extended_memory_size);
  2433 + case 3:
  2434 +- extended_memory_size = inb_cmos(0x35);
  2435 +- extended_memory_size <<= 8;
  2436 +- extended_memory_size |= inb_cmos(0x34);
  2437 +- extended_memory_size *= 64;
  2438 +- if(extended_memory_size > 0x3bc000) // greater than EFF00000???
  2439 +- {
  2440 +- extended_memory_size = 0x3bc000; // everything after this is reserved memory until we get to 0x100000000
  2441 +- }
  2442 +- extended_memory_size *= 1024;
  2443 +- extended_memory_size += (16L * 1024 * 1024);
146 2444 -
147   -- write_word(ES, regs.u.r16.di+16, 0x1);
148   -- write_word(ES, regs.u.r16.di+18, 0x0);
  2445 +- if(extended_memory_size <= (16L * 1024 * 1024))
  2446 +- {
  2447 +- extended_memory_size = inb_cmos(0x31);
  2448 +- extended_memory_size <<= 8;
  2449 +- extended_memory_size |= inb_cmos(0x30);
  2450 +- extended_memory_size *= 1024;
  2451 +- }
149 2452 -
150   -- regs.u.r32.ebx = 0;
151   -+ set_e820_range(ES, regs.u.r16.di,
152   -+ 0x00100000L, extended_memory_size, 1);
153   -+ regs.u.r32.ebx = 4;
  2453 + set_e820_range(ES, regs.u.r16.di,
  2454 +- 0x00100000L, extended_memory_size, 1);
  2455 ++ 0x00100000L,
  2456 ++ extended_memory_size - 0x10000L, 1);
  2457 + regs.u.r32.ebx = 4;
154 2458 regs.u.r32.eax = 0x534D4150;
155 2459 regs.u.r32.ecx = 0x14;
156   - CLEAR_CF();
  2460 +@@ -4143,6 +4152,16 @@
157 2461 return;
158 2462 break;
159   -+ case 4:
160   -+ /* 256KB BIOS area at the end of 4 GB */
  2463 + case 4:
161 2464 + set_e820_range(ES, regs.u.r16.di,
162   -+ 0xfffc0000L, 0x00000000L, 2);
163   -+ regs.u.r32.ebx = 0;
  2465 ++ extended_memory_size - 0x10000L,
  2466 ++ extended_memory_size, 3); // ACPI RAM
  2467 ++ regs.u.r32.ebx = 5;
164 2468 + regs.u.r32.eax = 0x534D4150;
165 2469 + regs.u.r32.ecx = 0x14;
166 2470 + CLEAR_CF();
167 2471 + return;
168   - default: /* AX=E820, DX=534D4150, BX unrecognized */
169   - goto int15_unimplemented;
170   - break;
171   -@@ -8713,6 +8742,7 @@
  2472 ++ break;
  2473 ++ case 5:
  2474 + /* 256KB BIOS area at the end of 4 GB */
  2475 + set_e820_range(ES, regs.u.r16.di,
  2476 + 0xfffc0000L, 0x00000000L, 2);
  2477 +@@ -8757,6 +8776,9 @@
  2478 + unknown_service:
172 2479 mov al, #0x80
173 2480 bios32_end:
  2481 ++#ifdef BX_QEMU
  2482 ++ and dword ptr[esp+8],0xfffffffc ;; reset CS.RPL for kqemu
  2483 ++#endif
174 2484 popf
175   -+ and dword ptr[esp+4],0xfffffffc ;; reset CS.RPL for kqemu
176 2485 retf
177 2486  
178   - .align 16
179   -@@ -8823,17 +8853,17 @@
  2487 +@@ -8868,6 +8890,9 @@
180 2488 pci_pro_fail:
181 2489 pop edi
182 2490 pop esi
183   -- sti
  2491 ++#ifdef BX_QEMU
  2492 ++ and dword ptr[esp+8],0xfffffffc ;; reset CS.RPL for kqemu
  2493 ++#endif
184 2494 popf
185 2495 stc
186   -+ and dword ptr[esp+4],0xfffffffc ;; reset CS.RPL for kqemu
187 2496 retf
188   - pci_pro_ok:
  2497 +@@ -8875,6 +8900,9 @@
189 2498 xor ah, ah
190 2499 pop edi
191 2500 pop esi
192   -- sti
  2501 ++#ifdef BX_QEMU
  2502 ++ and dword ptr[esp+8],0xfffffffc ;; reset CS.RPL for kqemu
  2503 ++#endif
193 2504 popf
194 2505 clc
195   -+ and dword ptr[esp+4],0xfffffffc ;; reset CS.RPL for kqemu
196 2506 retf
  2507 +@@ -9183,227 +9211,118 @@
  2508 + db 0 ;; reserved
  2509 + pci_routing_table_structure_end:
  2510 +
  2511 +-pci_irq_list:
  2512 +- db 11, 10, 9, 5;
  2513 ++#endif // BX_PCIBIOS
  2514 +
  2515 +-pcibios_init_sel_reg:
  2516 +- push eax
  2517 +- mov eax, #0x800000
  2518 +- mov ax, bx
  2519 +- shl eax, #8
  2520 +- and dl, #0xfc
  2521 +- or al, dl
  2522 +- mov dx, #0x0cf8
  2523 +- out dx, eax
  2524 +- pop eax
  2525 +- ret
  2526 +-
  2527 +-pcibios_init_iomem_bases:
  2528 +- push bp
  2529 +- mov bp, sp
  2530 +- mov eax, #0xe0000000 ;; base for memory init
  2531 +- push eax
  2532 +- mov ax, #0xc000 ;; base for i/o init
  2533 +- push ax
  2534 +- mov ax, #0x0010 ;; start at base address #0
  2535 ++#if BX_ROMBIOS32
  2536 ++rombios32_init:
  2537 ++ ;; save a20 and enable it
  2538 ++ in al, 0x92
  2539 + push ax
  2540 +- mov bx, #0x0008
  2541 +-pci_init_io_loop1:
  2542 +- mov dl, #0x00
  2543 +- call pcibios_init_sel_reg
  2544 +- mov dx, #0x0cfc
  2545 +- in ax, dx
  2546 +- cmp ax, #0xffff
  2547 +- jz next_pci_dev
  2548 +- mov dl, #0x04 ;; disable i/o and memory space access
  2549 +- call pcibios_init_sel_reg
  2550 +- mov dx, #0x0cfc
  2551 +- in al, dx
  2552 +- and al, #0xfc
  2553 +- out dx, al
  2554 +-pci_init_io_loop2:
  2555 +- mov dl, [bp-8]
  2556 +- call pcibios_init_sel_reg
  2557 +- mov dx, #0x0cfc
  2558 +- in eax, dx
  2559 +- test al, #0x01
  2560 +- jnz init_io_base
  2561 +- mov ecx, eax
  2562 +- mov eax, #0xffffffff
  2563 +- out dx, eax
  2564 +- in eax, dx
  2565 +- cmp eax, ecx
  2566 +- je next_pci_base
  2567 +- xor eax, #0xffffffff
  2568 +- mov ecx, eax
  2569 +- mov eax, [bp-4]
  2570 +- out dx, eax
  2571 +- add eax, ecx ;; calculate next free mem base
  2572 +- add eax, #0x01000000
  2573 +- and eax, #0xff000000
  2574 +- mov [bp-4], eax
  2575 +- jmp next_pci_base
  2576 +-init_io_base:
  2577 +- mov cx, ax
  2578 +- mov ax, #0xffff
  2579 +- out dx, ax
  2580 +- in ax, dx
  2581 +- cmp ax, cx
  2582 +- je next_pci_base
  2583 +- xor ax, #0xfffe
  2584 +- mov cx, ax
  2585 +- mov ax, [bp-6]
  2586 +- out dx, ax
  2587 +- add ax, cx ;; calculate next free i/o base
  2588 +- add ax, #0x0100
  2589 +- and ax, #0xff00
  2590 +- mov [bp-6], ax
  2591 +-next_pci_base:
  2592 +- mov al, [bp-8]
  2593 +- add al, #0x04
  2594 +- cmp al, #0x28
  2595 +- je enable_iomem_space
  2596 +- mov byte ptr[bp-8], al
  2597 +- jmp pci_init_io_loop2
  2598 +-enable_iomem_space:
  2599 +- mov dl, #0x04 ;; enable i/o and memory space access if available
  2600 +- call pcibios_init_sel_reg
  2601 +- mov dx, #0x0cfc
  2602 +- in al, dx
  2603 +- or al, #0x07
  2604 +- out dx, al
  2605 +-next_pci_dev:
  2606 +- mov byte ptr[bp-8], #0x10
  2607 +- inc bx
  2608 +- cmp bx, #0x0100
  2609 +- jne pci_init_io_loop1
  2610 +- mov sp, bp
  2611 +- pop bp
  2612 +- ret
  2613 ++ or al, #0x02
  2614 ++ out 0x92, al
197 2615  
198   - pci_pro_select_reg:
199   -@@ -8971,7 +9001,7 @@
200   - jmp pci_real_ok
201   - pci_real_f0d: ;; write configuration dword
202   - cmp al, #0x0d
203   -- jne pci_real_unknown
204   -+ jne pci_real_f0e
205   - call pci_real_select_reg
206   - push dx
207   - mov dx, #0x0cfc
208   -@@ -8979,6 +9009,46 @@
209   - out dx, eax
210   - pop dx
211   - jmp pci_real_ok
212   -+pci_real_f0e: ;; get irq routing options
213   -+ cmp al, #0x0e
214   -+ jne pci_real_unknown
215   -+ SEG ES
216   -+ cmp word ptr [di], #pci_routing_table_structure_end - pci_routing_table_structure_start
217   -+ jb pci_real_too_small
218   -+ SEG ES
219   -+ mov word ptr [di], #pci_routing_table_structure_end - pci_routing_table_structure_start
220   -+ pushf
221   -+ push ds
222   -+ push es
223   -+ push cx
224   -+ push si
225   -+ push di
  2616 +-pcibios_init_set_elcr:
  2617 +- push ax
  2618 +- push cx
  2619 +- mov dx, #0x04d0
  2620 +- test al, #0x08
  2621 +- jz is_master_pic
  2622 +- inc dx
  2623 +- and al, #0x07
  2624 +-is_master_pic:
  2625 +- mov cl, al
  2626 +- mov bl, #0x01
  2627 +- shl bl, cl
  2628 +- in al, dx
  2629 +- or al, bl
  2630 +- out dx, al
  2631 +- pop cx
  2632 +- pop ax
  2633 +- ret
  2634 ++ ;; save SS:SP to the BDA
  2635 ++ xor ax, ax
  2636 ++ mov ds, ax
  2637 ++ mov 0x0469, ss
  2638 ++ mov 0x0467, sp
  2639 +
  2640 +-pcibios_init_irqs:
  2641 +- push ds
  2642 +- push bp
  2643 +- mov ax, #0xf000
  2644 +- mov ds, ax
  2645 +- mov dx, #0x04d0 ;; reset ELCR1 + ELCR2
  2646 +- mov al, #0x00
  2647 +- out dx, al
  2648 +- inc dx
  2649 +- out dx, al
  2650 +- mov si, #pci_routing_table_structure
  2651 +- mov bh, [si+8]
  2652 +- mov bl, [si+9]
  2653 +- mov dl, #0x00
  2654 +- call pcibios_init_sel_reg
  2655 +- mov dx, #0x0cfc
  2656 +- in eax, dx
  2657 +- cmp eax, [si+12] ;; check irq router
  2658 +- jne pci_init_end
  2659 +- mov dl, [si+34]
  2660 +- call pcibios_init_sel_reg
  2661 +- push bx ;; save irq router bus + devfunc
  2662 +- mov dx, #0x0cfc
  2663 +- mov ax, #0x8080
  2664 +- out dx, ax ;; reset PIRQ route control
  2665 +- inc dx
  2666 +- inc dx
  2667 +- out dx, ax
  2668 +- mov ax, [si+6]
  2669 +- sub ax, #0x20
  2670 +- shr ax, #4
  2671 +- mov cx, ax
  2672 +- add si, #0x20 ;; set pointer to 1st entry
  2673 +- mov bp, sp
  2674 +- mov ax, #pci_irq_list
  2675 +- push ax
  2676 +- xor ax, ax
  2677 +- push ax
  2678 +-pci_init_irq_loop1:
  2679 +- mov bh, [si]
  2680 +- mov bl, [si+1]
  2681 +-pci_init_irq_loop2:
  2682 +- mov dl, #0x00
  2683 +- call pcibios_init_sel_reg
  2684 +- mov dx, #0x0cfc
  2685 +- in ax, dx
  2686 +- cmp ax, #0xffff
  2687 +- jnz pci_test_int_pin
  2688 +- test bl, #0x07
  2689 +- jz next_pir_entry
  2690 +- jmp next_pci_func
  2691 +-pci_test_int_pin:
  2692 +- mov dl, #0x3c
  2693 +- call pcibios_init_sel_reg
  2694 +- mov dx, #0x0cfd
  2695 +- in al, dx
  2696 +- and al, #0x07
  2697 +- jz next_pci_func
  2698 +- dec al ;; determine pirq reg
  2699 +- mov dl, #0x03
  2700 +- mul al, dl
  2701 +- add al, #0x02
  2702 +- xor ah, ah
  2703 +- mov bx, ax
  2704 +- mov al, [si+bx]
  2705 +- mov dl, al
  2706 +- mov bx, [bp]
  2707 +- call pcibios_init_sel_reg
  2708 +- mov dx, #0x0cfc
  2709 +- and al, #0x03
  2710 +- add dl, al
  2711 +- in al, dx
  2712 +- cmp al, #0x80
  2713 +- jb pirq_found
  2714 +- mov bx, [bp-2] ;; pci irq list pointer
  2715 +- mov al, [bx]
  2716 +- out dx, al
  2717 +- inc bx
  2718 +- mov [bp-2], bx
  2719 +- call pcibios_init_set_elcr
  2720 +-pirq_found:
  2721 +- mov bh, [si]
  2722 +- mov bl, [si+1]
  2723 +- add bl, [bp-3] ;; pci function number
  2724 +- mov dl, #0x3c
  2725 +- call pcibios_init_sel_reg
  2726 +- mov dx, #0x0cfc
  2727 +- out dx, al
  2728 +-next_pci_func:
  2729 +- inc byte ptr[bp-3]
  2730 +- inc bl
  2731 +- test bl, #0x07
  2732 +- jnz pci_init_irq_loop2
  2733 +-next_pir_entry:
  2734 +- add si, #0x10
  2735 +- mov byte ptr[bp-3], #0x00
  2736 +- loop pci_init_irq_loop1
  2737 +- mov sp, bp
  2738 +- pop bx
  2739 +-pci_init_end:
  2740 +- pop bp
  2741 +- pop ds
  2742 ++ SEG CS
  2743 ++ lidt [pmode_IDT_info]
  2744 ++ SEG CS
  2745 ++ lgdt [rombios32_gdt_48]
  2746 ++ ;; set PE bit in CR0
  2747 ++ mov eax, cr0
  2748 ++ or al, #0x01
  2749 ++ mov cr0, eax
  2750 ++ ;; start protected mode code: ljmpl 0x10:rombios32_init1
  2751 ++ db 0x66, 0xea
  2752 ++ dw rombios32_05
  2753 ++ dw 0x000f ;; high 16 bit address
  2754 ++ dw 0x0010
  2755 ++
  2756 ++use32 386
  2757 ++rombios32_05:
  2758 ++ ;; init data segments
  2759 ++ mov eax, #0x18
  2760 ++ mov ds, ax
  2761 ++ mov es, ax
  2762 ++ mov ss, ax
  2763 ++ xor eax, eax
  2764 ++ mov fs, ax
  2765 ++ mov gs, ax
226 2766 + cld
227   -+ mov si, #pci_routing_table_structure_start
228   -+ push cs
229   -+ pop ds
230   -+ SEG ES
231   -+ mov cx, [di+2]
232   -+ SEG ES
233   -+ mov es, [di+4]
234   -+ mov di, cx
235   -+ mov cx, #pci_routing_table_structure_end - pci_routing_table_structure_start
  2767 ++
  2768 ++ ;; copy rombios32 code to ram (ram offset = 1MB)
  2769 ++ mov esi, #0xfffe0000
  2770 ++ mov edi, #0x00040000
  2771 ++ mov ecx, #0x10000 / 4
236 2772 + rep
237   -+ movsb
238   -+ pop di
239   -+ pop si
240   -+ pop cx
241   -+ pop es
242   -+ pop ds
243   -+ popf
244   -+ mov bx, #(1 << 9) | (1 << 11) ;; irq 9 and 11 are used
245   -+ jmp pci_real_ok
246   -+pci_real_too_small:
247   -+ SEG ES
248   -+ mov word ptr [di], #pci_routing_table_structure_end - pci_routing_table_structure_start
249   -+ mov ah, #0x89
250   -+ jmp pci_real_fail
251   -+
252   - pci_real_unknown:
253   - mov ah, #0x81
254   - pci_real_fail:
255   -@@ -9019,6 +9089,7 @@
256   - dw 0,0 ;; Miniport data
257   - db 0,0,0,0,0,0,0,0,0,0,0 ;; reserved
258   - db 0x07 ;; checksum
259   -+pci_routing_table_structure_start:
260   - ;; first slot entry PCI-to-ISA (embedded)
261   - db 0 ;; pci bus number
262   - db 0x08 ;; pci device number (bit 7-3)
263   -@@ -9097,6 +9168,7 @@
264   - dw 0xdef8 ;; IRQ bitmap INTD#
265   - db 5 ;; physical slot (0 = embedded)
266   - db 0 ;; reserved
267   -+pci_routing_table_structure_end:
  2773 ++ movsd
  2774 ++
  2775 ++ ;; init the stack pointer
  2776 ++ mov esp, #0x00080000
  2777 ++
  2778 ++ ;; call rombios32 code
  2779 ++ mov eax, #0x00040000
  2780 ++ call eax
  2781 ++
  2782 ++ ;; return to 16 bit protected mode first
  2783 ++ db 0xea
  2784 ++ dd rombios32_10
  2785 ++ dw 0x20
  2786 ++
  2787 ++use16 386
  2788 ++rombios32_10:
  2789 ++ ;; restore data segment limits to 0xffff
  2790 ++ mov ax, #0x28
  2791 ++ mov ds, ax
  2792 ++ mov es, ax
  2793 ++ mov ss, ax
  2794 ++ mov fs, ax
  2795 ++ mov gs, ax
  2796 ++
  2797 ++ ;; reset PE bit in CR0
  2798 ++ mov eax, cr0
  2799 ++ and al, #0xFE
  2800 ++ mov cr0, eax
  2801 ++
  2802 ++ ;; far jump to flush CPU queue after transition to real mode
  2803 ++ JMP_AP(0xf000, rombios32_real_mode)
  2804 ++
  2805 ++rombios32_real_mode:
  2806 ++ ;; restore IDT to normal real-mode defaults
  2807 ++ SEG CS
  2808 ++ lidt [rmode_IDT_info]
  2809 ++
  2810 ++ xor ax, ax
  2811 ++ mov ds, ax
  2812 ++ mov es, ax
  2813 ++ mov fs, ax
  2814 ++ mov gs, ax
  2815 ++
  2816 ++ ;; restore SS:SP from the BDA
  2817 ++ mov ss, 0x0469
  2818 ++ mov sp, 0x0467
  2819 ++ ;; restore a20
  2820 ++ pop ax
  2821 ++ out 0x92, al
  2822 + ret
  2823 +-#endif // BX_PCIBIOS
  2824 ++
  2825 ++rombios32_gdt_48:
  2826 ++ dw 0x30
  2827 ++ dw rombios32_gdt
  2828 ++ dw 0x000f
  2829 ++
  2830 ++rombios32_gdt:
  2831 ++ dw 0, 0, 0, 0
  2832 ++ dw 0, 0, 0, 0
  2833 ++ dw 0xffff, 0, 0x9b00, 0x00cf ; 32 bit flat code segment (0x10)
  2834 ++ dw 0xffff, 0, 0x9300, 0x00cf ; 32 bit flat data segment (0x18)
  2835 ++ dw 0xffff, 0, 0x9b0f, 0x0000 ; 16 bit code segment base=0xf0000 limit=0xffff
  2836 ++ dw 0xffff, 0, 0x9300, 0x0000 ; 16 bit data segment base=0x0 limit=0xffff
  2837 ++#endif
  2838 ++
  2839 +
  2840 + ; parallel port detection: base address in DX, index in BX, timeout in CL
  2841 + detect_parport:
  2842 +@@ -9535,10 +9454,17 @@
  2843 + ;; DATA_SEG_DEFS_HERE
  2844 +
  2845 +
  2846 ++;; the following area can be used to write dynamically generated tables
  2847 ++ .align 16
  2848 ++bios_table_area_start:
  2849 ++ dd 0xaafb4442
  2850 ++ dd bios_table_area_end - bios_table_area_start - 8;
  2851 ++
  2852 + ;--------
  2853 + ;- POST -
  2854 + ;--------
  2855 + .org 0xe05b ; POST Entry Point
  2856 ++bios_table_area_end:
  2857 + post:
  2858 +
  2859 + xor ax, ax
  2860 +@@ -9802,9 +9728,9 @@
  2861 + #endif
  2862 + out 0xa1, AL ;slave pic: unmask IRQ 12, 13, 14
  2863 +
  2864 +- call pcibios_init_iomem_bases
  2865 +- call pcibios_init_irqs
  2866 +-
  2867 ++#if BX_ROMBIOS32
  2868 ++ call rombios32_init
  2869 ++#endif
  2870 + call rom_scan
268 2871  
269   - pci_irq_list:
270   - db 11, 10, 9, 5;
  2872 + call _print_bios_banner
... ...