├── .gitignore ├── COMMIT-QUEUE.ini ├── COPYING ├── COPYING.LESSER ├── Makefile ├── PRESUBMIT.cfg ├── README ├── README.CSM ├── chromeos ├── bootorder ├── default.config ├── etc │ ├── boot-menu-key │ ├── boot-menu-message │ └── boot-menu-wait └── links ├── scripts ├── acpi_extract.py ├── acpi_extract_preprocess.py ├── buildrom.py ├── buildversion.sh ├── checkrom.py ├── checkstack.py ├── checksum.py ├── encodeint.py ├── gen-offsets.sh ├── kconfig │ ├── .gitignore │ ├── Makefile │ ├── POTFILES.in │ ├── check.sh │ ├── conf.c │ ├── confdata.c │ ├── expr.c │ ├── expr.h │ ├── gconf.c │ ├── gconf.glade │ ├── images.c │ ├── kxgettext.c │ ├── lex.zconf.c │ ├── list.h │ ├── lkc.h │ ├── lkc_proto.h │ ├── lxdialog │ │ ├── .gitignore │ │ ├── BIG.FAT.WARNING │ │ ├── check-lxdialog.sh │ │ ├── checklist.c │ │ ├── dialog.h │ │ ├── inputbox.c │ │ ├── menubox.c │ │ ├── textbox.c │ │ ├── util.c │ │ └── yesno.c │ ├── mconf.c │ ├── menu.c │ ├── merge_config.sh │ ├── nconf.c │ ├── nconf.gui.c │ ├── nconf.h │ ├── qconf.cc │ ├── qconf.h │ ├── streamline_config.pl │ ├── symbol.c │ ├── util.c │ ├── zconf.gperf │ ├── zconf.hash.c_shipped │ ├── zconf.l │ ├── zconf.lex.c_shipped │ ├── zconf.tab.c_shipped │ └── zconf.y ├── layoutrom.py ├── python23compat.py ├── readserial.py ├── test-build.sh ├── transdump.py └── vgafixup.py ├── src ├── Kconfig ├── apm.c ├── asm-offsets.c ├── biosvar.h ├── block.c ├── block.h ├── bmp.c ├── boot.c ├── bootsplash.c ├── bregs.h ├── byteorder.h ├── cdrom.c ├── clock.c ├── code16gcc.s ├── config.h ├── disk.c ├── entryfuncs.S ├── farptr.h ├── font.c ├── fw │ ├── acpi-dsdt-cpu-hotplug.dsl │ ├── acpi-dsdt-dbug.dsl │ ├── acpi-dsdt-hpet.dsl │ ├── acpi-dsdt-isa.dsl │ ├── acpi-dsdt-pci-crs.dsl │ ├── acpi-dsdt.dsl │ ├── acpi.c │ ├── biostables.c │ ├── coreboot.c │ ├── csm.c │ ├── dev-piix.h │ ├── dev-q35.h │ ├── lzmadecode.c │ ├── lzmadecode.h │ ├── mptable.c │ ├── mtrr.c │ ├── paravirt.c │ ├── paravirt.h │ ├── pciinit.c │ ├── pirtable.c │ ├── q35-acpi-dsdt.dsl │ ├── romfile_loader.c │ ├── romfile_loader.h │ ├── shadow.c │ ├── smbios.c │ ├── smm.c │ ├── smp.c │ ├── ssdt-misc.dsl │ ├── ssdt-pcihp.dsl │ ├── ssdt-proc.dsl │ ├── xen.c │ └── xen.h ├── gen-defs.h ├── hw │ ├── ahci.c │ ├── ahci.h │ ├── ata.c │ ├── ata.h │ ├── bar.h │ ├── blockcmd.c │ ├── blockcmd.h │ ├── dma.c │ ├── esp-scsi.c │ ├── esp-scsi.h │ ├── floppy.c │ ├── lsi-scsi.c │ ├── lsi-scsi.h │ ├── megasas.c │ ├── megasas.h │ ├── mmc.c │ ├── mmc.h │ ├── pci.c │ ├── pci.h │ ├── pci_ids.h │ ├── pci_regs.h │ ├── pic.c │ ├── pic.h │ ├── ps2port.c │ ├── ps2port.h │ ├── pvscsi.c │ ├── pvscsi.h │ ├── ramdisk.c │ ├── rtc.c │ ├── rtc.h │ ├── sd.c │ ├── sd.h │ ├── sd_if.c │ ├── sd_if.h │ ├── sd_utils.c │ ├── sd_utils.h │ ├── sdhc_generic.c │ ├── sdhc_generic.h │ ├── sdhci.h │ ├── serialio.c │ ├── serialio.h │ ├── timer.c │ ├── usb-ehci.c │ ├── usb-ehci.h │ ├── usb-hid.c │ ├── usb-hid.h │ ├── usb-hub.c │ ├── usb-hub.h │ ├── usb-msc.c │ ├── usb-msc.h │ ├── usb-ohci.c │ ├── usb-ohci.h │ ├── usb-uas.c │ ├── usb-uas.h │ ├── usb-uhci.c │ ├── usb-uhci.h │ ├── usb-xhci.c │ ├── usb-xhci.h │ ├── usb.c │ ├── usb.h │ ├── virtio-blk.c │ ├── virtio-blk.h │ ├── virtio-pci.c │ ├── virtio-pci.h │ ├── virtio-ring.c │ ├── virtio-ring.h │ ├── virtio-scsi.c │ └── virtio-scsi.h ├── jpeg.c ├── kbd.c ├── list.h ├── malloc.c ├── malloc.h ├── memmap.c ├── memmap.h ├── misc.c ├── mouse.c ├── optionroms.c ├── output.c ├── output.h ├── pcibios.c ├── pmm.c ├── pnpbios.c ├── post.c ├── resume.c ├── romfile.c ├── romfile.h ├── romlayout.S ├── serial.c ├── stacks.c ├── stacks.h ├── std │ ├── LegacyBios.h │ ├── acpi.h │ ├── bda.h │ ├── disk.h │ ├── mptable.h │ ├── optionrom.h │ ├── pirtable.h │ ├── pmm.h │ ├── pnpbios.h │ ├── smbios.h │ ├── vbe.h │ └── vga.h ├── stdbool.h ├── stdint.h ├── string.c ├── string.h ├── system.c ├── types.h ├── util.h ├── vgahooks.c ├── x86.c └── x86.h └── vgasrc ├── Kconfig ├── bochsvga.c ├── bochsvga.h ├── cbvga.c ├── cbvga.h ├── clext.c ├── clext.h ├── geodevga.c ├── geodevga.h ├── stdvga.c ├── stdvga.h ├── stdvgaio.c ├── stdvgamodes.c ├── vbe.c ├── vgabios.c ├── vgabios.h ├── vgaentry.S ├── vgafb.c ├── vgafonts.c ├── vgahw.h ├── vgainit.c └── vgalayout.lds.S /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | *.pyc 3 | .config 4 | .config.old 5 | -------------------------------------------------------------------------------- /COMMIT-QUEUE.ini: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 2 | # Use of this source code is governed by a BSD-style license that can be 3 | # found in the LICENSE file. 4 | 5 | # Per-project Commit Queue settings. 6 | # Documentation: http://goo.gl/4rZhAx 7 | 8 | [GENERAL] 9 | 10 | # Stages to ignore in the commit queue. If these steps break, your CL will be 11 | # submitted anyway. Use with caution. 12 | ignored-stages: HWTest VMTest 13 | -------------------------------------------------------------------------------- /PRESUBMIT.cfg: -------------------------------------------------------------------------------- 1 | # This config file disables some of the ChromiumOS source style checks for 2 | # coreboot as they are directly conflicting with the coreboot coding 3 | # guidelines. 4 | 5 | [Hook Overrides] 6 | #stray_whitespace_check: false 7 | #long_line_check: false 8 | cros_license_check: false 9 | tab_check: false 10 | -------------------------------------------------------------------------------- /README.CSM: -------------------------------------------------------------------------------- 1 | Enabling CONFIG_CSM allows SeaBIOS to be built as a Compatibility Support 2 | Module for use with the OMVF/EDK-II UEFI firmware. 3 | 4 | It will provide "legacy" BIOS services for booting non-EFI operating 5 | systems and will also allow OVMF to display on otherwise unsupported 6 | video hardware by using the traditional VGA BIOS. 7 | 8 | Windows 2008r2 is known to use INT 10h BIOS calls even when booted via 9 | EFI, and the presence of a CSM makes this work as expected too. 10 | 11 | Having built SeaBIOS with CONFIG_CSM, you should be able to drop the 12 | result (out/Csm16.bin) into your OVMF build tree at 13 | OvmfPkg/Csm/Csm16/Csm16.bin and then build OVMF with 'build -D 14 | CSM_ENABLE'. The SeaBIOS binary will be included as a discrete file 15 | within the 'Flash Volume' which is created, and there are tools which 16 | will extract it and allow it to be replaced; satisfying the 17 | requirements of the LGPL licence. 18 | 19 | A patch to OVMF is required, to prevent it from marking the region from 20 | 0xC0000-0xFFFFF as read-only before invoking our Legacy16Boot method. See 21 | http://www.sourceforge.net/mailarchive/forum.php?thread_name=50FD7290.9060003%40redhat.com&forum_name=edk2-devel 22 | 23 | -------------------------------------------------------------------------------- /chromeos/bootorder: -------------------------------------------------------------------------------- 1 | /pci@i0cf8/usb@14/usb-*@0 2 | /pci@i0cf8/usb@14/usb-*@1 3 | /pci@i0cf8/usb@14/usb-*@2 4 | /pci@i0cf8/usb@14/usb-*@3 5 | /pci@i0cf8/usb@14/usb-*@4 6 | /pci@i0cf8/usb@14/usb-*@5 7 | /pci@i0cf8/usb@14/usb-*@6 8 | /pci@i0cf8/usb@14/usb-*@7 9 | /pci@i0cf8/usb@1d/hub@1/*@0 10 | /pci@i0cf8/usb@1d/hub@1/*@1 11 | /pci@i0cf8/usb@1d/hub@1/*@2 12 | /pci@i0cf8/usb@1d/hub@1/*@3 13 | /pci@i0cf8/usb@1d/hub@1/*@4 14 | /pci@i0cf8/usb@1d/hub@1/*@5 15 | /pci@i0cf8/usb@1d/hub@1/*@6 16 | /pci@i0cf8/usb@1d/hub@1/*@7 17 | /pci@i0cf8/*@1f,2/drive@0/disk@0 18 | -------------------------------------------------------------------------------- /chromeos/default.config: -------------------------------------------------------------------------------- 1 | CONFIG_COREBOOT=y 2 | CONFIG_CBFS_LOCATION=0xffe00000 3 | # CONFIG_THREADS is not set 4 | # CONFIG_BOOTSPLASH is not set 5 | # CONFIG_ATA is not set 6 | # CONFIG_FLOPPY is not set 7 | # CONFIG_USB_OHCI is not set 8 | # CONFIG_LPT is not set 9 | # CONFIG_MOUSE is not set 10 | CONFIG_VGA_COREBOOT=y 11 | CONFIG_DEBUG_LEVEL=8 12 | -------------------------------------------------------------------------------- /chromeos/etc/boot-menu-key: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /chromeos/etc/boot-menu-message: -------------------------------------------------------------------------------- 1 | 2 | Press ESC for boot menu. 3 | 4 | 5 | -------------------------------------------------------------------------------- /chromeos/etc/boot-menu-wait: -------------------------------------------------------------------------------- 1 | | -------------------------------------------------------------------------------- /chromeos/links: -------------------------------------------------------------------------------- 1 | pci8086,0402.rom pci8086,0406.rom # GT1 Desktop 2 | pci8086,0406.rom pci8086,0406.rom # GT1 Mobile 3 | pci8086,040a.rom pci8086,0406.rom # GT1 Server 4 | pci8086,0a06.rom pci8086,0406.rom # GT1 ULT 5 | pci8086,0412.rom pci8086,0406.rom # GT2 Desktop 6 | pci8086,0416.rom pci8086,0406.rom # GT2 Mobile 7 | pci8086,041a.rom pci8086,0406.rom # GT2 Server 8 | pci8086,0a16.rom pci8086,0406.rom # GT2 ULT 9 | pci8086,0422.rom pci8086,0406.rom # GT3 Desktop 10 | pci8086,0426.rom pci8086,0406.rom # GT3 Mobile 11 | pci8086,042a.rom pci8086,0406.rom # GT3 Server 12 | pci8086,0a26.rom pci8086,0406.rom # GT3 ULT 13 | pci8086,1606.rom pci8086,0406.rom # BDW U GT1 14 | pci8086,1616.rom pci8086,0406.rom # BDW U GT2 15 | pci8086,1626.rom pci8086,0406.rom # BDW U GT3 15W 16 | pci8086,162b.rom pci8086,0406.rom # BDW U GT3 28W 17 | pci8086,161e.rom pci8086,0406.rom # BDW Y GT2 18 | -------------------------------------------------------------------------------- /scripts/acpi_extract_preprocess.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Copyright (C) 2011 Red Hat, Inc., Michael S. Tsirkin 3 | # 4 | # This file may be distributed under the terms of the GNU GPLv3 license. 5 | 6 | # Read a preprocessed ASL listing and put each ACPI_EXTRACT 7 | # directive in a comment, to make iasl skip it. 8 | # We also put each directive on a new line, the machinery 9 | # in scripts/acpi_extract.py requires this. 10 | 11 | import re 12 | import sys 13 | import fileinput 14 | 15 | def die(diag): 16 | sys.stderr.write("Error: %s\n" % (diag)) 17 | sys.exit(1) 18 | 19 | # Note: () around pattern make split return matched string as part of list 20 | psplit = re.compile(r''' ( 21 | \b # At word boundary 22 | ACPI_EXTRACT_\w+ # directive 23 | \s+ # some whitespace 24 | \w+ # array name 25 | )''', re.VERBOSE) 26 | 27 | lineno = 0 28 | for line in fileinput.input(): 29 | # line number and debug string to output in case of errors 30 | lineno = lineno + 1 31 | debug = "input line %d: %s" % (lineno, line.rstrip()) 32 | 33 | s = psplit.split(line) 34 | # The way split works, each odd item is the matching ACPI_EXTRACT directive. 35 | # Put each in a comment, and on a line by itself. 36 | for i in range(len(s)): 37 | if (i % 2): 38 | sys.stdout.write("\n/* %s */\n" % s[i]) 39 | else: 40 | sys.stdout.write(s[i]) 41 | 42 | -------------------------------------------------------------------------------- /scripts/buildrom.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Fill in checksum/size of an option rom, and pad it to proper length. 3 | # 4 | # Copyright (C) 2009 Kevin O'Connor 5 | # 6 | # This file may be distributed under the terms of the GNU GPLv3 license. 7 | 8 | import sys, struct 9 | 10 | from python23compat import as_bytes 11 | 12 | def alignpos(pos, alignbytes): 13 | mask = alignbytes - 1 14 | return (pos + mask) & ~mask 15 | 16 | def checksum(data): 17 | if (sys.version_info > (3, 0)): 18 | cksum = sum(data) 19 | else: 20 | cksum = sum(map(ord, data)) 21 | return struct.pack(' ${OUTFILE} < ${OUTFILE} < 5 | # 6 | # This file may be distributed under the terms of the GNU GPLv3 license. 7 | 8 | import sys, struct 9 | import layoutrom, buildrom 10 | 11 | from python23compat import as_bytes 12 | 13 | def subst(data, offset, new): 14 | return data[:offset] + new + data[offset + len(new):] 15 | 16 | def checksum(data, start, size, csum): 17 | sumbyte = buildrom.checksum(data[start:start+size]) 18 | return subst(data, start+csum, sumbyte) 19 | 20 | def main(): 21 | # Get args 22 | objinfo, finalsize, rawfile, outfile = sys.argv[1:] 23 | 24 | # Read in symbols 25 | objinfofile = open(objinfo, 'r') 26 | symbols = layoutrom.parseObjDump(objinfofile, 'in')[1] 27 | 28 | # Read in raw file 29 | f = open(rawfile, 'rb') 30 | rawdata = f.read() 31 | f.close() 32 | datasize = len(rawdata) 33 | finalsize = int(finalsize) * 1024 34 | if finalsize == 0: 35 | finalsize = 64*1024 36 | if datasize > 64*1024: 37 | finalsize = 128*1024 38 | if datasize > 128*1024: 39 | finalsize = 256*1024 40 | if datasize > finalsize: 41 | print("Error! ROM doesn't fit (%d > %d)" % (datasize, finalsize)) 42 | print(" You have to either increate the size (CONFIG_ROM_SIZE)") 43 | print(" or turn off some features (such as hardware support not") 44 | print(" needed) to make it fit. Trying a more recent gcc version") 45 | print(" might work too.") 46 | sys.exit(1) 47 | 48 | # Sanity checks 49 | start = symbols['code32flat_start'].offset 50 | end = symbols['code32flat_end'].offset 51 | expend = layoutrom.BUILD_BIOS_ADDR + layoutrom.BUILD_BIOS_SIZE 52 | if end != expend: 53 | print("Error! Code does not end at 0x%x (got 0x%x)" % ( 54 | expend, end)) 55 | sys.exit(1) 56 | if datasize > finalsize: 57 | print("Error! Code is too big (0x%x vs 0x%x)" % ( 58 | datasize, finalsize)) 59 | sys.exit(1) 60 | expdatasize = end - start 61 | if datasize != expdatasize: 62 | print("Error! Unknown extra data (0x%x vs 0x%x)" % ( 63 | datasize, expdatasize)) 64 | sys.exit(1) 65 | 66 | # Fix up CSM Compatibility16 table 67 | if 'csm_compat_table' in symbols and 'entry_csm' in symbols: 68 | # Field offsets within EFI_COMPATIBILITY16_TABLE 69 | ENTRY_FIELD_OFS = 14 # Compatibility16CallOffset (UINT16) 70 | SIZE_FIELD_OFS = 5 # TableLength (UINT8) 71 | CSUM_FIELD_OFS = 4 # TableChecksum (UINT8) 72 | 73 | tableofs = symbols['csm_compat_table'].offset - symbols['code32flat_start'].offset 74 | entry_addr = symbols['entry_csm'].offset - layoutrom.BUILD_BIOS_ADDR 75 | entry_addr = struct.pack(' 5 | # 6 | # This file may be distributed under the terms of the GNU GPLv3 license. 7 | 8 | import sys 9 | 10 | def main(): 11 | data = sys.stdin.read() 12 | ords = map(ord, data) 13 | print("sum=%x\n" % sum(ords)) 14 | 15 | if __name__ == '__main__': 16 | main() 17 | -------------------------------------------------------------------------------- /scripts/encodeint.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Encode an integer in little endian format in a file. 3 | # 4 | # Copyright (C) 2011 Kevin O'Connor 5 | # 6 | # This file may be distributed under the terms of the GNU GPLv3 license. 7 | 8 | import sys 9 | import struct 10 | 11 | def main(): 12 | filename = sys.argv[1] 13 | value = int(sys.argv[2], 0) 14 | 15 | outval = struct.pack(' "$OUTFILE" </{s:->#\(.*\):/* \1 */:; \ 13 | s:^->\([^ ]*\) [\$\#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \ 14 | s:->::; p;}" < "$INFILE" >> "$OUTFILE" 15 | cat >> "$OUTFILE" < /dev/null 2>&1 << EOF 4 | #include 5 | int main() 6 | { 7 | gettext(""); 8 | return 0; 9 | } 10 | EOF 11 | if [ ! "$?" -eq "0" ]; then 12 | echo -DKBUILD_NO_NLS; 13 | fi 14 | -------------------------------------------------------------------------------- /scripts/kconfig/list.h: -------------------------------------------------------------------------------- 1 | #ifndef LIST_H 2 | #define LIST_H 3 | 4 | /* 5 | * Copied from include/linux/... 6 | */ 7 | 8 | #undef offsetof 9 | #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 10 | 11 | /** 12 | * container_of - cast a member of a structure out to the containing structure 13 | * @ptr: the pointer to the member. 14 | * @type: the type of the container struct this is embedded in. 15 | * @member: the name of the member within the struct. 16 | * 17 | */ 18 | #define container_of(ptr, type, member) ({ \ 19 | const typeof( ((type *)0)->member ) *__mptr = (ptr); \ 20 | (type *)( (char *)__mptr - offsetof(type,member) );}) 21 | 22 | 23 | struct list_head { 24 | struct list_head *next, *prev; 25 | }; 26 | 27 | 28 | #define LIST_HEAD_INIT(name) { &(name), &(name) } 29 | 30 | #define LIST_HEAD(name) \ 31 | struct list_head name = LIST_HEAD_INIT(name) 32 | 33 | /** 34 | * list_entry - get the struct for this entry 35 | * @ptr: the &struct list_head pointer. 36 | * @type: the type of the struct this is embedded in. 37 | * @member: the name of the list_struct within the struct. 38 | */ 39 | #define list_entry(ptr, type, member) \ 40 | container_of(ptr, type, member) 41 | 42 | /** 43 | * list_for_each_entry - iterate over list of given type 44 | * @pos: the type * to use as a loop cursor. 45 | * @head: the head for your list. 46 | * @member: the name of the list_struct within the struct. 47 | */ 48 | #define list_for_each_entry(pos, head, member) \ 49 | for (pos = list_entry((head)->next, typeof(*pos), member); \ 50 | &pos->member != (head); \ 51 | pos = list_entry(pos->member.next, typeof(*pos), member)) 52 | 53 | /** 54 | * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry 55 | * @pos: the type * to use as a loop cursor. 56 | * @n: another type * to use as temporary storage 57 | * @head: the head for your list. 58 | * @member: the name of the list_struct within the struct. 59 | */ 60 | #define list_for_each_entry_safe(pos, n, head, member) \ 61 | for (pos = list_entry((head)->next, typeof(*pos), member), \ 62 | n = list_entry(pos->member.next, typeof(*pos), member); \ 63 | &pos->member != (head); \ 64 | pos = n, n = list_entry(n->member.next, typeof(*n), member)) 65 | 66 | /** 67 | * list_empty - tests whether a list is empty 68 | * @head: the list to test. 69 | */ 70 | static inline int list_empty(const struct list_head *head) 71 | { 72 | return head->next == head; 73 | } 74 | 75 | /* 76 | * Insert a new entry between two known consecutive entries. 77 | * 78 | * This is only for internal list manipulation where we know 79 | * the prev/next entries already! 80 | */ 81 | static inline void __list_add(struct list_head *_new, 82 | struct list_head *prev, 83 | struct list_head *next) 84 | { 85 | next->prev = _new; 86 | _new->next = next; 87 | _new->prev = prev; 88 | prev->next = _new; 89 | } 90 | 91 | /** 92 | * list_add_tail - add a new entry 93 | * @new: new entry to be added 94 | * @head: list head to add it before 95 | * 96 | * Insert a new entry before the specified head. 97 | * This is useful for implementing queues. 98 | */ 99 | static inline void list_add_tail(struct list_head *_new, struct list_head *head) 100 | { 101 | __list_add(_new, head->prev, head); 102 | } 103 | 104 | /* 105 | * Delete a list entry by making the prev/next entries 106 | * point to each other. 107 | * 108 | * This is only for internal list manipulation where we know 109 | * the prev/next entries already! 110 | */ 111 | static inline void __list_del(struct list_head *prev, struct list_head *next) 112 | { 113 | next->prev = prev; 114 | prev->next = next; 115 | } 116 | 117 | #define LIST_POISON1 ((void *) 0x00100100) 118 | #define LIST_POISON2 ((void *) 0x00200200) 119 | /** 120 | * list_del - deletes entry from list. 121 | * @entry: the element to delete from the list. 122 | * Note: list_empty() on entry does not return true after this, the entry is 123 | * in an undefined state. 124 | */ 125 | static inline void list_del(struct list_head *entry) 126 | { 127 | __list_del(entry->prev, entry->next); 128 | entry->next = (struct list_head*)LIST_POISON1; 129 | entry->prev = (struct list_head*)LIST_POISON2; 130 | } 131 | #endif 132 | -------------------------------------------------------------------------------- /scripts/kconfig/lkc_proto.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* confdata.c */ 4 | P(conf_parse,void,(const char *name)); 5 | P(conf_read,int,(const char *name)); 6 | P(conf_read_simple,int,(const char *name, int)); 7 | P(conf_write_defconfig,int,(const char *name)); 8 | P(conf_write,int,(const char *name)); 9 | P(conf_write_autoconf,int,(void)); 10 | P(conf_get_changed,bool,(void)); 11 | P(conf_set_changed_callback, void,(void (*fn)(void))); 12 | P(conf_set_message_callback, void,(void (*fn)(const char *fmt, va_list ap))); 13 | 14 | /* menu.c */ 15 | P(rootmenu,struct menu,); 16 | 17 | P(menu_is_empty, bool, (struct menu *menu)); 18 | P(menu_is_visible, bool, (struct menu *menu)); 19 | P(menu_has_prompt, bool, (struct menu *menu)); 20 | P(menu_get_prompt,const char *,(struct menu *menu)); 21 | P(menu_get_root_menu,struct menu *,(struct menu *menu)); 22 | P(menu_get_parent_menu,struct menu *,(struct menu *menu)); 23 | P(menu_has_help,bool,(struct menu *menu)); 24 | P(menu_get_help,const char *,(struct menu *menu)); 25 | P(get_symbol_str, void, (struct gstr *r, struct symbol *sym, struct list_head 26 | *head)); 27 | P(get_relations_str, struct gstr, (struct symbol **sym_arr, struct list_head 28 | *head)); 29 | P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help)); 30 | 31 | /* symbol.c */ 32 | P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]); 33 | 34 | P(sym_lookup,struct symbol *,(const char *name, int flags)); 35 | P(sym_find,struct symbol *,(const char *name)); 36 | P(sym_expand_string_value,const char *,(const char *in)); 37 | P(sym_escape_string_value, const char *,(const char *in)); 38 | P(sym_re_search,struct symbol **,(const char *pattern)); 39 | P(sym_type_name,const char *,(enum symbol_type type)); 40 | P(sym_calc_value,void,(struct symbol *sym)); 41 | P(sym_get_type,enum symbol_type,(struct symbol *sym)); 42 | P(sym_tristate_within_range,bool,(struct symbol *sym,tristate tri)); 43 | P(sym_set_tristate_value,bool,(struct symbol *sym,tristate tri)); 44 | P(sym_toggle_tristate_value,tristate,(struct symbol *sym)); 45 | P(sym_string_valid,bool,(struct symbol *sym, const char *newval)); 46 | P(sym_string_within_range,bool,(struct symbol *sym, const char *str)); 47 | P(sym_set_string_value,bool,(struct symbol *sym, const char *newval)); 48 | P(sym_is_changable,bool,(struct symbol *sym)); 49 | P(sym_get_choice_prop,struct property *,(struct symbol *sym)); 50 | P(sym_get_default_prop,struct property *,(struct symbol *sym)); 51 | P(sym_get_string_value,const char *,(struct symbol *sym)); 52 | 53 | P(prop_get_type_name,const char *,(enum prop_type type)); 54 | 55 | /* expr.c */ 56 | P(expr_compare_type,int,(enum expr_type t1, enum expr_type t2)); 57 | P(expr_print,void,(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken)); 58 | -------------------------------------------------------------------------------- /scripts/kconfig/lxdialog/.gitignore: -------------------------------------------------------------------------------- 1 | # 2 | # Generated files 3 | # 4 | lxdialog 5 | -------------------------------------------------------------------------------- /scripts/kconfig/lxdialog/BIG.FAT.WARNING: -------------------------------------------------------------------------------- 1 | This is NOT the official version of dialog. This version has been 2 | significantly modified from the original. It is for use by the Linux 3 | kernel configuration script. Please do not bother Savio Lam with 4 | questions about this program. 5 | -------------------------------------------------------------------------------- /scripts/kconfig/lxdialog/check-lxdialog.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Check ncurses compatibility 3 | 4 | # What library to link 5 | ldflags() 6 | { 7 | pkg-config --libs ncursesw 2>/dev/null && exit 8 | pkg-config --libs ncurses 2>/dev/null && exit 9 | for ext in so a dll.a dylib ; do 10 | for lib in ncursesw ncurses curses ; do 11 | $cc -print-file-name=lib${lib}.${ext} | grep -q / 12 | if [ $? -eq 0 ]; then 13 | echo "-l${lib}" 14 | exit 15 | fi 16 | done 17 | done 18 | exit 1 19 | } 20 | 21 | # Where is ncurses.h? 22 | ccflags() 23 | { 24 | if [ -f /usr/include/ncursesw/curses.h ]; then 25 | echo '-I/usr/include/ncursesw -DCURSES_LOC=""' 26 | echo ' -DNCURSES_WIDECHAR=1' 27 | elif [ -f /usr/include/ncurses/ncurses.h ]; then 28 | echo '-I/usr/include/ncurses -DCURSES_LOC=""' 29 | elif [ -f /usr/include/ncurses/curses.h ]; then 30 | echo '-I/usr/include/ncurses -DCURSES_LOC=""' 31 | elif [ -f /usr/include/ncurses.h ]; then 32 | echo '-DCURSES_LOC=""' 33 | else 34 | echo '-DCURSES_LOC=""' 35 | fi 36 | } 37 | 38 | # Temp file, try to clean up after us 39 | tmp=.lxdialog.tmp 40 | trap "rm -f $tmp" 0 1 2 3 15 41 | 42 | # Check if we can link to ncurses 43 | check() { 44 | $cc -x c - -o $tmp 2>/dev/null <<'EOF' 45 | #include CURSES_LOC 46 | main() {} 47 | EOF 48 | if [ $? != 0 ]; then 49 | echo " *** Unable to find the ncurses libraries or the" 1>&2 50 | echo " *** required header files." 1>&2 51 | echo " *** 'make menuconfig' requires the ncurses libraries." 1>&2 52 | echo " *** " 1>&2 53 | echo " *** Install ncurses (ncurses-devel) and try again." 1>&2 54 | echo " *** " 1>&2 55 | exit 1 56 | fi 57 | } 58 | 59 | usage() { 60 | printf "Usage: $0 [-check compiler options|-ccflags|-ldflags compiler options]\n" 61 | } 62 | 63 | if [ $# -eq 0 ]; then 64 | usage 65 | exit 1 66 | fi 67 | 68 | cc="" 69 | case "$1" in 70 | "-check") 71 | shift 72 | cc="$@" 73 | check 74 | ;; 75 | "-ccflags") 76 | ccflags 77 | ;; 78 | "-ldflags") 79 | shift 80 | cc="$@" 81 | ldflags 82 | ;; 83 | "*") 84 | usage 85 | exit 1 86 | ;; 87 | esac 88 | -------------------------------------------------------------------------------- /scripts/kconfig/lxdialog/yesno.c: -------------------------------------------------------------------------------- 1 | /* 2 | * yesno.c -- implements the yes/no box 3 | * 4 | * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) 5 | * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) 6 | * 7 | * This program is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU General Public License 9 | * as published by the Free Software Foundation; either version 2 10 | * of the License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | */ 21 | 22 | #include "dialog.h" 23 | 24 | /* 25 | * Display termination buttons 26 | */ 27 | static void print_buttons(WINDOW * dialog, int height, int width, int selected) 28 | { 29 | int x = width / 2 - 10; 30 | int y = height - 2; 31 | 32 | print_button(dialog, gettext(" Yes "), y, x, selected == 0); 33 | print_button(dialog, gettext(" No "), y, x + 13, selected == 1); 34 | 35 | wmove(dialog, y, x + 1 + 13 * selected); 36 | wrefresh(dialog); 37 | } 38 | 39 | /* 40 | * Display a dialog box with two buttons - Yes and No 41 | */ 42 | int dialog_yesno(const char *title, const char *prompt, int height, int width) 43 | { 44 | int i, x, y, key = 0, button = 0; 45 | WINDOW *dialog; 46 | 47 | do_resize: 48 | if (getmaxy(stdscr) < (height + YESNO_HEIGTH_MIN)) 49 | return -ERRDISPLAYTOOSMALL; 50 | if (getmaxx(stdscr) < (width + YESNO_WIDTH_MIN)) 51 | return -ERRDISPLAYTOOSMALL; 52 | 53 | /* center dialog box on screen */ 54 | x = (getmaxx(stdscr) - width) / 2; 55 | y = (getmaxy(stdscr) - height) / 2; 56 | 57 | draw_shadow(stdscr, y, x, height, width); 58 | 59 | dialog = newwin(height, width, y, x); 60 | keypad(dialog, TRUE); 61 | 62 | draw_box(dialog, 0, 0, height, width, 63 | dlg.dialog.atr, dlg.border.atr); 64 | wattrset(dialog, dlg.border.atr); 65 | mvwaddch(dialog, height - 3, 0, ACS_LTEE); 66 | for (i = 0; i < width - 2; i++) 67 | waddch(dialog, ACS_HLINE); 68 | wattrset(dialog, dlg.dialog.atr); 69 | waddch(dialog, ACS_RTEE); 70 | 71 | print_title(dialog, title, width); 72 | 73 | wattrset(dialog, dlg.dialog.atr); 74 | print_autowrap(dialog, prompt, width - 2, 1, 3); 75 | 76 | print_buttons(dialog, height, width, 0); 77 | 78 | while (key != KEY_ESC) { 79 | key = wgetch(dialog); 80 | switch (key) { 81 | case 'Y': 82 | case 'y': 83 | delwin(dialog); 84 | return 0; 85 | case 'N': 86 | case 'n': 87 | delwin(dialog); 88 | return 1; 89 | 90 | case TAB: 91 | case KEY_LEFT: 92 | case KEY_RIGHT: 93 | button = ((key == KEY_LEFT ? --button : ++button) < 0) ? 1 : (button > 1 ? 0 : button); 94 | 95 | print_buttons(dialog, height, width, button); 96 | wrefresh(dialog); 97 | break; 98 | case ' ': 99 | case '\n': 100 | delwin(dialog); 101 | return button; 102 | case KEY_ESC: 103 | key = on_key_esc(dialog); 104 | break; 105 | case KEY_RESIZE: 106 | delwin(dialog); 107 | on_key_resize(); 108 | goto do_resize; 109 | } 110 | } 111 | 112 | delwin(dialog); 113 | return key; /* ESC pressed */ 114 | } 115 | -------------------------------------------------------------------------------- /scripts/kconfig/merge_config.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # merge_config.sh - Takes a list of config fragment values, and merges 3 | # them one by one. Provides warnings on overridden values, and specified 4 | # values that did not make it to the resulting .config file (due to missed 5 | # dependencies or config symbol removal). 6 | # 7 | # Portions reused from kconf_check and generate_cfg: 8 | # http://git.yoctoproject.org/cgit/cgit.cgi/yocto-kernel-tools/tree/tools/kconf_check 9 | # http://git.yoctoproject.org/cgit/cgit.cgi/yocto-kernel-tools/tree/tools/generate_cfg 10 | # 11 | # Copyright (c) 2009-2010 Wind River Systems, Inc. 12 | # Copyright 2011 Linaro 13 | # 14 | # This program is free software; you can redistribute it and/or modify 15 | # it under the terms of the GNU General Public License version 2 as 16 | # published by the Free Software Foundation. 17 | # 18 | # This program is distributed in the hope that it will be useful, 19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 21 | # See the GNU General Public License for more details. 22 | 23 | clean_up() { 24 | rm -f $TMP_FILE 25 | exit 26 | } 27 | trap clean_up HUP INT TERM 28 | 29 | usage() { 30 | echo "Usage: $0 [OPTIONS] [CONFIG [...]]" 31 | echo " -h display this help text" 32 | echo " -m only merge the fragments, do not execute the make command" 33 | echo " -n use allnoconfig instead of alldefconfig" 34 | echo " -r list redundant entries when merging fragments" 35 | echo " -O dir to put generated output files" 36 | } 37 | 38 | MAKE=true 39 | ALLTARGET=alldefconfig 40 | WARNREDUN=false 41 | OUTPUT=. 42 | 43 | while true; do 44 | case $1 in 45 | "-n") 46 | ALLTARGET=allnoconfig 47 | shift 48 | continue 49 | ;; 50 | "-m") 51 | MAKE=false 52 | shift 53 | continue 54 | ;; 55 | "-h") 56 | usage 57 | exit 58 | ;; 59 | "-r") 60 | WARNREDUN=true 61 | shift 62 | continue 63 | ;; 64 | "-O") 65 | if [ -d $2 ];then 66 | OUTPUT=$(echo $2 | sed 's/\/*$//') 67 | else 68 | echo "output directory $2 does not exist" 1>&2 69 | exit 1 70 | fi 71 | shift 2 72 | continue 73 | ;; 74 | *) 75 | break 76 | ;; 77 | esac 78 | done 79 | 80 | INITFILE=$1 81 | shift; 82 | 83 | MERGE_LIST=$* 84 | SED_CONFIG_EXP="s/^\(# \)\{0,1\}\(CONFIG_[a-zA-Z0-9_]*\)[= ].*/\2/p" 85 | TMP_FILE=$(mktemp ./.tmp.config.XXXXXXXXXX) 86 | 87 | echo "Using $INITFILE as base" 88 | cat $INITFILE > $TMP_FILE 89 | 90 | # Merge files, printing warnings on overrided values 91 | for MERGE_FILE in $MERGE_LIST ; do 92 | echo "Merging $MERGE_FILE" 93 | CFG_LIST=$(sed -n "$SED_CONFIG_EXP" $MERGE_FILE) 94 | 95 | for CFG in $CFG_LIST ; do 96 | grep -q -w $CFG $TMP_FILE 97 | if [ $? -eq 0 ] ; then 98 | PREV_VAL=$(grep -w $CFG $TMP_FILE) 99 | NEW_VAL=$(grep -w $CFG $MERGE_FILE) 100 | if [ "x$PREV_VAL" != "x$NEW_VAL" ] ; then 101 | echo Value of $CFG is redefined by fragment $MERGE_FILE: 102 | echo Previous value: $PREV_VAL 103 | echo New value: $NEW_VAL 104 | echo 105 | elif [ "$WARNREDUN" = "true" ]; then 106 | echo Value of $CFG is redundant by fragment $MERGE_FILE: 107 | fi 108 | sed -i "/$CFG[ =]/d" $TMP_FILE 109 | fi 110 | done 111 | cat $MERGE_FILE >> $TMP_FILE 112 | done 113 | 114 | if [ "$MAKE" = "false" ]; then 115 | cp $TMP_FILE $OUTPUT/.config 116 | echo "#" 117 | echo "# merged configuration written to $OUTPUT/.config (needs make)" 118 | echo "#" 119 | clean_up 120 | exit 121 | fi 122 | 123 | # If we have an output dir, setup the O= argument, otherwise leave 124 | # it blank, since O=. will create an unnecessary ./source softlink 125 | OUTPUT_ARG="" 126 | if [ "$OUTPUT" != "." ] ; then 127 | OUTPUT_ARG="O=$OUTPUT" 128 | fi 129 | 130 | 131 | # Use the merged file as the starting point for: 132 | # alldefconfig: Fills in any missing symbols with Kconfig default 133 | # allnoconfig: Fills in any missing symbols with # CONFIG_* is not set 134 | make KCONFIG_ALLCONFIG=$TMP_FILE $OUTPUT_ARG $ALLTARGET 135 | 136 | 137 | # Check all specified config values took (might have missed-dependency issues) 138 | for CFG in $(sed -n "$SED_CONFIG_EXP" $TMP_FILE); do 139 | 140 | REQUESTED_VAL=$(grep -w -e "$CFG" $TMP_FILE) 141 | ACTUAL_VAL=$(grep -w -e "$CFG" $OUTPUT/.config) 142 | if [ "x$REQUESTED_VAL" != "x$ACTUAL_VAL" ] ; then 143 | echo "Value requested for $CFG not in final .config" 144 | echo "Requested value: $REQUESTED_VAL" 145 | echo "Actual value: $ACTUAL_VAL" 146 | echo "" 147 | fi 148 | done 149 | 150 | clean_up 151 | -------------------------------------------------------------------------------- /scripts/kconfig/nconf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 Nir Tzachar 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include "ncurses.h" 28 | 29 | #define max(a, b) ({\ 30 | typeof(a) _a = a;\ 31 | typeof(b) _b = b;\ 32 | _a > _b ? _a : _b; }) 33 | 34 | #define min(a, b) ({\ 35 | typeof(a) _a = a;\ 36 | typeof(b) _b = b;\ 37 | _a < _b ? _a : _b; }) 38 | 39 | typedef enum { 40 | NORMAL = 1, 41 | MAIN_HEADING, 42 | MAIN_MENU_BOX, 43 | MAIN_MENU_FORE, 44 | MAIN_MENU_BACK, 45 | MAIN_MENU_GREY, 46 | MAIN_MENU_HEADING, 47 | SCROLLWIN_TEXT, 48 | SCROLLWIN_HEADING, 49 | SCROLLWIN_BOX, 50 | DIALOG_TEXT, 51 | DIALOG_MENU_FORE, 52 | DIALOG_MENU_BACK, 53 | DIALOG_BOX, 54 | INPUT_BOX, 55 | INPUT_HEADING, 56 | INPUT_TEXT, 57 | INPUT_FIELD, 58 | FUNCTION_TEXT, 59 | FUNCTION_HIGHLIGHT, 60 | ATTR_MAX 61 | } attributes_t; 62 | extern attributes_t attributes[]; 63 | 64 | typedef enum { 65 | F_HELP = 1, 66 | F_SYMBOL = 2, 67 | F_INSTS = 3, 68 | F_CONF = 4, 69 | F_BACK = 5, 70 | F_SAVE = 6, 71 | F_LOAD = 7, 72 | F_SEARCH = 8, 73 | F_EXIT = 9, 74 | } function_key; 75 | 76 | void set_colors(void); 77 | 78 | /* this changes the windows attributes !!! */ 79 | void print_in_middle(WINDOW *win, 80 | int starty, 81 | int startx, 82 | int width, 83 | const char *string, 84 | chtype color); 85 | int get_line_length(const char *line); 86 | int get_line_no(const char *text); 87 | const char *get_line(const char *text, int line_no); 88 | void fill_window(WINDOW *win, const char *text); 89 | int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...); 90 | int dialog_inputbox(WINDOW *main_window, 91 | const char *title, const char *prompt, 92 | const char *init, char **resultp, int *result_len); 93 | void refresh_all_windows(WINDOW *main_window); 94 | void show_scroll_win(WINDOW *main_window, 95 | const char *title, 96 | const char *text); 97 | -------------------------------------------------------------------------------- /scripts/kconfig/util.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2002-2005 Roman Zippel 3 | * Copyright (C) 2002-2005 Sam Ravnborg 4 | * 5 | * Released under the terms of the GNU GPL v2.0. 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include "lkc.h" 12 | 13 | /* file already present in list? If not add it */ 14 | struct file *file_lookup(const char *name) 15 | { 16 | struct file *file; 17 | const char *file_name = sym_expand_string_value(name); 18 | 19 | for (file = file_list; file; file = file->next) { 20 | if (!strcmp(name, file->name)) { 21 | free((void *)file_name); 22 | return file; 23 | } 24 | } 25 | 26 | file = xmalloc(sizeof(*file)); 27 | memset(file, 0, sizeof(*file)); 28 | file->name = file_name; 29 | file->next = file_list; 30 | file_list = file; 31 | return file; 32 | } 33 | 34 | /* write a dependency file as used by kbuild to track dependencies */ 35 | int file_write_dep(const char *name) 36 | { 37 | struct symbol *sym, *env_sym; 38 | struct expr *e; 39 | struct file *file; 40 | FILE *out; 41 | 42 | if (!name) 43 | name = ".kconfig.d"; 44 | out = fopen("..config.tmp", "w"); 45 | if (!out) 46 | return 1; 47 | fprintf(out, "deps_config := \\\n"); 48 | for (file = file_list; file; file = file->next) { 49 | if (file->next) 50 | fprintf(out, "\t%s \\\n", file->name); 51 | else 52 | fprintf(out, "\t%s\n", file->name); 53 | } 54 | fprintf(out, "\n%s: \\\n" 55 | "\t$(deps_config)\n\n", conf_get_autoconfig_name()); 56 | 57 | expr_list_for_each_sym(sym_env_list, e, sym) { 58 | struct property *prop; 59 | const char *value; 60 | 61 | prop = sym_get_env_prop(sym); 62 | env_sym = prop_get_symbol(prop); 63 | if (!env_sym) 64 | continue; 65 | value = getenv(env_sym->name); 66 | if (!value) 67 | value = ""; 68 | fprintf(out, "ifneq \"$(%s)\" \"%s\"\n", env_sym->name, value); 69 | fprintf(out, "%s: FORCE\n", conf_get_autoconfig_name()); 70 | fprintf(out, "endif\n"); 71 | } 72 | 73 | fprintf(out, "\n$(deps_config): ;\n"); 74 | fclose(out); 75 | rename("..config.tmp", name); 76 | return 0; 77 | } 78 | 79 | 80 | /* Allocate initial growable string */ 81 | struct gstr str_new(void) 82 | { 83 | struct gstr gs; 84 | gs.s = xmalloc(sizeof(char) * 64); 85 | gs.len = 64; 86 | gs.max_width = 0; 87 | strcpy(gs.s, "\0"); 88 | return gs; 89 | } 90 | 91 | /* Allocate and assign growable string */ 92 | struct gstr str_assign(const char *s) 93 | { 94 | struct gstr gs; 95 | gs.s = strdup(s); 96 | gs.len = strlen(s) + 1; 97 | gs.max_width = 0; 98 | return gs; 99 | } 100 | 101 | /* Free storage for growable string */ 102 | void str_free(struct gstr *gs) 103 | { 104 | if (gs->s) 105 | free(gs->s); 106 | gs->s = NULL; 107 | gs->len = 0; 108 | } 109 | 110 | /* Append to growable string */ 111 | void str_append(struct gstr *gs, const char *s) 112 | { 113 | size_t l; 114 | if (s) { 115 | l = strlen(gs->s) + strlen(s) + 1; 116 | if (l > gs->len) { 117 | gs->s = realloc(gs->s, l); 118 | gs->len = l; 119 | } 120 | strcat(gs->s, s); 121 | } 122 | } 123 | 124 | /* Append printf formatted string to growable string */ 125 | void str_printf(struct gstr *gs, const char *fmt, ...) 126 | { 127 | va_list ap; 128 | char s[10000]; /* big enough... */ 129 | va_start(ap, fmt); 130 | vsnprintf(s, sizeof(s), fmt, ap); 131 | str_append(gs, s); 132 | va_end(ap); 133 | } 134 | 135 | /* Retrieve value of growable string */ 136 | const char *str_get(struct gstr *gs) 137 | { 138 | return gs->s; 139 | } 140 | 141 | void *xmalloc(size_t size) 142 | { 143 | void *p = malloc(size); 144 | if (p) 145 | return p; 146 | fprintf(stderr, "Out of memory.\n"); 147 | exit(1); 148 | } 149 | 150 | void *xcalloc(size_t nmemb, size_t size) 151 | { 152 | void *p = calloc(nmemb, size); 153 | if (p) 154 | return p; 155 | fprintf(stderr, "Out of memory.\n"); 156 | exit(1); 157 | } 158 | -------------------------------------------------------------------------------- /scripts/kconfig/zconf.gperf: -------------------------------------------------------------------------------- 1 | %language=ANSI-C 2 | %define hash-function-name kconf_id_hash 3 | %define lookup-function-name kconf_id_lookup 4 | %define string-pool-name kconf_id_strings 5 | %compare-strncmp 6 | %enum 7 | %pic 8 | %struct-type 9 | 10 | struct kconf_id; 11 | 12 | static const struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len); 13 | 14 | %% 15 | mainmenu, T_MAINMENU, TF_COMMAND 16 | menu, T_MENU, TF_COMMAND 17 | endmenu, T_ENDMENU, TF_COMMAND 18 | source, T_SOURCE, TF_COMMAND 19 | choice, T_CHOICE, TF_COMMAND 20 | endchoice, T_ENDCHOICE, TF_COMMAND 21 | comment, T_COMMENT, TF_COMMAND 22 | config, T_CONFIG, TF_COMMAND 23 | menuconfig, T_MENUCONFIG, TF_COMMAND 24 | help, T_HELP, TF_COMMAND 25 | if, T_IF, TF_COMMAND|TF_PARAM 26 | endif, T_ENDIF, TF_COMMAND 27 | depends, T_DEPENDS, TF_COMMAND 28 | optional, T_OPTIONAL, TF_COMMAND 29 | default, T_DEFAULT, TF_COMMAND, S_UNKNOWN 30 | prompt, T_PROMPT, TF_COMMAND 31 | tristate, T_TYPE, TF_COMMAND, S_TRISTATE 32 | def_tristate, T_DEFAULT, TF_COMMAND, S_TRISTATE 33 | bool, T_TYPE, TF_COMMAND, S_BOOLEAN 34 | boolean, T_TYPE, TF_COMMAND, S_BOOLEAN 35 | def_bool, T_DEFAULT, TF_COMMAND, S_BOOLEAN 36 | int, T_TYPE, TF_COMMAND, S_INT 37 | hex, T_TYPE, TF_COMMAND, S_HEX 38 | string, T_TYPE, TF_COMMAND, S_STRING 39 | select, T_SELECT, TF_COMMAND 40 | range, T_RANGE, TF_COMMAND 41 | visible, T_VISIBLE, TF_COMMAND 42 | option, T_OPTION, TF_COMMAND 43 | on, T_ON, TF_PARAM 44 | modules, T_OPT_MODULES, TF_OPTION 45 | defconfig_list, T_OPT_DEFCONFIG_LIST,TF_OPTION 46 | env, T_OPT_ENV, TF_OPTION 47 | allnoconfig_y, T_OPT_ALLNOCONFIG_Y,TF_OPTION 48 | %% 49 | -------------------------------------------------------------------------------- /scripts/python23compat.py: -------------------------------------------------------------------------------- 1 | # Helper code for compatibility of the code with both Python 2 and Python 3 2 | # 3 | # Copyright (C) 2014 Johannes Krampf 4 | # 5 | # This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | import sys 8 | 9 | if (sys.version_info > (3, 0)): 10 | def as_bytes(str): 11 | return bytes(str, "ASCII") 12 | else: 13 | def as_bytes(str): 14 | return str 15 | -------------------------------------------------------------------------------- /scripts/test-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Script to test if the build works properly. 3 | 4 | # Test IASL is installed. 5 | $IASL -h > /dev/null 2>&1 6 | if [ $? -ne 0 ]; then 7 | echo "The SeaBIOS project requires the 'iasl' package be installed." >&2 8 | echo "Many Linux distributions have this package." >&2 9 | echo "Try: sudo yum install iasl" >&2 10 | echo "Or: sudo apt-get install iasl" >&2 11 | echo "" >&2 12 | echo "Please install iasl and retry." >&2 13 | echo -1 14 | exit 0 15 | fi 16 | 17 | mkdir -p ${OUT} 18 | TMPFILE1=${OUT}/tmp_testcompile1.c 19 | TMPFILE1o=${OUT}/tmp_testcompile1.o 20 | TMPFILE1_ld=${OUT}/tmp_testcompile1.lds 21 | TMPFILE2=${OUT}/tmp_testcompile2.c 22 | TMPFILE2o=${OUT}/tmp_testcompile2.o 23 | TMPFILE3o=${OUT}/tmp_testcompile3.o 24 | 25 | # Test if ld's alignment handling is correct. This is a known problem 26 | # with the linker that ships with Ubuntu 11.04. 27 | cat - > $TMPFILE1 < $TMPFILE1_ld < /dev/null 2>&1 44 | if [ $? -ne 0 ]; then 45 | echo "Unable to execute the C compiler ($CC)." >&2 46 | echo "" >&2 47 | echo "Please install a working compiler and retry." >&2 48 | echo -1 49 | exit 0 50 | fi 51 | $LD -T $TMPFILE1_ld $TMPFILE1o -o $TMPFILE2o > /dev/null 2>&1 52 | if [ $? -ne 0 ]; then 53 | echo "The version of LD on this system ($LD) does not properly handle" >&2 54 | echo "alignments. As a result, this project can not be built." >&2 55 | echo "" >&2 56 | echo "The problem may be the result of this LD bug report:" >&2 57 | echo " http://sourceware.org/bugzilla/show_bug.cgi?id=12726" >&2 58 | echo "" >&2 59 | echo "Please update to a working version of binutils and retry." >&2 60 | echo -1 61 | exit 0 62 | fi 63 | 64 | # Test for "-fwhole-program". Older versions of gcc (pre v4.1) don't 65 | # support the whole-program optimization - detect that. 66 | $CC -fwhole-program -S -o /dev/null -xc /dev/null > /dev/null 2>&1 67 | if [ $? -ne 0 ]; then 68 | echo " Working around no -fwhole-program" >&2 69 | echo 2 70 | exit 0 71 | fi 72 | 73 | # Test if "visible" variables and functions are marked global. On 74 | # OpenSuse 10.3 "visible" variables declared with "extern" first 75 | # aren't marked as global in the resulting assembler. On Ubuntu 7.10 76 | # "visible" functions aren't marked as global in the resulting 77 | # assembler. 78 | cat - > $TMPFILE1 < /dev/null 2>&1 84 | cat - > $TMPFILE2 < /dev/null 2>&1 90 | $CC -nostdlib -Os $TMPFILE1o $TMPFILE2o -o $TMPFILE3o > /dev/null 2>&1 91 | if [ $? -ne 0 ]; then 92 | echo " Working around non-functional -fwhole-program" >&2 93 | echo 2 94 | exit 0 95 | fi 96 | 97 | echo 0 98 | 99 | # Also, the Ubuntu 8.04 compiler has a bug causing corruption when the 100 | # "ebp" register is clobberred in an "asm" statement. The code has 101 | # been modified to not clobber "ebp" - no test is available yet. 102 | 103 | rm -f $TMPFILE1 $TMPFILE1o $TMPFILE1_ld $TMPFILE2 $TMPFILE2o $TMPFILE3o 104 | -------------------------------------------------------------------------------- /scripts/transdump.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # This script is useful for taking the output of memdump() and 4 | # converting it back into binary output. This can be useful, for 5 | # example, when one wants to push that data into other tools like 6 | # objdump or hexdump. 7 | # 8 | # (C) Copyright 2010 Kevin O'Connor 9 | # 10 | # This file may be distributed under the terms of the GNU GPLv3 license. 11 | 12 | import sys 13 | import struct 14 | 15 | def unhex(str): 16 | return int(str, 16) 17 | 18 | def parseMem(filehdl): 19 | mem = [] 20 | for line in filehdl: 21 | parts = line.split(':') 22 | if len(parts) < 2: 23 | continue 24 | try: 25 | vaddr = unhex(parts[0]) 26 | parts = parts[1].split() 27 | mem.extend([unhex(v) for v in parts]) 28 | except ValueError: 29 | continue 30 | return mem 31 | 32 | def printUsage(): 33 | sys.stderr.write("Usage:\n %s \n" 34 | % (sys.argv[0],)) 35 | sys.exit(1) 36 | 37 | def main(): 38 | if len(sys.argv) != 2: 39 | printUsage() 40 | filename = sys.argv[1] 41 | if filename == '-': 42 | filehdl = sys.stdin 43 | else: 44 | filehdl = open(filename, 'r') 45 | mem = parseMem(filehdl) 46 | for i in mem: 47 | if (sys.version_info > (3, 0)): 48 | sys.stdout.buffer.write(struct.pack(" 5 | # 6 | # This file may be distributed under the terms of the GNU GPLv3 license. 7 | 8 | # The x86emu code widely used in Linux distributions when running Xorg 9 | # in vesamode is known to have issues with "retl", "leavel", "entryl", 10 | # and some variants of "calll". This code modifies those instructions 11 | # (ret and leave) that are known to be generated by gcc to avoid 12 | # triggering the x86emu bugs. 13 | 14 | # It is also known that the Windows vgabios emulator has issues with 15 | # addressing negative offsets to the %esp register. That has been 16 | # worked around by not using the gcc parameter "-fomit-frame-pointer" 17 | # when compiling. 18 | 19 | import sys 20 | 21 | def main(): 22 | infilename, outfilename = sys.argv[1:] 23 | infile = open(infilename, 'r') 24 | out = [] 25 | for line in infile: 26 | sline = line.strip() 27 | if sline == 'ret': 28 | out.append('retw $2\n') 29 | elif sline == 'leave': 30 | out.append('movl %ebp, %esp ; popl %ebp\n') 31 | elif sline.startswith('call'): 32 | out.append('pushw %ax ; callw' + sline[4:] + '\n') 33 | else: 34 | out.append(line) 35 | infile.close() 36 | outfile = open(outfilename, 'w') 37 | outfile.write(''.join(out)) 38 | outfile.close() 39 | 40 | if __name__ == '__main__': 41 | main() 42 | -------------------------------------------------------------------------------- /src/asm-offsets.c: -------------------------------------------------------------------------------- 1 | // Generate assembler offsets. 2 | 3 | #include "gen-defs.h" // OFFSET 4 | #include "bregs.h" // struct bregs 5 | 6 | /* workaround for a warning with -Wmissing-prototypes */ 7 | void foo(void) VISIBLE16; 8 | 9 | void foo(void) 10 | { 11 | COMMENT("BREGS"); 12 | OFFSET(BREGS_es, bregs, es); 13 | OFFSET(BREGS_ds, bregs, ds); 14 | OFFSET(BREGS_eax, bregs, eax); 15 | OFFSET(BREGS_ebx, bregs, ebx); 16 | OFFSET(BREGS_ecx, bregs, ecx); 17 | OFFSET(BREGS_edx, bregs, edx); 18 | OFFSET(BREGS_ebp, bregs, ebp); 19 | OFFSET(BREGS_esi, bregs, esi); 20 | OFFSET(BREGS_edi, bregs, edi); 21 | OFFSET(BREGS_flags, bregs, flags); 22 | OFFSET(BREGS_code, bregs, code); 23 | DEFINE(BREGS_size, sizeof(struct bregs)); 24 | } 25 | -------------------------------------------------------------------------------- /src/block.h: -------------------------------------------------------------------------------- 1 | #ifndef __BLOCK_H 2 | #define __BLOCK_H 3 | 4 | #include "types.h" // u32 5 | 6 | 7 | /**************************************************************** 8 | * Disk command request 9 | ****************************************************************/ 10 | 11 | struct disk_op_s { 12 | u64 lba; 13 | void *buf_fl; 14 | struct drive_s *drive_gf; 15 | u16 count; 16 | u8 command; 17 | }; 18 | 19 | #define CMD_RESET 0x00 20 | #define CMD_READ 0x02 21 | #define CMD_WRITE 0x03 22 | #define CMD_VERIFY 0x04 23 | #define CMD_FORMAT 0x05 24 | #define CMD_SEEK 0x07 25 | #define CMD_ISREADY 0x10 26 | 27 | 28 | /**************************************************************** 29 | * Global storage 30 | ****************************************************************/ 31 | 32 | struct chs_s { 33 | u16 head; 34 | u16 cylinder; 35 | u16 sector; 36 | u16 pad; 37 | }; 38 | 39 | struct drive_s { 40 | u8 type; // Driver type (DTYPE_*) 41 | u8 floppy_type; // Type of floppy (only for floppy drives). 42 | struct chs_s lchs; // Logical CHS 43 | u64 sectors; // Total sectors count 44 | u32 cntl_id; // Unique id for a given driver type. 45 | u8 removable; // Is media removable (currently unused) 46 | 47 | // Info for EDD calls 48 | u8 translation; // type of translation 49 | u16 blksize; // block size 50 | struct chs_s pchs; // Physical CHS 51 | }; 52 | 53 | #define DISK_SECTOR_SIZE 512 54 | #define CDROM_SECTOR_SIZE 2048 55 | 56 | #define DTYPE_NONE 0x00 57 | #define DTYPE_FLOPPY 0x10 58 | #define DTYPE_ATA 0x20 59 | #define DTYPE_ATA_ATAPI 0x21 60 | #define DTYPE_RAMDISK 0x30 61 | #define DTYPE_CDEMU 0x40 62 | #define DTYPE_AHCI 0x50 63 | #define DTYPE_AHCI_ATAPI 0x51 64 | #define DTYPE_VIRTIO_SCSI 0x60 65 | #define DTYPE_VIRTIO_BLK 0x61 66 | #define DTYPE_USB 0x70 67 | #define DTYPE_USB_32 0x71 68 | #define DTYPE_UAS 0x72 69 | #define DTYPE_UAS_32 0x73 70 | #define DTYPE_LSI_SCSI 0x80 71 | #define DTYPE_ESP_SCSI 0x81 72 | #define DTYPE_MEGASAS 0x82 73 | #define DTYPE_PVSCSI 0x83 74 | #define DTYPE_SD 0x90 75 | 76 | #define MAXDESCSIZE 80 77 | 78 | #define TRANSLATION_NONE 0 79 | #define TRANSLATION_LBA 1 80 | #define TRANSLATION_LARGE 2 81 | #define TRANSLATION_RECHS 3 82 | 83 | #define EXTTYPE_FLOPPY 0 84 | #define EXTTYPE_HD 1 85 | #define EXTTYPE_CD 2 86 | 87 | #define EXTSTART_HD 0x80 88 | #define EXTSTART_CD 0xE0 89 | 90 | 91 | /**************************************************************** 92 | * Function defs 93 | ****************************************************************/ 94 | 95 | // block.c 96 | extern u8 FloppyCount, CDCount; 97 | extern u8 *bounce_buf_fl; 98 | struct drive_s *getDrive(u8 exttype, u8 extdriveoffset); 99 | int getDriveId(u8 exttype, struct drive_s *drive); 100 | void map_floppy_drive(struct drive_s *drive); 101 | void map_hd_drive(struct drive_s *drive); 102 | void map_cd_drive(struct drive_s *drive); 103 | void map_sd_drive(struct drive_s *drive); 104 | struct int13dpt_s; 105 | int fill_edd(u16 seg, struct int13dpt_s *param_far, struct drive_s *drive_gf); 106 | int process_op(struct disk_op_s *op); 107 | int send_disk_op(struct disk_op_s *op); 108 | int create_bounce_buf(void); 109 | 110 | #endif // block.h 111 | -------------------------------------------------------------------------------- /src/bmp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Basic BMP data process and Raw picture data handle functions. 3 | * Could be used to adjust pixel data format, get infomation, etc. 4 | * 5 | * Copyright (C) 2011 Wayne Xia 6 | * 7 | * This work is licensed under the terms of the GNU LGPLv3. 8 | */ 9 | #include "malloc.h" // malloc_tmphigh 10 | #include "string.h" // memcpy 11 | #include "util.h" // struct bmp_decdata 12 | 13 | struct bmp_decdata { 14 | struct tagRGBQUAD *quadp; 15 | unsigned char *datap; 16 | int width; 17 | int height; 18 | int bpp; 19 | }; 20 | 21 | #define bmp_load4byte(addr) (*(u32 *)(addr)) 22 | #define bmp_load2byte(addr) (*(u16 *)(addr)) 23 | 24 | typedef struct tagBITMAPFILEHEADER { 25 | u8 bfType[2]; 26 | u8 bfSize[4]; 27 | u8 bfReserved1[2]; 28 | u8 bfReserved2[2]; 29 | u8 bfOffBits[4]; 30 | } BITMAPFILEHEADER, tagBITMAPFILEHEADER; 31 | 32 | typedef struct tagBITMAPINFOHEADER { 33 | u8 biSize[4]; 34 | u8 biWidth[4]; 35 | u8 biHeight[4]; 36 | u8 biPlanes[2]; 37 | u8 biBitCount[2]; 38 | u8 biCompression[4]; 39 | u8 biSizeImage[4]; 40 | u8 biXPelsPerMeter[4]; 41 | u8 biYPelsPerMeter[4]; 42 | u8 biClrUsed[4]; 43 | u8 biClrImportant[4]; 44 | } BITMAPINFOHEADER, tagBITMAPINFOHEADER; 45 | 46 | typedef struct tagRGBQUAD { 47 | u8 rgbBlue; 48 | u8 rgbGreen; 49 | u8 rgbRed; 50 | u8 rgbReserved; 51 | } RGBQUAD, tagRGBQUAD; 52 | 53 | /* flat picture data adjusting function 54 | * description: 55 | * switch the vertical line sequence 56 | * arrange horizontal pixel data, add extra space in the dest buffer 57 | * for every line 58 | */ 59 | static void raw_data_format_adjust_24bpp(u8 *src, u8 *dest, int width, 60 | int height, int bytes_per_line_dest) 61 | { 62 | int bytes_per_line_src = 3 * width; 63 | int i; 64 | for (i = 0 ; i < height ; i++) { 65 | memcpy(dest + i * bytes_per_line_dest, 66 | src + (height - 1 - i) * bytes_per_line_src, bytes_per_line_src); 67 | } 68 | } 69 | 70 | /* allocate decdata struct */ 71 | struct bmp_decdata *bmp_alloc(void) 72 | { 73 | struct bmp_decdata *bmp = malloc_tmphigh(sizeof(*bmp)); 74 | return bmp; 75 | } 76 | 77 | /* extract information from bmp file data */ 78 | int bmp_decode(struct bmp_decdata *bmp, unsigned char *data, int data_size) 79 | { 80 | if (data_size < 54) 81 | return 1; 82 | 83 | u16 bmp_filehead = bmp_load2byte(data + 0); 84 | if (bmp_filehead != 0x4d42) 85 | return 2; 86 | u32 bmp_recordsize = bmp_load4byte(data + 2); 87 | if (bmp_recordsize != data_size) 88 | return 3; 89 | u32 bmp_dataoffset = bmp_load4byte(data + 10); 90 | bmp->datap = (unsigned char *)data + bmp_dataoffset; 91 | bmp->width = bmp_load4byte(data + 18); 92 | bmp->height = bmp_load4byte(data + 22); 93 | bmp->bpp = bmp_load2byte(data + 28); 94 | return 0; 95 | } 96 | 97 | /* get bmp properties */ 98 | void bmp_get_size(struct bmp_decdata *bmp, int *width, int *height) 99 | { 100 | *width = bmp->width; 101 | *height = bmp->height; 102 | } 103 | 104 | /* flush flat picture data to *pc */ 105 | int bmp_show(struct bmp_decdata *bmp, unsigned char *pic, int width 106 | , int height, int depth, int bytes_per_line_dest) 107 | { 108 | if (bmp->datap == pic) 109 | return 0; 110 | /* now only support 24bpp bmp file */ 111 | if ((depth == 24) && (bmp->bpp == 24)) { 112 | raw_data_format_adjust_24bpp(bmp->datap, pic, width, height, 113 | bytes_per_line_dest); 114 | return 0; 115 | } 116 | return 1; 117 | } 118 | -------------------------------------------------------------------------------- /src/bregs.h: -------------------------------------------------------------------------------- 1 | // Structure layout of cpu registers that the bios uses. 2 | // 3 | // Copyright (C) 2008 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU LGPLv3 license. 6 | 7 | #ifndef __BREGS_H 8 | #define __BREGS_H 9 | 10 | #include "types.h" // u16 11 | #include "x86.h" // F_CF 12 | 13 | 14 | /**************************************************************** 15 | * Registers saved/restored in romlayout.S 16 | ****************************************************************/ 17 | 18 | #define UREG(ER, R, RH, RL) union { u32 ER; struct { u16 R; u16 R ## _hi; }; struct { u8 RL; u8 RH; u8 R ## _hilo; u8 R ## _hihi; }; } 19 | 20 | // Layout of registers passed in to irq handlers. Note that this 21 | // layout corresponds to code in romlayout.S - don't change it here 22 | // without also updating the assembler code. 23 | struct bregs { 24 | u16 ds; 25 | u16 es; 26 | UREG(edi, di, di8u, di8l); 27 | UREG(esi, si, si8u, si8l); 28 | UREG(ebp, bp, bp8u, bp8l); 29 | UREG(ebx, bx, bh, bl); 30 | UREG(edx, dx, dh, dl); 31 | UREG(ecx, cx, ch, cl); 32 | UREG(eax, ax, ah, al); 33 | struct segoff_s code; 34 | u16 flags; 35 | } PACKED; 36 | 37 | 38 | /**************************************************************** 39 | * Helper functions 40 | ****************************************************************/ 41 | 42 | static inline void 43 | set_cf(struct bregs *regs, int cond) 44 | { 45 | if (cond) 46 | regs->flags |= F_CF; 47 | else 48 | regs->flags &= ~F_CF; 49 | } 50 | 51 | // Frequently used return codes 52 | #define RET_EUNSUPPORTED 0x86 53 | 54 | static inline void 55 | set_success(struct bregs *regs) 56 | { 57 | set_cf(regs, 0); 58 | } 59 | 60 | static inline void 61 | set_code_success(struct bregs *regs) 62 | { 63 | regs->ah = 0; 64 | set_cf(regs, 0); 65 | } 66 | 67 | static inline void 68 | set_invalid_silent(struct bregs *regs) 69 | { 70 | set_cf(regs, 1); 71 | } 72 | 73 | static inline void 74 | set_code_invalid_silent(struct bregs *regs, u8 code) 75 | { 76 | regs->ah = code; 77 | set_cf(regs, 1); 78 | } 79 | 80 | #endif // bregs.h 81 | -------------------------------------------------------------------------------- /src/byteorder.h: -------------------------------------------------------------------------------- 1 | #ifndef __BYTEORDER_H 2 | #define __BYTEORDER_H 3 | 4 | #include "types.h" // u32 5 | 6 | static inline u16 __swab16_constant(u16 val) { 7 | return (val<<8) | (val>>8); 8 | } 9 | static inline u32 __swab32_constant(u32 val) { 10 | return (val<<24) | ((val&0xff00)<<8) | ((val&0xff0000)>>8) | (val>>24); 11 | } 12 | static inline u64 __swab64_constant(u64 val) { 13 | return ((u64)__swab32_constant(val) << 32) | __swab32_constant(val>>32); 14 | } 15 | static inline u32 __swab32(u32 val) { 16 | asm("bswapl %0" : "+r"(val)); 17 | return val; 18 | } 19 | static inline u64 __swab64(u64 val) { 20 | union u64_u32_u i, o; 21 | i.val = val; 22 | o.lo = __swab32(i.hi); 23 | o.hi = __swab32(i.lo); 24 | return o.val; 25 | } 26 | 27 | #define swab16(x) __swab16_constant(x) 28 | #define swab32(x) (__builtin_constant_p((u32)(x)) \ 29 | ? __swab32_constant(x) : __swab32(x)) 30 | #define swab64(x) (__builtin_constant_p((u64)(x)) \ 31 | ? __swab64_constant(x) : __swab64(x)) 32 | 33 | static inline u16 cpu_to_le16(u16 x) { 34 | return x; 35 | } 36 | static inline u32 cpu_to_le32(u32 x) { 37 | return x; 38 | } 39 | static inline u64 cpu_to_le64(u64 x) { 40 | return x; 41 | } 42 | static inline u16 le16_to_cpu(u16 x) { 43 | return x; 44 | } 45 | static inline u32 le32_to_cpu(u32 x) { 46 | return x; 47 | } 48 | static inline u64 le64_to_cpu(u64 x) { 49 | return x; 50 | } 51 | 52 | static inline u16 cpu_to_be16(u16 x) { 53 | return swab16(x); 54 | } 55 | static inline u32 cpu_to_be32(u32 x) { 56 | return swab32(x); 57 | } 58 | static inline u64 cpu_to_be64(u64 x) { 59 | return swab64(x); 60 | } 61 | static inline u16 be16_to_cpu(u16 x) { 62 | return swab16(x); 63 | } 64 | static inline u32 be32_to_cpu(u32 x) { 65 | return swab32(x); 66 | } 67 | static inline u64 be64_to_cpu(u64 x) { 68 | return swab64(x); 69 | } 70 | 71 | #endif // byteorder.h 72 | -------------------------------------------------------------------------------- /src/code16gcc.s: -------------------------------------------------------------------------------- 1 | .code16gcc 2 | -------------------------------------------------------------------------------- /src/config.h: -------------------------------------------------------------------------------- 1 | #ifndef __CONFIG_H 2 | #define __CONFIG_H 3 | 4 | #include "autoconf.h" 5 | 6 | // Configuration definitions. 7 | 8 | //#define BUILD_APPNAME "QEMU" 9 | //#define BUILD_CPUNAME8 "QEMUCPU " 10 | //#define BUILD_APPNAME6 "QEMU " 11 | //#define BUILD_APPNAME4 "QEMU" 12 | #define BUILD_APPNAME "Bochs" 13 | #define BUILD_CPUNAME8 "BOCHSCPU" 14 | #define BUILD_APPNAME6 "BOCHS " 15 | #define BUILD_APPNAME4 "BXPC" 16 | 17 | // Maximum number of map entries in the e820 map 18 | #define BUILD_MAX_E820 32 19 | // Space to reserve in high-memory for tables 20 | #define BUILD_MAX_HIGHTABLE (256*1024) 21 | // Largest supported externaly facing drive id 22 | #define BUILD_MAX_EXTDRIVE 16 23 | // Number of bytes the smbios may be and still live in the f-segment 24 | #define BUILD_MAX_SMBIOS_FSEG 600 25 | 26 | #define BUILD_MODEL_ID 0xFC 27 | #define BUILD_SUBMODEL_ID 0x00 28 | #define BUILD_BIOS_REVISION 0x01 29 | 30 | // Various memory addresses used by the code. 31 | #define BUILD_STACK_ADDR 0x7000 32 | #define BUILD_S3RESUME_STACK_ADDR 0x1000 33 | #define BUILD_AP_BOOT_ADDR 0x10000 34 | #define BUILD_EBDA_MINIMUM 0x90000 35 | #define BUILD_LOWRAM_END 0xa0000 36 | #define BUILD_ROM_START 0xc0000 37 | #define BUILD_BIOS_ADDR 0xf0000 38 | #define BUILD_BIOS_SIZE 0x10000 39 | #define BUILD_EXTRA_STACK_SIZE 0x800 40 | // 32KB for shadow ram copying (works around emulator deficiencies) 41 | #define BUILD_BIOS_TMP_ADDR 0x30000 42 | #define BUILD_SMM_INIT_ADDR 0x30000 43 | #define BUILD_SMM_ADDR 0xa0000 44 | 45 | #define BUILD_PCIMEM_START 0xe0000000 46 | #define BUILD_PCIMEM_END 0xfec00000 /* IOAPIC is mapped at */ 47 | #define BUILD_PCIMEM64_START 0x8000000000ULL 48 | #define BUILD_PCIMEM64_END 0x10000000000ULL 49 | 50 | #define BUILD_IOAPIC_ADDR 0xfec00000 51 | #define BUILD_IOAPIC_ID 0 52 | #define BUILD_HPET_ADDRESS 0xfed00000 53 | #define BUILD_APIC_ADDR 0xfee00000 54 | 55 | // PCI IRQS 56 | #define BUILD_PCI_IRQS ((1<<5) | (1<<9) | (1<<10) | (1<<11)) 57 | 58 | // Important real-mode segments 59 | #define SEG_IVT 0x0000 60 | #define SEG_BDA 0x0040 61 | #define SEG_BIOS 0xf000 62 | 63 | // Segment definitions in protected mode (see rombios32_gdt in misc.c) 64 | #define SEG32_MODE32_CS (1 << 3) 65 | #define SEG32_MODE32_DS (2 << 3) 66 | #define SEG32_MODE16_CS (3 << 3) 67 | #define SEG32_MODE16_DS (4 << 3) 68 | #define SEG32_MODE16BIG_CS (5 << 3) 69 | #define SEG32_MODE16BIG_DS (6 << 3) 70 | 71 | // Debugging levels. If non-zero and CONFIG_DEBUG_LEVEL is greater 72 | // than the specified value, then the corresponding irq handler will 73 | // report every enter event. 74 | #define DEBUG_ISR_02 1 75 | #define DEBUG_HDL_05 1 76 | #define DEBUG_ISR_08 20 77 | #define DEBUG_ISR_09 9 78 | #define DEBUG_ISR_0e 9 79 | #define DEBUG_HDL_10 20 80 | #define DEBUG_HDL_11 2 81 | #define DEBUG_HDL_12 2 82 | #define DEBUG_HDL_13 10 83 | #define DEBUG_HDL_14 2 84 | #define DEBUG_HDL_15 9 85 | #define DEBUG_HDL_16 9 86 | #define DEBUG_HDL_17 2 87 | #define DEBUG_HDL_18 1 88 | #define DEBUG_HDL_19 1 89 | #define DEBUG_HDL_1a 9 90 | #define DEBUG_HDL_40 1 91 | #define DEBUG_ISR_70 9 92 | #define DEBUG_ISR_74 9 93 | #define DEBUG_ISR_75 1 94 | #define DEBUG_ISR_76 10 95 | #define DEBUG_ISR_hwpic1 5 96 | #define DEBUG_ISR_hwpic2 5 97 | #define DEBUG_HDL_smi 9 98 | #define DEBUG_HDL_smp 1 99 | #define DEBUG_HDL_pnp 1 100 | #define DEBUG_HDL_pmm 1 101 | #define DEBUG_HDL_pcibios 9 102 | #define DEBUG_HDL_apm 9 103 | #define DEBUG_HDL_SD 6 104 | 105 | #define DEBUG_unimplemented 2 106 | #define DEBUG_invalid 3 107 | #define DEBUG_thread 2 108 | 109 | #endif // config.h 110 | -------------------------------------------------------------------------------- /src/fw/acpi-dsdt-cpu-hotplug.dsl: -------------------------------------------------------------------------------- 1 | /**************************************************************** 2 | * CPU hotplug 3 | ****************************************************************/ 4 | 5 | Scope(\_SB) { 6 | /* Objects filled in by run-time generated SSDT */ 7 | External(NTFY, MethodObj) 8 | External(CPON, PkgObj) 9 | 10 | /* Methods called by run-time generated SSDT Processor objects */ 11 | Method(CPMA, 1, NotSerialized) { 12 | // _MAT method - create an madt apic buffer 13 | // Arg0 = Processor ID = Local APIC ID 14 | // Local0 = CPON flag for this cpu 15 | Store(DerefOf(Index(CPON, Arg0)), Local0) 16 | // Local1 = Buffer (in madt apic form) to return 17 | Store(Buffer(8) {0x00, 0x08, 0x00, 0x00, 0x00, 0, 0, 0}, Local1) 18 | // Update the processor id, lapic id, and enable/disable status 19 | Store(Arg0, Index(Local1, 2)) 20 | Store(Arg0, Index(Local1, 3)) 21 | Store(Local0, Index(Local1, 4)) 22 | Return (Local1) 23 | } 24 | Method(CPST, 1, NotSerialized) { 25 | // _STA method - return ON status of cpu 26 | // Arg0 = Processor ID = Local APIC ID 27 | // Local0 = CPON flag for this cpu 28 | Store(DerefOf(Index(CPON, Arg0)), Local0) 29 | If (Local0) { 30 | Return (0xF) 31 | } Else { 32 | Return (0x0) 33 | } 34 | } 35 | Method(CPEJ, 2, NotSerialized) { 36 | // _EJ0 method - eject callback 37 | Sleep(200) 38 | } 39 | 40 | /* CPU hotplug notify method */ 41 | OperationRegion(PRST, SystemIO, 0xaf00, 32) 42 | Field(PRST, ByteAcc, NoLock, Preserve) { 43 | PRS, 256 44 | } 45 | Method(PRSC, 0) { 46 | // Local5 = active cpu bitmap 47 | Store(PRS, Local5) 48 | // Local2 = last read byte from bitmap 49 | Store(Zero, Local2) 50 | // Local0 = Processor ID / APIC ID iterator 51 | Store(Zero, Local0) 52 | While (LLess(Local0, SizeOf(CPON))) { 53 | // Local1 = CPON flag for this cpu 54 | Store(DerefOf(Index(CPON, Local0)), Local1) 55 | If (And(Local0, 0x07)) { 56 | // Shift down previously read bitmap byte 57 | ShiftRight(Local2, 1, Local2) 58 | } Else { 59 | // Read next byte from cpu bitmap 60 | Store(DerefOf(Index(Local5, ShiftRight(Local0, 3))), Local2) 61 | } 62 | // Local3 = active state for this cpu 63 | Store(And(Local2, 1), Local3) 64 | 65 | If (LNotEqual(Local1, Local3)) { 66 | // State change - update CPON with new state 67 | Store(Local3, Index(CPON, Local0)) 68 | // Do CPU notify 69 | If (LEqual(Local3, 1)) { 70 | NTFY(Local0, 1) 71 | } Else { 72 | NTFY(Local0, 3) 73 | } 74 | } 75 | Increment(Local0) 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/fw/acpi-dsdt-dbug.dsl: -------------------------------------------------------------------------------- 1 | /**************************************************************** 2 | * Debugging 3 | ****************************************************************/ 4 | 5 | Scope(\) { 6 | /* Debug Output */ 7 | OperationRegion(DBG, SystemIO, 0x0402, 0x01) 8 | Field(DBG, ByteAcc, NoLock, Preserve) { 9 | DBGB, 8, 10 | } 11 | 12 | /* Debug method - use this method to send output to the QEMU 13 | * BIOS debug port. This method handles strings, integers, 14 | * and buffers. For example: DBUG("abc") DBUG(0x123) */ 15 | Method(DBUG, 1) { 16 | ToHexString(Arg0, Local0) 17 | ToBuffer(Local0, Local0) 18 | Subtract(SizeOf(Local0), 1, Local1) 19 | Store(Zero, Local2) 20 | While (LLess(Local2, Local1)) { 21 | Store(DerefOf(Index(Local0, Local2)), DBGB) 22 | Increment(Local2) 23 | } 24 | Store(0x0A, DBGB) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/fw/acpi-dsdt-hpet.dsl: -------------------------------------------------------------------------------- 1 | /**************************************************************** 2 | * HPET 3 | ****************************************************************/ 4 | 5 | Scope(\_SB) { 6 | Device(HPET) { 7 | Name(_HID, EISAID("PNP0103")) 8 | Name(_UID, 0) 9 | OperationRegion(HPTM, SystemMemory, 0xFED00000, 0x400) 10 | Field(HPTM, DWordAcc, Lock, Preserve) { 11 | VEND, 32, 12 | PRD, 32, 13 | } 14 | Method(_STA, 0, NotSerialized) { 15 | Store(VEND, Local0) 16 | Store(PRD, Local1) 17 | ShiftRight(Local0, 16, Local0) 18 | If (LOr(LEqual(Local0, 0), LEqual(Local0, 0xffff))) { 19 | Return (0x0) 20 | } 21 | If (LOr(LEqual(Local1, 0), LGreater(Local1, 100000000))) { 22 | Return (0x0) 23 | } 24 | Return (0x0F) 25 | } 26 | Name(_CRS, ResourceTemplate() { 27 | #if 0 /* This makes WinXP BSOD for not yet figured reasons. */ 28 | IRQNoFlags() {2, 8} 29 | #endif 30 | Memory32Fixed(ReadOnly, 31 | 0xFED00000, // Address Base 32 | 0x00000400, // Address Length 33 | ) 34 | }) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/fw/acpi-dsdt-isa.dsl: -------------------------------------------------------------------------------- 1 | /* Common legacy ISA style devices. */ 2 | Scope(\_SB.PCI0.ISA) { 3 | 4 | Device(RTC) { 5 | Name(_HID, EisaId("PNP0B00")) 6 | Name(_CRS, ResourceTemplate() { 7 | IO(Decode16, 0x0070, 0x0070, 0x10, 0x02) 8 | IRQNoFlags() { 8 } 9 | IO(Decode16, 0x0072, 0x0072, 0x02, 0x06) 10 | }) 11 | } 12 | 13 | Device(KBD) { 14 | Name(_HID, EisaId("PNP0303")) 15 | Method(_STA, 0, NotSerialized) { 16 | Return (0x0f) 17 | } 18 | Name(_CRS, ResourceTemplate() { 19 | IO(Decode16, 0x0060, 0x0060, 0x01, 0x01) 20 | IO(Decode16, 0x0064, 0x0064, 0x01, 0x01) 21 | IRQNoFlags() { 1 } 22 | }) 23 | } 24 | 25 | Device(MOU) { 26 | Name(_HID, EisaId("PNP0F13")) 27 | Method(_STA, 0, NotSerialized) { 28 | Return (0x0f) 29 | } 30 | Name(_CRS, ResourceTemplate() { 31 | IRQNoFlags() { 12 } 32 | }) 33 | } 34 | 35 | Device(FDC0) { 36 | Name(_HID, EisaId("PNP0700")) 37 | Method(_STA, 0, NotSerialized) { 38 | Store(FDEN, Local0) 39 | If (LEqual(Local0, 0)) { 40 | Return (0x00) 41 | } Else { 42 | Return (0x0F) 43 | } 44 | } 45 | Name(_CRS, ResourceTemplate() { 46 | IO(Decode16, 0x03F2, 0x03F2, 0x00, 0x04) 47 | IO(Decode16, 0x03F7, 0x03F7, 0x00, 0x01) 48 | IRQNoFlags() { 6 } 49 | DMA(Compatibility, NotBusMaster, Transfer8) { 2 } 50 | }) 51 | } 52 | 53 | Device(LPT) { 54 | Name(_HID, EisaId("PNP0400")) 55 | Method(_STA, 0, NotSerialized) { 56 | Store(LPEN, Local0) 57 | If (LEqual(Local0, 0)) { 58 | Return (0x00) 59 | } Else { 60 | Return (0x0F) 61 | } 62 | } 63 | Name(_CRS, ResourceTemplate() { 64 | IO(Decode16, 0x0378, 0x0378, 0x08, 0x08) 65 | IRQNoFlags() { 7 } 66 | }) 67 | } 68 | 69 | Device(COM1) { 70 | Name(_HID, EisaId("PNP0501")) 71 | Name(_UID, 0x01) 72 | Method(_STA, 0, NotSerialized) { 73 | Store(CAEN, Local0) 74 | If (LEqual(Local0, 0)) { 75 | Return (0x00) 76 | } Else { 77 | Return (0x0F) 78 | } 79 | } 80 | Name(_CRS, ResourceTemplate() { 81 | IO(Decode16, 0x03F8, 0x03F8, 0x00, 0x08) 82 | IRQNoFlags() { 4 } 83 | }) 84 | } 85 | 86 | Device(COM2) { 87 | Name(_HID, EisaId("PNP0501")) 88 | Name(_UID, 0x02) 89 | Method(_STA, 0, NotSerialized) { 90 | Store(CBEN, Local0) 91 | If (LEqual(Local0, 0)) { 92 | Return (0x00) 93 | } Else { 94 | Return (0x0F) 95 | } 96 | } 97 | Name(_CRS, ResourceTemplate() { 98 | IO(Decode16, 0x02F8, 0x02F8, 0x00, 0x08) 99 | IRQNoFlags() { 3 } 100 | }) 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/fw/acpi-dsdt-pci-crs.dsl: -------------------------------------------------------------------------------- 1 | /* PCI CRS (current resources) definition. */ 2 | Scope(\_SB.PCI0) { 3 | 4 | Name(CRES, ResourceTemplate() { 5 | WordBusNumber(ResourceProducer, MinFixed, MaxFixed, PosDecode, 6 | 0x0000, // Address Space Granularity 7 | 0x0000, // Address Range Minimum 8 | 0x00FF, // Address Range Maximum 9 | 0x0000, // Address Translation Offset 10 | 0x0100, // Address Length 11 | ,, ) 12 | IO(Decode16, 13 | 0x0CF8, // Address Range Minimum 14 | 0x0CF8, // Address Range Maximum 15 | 0x01, // Address Alignment 16 | 0x08, // Address Length 17 | ) 18 | WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, 19 | 0x0000, // Address Space Granularity 20 | 0x0000, // Address Range Minimum 21 | 0x0CF7, // Address Range Maximum 22 | 0x0000, // Address Translation Offset 23 | 0x0CF8, // Address Length 24 | ,, , TypeStatic) 25 | WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, 26 | 0x0000, // Address Space Granularity 27 | 0x0D00, // Address Range Minimum 28 | 0xFFFF, // Address Range Maximum 29 | 0x0000, // Address Translation Offset 30 | 0xF300, // Address Length 31 | ,, , TypeStatic) 32 | DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite, 33 | 0x00000000, // Address Space Granularity 34 | 0x000A0000, // Address Range Minimum 35 | 0x000BFFFF, // Address Range Maximum 36 | 0x00000000, // Address Translation Offset 37 | 0x00020000, // Address Length 38 | ,, , AddressRangeMemory, TypeStatic) 39 | DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite, 40 | 0x00000000, // Address Space Granularity 41 | 0xE0000000, // Address Range Minimum 42 | 0xFEBFFFFF, // Address Range Maximum 43 | 0x00000000, // Address Translation Offset 44 | 0x1EC00000, // Address Length 45 | ,, PW32, AddressRangeMemory, TypeStatic) 46 | }) 47 | 48 | Name(CR64, ResourceTemplate() { 49 | QWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite, 50 | 0x00000000, // Address Space Granularity 51 | 0x8000000000, // Address Range Minimum 52 | 0xFFFFFFFFFF, // Address Range Maximum 53 | 0x00000000, // Address Translation Offset 54 | 0x8000000000, // Address Length 55 | ,, PW64, AddressRangeMemory, TypeStatic) 56 | }) 57 | 58 | Method(_CRS, 0) { 59 | /* Fields provided by dynamically created ssdt */ 60 | External(P0S, IntObj) 61 | External(P0E, IntObj) 62 | External(P1V, IntObj) 63 | External(P1S, BuffObj) 64 | External(P1E, BuffObj) 65 | External(P1L, BuffObj) 66 | 67 | /* fixup 32bit pci io window */ 68 | CreateDWordField(CRES, \_SB.PCI0.PW32._MIN, PS32) 69 | CreateDWordField(CRES, \_SB.PCI0.PW32._MAX, PE32) 70 | CreateDWordField(CRES, \_SB.PCI0.PW32._LEN, PL32) 71 | Store(P0S, PS32) 72 | Store(P0E, PE32) 73 | Store(Add(Subtract(P0E, P0S), 1), PL32) 74 | 75 | If (LEqual(P1V, Zero)) { 76 | Return (CRES) 77 | } 78 | 79 | /* fixup 64bit pci io window */ 80 | CreateQWordField(CR64, \_SB.PCI0.PW64._MIN, PS64) 81 | CreateQWordField(CR64, \_SB.PCI0.PW64._MAX, PE64) 82 | CreateQWordField(CR64, \_SB.PCI0.PW64._LEN, PL64) 83 | Store(P1S, PS64) 84 | Store(P1E, PE64) 85 | Store(P1L, PL64) 86 | /* add window and return result */ 87 | ConcatenateResTemplate(CRES, CR64, Local0) 88 | Return (Local0) 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/fw/dev-piix.h: -------------------------------------------------------------------------------- 1 | #ifndef __DEV_PIIX_H 2 | #define __DEV_PIIX_H 3 | 4 | #define I440FX_PAM0 0x59 5 | #define I440FX_SMRAM 0x72 6 | 7 | #define PIIX_PMBASE 0x40 8 | #define PIIX_PMREGMISC 0x80 9 | #define PIIX_SMBHSTBASE 0x90 10 | #define PIIX_SMBHSTCFG 0xd2 11 | #define PIIX_DEVACTB 0x58 12 | #define PIIX_DEVACTB_APMC_EN (1 << 25) 13 | 14 | #define PIIX_PORT_ELCR1 0x4d0 15 | #define PIIX_PORT_ELCR2 0x4d1 16 | 17 | /* ICH9 PM I/O registers */ 18 | #define PIIX_GPE0_BLK 0xafe0 19 | #define PIIX_GPE0_BLK_LEN 4 20 | #define PIIX_PMIO_GLBCTL 0x28 21 | #define PIIX_PMIO_GLBCTL_SMI_EN 1 22 | 23 | /* FADT ACPI_ENABLE/ACPI_DISABLE */ 24 | #define PIIX_ACPI_ENABLE 0xf1 25 | #define PIIX_ACPI_DISABLE 0xf0 26 | 27 | #define PIIX_PM_INTRRUPT 9 // irq 9 28 | 29 | #endif // dev-piix.h 30 | -------------------------------------------------------------------------------- /src/fw/dev-q35.h: -------------------------------------------------------------------------------- 1 | #ifndef __DEV_Q35_H 2 | #define __DEV_Q35_H 3 | 4 | #include "types.h" // u16 5 | 6 | #define PCI_DEVICE_ID_INTEL_Q35_MCH 0x29c0 7 | #define Q35_HOST_BRIDGE_PAM0 0x90 8 | #define Q35_HOST_BRIDGE_SMRAM 0x9d 9 | #define Q35_HOST_BRIDGE_PCIEXBAR 0x60 10 | #define Q35_HOST_BRIDGE_PCIEXBAR_SIZE (256 * 1024 * 1024) 11 | #define Q35_HOST_BRIDGE_PCIEXBAR_ADDR 0xb0000000 12 | #define Q35_HOST_BRIDGE_PCIEXBAREN ((u64)1) 13 | #define Q35_HOST_PCIE_PCI_SEGMENT 0 14 | #define Q35_HOST_PCIE_START_BUS_NUMBER 0 15 | #define Q35_HOST_PCIE_END_BUS_NUMBER 255 16 | 17 | #define PCI_DEVICE_ID_INTEL_ICH9_LPC 0x2918 18 | #define ICH9_LPC_PMBASE 0x40 19 | #define ICH9_LPC_PMBASE_RTE 0x1 20 | 21 | #define ICH9_LPC_ACPI_CTRL 0x44 22 | #define ICH9_LPC_ACPI_CTRL_ACPI_EN 0x80 23 | #define ICH9_LPC_PIRQA_ROUT 0x60 24 | #define ICH9_LPC_PIRQE_ROUT 0x68 25 | #define ICH9_LPC_PIRQ_ROUT_IRQEN 0x80 26 | #define ICH9_LPC_GEN_PMCON_1 0xa0 27 | #define ICH9_LPC_GEN_PMCON_1_SMI_LOCK (1 << 4) 28 | #define ICH9_LPC_PORT_ELCR1 0x4d0 29 | #define ICH9_LPC_PORT_ELCR2 0x4d1 30 | #define PCI_DEVICE_ID_INTEL_ICH9_SMBUS 0x2930 31 | #define ICH9_SMB_SMB_BASE 0x20 32 | #define ICH9_SMB_HOSTC 0x40 33 | #define ICH9_SMB_HOSTC_HST_EN 0x01 34 | 35 | #define ICH9_ACPI_ENABLE 0x2 36 | #define ICH9_ACPI_DISABLE 0x3 37 | 38 | /* ICH9 LPC PM I/O registers are 128 ports and 128-aligned */ 39 | #define ICH9_PMIO_GPE0_STS 0x20 40 | #define ICH9_PMIO_GPE0_BLK_LEN 0x10 41 | #define ICH9_PMIO_SMI_EN 0x30 42 | #define ICH9_PMIO_SMI_EN_APMC_EN (1 << 5) 43 | #define ICH9_PMIO_SMI_EN_GLB_SMI_EN (1 << 0) 44 | 45 | /* FADT ACPI_ENABLE/ACPI_DISABLE */ 46 | #define ICH9_APM_ACPI_ENABLE 0x2 47 | #define ICH9_APM_ACPI_DISABLE 0x3 48 | 49 | #endif // dev-q35.h 50 | -------------------------------------------------------------------------------- /src/fw/lzmadecode.h: -------------------------------------------------------------------------------- 1 | /* 2 | LzmaDecode.h 3 | LZMA Decoder interface 4 | 5 | LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) 6 | http://www.7-zip.org/ 7 | 8 | LZMA SDK is licensed under two licenses: 9 | 1) GNU Lesser General Public License (GNU LGPL) 10 | 2) Common Public License (CPL) 11 | It means that you can select one of these two licenses and 12 | follow rules of that license. 13 | 14 | SPECIAL EXCEPTION: 15 | Igor Pavlov, as the author of this code, expressly permits you to 16 | statically or dynamically link your code (or bind by name) to the 17 | interfaces of this file without subjecting your linked code to the 18 | terms of the CPL or GNU LGPL. Any modifications or additions 19 | to this file, however, are subject to the LGPL or CPL terms. 20 | */ 21 | 22 | #ifndef __LZMADECODE_H 23 | #define __LZMADECODE_H 24 | 25 | typedef unsigned char Byte; 26 | typedef unsigned short UInt16; 27 | typedef unsigned int UInt32; 28 | typedef UInt32 SizeT; 29 | 30 | #define CProb UInt16 31 | 32 | #define LZMA_RESULT_OK 0 33 | #define LZMA_RESULT_DATA_ERROR 1 34 | 35 | 36 | #define LZMA_BASE_SIZE 1846 37 | #define LZMA_LIT_SIZE 768 38 | 39 | #define LZMA_PROPERTIES_SIZE 5 40 | 41 | typedef struct _CLzmaProperties 42 | { 43 | int lc; 44 | int lp; 45 | int pb; 46 | }CLzmaProperties; 47 | 48 | int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size); 49 | 50 | #define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp))) 51 | 52 | #define kLzmaNeedInitId (-2) 53 | 54 | typedef struct _CLzmaDecoderState 55 | { 56 | CLzmaProperties Properties; 57 | CProb *Probs; 58 | 59 | 60 | } CLzmaDecoderState; 61 | 62 | 63 | int LzmaDecode(CLzmaDecoderState *vs, 64 | const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, 65 | unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed); 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /src/fw/mtrr.c: -------------------------------------------------------------------------------- 1 | // Initialize MTRRs - mostly useful on KVM. 2 | // 3 | // Copyright (C) 2006 Fabrice Bellard 4 | // 5 | // This file may be distributed under the terms of the GNU LGPLv3 license. 6 | 7 | #include "config.h" // CONFIG_* 8 | #include "hw/pci.h" // pcimem_start 9 | #include "output.h" // dprintf 10 | #include "paravirt.h" // RamSize 11 | #include "util.h" // mtrr_setup 12 | #include "x86.h" // cpuid 13 | 14 | #define MSR_MTRRcap 0x000000fe 15 | #define MSR_MTRRfix64K_00000 0x00000250 16 | #define MSR_MTRRfix16K_80000 0x00000258 17 | #define MSR_MTRRfix16K_A0000 0x00000259 18 | #define MSR_MTRRfix4K_C0000 0x00000268 19 | #define MSR_MTRRfix4K_C8000 0x00000269 20 | #define MSR_MTRRfix4K_D0000 0x0000026a 21 | #define MSR_MTRRfix4K_D8000 0x0000026b 22 | #define MSR_MTRRfix4K_E0000 0x0000026c 23 | #define MSR_MTRRfix4K_E8000 0x0000026d 24 | #define MSR_MTRRfix4K_F0000 0x0000026e 25 | #define MSR_MTRRfix4K_F8000 0x0000026f 26 | #define MSR_MTRRdefType 0x000002ff 27 | 28 | #define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg)) 29 | #define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1) 30 | 31 | #define MTRR_MEMTYPE_UC 0 32 | #define MTRR_MEMTYPE_WC 1 33 | #define MTRR_MEMTYPE_WT 4 34 | #define MTRR_MEMTYPE_WP 5 35 | #define MTRR_MEMTYPE_WB 6 36 | 37 | void mtrr_setup(void) 38 | { 39 | if (!CONFIG_MTRR_INIT) 40 | return; 41 | 42 | u32 eax, ebx, ecx, edx, cpuid_features; 43 | cpuid(1, &eax, &ebx, &ecx, &cpuid_features); 44 | if (!(cpuid_features & CPUID_MTRR)) 45 | return; 46 | if (!(cpuid_features & CPUID_MSR)) 47 | return; 48 | 49 | dprintf(3, "init mtrr\n"); 50 | 51 | u32 mtrr_cap = rdmsr(MSR_MTRRcap); 52 | int vcnt = mtrr_cap & 0xff; 53 | int fix = mtrr_cap & 0x100; 54 | if (!vcnt || !fix) 55 | return; 56 | 57 | // Disable MTRRs 58 | wrmsr_smp(MSR_MTRRdefType, 0); 59 | 60 | // Set fixed MTRRs 61 | union u64b { 62 | u8 valb[8]; 63 | u64 val; 64 | } u; 65 | u.val = 0; 66 | int i; 67 | for (i = 0; i < 8; i++) 68 | if (RamSize >= 65536 * (i + 1)) 69 | u.valb[i] = MTRR_MEMTYPE_WB; 70 | wrmsr_smp(MSR_MTRRfix64K_00000, u.val); 71 | u.val = 0; 72 | for (i = 0; i < 8; i++) 73 | if (RamSize >= 0x80000 + 16384 * (i + 1)) 74 | u.valb[i] = MTRR_MEMTYPE_WB; 75 | wrmsr_smp(MSR_MTRRfix16K_80000, u.val); 76 | wrmsr_smp(MSR_MTRRfix16K_A0000, 0); // 0xA0000-0xC0000 is uncached 77 | int j; 78 | for (j = 0; j < 8; j++) { 79 | u.val = 0; 80 | for (i = 0; i < 8; i++) 81 | if (RamSize >= 0xC0000 + j * 0x8000 + 4096 * (i + 1)) 82 | u.valb[i] = MTRR_MEMTYPE_WP; 83 | wrmsr_smp(MSR_MTRRfix4K_C0000 + j, u.val); 84 | } 85 | 86 | // Set variable MTRRs 87 | int phys_bits = 36; 88 | cpuid(0x80000000u, &eax, &ebx, &ecx, &edx); 89 | if (eax >= 0x80000008) { 90 | /* Get physical bits from leaf 0x80000008 (if available) */ 91 | cpuid(0x80000008u, &eax, &ebx, &ecx, &edx); 92 | phys_bits = eax & 0xff; 93 | } 94 | u64 phys_mask = ((1ull << phys_bits) - 1); 95 | for (i=0; i 5 | // Copyright (C) 2002 MandrakeSoft S.A. 6 | // 7 | // This file may be distributed under the terms of the GNU LGPLv3 license. 8 | 9 | #include "config.h" // CONFIG_* 10 | #include "output.h" // dprintf 11 | #include "std/pirtable.h" // struct pir_header 12 | #include "string.h" // checksum 13 | #include "util.h" // PirAddr 14 | 15 | struct pir_table { 16 | struct pir_header pir; 17 | struct pir_slot slots[6]; 18 | } PACKED; 19 | 20 | static struct pir_table PIR_TABLE = { 21 | .pir = { 22 | .version = 0x0100, 23 | .size = sizeof(struct pir_table), 24 | .router_devfunc = 0x08, 25 | .compatible_devid = 0x122e8086, 26 | }, 27 | .slots = { 28 | { 29 | // first slot entry PCI-to-ISA (embedded) 30 | .dev = 1<<3, 31 | .links = { 32 | {.link = 0x60, .bitmap = 0xdef8}, // INTA# 33 | {.link = 0x61, .bitmap = 0xdef8}, // INTB# 34 | {.link = 0x62, .bitmap = 0xdef8}, // INTC# 35 | {.link = 0x63, .bitmap = 0xdef8}, // INTD# 36 | }, 37 | .slot_nr = 0, // embedded 38 | }, { 39 | // second slot entry: 1st PCI slot 40 | .dev = 2<<3, 41 | .links = { 42 | {.link = 0x61, .bitmap = 0xdef8}, // INTA# 43 | {.link = 0x62, .bitmap = 0xdef8}, // INTB# 44 | {.link = 0x63, .bitmap = 0xdef8}, // INTC# 45 | {.link = 0x60, .bitmap = 0xdef8}, // INTD# 46 | }, 47 | .slot_nr = 1, 48 | }, { 49 | // third slot entry: 2nd PCI slot 50 | .dev = 3<<3, 51 | .links = { 52 | {.link = 0x62, .bitmap = 0xdef8}, // INTA# 53 | {.link = 0x63, .bitmap = 0xdef8}, // INTB# 54 | {.link = 0x60, .bitmap = 0xdef8}, // INTC# 55 | {.link = 0x61, .bitmap = 0xdef8}, // INTD# 56 | }, 57 | .slot_nr = 2, 58 | }, { 59 | // 4th slot entry: 3rd PCI slot 60 | .dev = 4<<3, 61 | .links = { 62 | {.link = 0x63, .bitmap = 0xdef8}, // INTA# 63 | {.link = 0x60, .bitmap = 0xdef8}, // INTB# 64 | {.link = 0x61, .bitmap = 0xdef8}, // INTC# 65 | {.link = 0x62, .bitmap = 0xdef8}, // INTD# 66 | }, 67 | .slot_nr = 3, 68 | }, { 69 | // 5th slot entry: 4rd PCI slot 70 | .dev = 5<<3, 71 | .links = { 72 | {.link = 0x60, .bitmap = 0xdef8}, // INTA# 73 | {.link = 0x61, .bitmap = 0xdef8}, // INTB# 74 | {.link = 0x62, .bitmap = 0xdef8}, // INTC# 75 | {.link = 0x63, .bitmap = 0xdef8}, // INTD# 76 | }, 77 | .slot_nr = 4, 78 | }, { 79 | // 6th slot entry: 5rd PCI slot 80 | .dev = 6<<3, 81 | .links = { 82 | {.link = 0x61, .bitmap = 0xdef8}, // INTA# 83 | {.link = 0x62, .bitmap = 0xdef8}, // INTB# 84 | {.link = 0x63, .bitmap = 0xdef8}, // INTC# 85 | {.link = 0x60, .bitmap = 0xdef8}, // INTD# 86 | }, 87 | .slot_nr = 5, 88 | }, 89 | } 90 | }; 91 | 92 | void 93 | pirtable_setup(void) 94 | { 95 | if (! CONFIG_PIRTABLE) 96 | return; 97 | 98 | dprintf(3, "init PIR table\n"); 99 | 100 | PIR_TABLE.pir.signature = PIR_SIGNATURE; 101 | PIR_TABLE.pir.checksum -= checksum(&PIR_TABLE, sizeof(PIR_TABLE)); 102 | copy_pir(&PIR_TABLE); 103 | } 104 | -------------------------------------------------------------------------------- /src/fw/romfile_loader.h: -------------------------------------------------------------------------------- 1 | #ifndef __ROMFILE_LOADER_H 2 | #define __ROMFILE_LOADER_H 3 | 4 | #include "types.h" // u8 5 | #include "util.h" // romfile_s 6 | 7 | #define ROMFILE_LOADER_FILESZ 56 8 | 9 | /* ROM file linker/loader interface. Linker uses little endian format */ 10 | struct romfile_loader_entry_s { 11 | u32 command; 12 | union { 13 | /* 14 | * COMMAND_ALLOCATE - allocate a table from @alloc_file 15 | * subject to @alloc_align alignment (must be power of 2) 16 | * and @alloc_zone (can be HIGH or FSEG) requirements. 17 | * 18 | * Must appear exactly once for each file, and before 19 | * this file is referenced by any other command. 20 | */ 21 | struct { 22 | char alloc_file[ROMFILE_LOADER_FILESZ]; 23 | u32 alloc_align; 24 | u8 alloc_zone; 25 | }; 26 | 27 | /* 28 | * COMMAND_ADD_POINTER - patch the table (originating from 29 | * @dest_file) at @pointer_offset, by adding a pointer to the table 30 | * originating from @src_file. 1,2,4 or 8 byte unsigned 31 | * addition is used depending on @pointer_size. 32 | */ 33 | struct { 34 | char pointer_dest_file[ROMFILE_LOADER_FILESZ]; 35 | char pointer_src_file[ROMFILE_LOADER_FILESZ]; 36 | u32 pointer_offset; 37 | u8 pointer_size; 38 | }; 39 | 40 | /* 41 | * COMMAND_ADD_CHECKSUM - calculate checksum of the range specified by 42 | * @cksum_start and @cksum_length fields, 43 | * and then add the value at @cksum_offset. 44 | * Checksum simply sums -X for each byte X in the range 45 | * using 8-bit math. 46 | */ 47 | struct { 48 | char cksum_file[ROMFILE_LOADER_FILESZ]; 49 | u32 cksum_offset; 50 | u32 cksum_start; 51 | u32 cksum_length; 52 | }; 53 | 54 | /* padding */ 55 | char pad[124]; 56 | }; 57 | }; 58 | 59 | enum { 60 | ROMFILE_LOADER_COMMAND_ALLOCATE = 0x1, 61 | ROMFILE_LOADER_COMMAND_ADD_POINTER = 0x2, 62 | ROMFILE_LOADER_COMMAND_ADD_CHECKSUM = 0x3, 63 | }; 64 | 65 | enum { 66 | ROMFILE_LOADER_ALLOC_ZONE_HIGH = 0x1, 67 | ROMFILE_LOADER_ALLOC_ZONE_FSEG = 0x2, 68 | }; 69 | 70 | int romfile_loader_execute(const char *name); 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /src/fw/ssdt-misc.dsl: -------------------------------------------------------------------------------- 1 | ACPI_EXTRACT_ALL_CODE ssdp_misc_aml 2 | 3 | DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1) 4 | { 5 | 6 | /**************************************************************** 7 | * PCI memory ranges 8 | ****************************************************************/ 9 | 10 | Scope(\) { 11 | ACPI_EXTRACT_NAME_DWORD_CONST acpi_pci32_start 12 | Name(P0S, 0x12345678) 13 | ACPI_EXTRACT_NAME_DWORD_CONST acpi_pci32_end 14 | Name(P0E, 0x12345678) 15 | ACPI_EXTRACT_NAME_BYTE_CONST acpi_pci64_valid 16 | Name(P1V, 0x12) 17 | ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_start 18 | Name(P1S, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }) 19 | ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_end 20 | Name(P1E, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }) 21 | ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_length 22 | Name(P1L, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }) 23 | } 24 | 25 | 26 | /**************************************************************** 27 | * Suspend 28 | ****************************************************************/ 29 | 30 | Scope(\) { 31 | /* 32 | * S3 (suspend-to-ram), S4 (suspend-to-disk) and S5 (power-off) type codes: 33 | * must match piix4 emulation. 34 | */ 35 | 36 | ACPI_EXTRACT_NAME_STRING acpi_s3_name 37 | Name(_S3, Package(0x04) { 38 | One, /* PM1a_CNT.SLP_TYP */ 39 | One, /* PM1b_CNT.SLP_TYP */ 40 | Zero, /* reserved */ 41 | Zero /* reserved */ 42 | }) 43 | ACPI_EXTRACT_NAME_STRING acpi_s4_name 44 | ACPI_EXTRACT_PKG_START acpi_s4_pkg 45 | Name(_S4, Package(0x04) { 46 | 0x2, /* PM1a_CNT.SLP_TYP */ 47 | 0x2, /* PM1b_CNT.SLP_TYP */ 48 | Zero, /* reserved */ 49 | Zero /* reserved */ 50 | }) 51 | Name(_S5, Package(0x04) { 52 | Zero, /* PM1a_CNT.SLP_TYP */ 53 | Zero, /* PM1b_CNT.SLP_TYP */ 54 | Zero, /* reserved */ 55 | Zero /* reserved */ 56 | }) 57 | } 58 | 59 | External(\_SB.PCI0, DeviceObj) 60 | External(\_SB.PCI0.ISA, DeviceObj) 61 | 62 | Scope(\_SB.PCI0.ISA) { 63 | Device(PEVT) { 64 | Name(_HID, "QEMU0001") 65 | /* PEST will be patched to be Zero if no such device */ 66 | ACPI_EXTRACT_NAME_WORD_CONST ssdt_isa_pest 67 | Name(PEST, 0xFFFF) 68 | OperationRegion(PEOR, SystemIO, PEST, 0x01) 69 | Field(PEOR, ByteAcc, NoLock, Preserve) { 70 | PEPT, 8, 71 | } 72 | 73 | Method(_STA, 0, NotSerialized) { 74 | Store(PEST, Local0) 75 | If (LEqual(Local0, Zero)) { 76 | Return (0x00) 77 | } Else { 78 | Return (0x0F) 79 | } 80 | } 81 | 82 | Method(RDPT, 0, NotSerialized) { 83 | Store(PEPT, Local0) 84 | Return (Local0) 85 | } 86 | 87 | Method(WRPT, 1, NotSerialized) { 88 | Store(Arg0, PEPT) 89 | } 90 | 91 | Name(_CRS, ResourceTemplate() { 92 | IO(Decode16, 0x00, 0x00, 0x01, 0x01, IO) 93 | }) 94 | 95 | CreateWordField(_CRS, IO._MIN, IOMN) 96 | CreateWordField(_CRS, IO._MAX, IOMX) 97 | 98 | Method(_INI, 0, NotSerialized) { 99 | Store(PEST, IOMN) 100 | Store(PEST, IOMX) 101 | } 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/fw/ssdt-pcihp.dsl: -------------------------------------------------------------------------------- 1 | ACPI_EXTRACT_ALL_CODE ssdp_pcihp_aml 2 | 3 | DefinitionBlock ("ssdt-pcihp.aml", "SSDT", 0x01, "BXPC", "BXSSDTPCIHP", 0x1) 4 | { 5 | 6 | /**************************************************************** 7 | * PCI hotplug 8 | ****************************************************************/ 9 | 10 | /* Objects supplied by DSDT */ 11 | External(\_SB.PCI0, DeviceObj) 12 | External(\_SB.PCI0.PCEJ, MethodObj) 13 | 14 | Scope(\_SB.PCI0) { 15 | 16 | /* Bulk generated PCI hotplug devices */ 17 | ACPI_EXTRACT_DEVICE_START ssdt_pcihp_start 18 | ACPI_EXTRACT_DEVICE_END ssdt_pcihp_end 19 | ACPI_EXTRACT_DEVICE_STRING ssdt_pcihp_name 20 | 21 | // Method _EJ0 can be patched by BIOS to EJ0_ 22 | // at runtime, if the slot is detected to not support hotplug. 23 | // Extract the offset of the address dword and the 24 | // _EJ0 name to allow this patching. 25 | Device(SAA) { 26 | ACPI_EXTRACT_NAME_BYTE_CONST ssdt_pcihp_id 27 | Name(_SUN, 0xAA) 28 | ACPI_EXTRACT_NAME_DWORD_CONST ssdt_pcihp_adr 29 | Name(_ADR, 0xAA0000) 30 | ACPI_EXTRACT_METHOD_STRING ssdt_pcihp_ej0 31 | Method(_EJ0, 1) { 32 | PCEJ(_SUN) 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/fw/ssdt-proc.dsl: -------------------------------------------------------------------------------- 1 | /* This file is the basis for the ssdt table generated in src/acpi.c. 2 | * It defines the contents of the per-cpu Processor() object. At 3 | * runtime, a dynamically generated SSDT will contain one copy of this 4 | * AML snippet for every possible cpu in the system. The objects will 5 | * be placed in the \_SB_ namespace. 6 | * 7 | * In addition to the aml code generated from this file, the 8 | * src/acpi.c file creates a NTFY method with an entry for each cpu: 9 | * Method(NTFY, 2) { 10 | * If (LEqual(Arg0, 0x00)) { Notify(CP00, Arg1) } 11 | * If (LEqual(Arg0, 0x01)) { Notify(CP01, Arg1) } 12 | * ... 13 | * } 14 | * and a CPON array with the list of active and inactive cpus: 15 | * Name(CPON, Package() { One, One, ..., Zero, Zero, ... }) 16 | */ 17 | 18 | ACPI_EXTRACT_ALL_CODE ssdp_proc_aml 19 | 20 | DefinitionBlock ("ssdt-proc.aml", "SSDT", 0x01, "BXPC", "BXSSDT", 0x1) 21 | { 22 | ACPI_EXTRACT_PROCESSOR_START ssdt_proc_start 23 | ACPI_EXTRACT_PROCESSOR_END ssdt_proc_end 24 | ACPI_EXTRACT_PROCESSOR_STRING ssdt_proc_name 25 | Processor(CPAA, 0xAA, 0x0000b010, 0x06) { 26 | ACPI_EXTRACT_NAME_BYTE_CONST ssdt_proc_id 27 | Name(ID, 0xAA) 28 | /* 29 | * The src/acpi.c code requires the above ACP_EXTRACT tags so that it can update 30 | * CPAA and 0xAA with the appropriate CPU id (see 31 | * SD_OFFSET_CPUHEX/CPUID1/CPUID2). Don't change the above without 32 | * also updating the C code. 33 | */ 34 | Name(_HID, "ACPI0007") 35 | External(CPMA, MethodObj) 36 | External(CPST, MethodObj) 37 | External(CPEJ, MethodObj) 38 | Method(_MAT, 0) { 39 | Return (CPMA(ID)) 40 | } 41 | Method(_STA, 0) { 42 | Return (CPST(ID)) 43 | } 44 | Method(_EJ0, 1, NotSerialized) { 45 | CPEJ(ID, Arg0) 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/gen-defs.h: -------------------------------------------------------------------------------- 1 | // Tool for building defintions accessible from assembler code. This 2 | // is based on code from the Linux Kernel. 3 | #ifndef __GEN_DEFS_H 4 | #define __GEN_DEFS_H 5 | 6 | 7 | #define DEFINE(sym, val) \ 8 | asm volatile("\n->" #sym " %0 " #val : : "i" (val)) 9 | 10 | #define BLANK() \ 11 | asm volatile("\n->" : : ) 12 | 13 | #define OFFSET(sym, str, mem) \ 14 | DEFINE(sym, offsetof(struct str, mem)) 15 | 16 | #define COMMENT(x) \ 17 | asm volatile("\n->#" x) 18 | 19 | #endif // gen-defs.h 20 | -------------------------------------------------------------------------------- /src/hw/bar.h: -------------------------------------------------------------------------------- 1 | //***************************************************************************** 2 | // 3 | // 4 | // Copyright (c) 2012 Sage Electronic Engineering. All rights reserved. 5 | // Software License Agreement 6 | // 7 | // THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED 8 | // OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF 9 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. 10 | // Sage Electronic Engineering SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR 11 | // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. 12 | // 13 | //***************************************************************************** 14 | 15 | #ifndef __BAR_H 16 | #define __BAR_H 17 | 18 | #include 19 | 20 | // write functions 21 | static inline void bar_write8( uint32_t bar, uint32_t offset, uint8_t value ) 22 | { 23 | volatile uint8_t* preg = (volatile uint8_t*)(bar | ( offset & 0xFF ) ); 24 | *preg = value; 25 | } 26 | 27 | static inline void bar_write16( uint32_t bar, uint32_t offset, uint16_t value ) 28 | { 29 | volatile uint16_t* preg = (volatile uint16_t*)(bar | ( offset & 0xFF ) ); 30 | *preg = value; 31 | } 32 | 33 | static inline void bar_write32( uint32_t bar, uint32_t offset, uint32_t value ) 34 | { 35 | volatile uint32_t* preg = (volatile uint32_t*)(bar | ( offset & 0xFF ) ); 36 | *preg = value; 37 | } 38 | 39 | // read functions 40 | static inline uint8_t bar_read8( uint32_t bar, uint32_t offset ) 41 | { 42 | volatile uint8_t* preg = (volatile uint8_t*)(bar | ( offset & 0xFF ) ); 43 | return( *preg ); 44 | } 45 | 46 | static inline uint16_t bar_read16( uint32_t bar, uint32_t offset ) 47 | { 48 | volatile uint16_t* preg = (volatile uint16_t*)(bar | ( offset & 0xFF ) ); 49 | return( *preg ); 50 | } 51 | 52 | static inline uint32_t bar_read32( uint32_t bar, uint32_t offset ) 53 | { 54 | volatile uint32_t* preg = (volatile uint32_t*)(bar | ( offset & 0xFF ) ); 55 | return( *preg ); 56 | } 57 | 58 | #endif /* __BAR_H */ 59 | -------------------------------------------------------------------------------- /src/hw/blockcmd.h: -------------------------------------------------------------------------------- 1 | // Definitions for SCSI style command data blocks. 2 | #ifndef __BLOCKCMD_H 3 | #define __BLOCKCMD_H 4 | 5 | #include "types.h" // u8 6 | 7 | #define CDB_CMD_READ_10 0x28 8 | #define CDB_CMD_VERIFY_10 0x2f 9 | #define CDB_CMD_WRITE_10 0x2a 10 | 11 | struct cdb_rwdata_10 { 12 | u8 command; 13 | u8 flags; 14 | u32 lba; 15 | u8 resreved_06; 16 | u16 count; 17 | u8 reserved_09; 18 | u8 pad[6]; 19 | } PACKED; 20 | 21 | #define CDB_CMD_READ_CAPACITY 0x25 22 | 23 | struct cdb_read_capacity { 24 | u8 command; 25 | u8 flags; 26 | u8 resreved_02[8]; 27 | u8 pad[6]; 28 | } PACKED; 29 | 30 | struct cdbres_read_capacity { 31 | u32 sectors; 32 | u32 blksize; 33 | } PACKED; 34 | 35 | #define CDB_CMD_TEST_UNIT_READY 0x00 36 | #define CDB_CMD_INQUIRY 0x12 37 | #define CDB_CMD_REQUEST_SENSE 0x03 38 | 39 | struct cdb_request_sense { 40 | u8 command; 41 | u8 flags; 42 | u16 reserved_02; 43 | u8 length; 44 | u8 reserved_05; 45 | u8 pad[10]; 46 | } PACKED; 47 | 48 | struct cdbres_request_sense { 49 | u8 errcode; 50 | u8 segment; 51 | u8 flags; 52 | u32 info; 53 | u8 additional; 54 | u32 specific; 55 | u8 asc; 56 | u8 ascq; 57 | u32 reserved_0e; 58 | } PACKED; 59 | 60 | #define SCSI_TYPE_DISK 0x00 61 | #define SCSI_TYPE_CDROM 0x05 62 | 63 | struct cdbres_inquiry { 64 | u8 pdt; 65 | u8 removable; 66 | u8 reserved_02[2]; 67 | u8 additional; 68 | u8 reserved_05[3]; 69 | char vendor[8]; 70 | char product[16]; 71 | char rev[4]; 72 | } PACKED; 73 | 74 | #define CDB_CMD_MODE_SENSE 0x5A 75 | #define MODE_PAGE_HD_GEOMETRY 0x04 76 | 77 | struct cdb_mode_sense { 78 | u8 command; 79 | u8 flags; 80 | u8 page; 81 | u32 reserved_03; 82 | u16 count; 83 | u8 reserved_09; 84 | u8 pad[6]; 85 | } PACKED; 86 | 87 | struct cdbres_mode_sense_geom { 88 | u8 unused_00[3]; 89 | u8 read_only; 90 | u32 unused_04; 91 | u8 page; 92 | u8 length; 93 | u8 cyl[3]; 94 | u8 heads; 95 | u8 precomp[3]; 96 | u8 reduced[3]; 97 | u16 step_rate; 98 | u8 landing[3]; 99 | u16 rpm; 100 | } PACKED; 101 | 102 | // blockcmd.c 103 | int cdb_is_read(u8 *cdbcmd, u16 blocksize); 104 | struct disk_op_s; 105 | int cdb_get_inquiry(struct disk_op_s *op, struct cdbres_inquiry *data); 106 | int cdb_get_sense(struct disk_op_s *op, struct cdbres_request_sense *data); 107 | int cdb_test_unit_ready(struct disk_op_s *op); 108 | int cdb_read_capacity(struct disk_op_s *op, struct cdbres_read_capacity *data); 109 | int cdb_mode_sense_geom(struct disk_op_s *op, struct cdbres_mode_sense_geom *data); 110 | int cdb_inquiry(struct disk_op_s *op, struct cdbres_inquiry *data); 111 | int cdb_read(struct disk_op_s *op); 112 | int cdb_write(struct disk_op_s *op); 113 | 114 | int scsi_is_ready(struct disk_op_s *op); 115 | struct drive_s; 116 | int scsi_drive_setup(struct drive_s *drive, const char *s, int prio); 117 | 118 | #endif // blockcmd.h 119 | -------------------------------------------------------------------------------- /src/hw/dma.c: -------------------------------------------------------------------------------- 1 | // Code to support legacy Intel 8237 DMA chip. 2 | // 3 | // Copyright (C) 2008,2009 Kevin O'Connor 4 | // Copyright (C) 2002 MandrakeSoft S.A. 5 | // 6 | // This file may be distributed under the terms of the GNU LGPLv3 license. 7 | 8 | #include "util.h" // dma_setup 9 | #include "x86.h" // outb 10 | 11 | #define PORT_DMA_ADDR_2 0x0004 12 | #define PORT_DMA_CNT_2 0x0005 13 | #define PORT_DMA1_MASK_REG 0x000a 14 | #define PORT_DMA1_MODE_REG 0x000b 15 | #define PORT_DMA1_CLEAR_FF_REG 0x000c 16 | #define PORT_DMA1_MASTER_CLEAR 0x000d 17 | #define PORT_DMA_PAGE_2 0x0081 18 | #define PORT_DMA2_MASK_REG 0x00d4 19 | #define PORT_DMA2_MODE_REG 0x00d6 20 | #define PORT_DMA2_MASTER_CLEAR 0x00da 21 | 22 | // Setup the DMA controller for a floppy transfer. 23 | int 24 | dma_floppy(u32 addr, int count, int isWrite) 25 | { 26 | // check for 64K boundary overrun 27 | u16 end = count - 1; 28 | u32 last_addr = addr + end; 29 | if ((addr >> 16) != (last_addr >> 16)) 30 | return -1; 31 | 32 | u8 mode_register = 0x46; // single mode, increment, autoinit disable, 33 | if (isWrite) 34 | mode_register = 0x4a; 35 | 36 | outb(0x06, PORT_DMA1_MASK_REG); 37 | outb(0x00, PORT_DMA1_CLEAR_FF_REG); // clear flip-flop 38 | outb(addr, PORT_DMA_ADDR_2); 39 | outb(addr>>8, PORT_DMA_ADDR_2); 40 | outb(0x00, PORT_DMA1_CLEAR_FF_REG); // clear flip-flop 41 | outb(end, PORT_DMA_CNT_2); 42 | outb(end>>8, PORT_DMA_CNT_2); 43 | 44 | // port 0b: DMA-1 Mode Register 45 | // transfer type=write, channel 2 46 | outb(mode_register, PORT_DMA1_MODE_REG); 47 | 48 | // port 81: DMA-1 Page Register, channel 2 49 | outb(addr>>16, PORT_DMA_PAGE_2); 50 | 51 | outb(0x02, PORT_DMA1_MASK_REG); // unmask channel 2 52 | 53 | return 0; 54 | } 55 | 56 | // Reset DMA controller 57 | void 58 | dma_setup(void) 59 | { 60 | // first reset the DMA controllers 61 | outb(0, PORT_DMA1_MASTER_CLEAR); 62 | outb(0, PORT_DMA2_MASTER_CLEAR); 63 | 64 | // then initialize the DMA controllers 65 | outb(0xc0, PORT_DMA2_MODE_REG); 66 | outb(0x00, PORT_DMA2_MASK_REG); 67 | } 68 | -------------------------------------------------------------------------------- /src/hw/esp-scsi.h: -------------------------------------------------------------------------------- 1 | #ifndef __ESP_SCSI_H 2 | #define __ESP_SCSI_H 3 | 4 | struct disk_op_s; 5 | int esp_scsi_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize); 6 | void esp_scsi_setup(void); 7 | 8 | #endif /* __ESP_SCSI_H */ 9 | -------------------------------------------------------------------------------- /src/hw/lsi-scsi.h: -------------------------------------------------------------------------------- 1 | #ifndef __LSI_SCSI_H 2 | #define __LSI_SCSI_H 3 | 4 | struct disk_op_s; 5 | int lsi_scsi_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize); 6 | void lsi_scsi_setup(void); 7 | 8 | #endif /* __LSI_SCSI_H */ 9 | -------------------------------------------------------------------------------- /src/hw/megasas.h: -------------------------------------------------------------------------------- 1 | #ifndef __MEGASAS_H 2 | #define __MEGASAS_H 3 | 4 | struct disk_op_s; 5 | int megasas_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize); 6 | void megasas_setup(void); 7 | 8 | #endif /* __MEGASAS_H */ 9 | -------------------------------------------------------------------------------- /src/hw/mmc.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2006 Bernd Walter. All rights reserved. 3 | * Copyright (c) 2006 M. Warner Losh. All rights reserved. 4 | * Copyright (c) 2014 Sage Electronic Engineering. All rights reserved. 5 | * 6 | * Originated from FreeBSD source file source/dev/mmc/mmc.c 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | * Portions of this software may have been developed with reference to 29 | * the SD Simplified Specification. The following disclaimer may apply: 30 | * 31 | * The following conditions apply to the release of the simplified 32 | * specification ("Simplified Specification") by the SD Card Association and 33 | * the SD Group. The Simplified Specification is a subset of the complete SD 34 | * Specification which is owned by the SD Card Association and the SD 35 | * Group. This Simplified Specification is provided on a non-confidential 36 | * basis subject to the disclaimers below. Any implementation of the 37 | * Simplified Specification may require a license from the SD Card 38 | * Association, SD Group, SD-3C LLC or other third parties. 39 | * 40 | * Disclaimers: 41 | * 42 | * The information contained in the Simplified Specification is presented only 43 | * as a standard specification for SD Cards and SD Host/Ancillary products and 44 | * is provided "AS-IS" without any representations or warranties of any 45 | * kind. No responsibility is assumed by the SD Group, SD-3C LLC or the SD 46 | * Card Association for any damages, any infringements of patents or other 47 | * right of the SD Group, SD-3C LLC, the SD Card Association or any third 48 | * parties, which may result from its use. No license is granted by 49 | * implication, estoppel or otherwise under any patent or other rights of the 50 | * SD Group, SD-3C LLC, the SD Card Association or any third party. Nothing 51 | * herein shall be construed as an obligation by the SD Group, the SD-3C LLC 52 | * or the SD Card Association to disclose or distribute any technical 53 | * information, know-how or other confidential information to any third party. 54 | */ 55 | 56 | #define MMC_SEND_OP_COND_CMD1 1 57 | #define MMC_OCR_VOLTAGE_MASK 0x00ff8080 58 | #define MMC_OCR_ACCESS_MODE 0x40000000 59 | 60 | bool mmc_send_op_cond(sdcard_t* card_p); 61 | bool mmc_send_ext_csd(sdcard_t* card_p); 62 | bool mmc_set_relative_addr(sdcard_t* card_p); 63 | 64 | -------------------------------------------------------------------------------- /src/hw/pic.c: -------------------------------------------------------------------------------- 1 | // Helpers for working with i8259 interrupt controller. 2 | // 3 | // Copyright (C) 2008 Kevin O'Connor 4 | // Copyright (C) 2002 MandrakeSoft S.A. 5 | // 6 | // This file may be distributed under the terms of the GNU LGPLv3 license. 7 | 8 | #include "biosvar.h" // SET_IVT 9 | #include "config.h" // CONFIG_* 10 | #include "output.h" // dprintf 11 | #include "pic.h" // pic_* 12 | 13 | u16 14 | pic_irqmask_read(void) 15 | { 16 | return inb(PORT_PIC1_DATA) | (inb(PORT_PIC2_DATA) << 8); 17 | } 18 | 19 | void 20 | pic_irqmask_write(u16 mask) 21 | { 22 | outb(mask, PORT_PIC1_DATA); 23 | outb(mask >> 8, PORT_PIC2_DATA); 24 | } 25 | 26 | void 27 | pic_irqmask_mask(u16 off, u16 on) 28 | { 29 | u8 pic1off = off, pic1on = on, pic2off = off>>8, pic2on = on>>8; 30 | outb((inb(PORT_PIC1_DATA) & ~pic1off) | pic1on, PORT_PIC1_DATA); 31 | outb((inb(PORT_PIC2_DATA) & ~pic2off) | pic2on, PORT_PIC2_DATA); 32 | } 33 | 34 | void 35 | pic_reset(u8 irq0, u8 irq8) 36 | { 37 | // Send ICW1 (select OCW1 + will send ICW4) 38 | outb(0x11, PORT_PIC1_CMD); 39 | outb(0x11, PORT_PIC2_CMD); 40 | // Send ICW2 (base irqs: 0x08-0x0f for irq0-7, 0x70-0x77 for irq8-15) 41 | outb(irq0, PORT_PIC1_DATA); 42 | outb(irq8, PORT_PIC2_DATA); 43 | // Send ICW3 (cascaded pic ids) 44 | outb(0x04, PORT_PIC1_DATA); 45 | outb(0x02, PORT_PIC2_DATA); 46 | // Send ICW4 (enable 8086 mode) 47 | outb(0x01, PORT_PIC1_DATA); 48 | outb(0x01, PORT_PIC2_DATA); 49 | // Mask all irqs (except cascaded PIC2 irq) 50 | pic_irqmask_write(PIC_IRQMASK_DEFAULT); 51 | } 52 | 53 | void 54 | pic_setup(void) 55 | { 56 | dprintf(3, "init pic\n"); 57 | pic_reset(BIOS_HWIRQ0_VECTOR, BIOS_HWIRQ8_VECTOR); 58 | } 59 | 60 | void 61 | enable_hwirq(int hwirq, struct segoff_s func) 62 | { 63 | pic_irqmask_mask(1 << hwirq, 0); 64 | int vector; 65 | if (hwirq < 8) 66 | vector = BIOS_HWIRQ0_VECTOR + hwirq; 67 | else 68 | vector = BIOS_HWIRQ8_VECTOR + hwirq - 8; 69 | SET_IVT(vector, func); 70 | } 71 | 72 | static u8 73 | pic_isr1_read(void) 74 | { 75 | // 0x0b == select OCW1 + read ISR 76 | outb(0x0b, PORT_PIC1_CMD); 77 | return inb(PORT_PIC1_CMD); 78 | } 79 | 80 | static u8 81 | pic_isr2_read(void) 82 | { 83 | // 0x0b == select OCW1 + read ISR 84 | outb(0x0b, PORT_PIC2_CMD); 85 | return inb(PORT_PIC2_CMD); 86 | } 87 | 88 | // Handler for otherwise unused hardware irqs. 89 | void VISIBLE16 90 | handle_hwpic1(struct bregs *regs) 91 | { 92 | dprintf(DEBUG_ISR_hwpic1, "handle_hwpic1 irq=%x\n", pic_isr1_read()); 93 | pic_eoi1(); 94 | } 95 | 96 | void VISIBLE16 97 | handle_hwpic2(struct bregs *regs) 98 | { 99 | dprintf(DEBUG_ISR_hwpic2, "handle_hwpic2 irq=%x\n", pic_isr2_read()); 100 | pic_eoi2(); 101 | } 102 | -------------------------------------------------------------------------------- /src/hw/pic.h: -------------------------------------------------------------------------------- 1 | // Helpers for working with i8259 interrupt controller. 2 | // 3 | // Copyright (C) 2008 Kevin O'Connor 4 | // Copyright (C) 2002 MandrakeSoft S.A. 5 | // 6 | // This file may be distributed under the terms of the GNU LGPLv3 license. 7 | #ifndef __PIC_H 8 | #define __PIC_H 9 | 10 | #include "x86.h" // outb 11 | 12 | #define PORT_PIC1_CMD 0x0020 13 | #define PORT_PIC1_DATA 0x0021 14 | #define PORT_PIC2_CMD 0x00a0 15 | #define PORT_PIC2_DATA 0x00a1 16 | 17 | // PORT_PIC1 bitdefs 18 | #define PIC1_IRQ0 (1<<0) 19 | #define PIC1_IRQ1 (1<<1) 20 | #define PIC1_IRQ2 (1<<2) 21 | #define PIC1_IRQ5 (1<<5) 22 | #define PIC1_IRQ6 (1<<6) 23 | // PORT_PIC2 bitdefs 24 | #define PIC2_IRQ8 (1<<8) 25 | #define PIC2_IRQ12 (1<<12) 26 | #define PIC2_IRQ13 (1<<13) 27 | #define PIC2_IRQ14 (1<<14) 28 | 29 | #define PIC_IRQMASK_DEFAULT ((u16)~PIC1_IRQ2) 30 | 31 | #define BIOS_HWIRQ0_VECTOR 0x08 32 | #define BIOS_HWIRQ8_VECTOR 0x70 33 | 34 | static inline void 35 | pic_eoi1(void) 36 | { 37 | // Send eoi (select OCW2 + eoi) 38 | outb(0x20, PORT_PIC1_CMD); 39 | } 40 | 41 | static inline void 42 | pic_eoi2(void) 43 | { 44 | // Send eoi (select OCW2 + eoi) 45 | outb(0x20, PORT_PIC2_CMD); 46 | pic_eoi1(); 47 | } 48 | 49 | u16 pic_irqmask_read(void); 50 | void pic_irqmask_write(u16 mask); 51 | void pic_irqmask_mask(u16 off, u16 on); 52 | void pic_reset(u8 irq0, u8 irq8); 53 | void pic_setup(void); 54 | void enable_hwirq(int hwirq, struct segoff_s func); 55 | 56 | #endif // pic.h 57 | -------------------------------------------------------------------------------- /src/hw/ps2port.h: -------------------------------------------------------------------------------- 1 | // Basic ps2 port (keyboard/mouse) command handling. 2 | #ifndef __PS2PORT_H 3 | #define __PS2PORT_H 4 | 5 | #include "types.h" // u8 6 | 7 | #define PORT_PS2_DATA 0x0060 8 | #define PORT_PS2_CTRLB 0x0061 9 | #define PORT_PS2_STATUS 0x0064 10 | 11 | // Standard commands. 12 | #define I8042_CMD_CTL_RCTR 0x0120 13 | #define I8042_CMD_CTL_WCTR 0x1060 14 | #define I8042_CMD_CTL_TEST 0x01aa 15 | 16 | #define I8042_CMD_KBD_TEST 0x01ab 17 | #define I8042_CMD_KBD_DISABLE 0x00ad 18 | #define I8042_CMD_KBD_ENABLE 0x00ae 19 | 20 | #define I8042_CMD_AUX_DISABLE 0x00a7 21 | #define I8042_CMD_AUX_ENABLE 0x00a8 22 | #define I8042_CMD_AUX_SEND 0x10d4 23 | 24 | // Keyboard commands 25 | #define ATKBD_CMD_SETLEDS 0x10ed 26 | #define ATKBD_CMD_SSCANSET 0x10f0 27 | #define ATKBD_CMD_GETID 0x02f2 28 | #define ATKBD_CMD_ENABLE 0x00f4 29 | #define ATKBD_CMD_RESET_DIS 0x00f5 30 | #define ATKBD_CMD_RESET_BAT 0x02ff 31 | 32 | // Mouse commands 33 | #define PSMOUSE_CMD_SETSCALE11 0x00e6 34 | #define PSMOUSE_CMD_SETSCALE21 0x00e7 35 | #define PSMOUSE_CMD_SETRES 0x10e8 36 | #define PSMOUSE_CMD_GETINFO 0x03e9 37 | #define PSMOUSE_CMD_GETID 0x02f2 38 | #define PSMOUSE_CMD_SETRATE 0x10f3 39 | #define PSMOUSE_CMD_ENABLE 0x00f4 40 | #define PSMOUSE_CMD_DISABLE 0x00f5 41 | #define PSMOUSE_CMD_RESET_BAT 0x02ff 42 | 43 | // Status register bits. 44 | #define I8042_STR_PARITY 0x80 45 | #define I8042_STR_TIMEOUT 0x40 46 | #define I8042_STR_AUXDATA 0x20 47 | #define I8042_STR_KEYLOCK 0x10 48 | #define I8042_STR_CMDDAT 0x08 49 | #define I8042_STR_MUXERR 0x04 50 | #define I8042_STR_IBF 0x02 51 | #define I8042_STR_OBF 0x01 52 | 53 | // Control register bits. 54 | #define I8042_CTR_KBDINT 0x01 55 | #define I8042_CTR_AUXINT 0x02 56 | #define I8042_CTR_IGNKEYLOCK 0x08 57 | #define I8042_CTR_KBDDIS 0x10 58 | #define I8042_CTR_AUXDIS 0x20 59 | #define I8042_CTR_XLATE 0x40 60 | 61 | // ps2port.c 62 | void i8042_reboot(void); 63 | int ps2_kbd_command(int command, u8 *param); 64 | int ps2_mouse_command(int command, u8 *param); 65 | void ps2port_setup(void); 66 | 67 | #endif // ps2port.h 68 | -------------------------------------------------------------------------------- /src/hw/pvscsi.h: -------------------------------------------------------------------------------- 1 | #ifndef _PVSCSI_H_ 2 | #define _PVSCSI_H_ 3 | 4 | struct disk_op_s; 5 | int pvscsi_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize); 6 | void pvscsi_setup(void); 7 | 8 | #endif /* _PVSCSI_H_ */ 9 | -------------------------------------------------------------------------------- /src/hw/ramdisk.c: -------------------------------------------------------------------------------- 1 | // Code for emulating a drive via high-memory accesses. 2 | // 3 | // Copyright (C) 2009 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU LGPLv3 license. 6 | 7 | #include "biosvar.h" // GET_GLOBALFLAT 8 | #include "block.h" // struct drive_s 9 | #include "bregs.h" // struct bregs 10 | #include "malloc.h" // malloc_fseg 11 | #include "memmap.h" // add_e820 12 | #include "output.h" // dprintf 13 | #include "romfile.h" // romfile_findprefix 14 | #include "stacks.h" // call16_int 15 | #include "std/disk.h" // DISK_RET_SUCCESS 16 | #include "string.h" // memset 17 | #include "util.h" // process_ramdisk_op 18 | 19 | void 20 | ramdisk_setup(void) 21 | { 22 | if (!CONFIG_FLASH_FLOPPY) 23 | return; 24 | 25 | // Find image. 26 | struct romfile_s *file = romfile_findprefix("floppyimg/", NULL); 27 | if (!file) 28 | return; 29 | const char *filename = file->name; 30 | u32 size = file->size; 31 | dprintf(3, "Found floppy file %s of size %d\n", filename, size); 32 | int ftype = find_floppy_type(size); 33 | if (ftype < 0) { 34 | dprintf(3, "No floppy type found for ramdisk size\n"); 35 | return; 36 | } 37 | 38 | // Allocate ram for image. 39 | void *pos = memalign_tmphigh(PAGE_SIZE, size); 40 | if (!pos) { 41 | warn_noalloc(); 42 | return; 43 | } 44 | add_e820((u32)pos, size, E820_RESERVED); 45 | 46 | // Copy image into ram. 47 | int ret = file->copy(file, pos, size); 48 | if (ret < 0) 49 | return; 50 | 51 | // Setup driver. 52 | struct drive_s *drive = init_floppy((u32)pos, ftype); 53 | if (!drive) 54 | return; 55 | drive->type = DTYPE_RAMDISK; 56 | dprintf(1, "Mapping CBFS floppy %s to addr %p\n", filename, pos); 57 | char *desc = znprintf(MAXDESCSIZE, "Ramdisk [%s]", &filename[10]); 58 | boot_add_floppy(drive, desc, bootprio_find_named_rom(filename, 0)); 59 | } 60 | 61 | static int 62 | ramdisk_copy(struct disk_op_s *op, int iswrite) 63 | { 64 | u32 offset = GET_GLOBALFLAT(op->drive_gf->cntl_id); 65 | offset += (u32)op->lba * DISK_SECTOR_SIZE; 66 | u64 opd = GDT_DATA | GDT_LIMIT(0xfffff) | GDT_BASE((u32)op->buf_fl); 67 | u64 ramd = GDT_DATA | GDT_LIMIT(0xfffff) | GDT_BASE(offset); 68 | 69 | u64 gdt[6]; 70 | if (iswrite) { 71 | gdt[2] = opd; 72 | gdt[3] = ramd; 73 | } else { 74 | gdt[2] = ramd; 75 | gdt[3] = opd; 76 | } 77 | 78 | // Call int 1587 to copy data. 79 | struct bregs br; 80 | memset(&br, 0, sizeof(br)); 81 | br.flags = F_CF|F_IF; 82 | br.ah = 0x87; 83 | br.es = GET_SEG(SS); 84 | br.si = (u32)gdt; 85 | br.cx = op->count * DISK_SECTOR_SIZE / 2; 86 | call16_int(0x15, &br); 87 | 88 | if (br.flags & F_CF) 89 | return DISK_RET_EBADTRACK; 90 | return DISK_RET_SUCCESS; 91 | } 92 | 93 | int 94 | process_ramdisk_op(struct disk_op_s *op) 95 | { 96 | if (!CONFIG_FLASH_FLOPPY) 97 | return 0; 98 | 99 | switch (op->command) { 100 | case CMD_READ: 101 | return ramdisk_copy(op, 0); 102 | case CMD_WRITE: 103 | return ramdisk_copy(op, 1); 104 | case CMD_VERIFY: 105 | case CMD_FORMAT: 106 | case CMD_RESET: 107 | return DISK_RET_SUCCESS; 108 | default: 109 | return DISK_RET_EPARAM; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/hw/rtc.c: -------------------------------------------------------------------------------- 1 | // Support for MC146818 Real Time Clock chip. 2 | // 3 | // Copyright (C) 2008-2013 Kevin O'Connor 4 | // Copyright (C) 2002 MandrakeSoft S.A. 5 | // 6 | // This file may be distributed under the terms of the GNU LGPLv3 license. 7 | 8 | #include "biosvar.h" // GET_LOW 9 | #include "rtc.h" // rtc_read 10 | #include "stacks.h" // yield 11 | #include "util.h" // timer_calc 12 | #include "x86.h" // inb 13 | 14 | u8 15 | rtc_read(u8 index) 16 | { 17 | index |= NMI_DISABLE_BIT; 18 | outb(index, PORT_CMOS_INDEX); 19 | return inb(PORT_CMOS_DATA); 20 | } 21 | 22 | void 23 | rtc_write(u8 index, u8 val) 24 | { 25 | index |= NMI_DISABLE_BIT; 26 | outb(index, PORT_CMOS_INDEX); 27 | outb(val, PORT_CMOS_DATA); 28 | } 29 | 30 | void 31 | rtc_mask(u8 index, u8 off, u8 on) 32 | { 33 | outb(index, PORT_CMOS_INDEX); 34 | u8 val = inb(PORT_CMOS_DATA); 35 | outb((val & ~off) | on, PORT_CMOS_DATA); 36 | } 37 | 38 | int 39 | rtc_updating(void) 40 | { 41 | // This function checks to see if the update-in-progress bit 42 | // is set in CMOS Status Register A. If not, it returns 0. 43 | // If it is set, it tries to wait until there is a transition 44 | // to 0, and will return 0 if such a transition occurs. A -1 45 | // is returned only after timing out. The maximum period 46 | // that this bit should be set is constrained to (1984+244) 47 | // useconds, but we wait for longer just to be sure. 48 | 49 | if ((rtc_read(CMOS_STATUS_A) & RTC_A_UIP) == 0) 50 | return 0; 51 | u32 end = timer_calc(15); 52 | for (;;) { 53 | if ((rtc_read(CMOS_STATUS_A) & RTC_A_UIP) == 0) 54 | return 0; 55 | if (timer_check(end)) 56 | // update-in-progress never transitioned to 0 57 | return -1; 58 | yield(); 59 | } 60 | } 61 | 62 | void 63 | rtc_setup(void) 64 | { 65 | rtc_write(CMOS_STATUS_A, 0x26); // 32,768Khz src, 976.5625us updates 66 | rtc_mask(CMOS_STATUS_B, ~RTC_B_DSE, RTC_B_24HR); 67 | rtc_read(CMOS_STATUS_C); 68 | rtc_read(CMOS_STATUS_D); 69 | } 70 | 71 | int RTCusers VARLOW; 72 | 73 | void 74 | rtc_use(void) 75 | { 76 | int count = GET_LOW(RTCusers); 77 | SET_LOW(RTCusers, count+1); 78 | if (count) 79 | return; 80 | // Turn on the Periodic Interrupt timer 81 | rtc_mask(CMOS_STATUS_B, 0, RTC_B_PIE); 82 | } 83 | 84 | void 85 | rtc_release(void) 86 | { 87 | int count = GET_LOW(RTCusers); 88 | SET_LOW(RTCusers, count-1); 89 | if (count != 1) 90 | return; 91 | // Clear the Periodic Interrupt. 92 | rtc_mask(CMOS_STATUS_B, RTC_B_PIE, 0); 93 | } 94 | -------------------------------------------------------------------------------- /src/hw/rtc.h: -------------------------------------------------------------------------------- 1 | #ifndef __RTC_H 2 | #define __RTC_H 3 | 4 | #define PORT_CMOS_INDEX 0x0070 5 | #define PORT_CMOS_DATA 0x0071 6 | 7 | // PORT_CMOS_INDEX nmi disable bit 8 | #define NMI_DISABLE_BIT 0x80 9 | 10 | // Standard BIOS RTC chip entries 11 | #define CMOS_RTC_SECONDS 0x00 12 | #define CMOS_RTC_SECONDS_ALARM 0x01 13 | #define CMOS_RTC_MINUTES 0x02 14 | #define CMOS_RTC_MINUTES_ALARM 0x03 15 | #define CMOS_RTC_HOURS 0x04 16 | #define CMOS_RTC_HOURS_ALARM 0x05 17 | #define CMOS_RTC_DAY_WEEK 0x06 18 | #define CMOS_RTC_DAY_MONTH 0x07 19 | #define CMOS_RTC_MONTH 0x08 20 | #define CMOS_RTC_YEAR 0x09 21 | #define CMOS_STATUS_A 0x0a 22 | #define CMOS_STATUS_B 0x0b 23 | #define CMOS_STATUS_C 0x0c 24 | #define CMOS_STATUS_D 0x0d 25 | #define CMOS_RESET_CODE 0x0f 26 | 27 | // QEMU cmos config fields. DO NOT ADD MORE. (All new content should 28 | // be passed via the fw_cfg "file" interface.) 29 | #define CMOS_FLOPPY_DRIVE_TYPE 0x10 30 | #define CMOS_DISK_DATA 0x12 31 | #define CMOS_EQUIPMENT_INFO 0x14 32 | #define CMOS_DISK_DRIVE1_TYPE 0x19 33 | #define CMOS_DISK_DRIVE2_TYPE 0x1a 34 | #define CMOS_DISK_DRIVE1_CYL 0x1b 35 | #define CMOS_DISK_DRIVE2_CYL 0x24 36 | #define CMOS_MEM_EXTMEM_LOW 0x30 37 | #define CMOS_MEM_EXTMEM_HIGH 0x31 38 | #define CMOS_CENTURY 0x32 39 | #define CMOS_MEM_EXTMEM2_LOW 0x34 40 | #define CMOS_MEM_EXTMEM2_HIGH 0x35 41 | #define CMOS_BIOS_BOOTFLAG1 0x38 42 | #define CMOS_BIOS_DISKTRANSFLAG 0x39 43 | #define CMOS_BIOS_BOOTFLAG2 0x3d 44 | #define CMOS_MEM_HIGHMEM_LOW 0x5b 45 | #define CMOS_MEM_HIGHMEM_MID 0x5c 46 | #define CMOS_MEM_HIGHMEM_HIGH 0x5d 47 | #define CMOS_BIOS_SMP_COUNT 0x5f 48 | 49 | // RTC register flags 50 | #define RTC_A_UIP 0x80 51 | 52 | #define RTC_B_SET 0x80 53 | #define RTC_B_PIE 0x40 54 | #define RTC_B_AIE 0x20 55 | #define RTC_B_UIE 0x10 56 | #define RTC_B_BIN 0x04 57 | #define RTC_B_24HR 0x02 58 | #define RTC_B_DSE 0x01 59 | 60 | #ifndef __ASSEMBLY__ 61 | 62 | #include "types.h" // u8 63 | 64 | // rtc.c 65 | u8 rtc_read(u8 index); 66 | void rtc_write(u8 index, u8 val); 67 | void rtc_mask(u8 index, u8 off, u8 on); 68 | int rtc_updating(void); 69 | void rtc_setup(void); 70 | void rtc_use(void); 71 | void rtc_release(void); 72 | 73 | #endif // !__ASSEMBLY__ 74 | 75 | #endif // rtc.h 76 | -------------------------------------------------------------------------------- /src/hw/sd_if.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2012 - 2014 Sage Electronic Engineering. All rights reserved. 3 | * 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | * 25 | * Portions of this software may have been developed with reference to 26 | * the SD Simplified Specification. The following disclaimer may apply: 27 | * 28 | * The following conditions apply to the release of the simplified 29 | * specification ("Simplified Specification") by the SD Card Association and 30 | * the SD Group. The Simplified Specification is a subset of the complete SD 31 | * Specification which is owned by the SD Card Association and the SD 32 | * Group. This Simplified Specification is provided on a non-confidential 33 | * basis subject to the disclaimers below. Any implementation of the 34 | * Simplified Specification may require a license from the SD Card 35 | * Association, SD Group, SD-3C LLC or other third parties. 36 | * 37 | * Disclaimers: 38 | * 39 | * The information contained in the Simplified Specification is presented only 40 | * as a standard specification for SD Cards and SD Host/Ancillary products and 41 | * is provided "AS-IS" without any representations or warranties of any 42 | * kind. No responsibility is assumed by the SD Group, SD-3C LLC or the SD 43 | * Card Association for any damages, any infringements of patents or other 44 | * right of the SD Group, SD-3C LLC, the SD Card Association or any third 45 | * parties, which may result from its use. No license is granted by 46 | * implication, estoppel or otherwise under any patent or other rights of the 47 | * SD Group, SD-3C LLC, the SD Card Association or any third party. Nothing 48 | * herein shall be construed as an obligation by the SD Group, the SD-3C LLC 49 | * or the SD Card Association to disclose or distribute any technical 50 | * information, know-how or other confidential information to any third party. 51 | */ 52 | 53 | #ifndef __SD_IF_H 54 | #define __SD_IF_H 55 | 56 | #include 57 | #include "block.h" 58 | #include "config.h" 59 | #include "pci.h" 60 | #include "sd.h" 61 | 62 | /** @file sd_if.h*/ 63 | 64 | // SeaBIOS to SD driver interface (to allow portability for reuse of SD driver 65 | typedef struct { 66 | struct drive_s drive; 67 | int32_t boot_priority; 68 | const char* desc; 69 | struct pci_device* pci_p; 70 | sdhc_t* hostctrl_p; 71 | } sdif_t; 72 | 73 | void sd_setup(void); 74 | int sd_cmd_data(struct disk_op_s *op, void *cdbcmd, uint16_t blocksize); 75 | int process_sd_op(struct disk_op_s *op); 76 | #endif // __SD_IF_H 77 | -------------------------------------------------------------------------------- /src/hw/sdhc_generic.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2012 - 2014 Sage Electronic Engineering. All rights reserved. 3 | * 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | * 25 | * Portions of this software may have been developed with reference to 26 | * the SD Simplified Specification. The following disclaimer may apply: 27 | * 28 | * The following conditions apply to the release of the simplified 29 | * specification ("Simplified Specification") by the SD Card Association and 30 | * the SD Group. The Simplified Specification is a subset of the complete SD 31 | * Specification which is owned by the SD Card Association and the SD 32 | * Group. This Simplified Specification is provided on a non-confidential 33 | * basis subject to the disclaimers below. Any implementation of the 34 | * Simplified Specification may require a license from the SD Card 35 | * Association, SD Group, SD-3C LLC or other third parties. 36 | * 37 | * Disclaimers: 38 | * 39 | * The information contained in the Simplified Specification is presented only 40 | * as a standard specification for SD Cards and SD Host/Ancillary products and 41 | * is provided "AS-IS" without any representations or warranties of any 42 | * kind. No responsibility is assumed by the SD Group, SD-3C LLC or the SD 43 | * Card Association for any damages, any infringements of patents or other 44 | * right of the SD Group, SD-3C LLC, the SD Card Association or any third 45 | * parties, which may result from its use. No license is granted by 46 | * implication, estoppel or otherwise under any patent or other rights of the 47 | * SD Group, SD-3C LLC, the SD Card Association or any third party. Nothing 48 | * herein shall be construed as an obligation by the SD Group, the SD-3C LLC 49 | * or the SD Card Association to disclose or distribute any technical 50 | * information, know-how or other confidential information to any third party. 51 | */ 52 | 53 | #ifndef __SDHC_GENERIC_H 54 | #define __SDHC_GENERIC_H 55 | 56 | /** @file sdhc_generic.h */ 57 | /* 58 | * @brief SD PCI host controller driver header file. This driver is intended 59 | * to be a generic driver for use with booting from SD cards. It 60 | * only supports the minimum controls necessary to boot. 61 | */ 62 | #include 63 | #include "block.h" 64 | #include "config.h" 65 | #include "sd.h" 66 | 67 | bool sdhc_init(sdhc_t* sd_ctrl_p); 68 | void sdhc_prep_boot(sdhc_t* sd_ctrl_p); 69 | bool sdhc_is_initialized(sdhc_t* sd_ctrl_p); 70 | bool sdhc_reset(sdhc_t* sd_ctrl_p, uint8_t reset_flags); 71 | bool sdhc_cmd(sdhc_t* sdctrl_p, sdxfer_t* xfer_p); 72 | 73 | #endif /* __SDHC_GENERIC_H */ 74 | -------------------------------------------------------------------------------- /src/hw/serialio.c: -------------------------------------------------------------------------------- 1 | // Low-level serial (and serial-like) device access. 2 | // 3 | // Copyright (C) 2008-1013 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU LGPLv3 license. 6 | 7 | #include "config.h" // CONFIG_DEBUG_SERIAL 8 | #include "fw/paravirt.h" // RunningOnQEMU 9 | #include "output.h" // dprintf 10 | #include "serialio.h" // serial_debug_preinit 11 | #include "x86.h" // outb 12 | 13 | 14 | /**************************************************************** 15 | * Serial port debug output 16 | ****************************************************************/ 17 | 18 | #define DEBUG_TIMEOUT 100000 19 | 20 | // Setup the debug serial port for output. 21 | void 22 | serial_debug_preinit(void) 23 | { 24 | if (!CONFIG_DEBUG_SERIAL) 25 | return; 26 | // setup for serial logging: 8N1 27 | u8 oldparam, newparam = 0x03; 28 | oldparam = inb(CONFIG_DEBUG_SERIAL_PORT+SEROFF_LCR); 29 | outb(newparam, CONFIG_DEBUG_SERIAL_PORT+SEROFF_LCR); 30 | // Disable irqs 31 | u8 oldier, newier = 0; 32 | oldier = inb(CONFIG_DEBUG_SERIAL_PORT+SEROFF_IER); 33 | outb(newier, CONFIG_DEBUG_SERIAL_PORT+SEROFF_IER); 34 | 35 | if (oldparam != newparam || oldier != newier) 36 | dprintf(1, "Changing serial settings was %x/%x now %x/%x\n" 37 | , oldparam, oldier, newparam, newier); 38 | } 39 | 40 | // Write a character to the serial port. 41 | static void 42 | serial_debug(char c) 43 | { 44 | if (!CONFIG_DEBUG_SERIAL) 45 | return; 46 | int timeout = DEBUG_TIMEOUT; 47 | while ((inb(CONFIG_DEBUG_SERIAL_PORT+SEROFF_LSR) & 0x20) != 0x20) 48 | if (!timeout--) 49 | // Ran out of time. 50 | return; 51 | outb(c, CONFIG_DEBUG_SERIAL_PORT+SEROFF_DATA); 52 | } 53 | 54 | void 55 | serial_debug_putc(char c) 56 | { 57 | if (c == '\n') 58 | serial_debug('\r'); 59 | serial_debug(c); 60 | } 61 | 62 | // Make sure all serial port writes have been completely sent. 63 | void 64 | serial_debug_flush(void) 65 | { 66 | if (!CONFIG_DEBUG_SERIAL) 67 | return; 68 | int timeout = DEBUG_TIMEOUT; 69 | while ((inb(CONFIG_DEBUG_SERIAL_PORT+SEROFF_LSR) & 0x60) != 0x60) 70 | if (!timeout--) 71 | // Ran out of time. 72 | return; 73 | } 74 | 75 | 76 | /**************************************************************** 77 | * QEMU debug port 78 | ****************************************************************/ 79 | 80 | u16 DebugOutputPort VARFSEG = 0x402; 81 | 82 | // Write a character to the special debugging port. 83 | void 84 | qemu_debug_putc(char c) 85 | { 86 | if (CONFIG_DEBUG_IO && runningOnQEMU()) 87 | // Send character to debug port. 88 | outb(c, GET_GLOBAL(DebugOutputPort)); 89 | } 90 | -------------------------------------------------------------------------------- /src/hw/serialio.h: -------------------------------------------------------------------------------- 1 | #ifndef __SERIALIO_H 2 | #define __SERIALIO_H 3 | 4 | #include "types.h" // u16 5 | 6 | #define PORT_LPT2 0x0278 7 | #define PORT_SERIAL4 0x02e8 8 | #define PORT_SERIAL2 0x02f8 9 | #define PORT_LPT1 0x0378 10 | #define PORT_SERIAL3 0x03e8 11 | #define PORT_SERIAL1 0x03f8 12 | 13 | // Serial port offsets 14 | #define SEROFF_DATA 0 15 | #define SEROFF_DLL 0 16 | #define SEROFF_IER 1 17 | #define SEROFF_DLH 1 18 | #define SEROFF_IIR 2 19 | #define SEROFF_LCR 3 20 | #define SEROFF_LSR 5 21 | #define SEROFF_MSR 6 22 | 23 | void serial_debug_preinit(void); 24 | void serial_debug_putc(char c); 25 | void serial_debug_flush(void); 26 | extern u16 DebugOutputPort; 27 | void qemu_debug_putc(char c); 28 | 29 | #endif // serialio.h 30 | -------------------------------------------------------------------------------- /src/hw/usb-hid.h: -------------------------------------------------------------------------------- 1 | #ifndef __USB_HID_H 2 | #define __USB_HID_H 3 | 4 | // usb-hid.c 5 | struct usbdevice_s; 6 | int usb_hid_setup(struct usbdevice_s *usbdev); 7 | inline int usb_kbd_active(void); 8 | inline int usb_kbd_command(int command, u8 *param); 9 | inline int usb_mouse_active(void); 10 | inline int usb_mouse_command(int command, u8 *param); 11 | void usb_check_event(void); 12 | 13 | 14 | /**************************************************************** 15 | * hid flags 16 | ****************************************************************/ 17 | 18 | #define USB_INTERFACE_SUBCLASS_BOOT 1 19 | #define USB_INTERFACE_PROTOCOL_KEYBOARD 1 20 | #define USB_INTERFACE_PROTOCOL_MOUSE 2 21 | 22 | #define HID_REQ_GET_REPORT 0x01 23 | #define HID_REQ_GET_IDLE 0x02 24 | #define HID_REQ_GET_PROTOCOL 0x03 25 | #define HID_REQ_SET_REPORT 0x09 26 | #define HID_REQ_SET_IDLE 0x0A 27 | #define HID_REQ_SET_PROTOCOL 0x0B 28 | 29 | #endif // ush-hid.h 30 | -------------------------------------------------------------------------------- /src/hw/usb-hub.h: -------------------------------------------------------------------------------- 1 | #ifndef __USB_HUB_H 2 | #define __USB_HUB_H 3 | 4 | // usb-hub.c 5 | struct usbdevice_s; 6 | int usb_hub_setup(struct usbdevice_s *usbdev); 7 | 8 | 9 | /**************************************************************** 10 | * hub flags 11 | ****************************************************************/ 12 | 13 | #define USB_DT_HUB (USB_TYPE_CLASS | 0x09) 14 | 15 | struct usb_hub_descriptor { 16 | u8 bDescLength; 17 | u8 bDescriptorType; 18 | u8 bNbrPorts; 19 | u16 wHubCharacteristics; 20 | u8 bPwrOn2PwrGood; 21 | u8 bHubContrCurrent; 22 | // Variable length fields for DeviceRemovable[], PortPwrCtrlMask[] follow. 23 | } PACKED; 24 | 25 | #define USB_PORT_FEAT_CONNECTION 0 26 | #define USB_PORT_FEAT_ENABLE 1 27 | #define USB_PORT_FEAT_SUSPEND 2 28 | #define USB_PORT_FEAT_OVER_CURRENT 3 29 | #define USB_PORT_FEAT_RESET 4 30 | #define USB_PORT_FEAT_POWER 8 31 | #define USB_PORT_FEAT_LOWSPEED 9 32 | #define USB_PORT_FEAT_C_CONNECTION 16 33 | #define USB_PORT_FEAT_C_ENABLE 17 34 | #define USB_PORT_FEAT_C_SUSPEND 18 35 | #define USB_PORT_FEAT_C_OVER_CURRENT 19 36 | #define USB_PORT_FEAT_C_RESET 20 37 | #define USB_PORT_FEAT_TEST 21 38 | #define USB_PORT_FEAT_INDICATOR 22 39 | #define USB_PORT_FEAT_C_PORT_L1 23 40 | 41 | struct usb_port_status { 42 | u16 wPortStatus; 43 | u16 wPortChange; 44 | } PACKED; 45 | 46 | #define USB_PORT_STAT_CONNECTION 0x0001 47 | #define USB_PORT_STAT_ENABLE 0x0002 48 | #define USB_PORT_STAT_SUSPEND 0x0004 49 | #define USB_PORT_STAT_OVERCURRENT 0x0008 50 | #define USB_PORT_STAT_RESET 0x0010 51 | #define USB_PORT_STAT_L1 0x0020 52 | #define USB_PORT_STAT_POWER 0x0100 53 | #define USB_PORT_STAT_SPEED_SHIFT 9 54 | #define USB_PORT_STAT_SPEED_MASK (0x3 << USB_PORT_STAT_SPEED_SHIFT) 55 | #define USB_PORT_STAT_LOW_SPEED 0x0200 56 | #define USB_PORT_STAT_HIGH_SPEED 0x0400 57 | #define USB_PORT_STAT_TEST 0x0800 58 | #define USB_PORT_STAT_INDICATOR 0x1000 59 | 60 | #endif // ush-hid.h 61 | -------------------------------------------------------------------------------- /src/hw/usb-msc.h: -------------------------------------------------------------------------------- 1 | #ifndef __USB_MSC_H 2 | #define __USB_MSC_H 3 | 4 | // usb-msc.c 5 | struct disk_op_s; 6 | int usb_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize); 7 | struct usbdevice_s; 8 | int usb_msc_setup(struct usbdevice_s *usbdev); 9 | 10 | #endif // ush-msc.h 11 | -------------------------------------------------------------------------------- /src/hw/usb-ohci.h: -------------------------------------------------------------------------------- 1 | #ifndef __USB_OHCI_H 2 | #define __USB_OHCI_H 3 | 4 | // usb-ohci.c 5 | void ohci_setup(void); 6 | struct usbdevice_s; 7 | struct usb_endpoint_descriptor; 8 | struct usb_pipe; 9 | struct usb_pipe *ohci_realloc_pipe(struct usbdevice_s *usbdev 10 | , struct usb_pipe *upipe 11 | , struct usb_endpoint_descriptor *epdesc); 12 | int ohci_send_control(struct usb_pipe *p, int dir, const void *cmd, int cmdsize 13 | , void *data, int datasize); 14 | int ohci_send_bulk(struct usb_pipe *p, int dir, void *data, int datasize); 15 | int ohci_poll_intr(struct usb_pipe *p, void *data); 16 | 17 | 18 | /**************************************************************** 19 | * ohci structs and flags 20 | ****************************************************************/ 21 | 22 | struct ohci_ed { 23 | u32 hwINFO; 24 | u32 hwTailP; 25 | u32 hwHeadP; 26 | u32 hwNextED; 27 | } PACKED; 28 | 29 | #define ED_ISO (1 << 15) 30 | #define ED_SKIP (1 << 14) 31 | #define ED_LOWSPEED (1 << 13) 32 | #define ED_OUT (0x01 << 11) 33 | #define ED_IN (0x02 << 11) 34 | 35 | #define ED_C (0x02) 36 | #define ED_H (0x01) 37 | 38 | struct ohci_td { 39 | u32 hwINFO; 40 | u32 hwCBP; 41 | u32 hwNextTD; 42 | u32 hwBE; 43 | } PACKED; 44 | 45 | #define TD_CC 0xf0000000 46 | #define TD_CC_GET(td_p) ((td_p >>28) & 0x0f) 47 | #define TD_DI 0x00E00000 48 | 49 | #define TD_DONE 0x00020000 50 | #define TD_ISO 0x00010000 51 | 52 | #define TD_EC 0x0C000000 53 | #define TD_T 0x03000000 54 | #define TD_T_DATA0 0x02000000 55 | #define TD_T_DATA1 0x03000000 56 | #define TD_T_TOGGLE 0x00000000 57 | #define TD_DP 0x00180000 58 | #define TD_DP_SETUP 0x00000000 59 | #define TD_DP_IN 0x00100000 60 | #define TD_DP_OUT 0x00080000 61 | 62 | #define TD_R 0x00040000 63 | 64 | struct ohci_hcca { 65 | u32 int_table[32]; 66 | u32 frame_no; 67 | u32 done_head; 68 | u8 reserved[120]; 69 | } PACKED; 70 | 71 | struct ohci_regs { 72 | u32 revision; 73 | u32 control; 74 | u32 cmdstatus; 75 | u32 intrstatus; 76 | u32 intrenable; 77 | u32 intrdisable; 78 | 79 | u32 hcca; 80 | u32 ed_periodcurrent; 81 | u32 ed_controlhead; 82 | u32 ed_controlcurrent; 83 | u32 ed_bulkhead; 84 | u32 ed_bulkcurrent; 85 | u32 donehead; 86 | 87 | u32 fminterval; 88 | u32 fmremaining; 89 | u32 fmnumber; 90 | u32 periodicstart; 91 | u32 lsthresh; 92 | 93 | u32 roothub_a; 94 | u32 roothub_b; 95 | u32 roothub_status; 96 | u32 roothub_portstatus[15]; 97 | } PACKED; 98 | 99 | #define OHCI_CTRL_CBSR (3 << 0) 100 | #define OHCI_CTRL_PLE (1 << 2) 101 | #define OHCI_CTRL_CLE (1 << 4) 102 | #define OHCI_CTRL_BLE (1 << 5) 103 | #define OHCI_CTRL_HCFS (3 << 6) 104 | # define OHCI_USB_RESET (0 << 6) 105 | # define OHCI_USB_OPER (2 << 6) 106 | #define OHCI_CTRL_RWC (1 << 9) 107 | 108 | #define OHCI_HCR (1 << 0) 109 | #define OHCI_CLF (1 << 1) 110 | 111 | #define OHCI_INTR_MIE (1 << 31) 112 | 113 | #define RH_PS_CCS 0x00000001 114 | #define RH_PS_PES 0x00000002 115 | #define RH_PS_PSS 0x00000004 116 | #define RH_PS_POCI 0x00000008 117 | #define RH_PS_PRS 0x00000010 118 | #define RH_PS_PPS 0x00000100 119 | #define RH_PS_LSDA 0x00000200 120 | #define RH_PS_CSC 0x00010000 121 | #define RH_PS_PESC 0x00020000 122 | #define RH_PS_PSSC 0x00040000 123 | #define RH_PS_OCIC 0x00080000 124 | #define RH_PS_PRSC 0x00100000 125 | 126 | #define RH_HS_LPS 0x00000001 127 | #define RH_HS_OCI 0x00000002 128 | #define RH_HS_DRWE 0x00008000 129 | #define RH_HS_LPSC 0x00010000 130 | #define RH_HS_OCIC 0x00020000 131 | #define RH_HS_CRWE 0x80000000 132 | 133 | #define RH_B_DR 0x0000ffff 134 | #define RH_B_PPCM 0xffff0000 135 | 136 | #define RH_A_NDP (0xff << 0) 137 | #define RH_A_PSM (1 << 8) 138 | #define RH_A_NPS (1 << 9) 139 | #define RH_A_DT (1 << 10) 140 | #define RH_A_OCPM (1 << 11) 141 | #define RH_A_NOCP (1 << 12) 142 | #define RH_A_POTPGT (0xff << 24) 143 | 144 | #endif // usb-ohci.h 145 | -------------------------------------------------------------------------------- /src/hw/usb-uas.h: -------------------------------------------------------------------------------- 1 | #ifndef __USB_UAS_H 2 | #define __USB_UAS_H 3 | 4 | struct disk_op_s; 5 | int uas_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize); 6 | struct usbdevice_s; 7 | int usb_uas_setup(struct usbdevice_s *usbdev); 8 | 9 | #endif /* __USB_UAS_H */ 10 | -------------------------------------------------------------------------------- /src/hw/usb-xhci.h: -------------------------------------------------------------------------------- 1 | #ifndef __USB_XHCI_H 2 | #define __USB_XHCI_H 3 | 4 | struct usbdevice_s; 5 | struct usb_endpoint_descriptor; 6 | struct usb_pipe; 7 | 8 | // -------------------------------------------------------------- 9 | 10 | // usb-xhci.c 11 | void xhci_setup(void); 12 | struct usb_pipe *xhci_realloc_pipe(struct usbdevice_s *usbdev 13 | , struct usb_pipe *upipe 14 | , struct usb_endpoint_descriptor *epdesc); 15 | int xhci_send_control(struct usb_pipe *p, int dir, const void *cmd, int cmdsize 16 | , void *data, int datasize); 17 | int xhci_send_bulk(struct usb_pipe *p, int dir, void *data, int datasize); 18 | int xhci_poll_intr(struct usb_pipe *p, void *data); 19 | 20 | // -------------------------------------------------------------- 21 | // register interface 22 | 23 | // capabilities 24 | struct xhci_caps { 25 | u8 caplength; 26 | u8 reserved_01; 27 | u16 hciversion; 28 | u32 hcsparams1; 29 | u32 hcsparams2; 30 | u32 hcsparams3; 31 | u32 hccparams; 32 | u32 dboff; 33 | u32 rtsoff; 34 | } PACKED; 35 | 36 | // extended capabilities 37 | struct xhci_xcap { 38 | u32 cap; 39 | u32 data[]; 40 | } PACKED; 41 | 42 | // operational registers 43 | struct xhci_op { 44 | u32 usbcmd; 45 | u32 usbsts; 46 | u32 pagesize; 47 | u32 reserved_01[2]; 48 | u32 dnctl; 49 | u32 crcr_low; 50 | u32 crcr_high; 51 | u32 reserved_02[4]; 52 | u32 dcbaap_low; 53 | u32 dcbaap_high; 54 | u32 config; 55 | } PACKED; 56 | 57 | // port registers 58 | struct xhci_pr { 59 | u32 portsc; 60 | u32 portpmsc; 61 | u32 portli; 62 | u32 reserved_01; 63 | } PACKED; 64 | 65 | // doorbell registers 66 | struct xhci_db { 67 | u32 doorbell; 68 | } PACKED; 69 | 70 | // runtime registers 71 | struct xhci_rts { 72 | u32 mfindex; 73 | } PACKED; 74 | 75 | // interrupter registers 76 | struct xhci_ir { 77 | u32 iman; 78 | u32 imod; 79 | u32 erstsz; 80 | u32 reserved_01; 81 | u32 erstba_low; 82 | u32 erstba_high; 83 | u32 erdp_low; 84 | u32 erdp_high; 85 | } PACKED; 86 | 87 | // -------------------------------------------------------------- 88 | // memory data structs 89 | 90 | // slot context 91 | struct xhci_slotctx { 92 | u32 ctx[4]; 93 | u32 reserved_01[4]; 94 | } PACKED; 95 | 96 | // endpoint context 97 | struct xhci_epctx { 98 | u32 ctx[2]; 99 | u32 deq_low; 100 | u32 deq_high; 101 | u32 length; 102 | u32 reserved_01[3]; 103 | } PACKED; 104 | 105 | // device context array element 106 | struct xhci_devlist { 107 | u32 ptr_low; 108 | u32 ptr_high; 109 | } PACKED; 110 | 111 | // input context 112 | struct xhci_inctx { 113 | u32 del; 114 | u32 add; 115 | u32 reserved_01[6]; 116 | } PACKED; 117 | 118 | // transfer block (ring element) 119 | struct xhci_trb { 120 | u32 ptr_low; 121 | u32 ptr_high; 122 | u32 status; 123 | u32 control; 124 | } PACKED; 125 | 126 | // event ring segment 127 | struct xhci_er_seg { 128 | u32 ptr_low; 129 | u32 ptr_high; 130 | u32 size; 131 | u32 reserved_01; 132 | } PACKED; 133 | 134 | #endif // usb-xhci.h 135 | -------------------------------------------------------------------------------- /src/hw/virtio-blk.h: -------------------------------------------------------------------------------- 1 | #ifndef _VIRTIO_BLK_H 2 | #define _VIRTIO_BLK_H 3 | 4 | struct virtio_blk_config 5 | { 6 | u64 capacity; 7 | u32 size_max; 8 | u32 seg_max; 9 | u16 cylinders; 10 | u8 heads; 11 | u8 sectors; 12 | u32 blk_size; 13 | u8 physical_block_exp; 14 | u8 alignment_offset; 15 | u16 min_io_size; 16 | u32 opt_io_size; 17 | } __attribute__((packed)); 18 | 19 | #define VIRTIO_BLK_F_BLK_SIZE 6 20 | 21 | /* These two define direction. */ 22 | #define VIRTIO_BLK_T_IN 0 23 | #define VIRTIO_BLK_T_OUT 1 24 | 25 | /* This is the first element of the read scatter-gather list. */ 26 | struct virtio_blk_outhdr { 27 | /* VIRTIO_BLK_T* */ 28 | u32 type; 29 | /* io priority. */ 30 | u32 ioprio; 31 | /* Sector (ie. 512 byte offset) */ 32 | u64 sector; 33 | }; 34 | 35 | #define VIRTIO_BLK_S_OK 0 36 | #define VIRTIO_BLK_S_IOERR 1 37 | #define VIRTIO_BLK_S_UNSUPP 2 38 | 39 | struct disk_op_s; 40 | int process_virtio_blk_op(struct disk_op_s *op); 41 | void virtio_blk_setup(void); 42 | 43 | #endif /* _VIRTIO_BLK_H */ 44 | -------------------------------------------------------------------------------- /src/hw/virtio-pci.c: -------------------------------------------------------------------------------- 1 | /* virtio-pci.c - pci interface for virtio interface 2 | * 3 | * (c) Copyright 2008 Bull S.A.S. 4 | * 5 | * Author: Laurent Vivier 6 | * 7 | * some parts from Linux Virtio PCI driver 8 | * 9 | * Copyright IBM Corp. 2007 10 | * Authors: Anthony Liguori 11 | * 12 | * Adopted for Seabios: Gleb Natapov 13 | * 14 | * This work is licensed under the terms of the GNU LGPLv3 15 | * See the COPYING file in the top-level directory. 16 | */ 17 | 18 | #include "config.h" // CONFIG_DEBUG_LEVEL 19 | #include "malloc.h" // free 20 | #include "output.h" // dprintf 21 | #include "pci.h" // pci_config_readl 22 | #include "pci_regs.h" // PCI_BASE_ADDRESS_0 23 | #include "string.h" // memset 24 | #include "virtio-pci.h" 25 | #include "virtio-ring.h" 26 | 27 | int vp_find_vq(unsigned int ioaddr, int queue_index, 28 | struct vring_virtqueue **p_vq) 29 | { 30 | u16 num; 31 | 32 | ASSERT32FLAT(); 33 | struct vring_virtqueue *vq = *p_vq = memalign_low(PAGE_SIZE, sizeof(*vq)); 34 | if (!vq) { 35 | warn_noalloc(); 36 | goto fail; 37 | } 38 | memset(vq, 0, sizeof(*vq)); 39 | 40 | /* select the queue */ 41 | 42 | outw(queue_index, ioaddr + VIRTIO_PCI_QUEUE_SEL); 43 | 44 | /* check if the queue is available */ 45 | 46 | num = inw(ioaddr + VIRTIO_PCI_QUEUE_NUM); 47 | if (!num) { 48 | dprintf(1, "ERROR: queue size is 0\n"); 49 | goto fail; 50 | } 51 | 52 | if (num > MAX_QUEUE_NUM) { 53 | dprintf(1, "ERROR: queue size %d > %d\n", num, MAX_QUEUE_NUM); 54 | goto fail; 55 | } 56 | 57 | /* check if the queue is already active */ 58 | 59 | if (inl(ioaddr + VIRTIO_PCI_QUEUE_PFN)) { 60 | dprintf(1, "ERROR: queue already active\n"); 61 | goto fail; 62 | } 63 | 64 | vq->queue_index = queue_index; 65 | 66 | /* initialize the queue */ 67 | 68 | struct vring * vr = &vq->vring; 69 | vring_init(vr, num, (unsigned char*)&vq->queue); 70 | 71 | /* activate the queue 72 | * 73 | * NOTE: vr->desc is initialized by vring_init() 74 | */ 75 | 76 | outl((unsigned long)virt_to_phys(vr->desc) >> PAGE_SHIFT, 77 | ioaddr + VIRTIO_PCI_QUEUE_PFN); 78 | 79 | return num; 80 | 81 | fail: 82 | free(vq); 83 | *p_vq = NULL; 84 | return -1; 85 | } 86 | 87 | u16 vp_init_simple(u16 bdf) 88 | { 89 | u16 ioaddr = pci_config_readl(bdf, PCI_BASE_ADDRESS_0) & 90 | PCI_BASE_ADDRESS_IO_MASK; 91 | 92 | vp_reset(ioaddr); 93 | pci_config_maskw(bdf, PCI_COMMAND, 0, PCI_COMMAND_MASTER); 94 | vp_set_status(ioaddr, VIRTIO_CONFIG_S_ACKNOWLEDGE | 95 | VIRTIO_CONFIG_S_DRIVER ); 96 | return ioaddr; 97 | } 98 | -------------------------------------------------------------------------------- /src/hw/virtio-pci.h: -------------------------------------------------------------------------------- 1 | #ifndef _VIRTIO_PCI_H 2 | #define _VIRTIO_PCI_H 3 | 4 | #include "x86.h" // inl 5 | 6 | /* A 32-bit r/o bitmask of the features supported by the host */ 7 | #define VIRTIO_PCI_HOST_FEATURES 0 8 | 9 | /* A 32-bit r/w bitmask of features activated by the guest */ 10 | #define VIRTIO_PCI_GUEST_FEATURES 4 11 | 12 | /* A 32-bit r/w PFN for the currently selected queue */ 13 | #define VIRTIO_PCI_QUEUE_PFN 8 14 | 15 | /* A 16-bit r/o queue size for the currently selected queue */ 16 | #define VIRTIO_PCI_QUEUE_NUM 12 17 | 18 | /* A 16-bit r/w queue selector */ 19 | #define VIRTIO_PCI_QUEUE_SEL 14 20 | 21 | /* A 16-bit r/w queue notifier */ 22 | #define VIRTIO_PCI_QUEUE_NOTIFY 16 23 | 24 | /* An 8-bit device status register. */ 25 | #define VIRTIO_PCI_STATUS 18 26 | 27 | /* An 8-bit r/o interrupt status register. Reading the value will return the 28 | * current contents of the ISR and will also clear it. This is effectively 29 | * a read-and-acknowledge. */ 30 | #define VIRTIO_PCI_ISR 19 31 | 32 | /* The bit of the ISR which indicates a device configuration change. */ 33 | #define VIRTIO_PCI_ISR_CONFIG 0x2 34 | 35 | /* The remaining space is defined by each driver as the per-driver 36 | * configuration space */ 37 | #define VIRTIO_PCI_CONFIG 20 38 | 39 | /* Virtio ABI version, this must match exactly */ 40 | #define VIRTIO_PCI_ABI_VERSION 0 41 | 42 | static inline u32 vp_get_features(unsigned int ioaddr) 43 | { 44 | return inl(ioaddr + VIRTIO_PCI_HOST_FEATURES); 45 | } 46 | 47 | static inline void vp_set_features(unsigned int ioaddr, u32 features) 48 | { 49 | outl(features, ioaddr + VIRTIO_PCI_GUEST_FEATURES); 50 | } 51 | 52 | static inline void vp_get(unsigned int ioaddr, unsigned offset, 53 | void *buf, unsigned len) 54 | { 55 | u8 *ptr = buf; 56 | unsigned i; 57 | 58 | for (i = 0; i < len; i++) 59 | ptr[i] = inb(ioaddr + VIRTIO_PCI_CONFIG + offset + i); 60 | } 61 | 62 | static inline u8 vp_get_status(unsigned int ioaddr) 63 | { 64 | return inb(ioaddr + VIRTIO_PCI_STATUS); 65 | } 66 | 67 | static inline void vp_set_status(unsigned int ioaddr, u8 status) 68 | { 69 | if (status == 0) /* reset */ 70 | return; 71 | outb(status, ioaddr + VIRTIO_PCI_STATUS); 72 | } 73 | 74 | static inline u8 vp_get_isr(unsigned int ioaddr) 75 | { 76 | return inb(ioaddr + VIRTIO_PCI_ISR); 77 | } 78 | 79 | static inline void vp_reset(unsigned int ioaddr) 80 | { 81 | outb(0, ioaddr + VIRTIO_PCI_STATUS); 82 | (void)inb(ioaddr + VIRTIO_PCI_ISR); 83 | } 84 | 85 | static inline void vp_notify(unsigned int ioaddr, int queue_index) 86 | { 87 | outw(queue_index, ioaddr + VIRTIO_PCI_QUEUE_NOTIFY); 88 | } 89 | 90 | static inline void vp_del_vq(unsigned int ioaddr, int queue_index) 91 | { 92 | /* select the queue */ 93 | 94 | outw(queue_index, ioaddr + VIRTIO_PCI_QUEUE_SEL); 95 | 96 | /* deactivate the queue */ 97 | 98 | outl(0, ioaddr + VIRTIO_PCI_QUEUE_PFN); 99 | } 100 | 101 | struct vring_virtqueue; 102 | u16 vp_init_simple(u16 bdf); 103 | int vp_find_vq(unsigned int ioaddr, int queue_index, 104 | struct vring_virtqueue **p_vq); 105 | #endif /* _VIRTIO_PCI_H_ */ 106 | -------------------------------------------------------------------------------- /src/hw/virtio-ring.h: -------------------------------------------------------------------------------- 1 | #ifndef _VIRTIO_RING_H 2 | #define _VIRTIO_RING_H 3 | 4 | #include "types.h" // u64 5 | #include "memmap.h" // PAGE_SIZE 6 | 7 | #define PAGE_SHIFT 12 8 | #define PAGE_MASK (PAGE_SIZE-1) 9 | 10 | #define virt_to_phys(v) (unsigned long)(v) 11 | #define phys_to_virt(p) (void*)(p) 12 | /* Compiler barrier is enough as an x86 CPU does not reorder reads or writes */ 13 | #define smp_rmb() barrier() 14 | #define smp_wmb() barrier() 15 | 16 | /* Status byte for guest to report progress, and synchronize features. */ 17 | /* We have seen device and processed generic fields (VIRTIO_CONFIG_F_VIRTIO) */ 18 | #define VIRTIO_CONFIG_S_ACKNOWLEDGE 1 19 | /* We have found a driver for the device. */ 20 | #define VIRTIO_CONFIG_S_DRIVER 2 21 | /* Driver has used its parts of the config, and is happy */ 22 | #define VIRTIO_CONFIG_S_DRIVER_OK 4 23 | /* We've given up on this device. */ 24 | #define VIRTIO_CONFIG_S_FAILED 0x80 25 | 26 | #define MAX_QUEUE_NUM (128) 27 | 28 | #define VRING_DESC_F_NEXT 1 29 | #define VRING_DESC_F_WRITE 2 30 | 31 | #define VRING_AVAIL_F_NO_INTERRUPT 1 32 | 33 | #define VRING_USED_F_NO_NOTIFY 1 34 | 35 | struct vring_desc 36 | { 37 | u64 addr; 38 | u32 len; 39 | u16 flags; 40 | u16 next; 41 | }; 42 | 43 | struct vring_avail 44 | { 45 | u16 flags; 46 | u16 idx; 47 | u16 ring[0]; 48 | }; 49 | 50 | struct vring_used_elem 51 | { 52 | u32 id; 53 | u32 len; 54 | }; 55 | 56 | struct vring_used 57 | { 58 | u16 flags; 59 | u16 idx; 60 | struct vring_used_elem ring[]; 61 | }; 62 | 63 | struct vring { 64 | unsigned int num; 65 | struct vring_desc *desc; 66 | struct vring_avail *avail; 67 | struct vring_used *used; 68 | }; 69 | 70 | #define vring_size(num) \ 71 | (((((sizeof(struct vring_desc) * num) + \ 72 | (sizeof(struct vring_avail) + sizeof(u16) * num)) \ 73 | + PAGE_MASK) & ~PAGE_MASK) + \ 74 | (sizeof(struct vring_used) + sizeof(struct vring_used_elem) * num)) 75 | 76 | typedef unsigned char virtio_queue_t[vring_size(MAX_QUEUE_NUM)]; 77 | 78 | struct vring_virtqueue { 79 | virtio_queue_t queue; 80 | struct vring vring; 81 | u16 free_head; 82 | u16 last_used_idx; 83 | u16 vdata[MAX_QUEUE_NUM]; 84 | /* PCI */ 85 | int queue_index; 86 | }; 87 | 88 | struct vring_list { 89 | char *addr; 90 | unsigned int length; 91 | }; 92 | 93 | static inline void vring_init(struct vring *vr, 94 | unsigned int num, unsigned char *queue) 95 | { 96 | unsigned int i; 97 | unsigned long pa; 98 | 99 | ASSERT32FLAT(); 100 | vr->num = num; 101 | 102 | /* physical address of desc must be page aligned */ 103 | 104 | pa = virt_to_phys(queue); 105 | pa = (pa + PAGE_MASK) & ~PAGE_MASK; 106 | vr->desc = phys_to_virt(pa); 107 | 108 | vr->avail = (struct vring_avail *)&vr->desc[num]; 109 | /* disable interrupts */ 110 | vr->avail->flags |= VRING_AVAIL_F_NO_INTERRUPT; 111 | 112 | /* physical address of used must be page aligned */ 113 | 114 | pa = virt_to_phys(&vr->avail->ring[num]); 115 | pa = (pa + PAGE_MASK) & ~PAGE_MASK; 116 | vr->used = phys_to_virt(pa); 117 | 118 | for (i = 0; i < num - 1; i++) 119 | vr->desc[i].next = i + 1; 120 | vr->desc[i].next = 0; 121 | } 122 | 123 | int vring_more_used(struct vring_virtqueue *vq); 124 | void vring_detach(struct vring_virtqueue *vq, unsigned int head); 125 | int vring_get_buf(struct vring_virtqueue *vq, unsigned int *len); 126 | void vring_add_buf(struct vring_virtqueue *vq, struct vring_list list[], 127 | unsigned int out, unsigned int in, 128 | int index, int num_added); 129 | void vring_kick(unsigned int ioaddr, struct vring_virtqueue *vq, int num_added); 130 | 131 | #endif /* _VIRTIO_RING_H_ */ 132 | -------------------------------------------------------------------------------- /src/hw/virtio-scsi.h: -------------------------------------------------------------------------------- 1 | #ifndef _VIRTIO_SCSI_H 2 | #define _VIRTIO_SCSI_H 3 | 4 | #define VIRTIO_SCSI_CDB_SIZE 32 5 | #define VIRTIO_SCSI_SENSE_SIZE 96 6 | 7 | struct virtio_scsi_config 8 | { 9 | u32 num_queues; 10 | u32 seg_max; 11 | u32 max_sectors; 12 | u32 cmd_per_lun; 13 | u32 event_info_size; 14 | u32 sense_size; 15 | u32 cdb_size; 16 | u16 max_channel; 17 | u16 max_target; 18 | u32 max_lun; 19 | } __attribute__((packed)); 20 | 21 | /* This is the first element of the "out" scatter-gather list. */ 22 | struct virtio_scsi_req_cmd { 23 | u8 lun[8]; 24 | u64 id; 25 | u8 task_attr; 26 | u8 prio; 27 | u8 crn; 28 | char cdb[VIRTIO_SCSI_CDB_SIZE]; 29 | } __attribute__((packed)); 30 | 31 | /* This is the first element of the "in" scatter-gather list. */ 32 | struct virtio_scsi_resp_cmd { 33 | u32 sense_len; 34 | u32 residual; 35 | u16 status_qualifier; 36 | u8 status; 37 | u8 response; 38 | u8 sense[VIRTIO_SCSI_SENSE_SIZE]; 39 | } __attribute__((packed)); 40 | 41 | #define VIRTIO_SCSI_S_OK 0 42 | 43 | struct disk_op_s; 44 | int virtio_scsi_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize); 45 | void virtio_scsi_setup(void); 46 | 47 | #endif /* _VIRTIO_SCSI_H */ 48 | -------------------------------------------------------------------------------- /src/list.h: -------------------------------------------------------------------------------- 1 | #ifndef __LIST_H 2 | #define __LIST_H 3 | 4 | #include "types.h" // container_of 5 | 6 | 7 | /**************************************************************** 8 | * hlist - Double linked lists with a single pointer list head 9 | ****************************************************************/ 10 | 11 | struct hlist_node { 12 | struct hlist_node *next, **pprev; 13 | }; 14 | 15 | struct hlist_head { 16 | struct hlist_node *first; 17 | }; 18 | 19 | static inline int 20 | hlist_empty(const struct hlist_head *h) 21 | { 22 | return !h->first; 23 | } 24 | 25 | static inline void 26 | hlist_del(struct hlist_node *n) 27 | { 28 | struct hlist_node *next = n->next; 29 | struct hlist_node **pprev = n->pprev; 30 | *pprev = next; 31 | if (next) 32 | next->pprev = pprev; 33 | } 34 | 35 | static inline void 36 | hlist_add(struct hlist_node *n, struct hlist_node **pprev) 37 | { 38 | struct hlist_node *next = *pprev; 39 | n->pprev = pprev; 40 | n->next = next; 41 | if (next) 42 | next->pprev = &n->next; 43 | *pprev = n; 44 | } 45 | 46 | static inline void 47 | hlist_add_head(struct hlist_node *n, struct hlist_head *h) 48 | { 49 | hlist_add(n, &h->first); 50 | } 51 | 52 | static inline void 53 | hlist_add_before(struct hlist_node *n, struct hlist_node *next) 54 | { 55 | hlist_add(n, next->pprev); 56 | } 57 | 58 | static inline void 59 | hlist_add_after(struct hlist_node *n, struct hlist_node *prev) 60 | { 61 | hlist_add(n, &prev->next); 62 | } 63 | 64 | #define hlist_for_each_entry(pos, head, member) \ 65 | for (pos = container_of((head)->first, typeof(*pos), member) \ 66 | ; pos != container_of(NULL, typeof(*pos), member) \ 67 | ; pos = container_of(pos->member.next, typeof(*pos), member)) 68 | 69 | #define hlist_for_each_entry_safe(pos, n, head, member) \ 70 | for (pos = container_of((head)->first, typeof(*pos), member) \ 71 | ; pos != container_of(NULL, typeof(*pos), member) \ 72 | && ({ n = pos->member.next; 1; }) \ 73 | ; pos = container_of(n, typeof(*pos), member)) 74 | 75 | #define hlist_for_each_entry_pprev(pos, pprev, head, member) \ 76 | for (pprev = &(head)->first \ 77 | ; *pprev && ({ pos=container_of(*pprev, typeof(*pos), member); 1; }) \ 78 | ; pprev = &(*pprev)->next) 79 | 80 | 81 | #endif // list.h 82 | -------------------------------------------------------------------------------- /src/malloc.h: -------------------------------------------------------------------------------- 1 | #ifndef __MALLOC_H 2 | #define __MALLOC_H 3 | 4 | #include "types.h" // u32 5 | 6 | // malloc.c 7 | extern struct zone_s ZoneLow, ZoneHigh, ZoneFSeg, ZoneTmpLow, ZoneTmpHigh; 8 | u32 rom_get_max(void); 9 | u32 rom_get_last(void); 10 | struct rom_header *rom_reserve(u32 size); 11 | int rom_confirm(u32 size); 12 | void csm_malloc_preinit(u32 low_pmm, u32 low_pmm_size, u32 hi_pmm, 13 | u32 hi_pmm_size); 14 | void malloc_preinit(void); 15 | extern u32 LegacyRamSize; 16 | void malloc_init(void); 17 | void malloc_prepboot(void); 18 | void *_malloc(struct zone_s *zone, u32 size, u32 align); 19 | int _free(void *data); 20 | u32 malloc_getspace(struct zone_s *zone); 21 | void malloc_sethandle(void *data, u32 handle); 22 | void *malloc_findhandle(u32 handle); 23 | 24 | #define MALLOC_DEFAULT_HANDLE 0xFFFFFFFF 25 | // Minimum alignment of malloc'd memory 26 | #define MALLOC_MIN_ALIGN 16 27 | // Helper functions for memory allocation. 28 | static inline void *malloc_low(u32 size) { 29 | return _malloc(&ZoneLow, size, MALLOC_MIN_ALIGN); 30 | } 31 | static inline void *malloc_high(u32 size) { 32 | return _malloc(&ZoneHigh, size, MALLOC_MIN_ALIGN); 33 | } 34 | static inline void *malloc_fseg(u32 size) { 35 | return _malloc(&ZoneFSeg, size, MALLOC_MIN_ALIGN); 36 | } 37 | static inline void *malloc_tmplow(u32 size) { 38 | return _malloc(&ZoneTmpLow, size, MALLOC_MIN_ALIGN); 39 | } 40 | static inline void *malloc_tmphigh(u32 size) { 41 | return _malloc(&ZoneTmpHigh, size, MALLOC_MIN_ALIGN); 42 | } 43 | static inline void *malloc_tmp(u32 size) { 44 | void *ret = malloc_tmphigh(size); 45 | if (ret) 46 | return ret; 47 | return malloc_tmplow(size); 48 | } 49 | static inline void *memalign_low(u32 align, u32 size) { 50 | return _malloc(&ZoneLow, size, align); 51 | } 52 | static inline void *memalign_high(u32 align, u32 size) { 53 | return _malloc(&ZoneHigh, size, align); 54 | } 55 | static inline void *memalign_tmplow(u32 align, u32 size) { 56 | return _malloc(&ZoneTmpLow, size, align); 57 | } 58 | static inline void *memalign_tmphigh(u32 align, u32 size) { 59 | return _malloc(&ZoneTmpHigh, size, align); 60 | } 61 | static inline void *memalign_tmp(u32 align, u32 size) { 62 | void *ret = memalign_tmphigh(align, size); 63 | if (ret) 64 | return ret; 65 | return memalign_tmplow(align, size); 66 | } 67 | static inline void free(void *data) { 68 | _free(data); 69 | } 70 | 71 | #endif // malloc.h 72 | -------------------------------------------------------------------------------- /src/memmap.h: -------------------------------------------------------------------------------- 1 | #ifndef __E820MAP_H 2 | #define __E820MAP_H 3 | 4 | #include "types.h" // u64 5 | 6 | #define E820_RAM 1 7 | #define E820_RESERVED 2 8 | #define E820_ACPI 3 9 | #define E820_NVS 4 10 | #define E820_UNUSABLE 5 11 | #define E820_HOLE ((u32)-1) // Useful for removing entries 12 | 13 | struct e820entry { 14 | u64 start; 15 | u64 size; 16 | u32 type; 17 | }; 18 | 19 | void add_e820(u64 start, u64 size, u32 type); 20 | void memmap_prepboot(void); 21 | 22 | // A typical OS page size 23 | #define PAGE_SIZE 4096 24 | 25 | // e820 map storage 26 | extern struct e820entry e820_list[]; 27 | extern int e820_count; 28 | 29 | #endif // e820map.h 30 | -------------------------------------------------------------------------------- /src/output.h: -------------------------------------------------------------------------------- 1 | #ifndef __OUTPUT_H 2 | #define __OUTPUT_H 3 | 4 | #include "config.h" // CONFIG_DEBUG_LEVEL 5 | #include "types.h" // u32 6 | 7 | // output.c 8 | void debug_banner(void); 9 | void panic(const char *fmt, ...) 10 | __attribute__ ((format (printf, 1, 2))) __noreturn; 11 | void printf(const char *fmt, ...) 12 | __attribute__ ((format (printf, 1, 2))); 13 | int snprintf(char *str, size_t size, const char *fmt, ...) 14 | __attribute__ ((format (printf, 3, 4))); 15 | char * znprintf(size_t size, const char *fmt, ...) 16 | __attribute__ ((format (printf, 2, 3))); 17 | void __dprintf(const char *fmt, ...) 18 | __attribute__ ((format (printf, 1, 2))); 19 | struct bregs; 20 | void __debug_enter(struct bregs *regs, const char *fname); 21 | void __debug_isr(const char *fname); 22 | void __debug_stub(struct bregs *regs, int lineno, const char *fname); 23 | void __warn_invalid(struct bregs *regs, int lineno, const char *fname); 24 | void __warn_unimplemented(struct bregs *regs, int lineno, const char *fname); 25 | void __warn_internalerror(int lineno, const char *fname); 26 | void __warn_noalloc(int lineno, const char *fname); 27 | void __warn_timeout(int lineno, const char *fname); 28 | void __set_invalid(struct bregs *regs, int lineno, const char *fname); 29 | void __set_unimplemented(struct bregs *regs, int lineno, const char *fname); 30 | void __set_code_invalid(struct bregs *regs, u32 linecode, const char *fname); 31 | void __set_code_unimplemented(struct bregs *regs, u32 linecode 32 | , const char *fname); 33 | void hexdump(const void *d, int len); 34 | 35 | #define dprintf(lvl, fmt, args...) do { \ 36 | if (CONFIG_DEBUG_LEVEL && (lvl) <= CONFIG_DEBUG_LEVEL) \ 37 | __dprintf((fmt) , ##args ); \ 38 | } while (0) 39 | #define debug_enter(regs, lvl) do { \ 40 | if ((lvl) && (lvl) <= CONFIG_DEBUG_LEVEL) \ 41 | __debug_enter((regs), __func__); \ 42 | } while (0) 43 | #define debug_isr(lvl) do { \ 44 | if ((lvl) && (lvl) <= CONFIG_DEBUG_LEVEL) \ 45 | __debug_isr(__func__); \ 46 | } while (0) 47 | #define debug_stub(regs) \ 48 | __debug_stub((regs), __LINE__, __func__) 49 | #define warn_invalid(regs) \ 50 | __warn_invalid((regs), __LINE__, __func__) 51 | #define warn_unimplemented(regs) \ 52 | __warn_unimplemented((regs), __LINE__, __func__) 53 | #define warn_internalerror() \ 54 | __warn_internalerror(__LINE__, __func__) 55 | #define warn_noalloc() \ 56 | __warn_noalloc(__LINE__, __func__) 57 | #define warn_timeout() \ 58 | __warn_timeout(__LINE__, __func__) 59 | #define set_invalid(regs) \ 60 | __set_invalid((regs), __LINE__, __func__) 61 | #define set_code_invalid(regs, code) \ 62 | __set_code_invalid((regs), (code) | (__LINE__ << 8), __func__) 63 | #define set_unimplemented(regs) \ 64 | __set_unimplemented((regs), __LINE__, __func__) 65 | #define set_code_unimplemented(regs, code) \ 66 | __set_code_unimplemented((regs), (code) | (__LINE__ << 8), __func__) 67 | 68 | #endif // output.h 69 | -------------------------------------------------------------------------------- /src/pmm.c: -------------------------------------------------------------------------------- 1 | // Post memory manager (PMM) calls 2 | // 3 | // Copyright (C) 2009-2013 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU LGPLv3 license. 6 | 7 | #include "biosvar.h" // FUNC16 8 | #include "config.h" // CONFIG_* 9 | #include "malloc.h" // _malloc 10 | #include "output.h" // dprintf 11 | #include "std/pmm.h" // PMM_SIGNATURE 12 | #include "string.h" // checksum 13 | #include "util.h" // pmm_init 14 | #include "x86.h" // __ffs 15 | 16 | extern struct pmmheader PMMHEADER; 17 | 18 | #if CONFIG_PMM 19 | struct pmmheader PMMHEADER __aligned(16) VARFSEG = { 20 | .signature = PMM_SIGNATURE, 21 | .version = 0x01, 22 | .length = sizeof(PMMHEADER), 23 | }; 24 | #endif 25 | 26 | // PMM - allocate 27 | static u32 28 | handle_pmm00(u16 *args) 29 | { 30 | u32 length = *(u32*)&args[1], handle = *(u32*)&args[3]; 31 | u16 flags = args[5]; 32 | dprintf(3, "pmm00: length=%x handle=%x flags=%x\n" 33 | , length, handle, flags); 34 | struct zone_s *lowzone = &ZoneTmpLow, *highzone = &ZoneTmpHigh; 35 | if (flags & 8) { 36 | // Permanent memory request. 37 | lowzone = &ZoneLow; 38 | highzone = &ZoneHigh; 39 | } 40 | if (!length) { 41 | // Memory size request 42 | switch (flags & 3) { 43 | default: 44 | case 0: 45 | return 0; 46 | case 1: 47 | return malloc_getspace(lowzone); 48 | case 2: 49 | return malloc_getspace(highzone); 50 | case 3: { 51 | u32 spacelow = malloc_getspace(lowzone); 52 | u32 spacehigh = malloc_getspace(highzone); 53 | if (spacelow > spacehigh) 54 | return spacelow; 55 | return spacehigh; 56 | } 57 | } 58 | } 59 | u32 size = length * 16; 60 | if ((s32)size <= 0) 61 | return 0; 62 | u32 align = MALLOC_MIN_ALIGN; 63 | if (flags & 4) { 64 | align = 1<<__ffs(size); 65 | if (align < MALLOC_MIN_ALIGN) 66 | align = MALLOC_MIN_ALIGN; 67 | } 68 | void *data; 69 | switch (flags & 3) { 70 | default: 71 | case 0: 72 | return 0; 73 | case 1: 74 | data = _malloc(lowzone, size, align); 75 | break; 76 | case 2: 77 | data = _malloc(highzone, size, align); 78 | break; 79 | case 3: { 80 | data = _malloc(lowzone, size, align); 81 | if (!data) 82 | data = _malloc(highzone, size, align); 83 | } 84 | } 85 | if (data && handle != MALLOC_DEFAULT_HANDLE) 86 | malloc_sethandle(data, handle); 87 | return (u32)data; 88 | } 89 | 90 | // PMM - find 91 | static u32 92 | handle_pmm01(u16 *args) 93 | { 94 | u32 handle = *(u32*)&args[1]; 95 | dprintf(3, "pmm01: handle=%x\n", handle); 96 | if (handle == MALLOC_DEFAULT_HANDLE) 97 | return 0; 98 | return (u32)malloc_findhandle(handle); 99 | } 100 | 101 | // PMM - deallocate 102 | static u32 103 | handle_pmm02(u16 *args) 104 | { 105 | u32 buffer = *(u32*)&args[1]; 106 | dprintf(3, "pmm02: buffer=%x\n", buffer); 107 | int ret = _free((void*)buffer); 108 | if (ret) 109 | // Error 110 | return 1; 111 | return 0; 112 | } 113 | 114 | static u32 115 | handle_pmmXX(u16 *args) 116 | { 117 | return PMM_FUNCTION_NOT_SUPPORTED; 118 | } 119 | 120 | u32 VISIBLE32INIT 121 | handle_pmm(u16 *args) 122 | { 123 | ASSERT32FLAT(); 124 | if (! CONFIG_PMM) 125 | return PMM_FUNCTION_NOT_SUPPORTED; 126 | 127 | u16 arg1 = args[0]; 128 | dprintf(DEBUG_HDL_pmm, "pmm call arg1=%x\n", arg1); 129 | 130 | u32 ret; 131 | switch (arg1) { 132 | case 0x00: ret = handle_pmm00(args); break; 133 | case 0x01: ret = handle_pmm01(args); break; 134 | case 0x02: ret = handle_pmm02(args); break; 135 | default: ret = handle_pmmXX(args); break; 136 | } 137 | 138 | return ret; 139 | } 140 | 141 | void 142 | pmm_init(void) 143 | { 144 | if (! CONFIG_PMM) 145 | return; 146 | 147 | dprintf(3, "init PMM\n"); 148 | 149 | PMMHEADER.entry = FUNC16(entry_pmm); 150 | PMMHEADER.checksum -= checksum(&PMMHEADER, sizeof(PMMHEADER)); 151 | } 152 | 153 | void 154 | pmm_prepboot(void) 155 | { 156 | if (! CONFIG_PMM) 157 | return; 158 | 159 | dprintf(3, "finalize PMM\n"); 160 | 161 | PMMHEADER.signature = 0; 162 | PMMHEADER.entry.segoff = 0; 163 | } 164 | -------------------------------------------------------------------------------- /src/pnpbios.c: -------------------------------------------------------------------------------- 1 | // PNP BIOS calls 2 | // 3 | // Copyright (C) 2008 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU LGPLv3 license. 6 | 7 | #include "config.h" // BUILD_BIOS_ADDR 8 | #include "farptr.h" // SET_FARVAR 9 | #include "output.h" // dprintf 10 | #include "std/pnpbios.h" // PNP_SIGNATURE 11 | #include "string.h" // checksum 12 | #include "util.h" // pnp_init 13 | 14 | extern struct pnpheader PNPHEADER; 15 | extern char pnp_string[]; 16 | 17 | #if CONFIG_PNPBIOS 18 | struct pnpheader PNPHEADER __aligned(16) VARFSEG = { 19 | .signature = PNP_SIGNATURE, 20 | .version = 0x10, 21 | .length = sizeof(PNPHEADER), 22 | .real_cs = SEG_BIOS, 23 | .prot_base = BUILD_BIOS_ADDR, 24 | .real_ds = SEG_BIOS, 25 | .prot_database = BUILD_BIOS_ADDR, 26 | }; 27 | #else 28 | // We need a copy of this string in the 0xf000 segment, but we are not 29 | // actually a PnP BIOS, so make sure it is *not* aligned, so OSes will 30 | // not see it if they scan. 31 | char pnp_string[] __aligned(2) VARFSEG = " $PnP"; 32 | #endif 33 | 34 | // BBS - Get Version and Installation Check 35 | static u16 36 | handle_pnp60(u16 *args) 37 | { 38 | u16 version_ptr = args[1]; 39 | u16 version_seg = args[2]; 40 | SET_FARVAR(version_seg, *(u16*)(version_ptr+0), 0x0101); 41 | return 0; 42 | } 43 | 44 | static u16 45 | handle_pnpXX(u16 *args) 46 | { 47 | return FUNCTION_NOT_SUPPORTED; 48 | } 49 | 50 | u16 VISIBLE16 51 | handle_pnp(u16 *args) 52 | { 53 | if (! CONFIG_PNPBIOS) 54 | return FUNCTION_NOT_SUPPORTED; 55 | 56 | u16 arg1 = args[0]; 57 | dprintf(DEBUG_HDL_pnp, "pnp call arg1=%x\n", arg1); 58 | 59 | switch (arg1) { 60 | case 0x60: return handle_pnp60(args); 61 | default: return handle_pnpXX(args); 62 | } 63 | } 64 | 65 | u16 66 | get_pnp_offset(void) 67 | { 68 | if (! CONFIG_PNPBIOS) 69 | return (u32)pnp_string + 1 - BUILD_BIOS_ADDR; 70 | return (u32)&PNPHEADER - BUILD_BIOS_ADDR; 71 | } 72 | 73 | // romlayout.S 74 | extern void entry_pnp_real(void); 75 | extern void entry_pnp_prot(void); 76 | 77 | void 78 | pnp_init(void) 79 | { 80 | if (! CONFIG_PNPBIOS) 81 | return; 82 | 83 | dprintf(3, "init PNPBIOS table\n"); 84 | 85 | PNPHEADER.real_ip = (u32)entry_pnp_real - BUILD_BIOS_ADDR; 86 | PNPHEADER.prot_ip = (u32)entry_pnp_prot - BUILD_BIOS_ADDR; 87 | PNPHEADER.checksum -= checksum(&PNPHEADER, sizeof(PNPHEADER)); 88 | } 89 | -------------------------------------------------------------------------------- /src/resume.c: -------------------------------------------------------------------------------- 1 | // Code for handling calls to "post" that are resume related. 2 | // 3 | // Copyright (C) 2008,2009 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU LGPLv3 license. 6 | 7 | #include "bregs.h" // struct bregs 8 | #include "config.h" // CONFIG_* 9 | #include "farptr.h" // FLATPTR_TO_SEGOFF 10 | #include "hw/pci.h" // pci_reboot 11 | #include "hw/pic.h" // pic_eoi2 12 | #include "hw/ps2port.h" // i8042_reboot 13 | #include "hw/rtc.h" // rtc_read 14 | #include "output.h" // dprintf 15 | #include "stacks.h" // farcall16big 16 | #include "std/bda.h" // struct bios_data_area_s 17 | #include "string.h" // memset 18 | #include "util.h" // dma_setup 19 | 20 | // Handler for post calls that look like a resume. 21 | void VISIBLE16 22 | handle_resume(void) 23 | { 24 | ASSERT16(); 25 | int status = rtc_read(CMOS_RESET_CODE); 26 | rtc_write(CMOS_RESET_CODE, 0); 27 | dprintf(1, "In resume (status=%d)\n", status); 28 | 29 | dma_setup(); 30 | 31 | switch (status) { 32 | case 0x01 ... 0x04: 33 | case 0x06 ... 0x09: 34 | panic("Unimplemented shutdown status: %02x\n", status); 35 | 36 | case 0x05: 37 | // flush keyboard (issue EOI) and jump via 40h:0067h 38 | pic_eoi2(); 39 | // NO BREAK 40 | case 0x0a: 41 | #define BDA_JUMP (((struct bios_data_area_s *)0)->jump) 42 | // resume execution by jump via 40h:0067h 43 | asm volatile( 44 | "movw %w1, %%ds\n" 45 | "ljmpw *%0\n" 46 | : : "m"(BDA_JUMP), "r"(SEG_BDA) 47 | ); 48 | break; 49 | 50 | case 0x0b: 51 | // resume execution via IRET via 40h:0067h 52 | asm volatile( 53 | "movw %w1, %%ds\n" 54 | "lssw %0, %%sp\n" 55 | "iretw\n" 56 | : : "m"(BDA_JUMP), "r"(SEG_BDA) 57 | ); 58 | break; 59 | 60 | case 0x0c: 61 | // resume execution via RETF via 40h:0067h 62 | asm volatile( 63 | "movw %w1, %%ds\n" 64 | "lssw %0, %%sp\n" 65 | "lretw\n" 66 | : : "m"(BDA_JUMP), "r"(SEG_BDA) 67 | ); 68 | break; 69 | 70 | default: 71 | break; 72 | } 73 | 74 | // Not a 16bit resume - do remaining checks in 32bit mode 75 | asm volatile( 76 | "movw %w1, %%ss\n" 77 | "movl %0, %%esp\n" 78 | "movl $_cfunc32flat_handle_resume32, %%edx\n" 79 | "jmp transition32\n" 80 | : : "i"(BUILD_S3RESUME_STACK_ADDR), "r"(0), "a"(status) 81 | ); 82 | } 83 | 84 | // Handle an S3 resume event 85 | static void 86 | s3_resume(void) 87 | { 88 | if (!CONFIG_S3_RESUME) 89 | return; 90 | 91 | u32 s3_resume_vector = find_resume_vector(); 92 | if (!s3_resume_vector) { 93 | dprintf(1, "No resume vector set!\n"); 94 | return; 95 | } 96 | 97 | pic_setup(); 98 | smm_setup(); 99 | 100 | pci_resume(); 101 | 102 | s3_resume_vga(); 103 | 104 | make_bios_readonly(); 105 | 106 | // Invoke the resume vector. 107 | struct bregs br; 108 | memset(&br, 0, sizeof(br)); 109 | dprintf(1, "Jump to resume vector (%x)\n", s3_resume_vector); 110 | br.code = FLATPTR_TO_SEGOFF((void*)s3_resume_vector); 111 | farcall16big(&br); 112 | } 113 | 114 | u8 HaveAttemptedReboot VARLOW; 115 | 116 | // Attempt to invoke a hard-reboot. 117 | static void 118 | tryReboot(void) 119 | { 120 | if (HaveAttemptedReboot) { 121 | // Hard reboot has failed - try to shutdown machine. 122 | dprintf(1, "Unable to hard-reboot machine - attempting shutdown.\n"); 123 | apm_shutdown(); 124 | } 125 | HaveAttemptedReboot = 1; 126 | 127 | dprintf(1, "Attempting a hard reboot\n"); 128 | 129 | // Setup for reset on qemu. 130 | qemu_prep_reset(); 131 | 132 | // Reboot using ACPI RESET_REG 133 | acpi_reboot(); 134 | 135 | // Try keyboard controller reboot. 136 | i8042_reboot(); 137 | 138 | // Try PCI 0xcf9 reboot 139 | pci_reboot(); 140 | 141 | // Try triple fault 142 | asm volatile("int3"); 143 | 144 | panic("Could not reboot"); 145 | } 146 | 147 | void VISIBLE32FLAT 148 | handle_resume32(int status) 149 | { 150 | ASSERT32FLAT(); 151 | dprintf(1, "In 32bit resume\n"); 152 | 153 | if (status == 0xfe) 154 | s3_resume(); 155 | 156 | // Must be a soft reboot - invoke a hard reboot. 157 | tryReboot(); 158 | } 159 | -------------------------------------------------------------------------------- /src/romfile.c: -------------------------------------------------------------------------------- 1 | // Access to pseudo "file" interface for configuration information. 2 | // 3 | // Copyright (C) 2012 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU LGPLv3 license. 6 | 7 | #include "config.h" // CONFIG_* 8 | #include "malloc.h" // free 9 | #include "output.h" // dprintf 10 | #include "romfile.h" // struct romfile_s 11 | #include "string.h" // memcmp 12 | 13 | static struct romfile_s *RomfileRoot VARVERIFY32INIT; 14 | 15 | void 16 | romfile_add(struct romfile_s *file) 17 | { 18 | dprintf(3, "Add romfile: %s (size=%d)\n", file->name, file->size); 19 | file->next = RomfileRoot; 20 | RomfileRoot = file; 21 | } 22 | 23 | // Search for the specified file. 24 | static struct romfile_s * 25 | __romfile_findprefix(const char *prefix, int prefixlen, struct romfile_s *prev) 26 | { 27 | struct romfile_s *cur = RomfileRoot; 28 | if (prev) 29 | cur = prev->next; 30 | while (cur) { 31 | if (memcmp(prefix, cur->name, prefixlen) == 0) 32 | return cur; 33 | cur = cur->next; 34 | } 35 | return NULL; 36 | } 37 | 38 | struct romfile_s * 39 | romfile_findprefix(const char *prefix, struct romfile_s *prev) 40 | { 41 | return __romfile_findprefix(prefix, strlen(prefix), prev); 42 | } 43 | 44 | struct romfile_s * 45 | romfile_find(const char *name) 46 | { 47 | return __romfile_findprefix(name, strlen(name) + 1, NULL); 48 | } 49 | 50 | // Helper function to find, malloc_tmphigh, and copy a romfile. This 51 | // function adds a trailing zero to the malloc'd copy. 52 | void * 53 | romfile_loadfile(const char *name, int *psize) 54 | { 55 | struct romfile_s *file = romfile_find(name); 56 | if (!file) 57 | return NULL; 58 | 59 | int filesize = file->size; 60 | if (!filesize) 61 | return NULL; 62 | 63 | char *data = malloc_tmphigh(filesize+1); 64 | if (!data) { 65 | warn_noalloc(); 66 | return NULL; 67 | } 68 | 69 | dprintf(5, "Copying romfile '%s' (len %d)\n", name, filesize); 70 | int ret = file->copy(file, data, filesize); 71 | if (ret < 0) { 72 | free(data); 73 | return NULL; 74 | } 75 | if (psize) 76 | *psize = filesize; 77 | data[filesize] = '\0'; 78 | return data; 79 | } 80 | 81 | // Attempt to load an integer from the given file - return 'defval' 82 | // if unsuccessful. 83 | u64 84 | romfile_loadint(const char *name, u64 defval) 85 | { 86 | struct romfile_s *file = romfile_find(name); 87 | if (!file) 88 | return defval; 89 | 90 | int filesize = file->size; 91 | if (!filesize || filesize > sizeof(u64) || (filesize & (filesize-1))) 92 | // Doesn't look like a valid integer. 93 | return defval; 94 | 95 | u64 val = 0; 96 | int ret = file->copy(file, &val, sizeof(val)); 97 | if (ret < 0) 98 | return defval; 99 | return val; 100 | } 101 | -------------------------------------------------------------------------------- /src/romfile.h: -------------------------------------------------------------------------------- 1 | #ifndef __ROMFILE_H 2 | #define __ROMFILE_H 3 | 4 | #include "types.h" // u32 5 | 6 | // romfile.c 7 | struct romfile_s { 8 | struct romfile_s *next; 9 | char name[128]; 10 | u32 size; 11 | int (*copy)(struct romfile_s *file, void *dest, u32 maxlen); 12 | }; 13 | void romfile_add(struct romfile_s *file); 14 | struct romfile_s *romfile_findprefix(const char *prefix, struct romfile_s *prev); 15 | struct romfile_s *romfile_find(const char *name); 16 | void *romfile_loadfile(const char *name, int *psize); 17 | u64 romfile_loadint(const char *name, u64 defval); 18 | 19 | #endif // romfile.h 20 | -------------------------------------------------------------------------------- /src/stacks.h: -------------------------------------------------------------------------------- 1 | // Misc function and variable declarations. 2 | #ifndef __STACKS_H 3 | #define __STACKS_H 4 | 5 | #include "types.h" // u32 6 | 7 | #define CALL32SMM_CMDID 0xb5 8 | #define CALL32SMM_ENTERID 0x1234 9 | #define CALL32SMM_RETURNID 0x5678 10 | 11 | // stacks.c 12 | extern int HaveSmmCall32; 13 | u32 call32(void *func, u32 eax, u32 errret); 14 | extern u8 ExtraStack[], *StackPos; 15 | u32 stack_hop(u32 eax, u32 edx, void *func); 16 | u32 stack_hop_back(u32 eax, u32 edx, void *func); 17 | int on_extra_stack(void); 18 | struct bregs; 19 | void farcall16(struct bregs *callregs); 20 | void farcall16big(struct bregs *callregs); 21 | void __call16_int(struct bregs *callregs, u16 offset); 22 | #define call16_int(nr, callregs) do { \ 23 | extern void irq_trampoline_ ##nr (); \ 24 | __call16_int((callregs), (u32)&irq_trampoline_ ##nr ); \ 25 | } while (0) 26 | void reset(void); 27 | extern struct thread_info MainThread; 28 | struct thread_info *getCurThread(void); 29 | void yield(void); 30 | void yield_toirq(void); 31 | void thread_init(void); 32 | int threads_during_optionroms(void); 33 | void run_thread(void (*func)(void*), void *data); 34 | void wait_threads(void); 35 | struct mutex_s { u32 isLocked; }; 36 | void mutex_lock(struct mutex_s *mutex); 37 | void mutex_unlock(struct mutex_s *mutex); 38 | void start_preempt(void); 39 | void finish_preempt(void); 40 | int wait_preempt(void); 41 | void check_preempt(void); 42 | u32 call32_params(void *func, u32 eax, u32 edx, u32 ecx, u32 errret); 43 | 44 | // Inline functions 45 | 46 | // Check if a call to stack_hop_back is needed. 47 | static inline int 48 | need_hop_back(void) 49 | { 50 | return !MODESEGMENT || on_extra_stack(); 51 | } 52 | 53 | #endif // stacks.h 54 | -------------------------------------------------------------------------------- /src/std/bda.h: -------------------------------------------------------------------------------- 1 | // BIOS Data Area (and similar) definitions 2 | #ifndef __BDA_H 3 | #define __BDA_H 4 | 5 | #include "disk.h" // struct fdpt_s 6 | #include "types.h" // u8 7 | 8 | 9 | /**************************************************************** 10 | * Interupt vector table 11 | ****************************************************************/ 12 | 13 | struct rmode_IVT { 14 | struct segoff_s ivec[256]; 15 | }; 16 | 17 | 18 | /**************************************************************** 19 | * Bios Data Area (BDA) 20 | ****************************************************************/ 21 | 22 | struct bios_data_area_s { 23 | // 40:00 24 | u16 port_com[4]; 25 | u16 port_lpt[3]; 26 | u16 ebda_seg; 27 | // 40:10 28 | u16 equipment_list_flags; 29 | u8 pad1; 30 | u16 mem_size_kb; 31 | u8 pad2; 32 | u8 ps2_ctrl_flag; 33 | u8 kbd_flag0; 34 | u8 kbd_flag1; 35 | u8 alt_keypad; 36 | u16 kbd_buf_head; 37 | u16 kbd_buf_tail; 38 | // 40:1e 39 | u8 kbd_buf[32]; 40 | u8 floppy_recalibration_status; 41 | u8 floppy_motor_status; 42 | // 40:40 43 | u8 floppy_motor_counter; 44 | u8 floppy_last_status; 45 | u8 floppy_return_status[7]; 46 | u8 video_mode; 47 | u16 video_cols; 48 | u16 video_pagesize; 49 | u16 video_pagestart; 50 | // 40:50 51 | u16 cursor_pos[8]; 52 | // 40:60 53 | u16 cursor_type; 54 | u8 video_page; 55 | u16 crtc_address; 56 | u8 video_msr; 57 | u8 video_pal; 58 | struct segoff_s jump; 59 | u8 other_6b; 60 | u32 timer_counter; 61 | // 40:70 62 | u8 timer_rollover; 63 | u8 break_flag; 64 | u16 soft_reset_flag; 65 | u8 disk_last_status; 66 | u8 hdcount; 67 | u8 disk_control_byte; 68 | u8 port_disk; 69 | u8 lpt_timeout[4]; 70 | u8 com_timeout[4]; 71 | // 40:80 72 | u16 kbd_buf_start_offset; 73 | u16 kbd_buf_end_offset; 74 | u8 video_rows; 75 | u16 char_height; 76 | u8 video_ctl; 77 | u8 video_switches; 78 | u8 modeset_ctl; 79 | u8 dcc_index; 80 | u8 floppy_last_data_rate; 81 | u8 disk_status_controller; 82 | u8 disk_error_controller; 83 | u8 disk_interrupt_flag; 84 | u8 floppy_harddisk_info; 85 | // 40:90 86 | u8 floppy_media_state[4]; 87 | u8 floppy_track[2]; 88 | u8 kbd_flag2; 89 | u8 kbd_led; 90 | struct segoff_s user_wait_complete_flag; 91 | u32 user_wait_timeout; 92 | // 40:A0 93 | u8 rtc_wait_flag; 94 | u8 other_a1[7]; 95 | struct segoff_s video_savetable; 96 | u8 other_ac[4]; 97 | // 40:B0 98 | u8 other_b0[5*16]; 99 | } PACKED; 100 | 101 | // BDA floppy_recalibration_status bitdefs 102 | #define FRS_IRQ (1<<7) 103 | 104 | // BDA rtc_wait_flag bitdefs 105 | #define RWS_WAIT_PENDING (1<<0) 106 | #define RWS_WAIT_ELAPSED (1<<7) 107 | 108 | // BDA floppy_media_state bitdefs 109 | #define FMS_DRIVE_STATE_MASK (0x07) 110 | #define FMS_MEDIA_DRIVE_ESTABLISHED (1<<4) 111 | #define FMS_DOUBLE_STEPPING (1<<5) 112 | #define FMS_DATA_RATE_MASK (0xc0) 113 | 114 | // Limit of BDA timer_counter field 115 | #define TICKS_PER_DAY 1573040 116 | 117 | 118 | /**************************************************************** 119 | * Extended Bios Data Area (EBDA) 120 | ****************************************************************/ 121 | 122 | struct extended_bios_data_area_s { 123 | u8 size; 124 | u8 reserved1[0x21]; 125 | struct segoff_s far_call_pointer; 126 | u8 mouse_flag1; 127 | u8 mouse_flag2; 128 | u8 mouse_data[0x08]; 129 | // 0x30 130 | u8 other1[0x0d]; 131 | 132 | // 0x3d 133 | struct fdpt_s fdpt[2]; 134 | 135 | // 0x5d 136 | u8 other2[0xC4]; 137 | 138 | // 0x121 - Begin custom storage. 139 | } PACKED; 140 | 141 | 142 | /**************************************************************** 143 | * Bios Config Table 144 | ****************************************************************/ 145 | 146 | struct bios_config_table_s { 147 | u16 size; 148 | u8 model; 149 | u8 submodel; 150 | u8 biosrev; 151 | u8 feature1, feature2, feature3, feature4, feature5; 152 | } PACKED; 153 | 154 | #endif // bda.h 155 | -------------------------------------------------------------------------------- /src/std/disk.h: -------------------------------------------------------------------------------- 1 | // Standard disk BIOS definitions. 2 | #ifndef __DISK_H 3 | #define __DISK_H 4 | 5 | #include "types.h" // u8 6 | 7 | #define DISK_RET_SUCCESS 0x00 8 | #define DISK_RET_EPARAM 0x01 9 | #define DISK_RET_EADDRNOTFOUND 0x02 10 | #define DISK_RET_EWRITEPROTECT 0x03 11 | #define DISK_RET_ECHANGED 0x06 12 | #define DISK_RET_EBOUNDARY 0x09 13 | #define DISK_RET_EBADTRACK 0x0c 14 | #define DISK_RET_ECONTROLLER 0x20 15 | #define DISK_RET_ETIMEOUT 0x80 16 | #define DISK_RET_ENOTLOCKED 0xb0 17 | #define DISK_RET_ELOCKED 0xb1 18 | #define DISK_RET_ENOTREMOVABLE 0xb2 19 | #define DISK_RET_ETOOMANYLOCKS 0xb4 20 | #define DISK_RET_EMEDIA 0xC0 21 | #define DISK_RET_ENOTREADY 0xAA 22 | 23 | 24 | /**************************************************************** 25 | * Interface structs 26 | ****************************************************************/ 27 | 28 | // Bios disk structures. 29 | struct int13ext_s { 30 | u8 size; 31 | u8 reserved; 32 | u16 count; 33 | struct segoff_s data; 34 | u64 lba; 35 | } PACKED; 36 | 37 | // DPTE definition 38 | struct dpte_s { 39 | u16 iobase1; 40 | u16 iobase2; 41 | u8 prefix; 42 | u8 unused; 43 | u8 irq; 44 | u8 blkcount; 45 | u8 dma; 46 | u8 pio; 47 | u16 options; 48 | u16 reserved; 49 | u8 revision; 50 | u8 checksum; 51 | }; 52 | 53 | // Disk Physical Table definition 54 | struct int13dpt_s { 55 | u16 size; 56 | u16 infos; 57 | u32 cylinders; 58 | u32 heads; 59 | u32 spt; 60 | u64 sector_count; 61 | u16 blksize; 62 | struct segoff_s dpte; 63 | u16 key; 64 | u8 dpi_length; 65 | u8 reserved1; 66 | u16 reserved2; 67 | u8 host_bus[4]; 68 | u8 iface_type[8]; 69 | u64 iface_path; 70 | union { 71 | struct { 72 | u64 device_path; 73 | u8 reserved3; 74 | u8 checksum; 75 | } phoenix; 76 | struct { 77 | u64 device_path[2]; 78 | u8 reserved3; 79 | u8 checksum; 80 | } t13; 81 | }; 82 | } PACKED; 83 | 84 | // Floppy info 85 | struct fdpt_s { 86 | u16 cylinders; 87 | u8 heads; 88 | u8 a0h_signature; 89 | u8 phys_sectors; 90 | u16 precompensation; 91 | u8 reserved; 92 | u8 drive_control_byte; 93 | u16 phys_cylinders; 94 | u8 phys_heads; 95 | u16 landing_zone; 96 | u8 sectors; 97 | u8 checksum; 98 | } PACKED; 99 | 100 | // Floppy "Disk Base Table" 101 | struct floppy_dbt_s { 102 | u8 specify1; 103 | u8 specify2; 104 | u8 shutoff_ticks; 105 | u8 bps_code; 106 | u8 sectors; 107 | u8 interblock_len; 108 | u8 data_len; 109 | u8 gap_len; 110 | u8 fill_byte; 111 | u8 settle_time; 112 | u8 startup_time; 113 | } PACKED; 114 | 115 | struct floppy_ext_dbt_s { 116 | struct floppy_dbt_s dbt; 117 | // Extra fields 118 | u8 max_track; 119 | u8 data_rate; 120 | u8 drive_type; 121 | } PACKED; 122 | 123 | 124 | /**************************************************************** 125 | * Master boot record 126 | ****************************************************************/ 127 | 128 | struct packed_chs_s { 129 | u8 heads; 130 | u8 sptcyl; 131 | u8 cyllow; 132 | } PACKED; 133 | 134 | struct partition_s { 135 | u8 status; 136 | struct packed_chs_s first; 137 | u8 type; 138 | struct packed_chs_s last; 139 | u32 lba; 140 | u32 count; 141 | } PACKED; 142 | 143 | struct mbr_s { 144 | u8 code[440]; 145 | // 0x01b8 146 | u32 diskseg; 147 | // 0x01bc 148 | u16 null; 149 | // 0x01be 150 | struct partition_s partitions[4]; 151 | // 0x01fe 152 | u16 signature; 153 | } PACKED; 154 | 155 | #define MBR_SIGNATURE 0xaa55 156 | 157 | 158 | /**************************************************************** 159 | * ElTorito CDROM interface 160 | ****************************************************************/ 161 | 162 | struct eltorito_s { 163 | u8 size; 164 | u8 media; 165 | u8 emulated_drive; 166 | u8 controller_index; 167 | u32 ilba; 168 | u16 device_spec; 169 | u16 buffer_segment; 170 | u16 load_segment; 171 | u16 sector_count; 172 | struct packed_chs_s chs; 173 | } PACKED; 174 | 175 | #endif // disk.h 176 | -------------------------------------------------------------------------------- /src/std/mptable.h: -------------------------------------------------------------------------------- 1 | #ifndef __MPTABLE_H 2 | #define __MPTABLE_H 3 | 4 | #include "types.h" // u32 5 | 6 | #define MPTABLE_SIGNATURE 0x5f504d5f // "_MP_" 7 | 8 | struct mptable_floating_s { 9 | u32 signature; 10 | u32 physaddr; 11 | u8 length; 12 | u8 spec_rev; 13 | u8 checksum; 14 | u8 feature1; 15 | u8 feature2; 16 | u8 reserved[3]; 17 | }; 18 | 19 | #define MPCONFIG_SIGNATURE 0x504d4350 // "PCMP" 20 | 21 | struct mptable_config_s { 22 | u32 signature; 23 | u16 length; 24 | u8 spec; 25 | u8 checksum; 26 | char oemid[8]; 27 | char productid[12]; 28 | u32 oemptr; 29 | u16 oemsize; 30 | u16 entrycount; 31 | u32 lapic; 32 | u16 exttable_length; 33 | u8 exttable_checksum; 34 | u8 reserved; 35 | } PACKED; 36 | 37 | #define MPT_TYPE_CPU 0 38 | #define MPT_TYPE_BUS 1 39 | #define MPT_TYPE_IOAPIC 2 40 | #define MPT_TYPE_INTSRC 3 41 | #define MPT_TYPE_LOCAL_INT 4 42 | 43 | struct mpt_cpu { 44 | u8 type; 45 | u8 apicid; 46 | u8 apicver; 47 | u8 cpuflag; 48 | u32 cpusignature; 49 | u32 featureflag; 50 | u32 reserved[2]; 51 | } PACKED; 52 | 53 | struct mpt_bus { 54 | u8 type; 55 | u8 busid; 56 | char bustype[6]; 57 | } PACKED; 58 | 59 | struct mpt_ioapic { 60 | u8 type; 61 | u8 apicid; 62 | u8 apicver; 63 | u8 flags; 64 | u32 apicaddr; 65 | } PACKED; 66 | 67 | struct mpt_intsrc { 68 | u8 type; 69 | u8 irqtype; 70 | u16 irqflag; 71 | u8 srcbus; 72 | u8 srcbusirq; 73 | u8 dstapic; 74 | u8 dstirq; 75 | } PACKED; 76 | 77 | #endif // mptable.h 78 | -------------------------------------------------------------------------------- /src/std/optionrom.h: -------------------------------------------------------------------------------- 1 | #ifndef __OPTIONROMS_H 2 | #define __OPTIONROMS_H 3 | 4 | #include "types.h" // u32 5 | 6 | #define OPTION_ROM_SIGNATURE 0xaa55 7 | 8 | struct rom_header { 9 | u16 signature; 10 | u8 size; 11 | u8 initVector[4]; 12 | u8 reserved[17]; 13 | u16 pcioffset; 14 | u16 pnpoffset; 15 | } PACKED; 16 | 17 | #define PCI_ROM_SIGNATURE 0x52494350 // "PCIR" 18 | 19 | struct pci_data { 20 | u32 signature; 21 | u16 vendor; 22 | u16 device; 23 | u16 vitaldata; 24 | u16 dlen; 25 | u8 drevision; 26 | u8 class_lo; 27 | u16 class_hi; 28 | u16 ilen; 29 | u16 irevision; 30 | u8 type; 31 | u8 indicator; 32 | u16 reserved; 33 | } PACKED; 34 | 35 | struct pnp_data { 36 | u32 signature; 37 | u8 revision; 38 | u8 len; 39 | u16 nextoffset; 40 | u8 reserved_08; 41 | u8 checksum; 42 | u32 devid; 43 | u16 manufacturer; 44 | u16 productname; 45 | u8 type_lo; 46 | u16 type_hi; 47 | u8 dev_flags; 48 | u16 bcv; 49 | u16 dv; 50 | u16 bev; 51 | u16 reserved_1c; 52 | u16 staticresource; 53 | } PACKED; 54 | 55 | #define OPTION_ROM_ALIGN 2048 56 | #define OPTION_ROM_INITVECTOR offsetof(struct rom_header, initVector[0]) 57 | #define PCIROM_CODETYPE_X86 0 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /src/std/pirtable.h: -------------------------------------------------------------------------------- 1 | #ifndef __PIRTABLE_H 2 | #define __PIRTABLE_H 3 | 4 | #include "types.h" // u32 5 | 6 | struct link_info { 7 | u8 link; 8 | u16 bitmap; 9 | } PACKED; 10 | 11 | struct pir_slot { 12 | u8 bus; 13 | u8 dev; 14 | struct link_info links[4]; 15 | u8 slot_nr; 16 | u8 reserved; 17 | } PACKED; 18 | 19 | struct pir_header { 20 | u32 signature; 21 | u16 version; 22 | u16 size; 23 | u8 router_bus; 24 | u8 router_devfunc; 25 | u16 exclusive_irqs; 26 | u32 compatible_devid; 27 | u32 miniport_data; 28 | u8 reserved[11]; 29 | u8 checksum; 30 | struct pir_slot slots[0]; 31 | } PACKED; 32 | 33 | #define PIR_SIGNATURE 0x52495024 // $PIR 34 | 35 | #endif // pirtable.h 36 | -------------------------------------------------------------------------------- /src/std/pmm.h: -------------------------------------------------------------------------------- 1 | #ifndef __PMM_H 2 | #define __PMM_H 3 | 4 | #include "types.h" // u32 5 | 6 | #define PMM_SIGNATURE 0x4d4d5024 // $PMM 7 | 8 | struct pmmheader { 9 | u32 signature; 10 | u8 version; 11 | u8 length; 12 | u8 checksum; 13 | struct segoff_s entry; 14 | u8 reserved[5]; 15 | } PACKED; 16 | 17 | #define PMM_FUNCTION_NOT_SUPPORTED 0xffffffff 18 | 19 | #endif // pmm.h 20 | -------------------------------------------------------------------------------- /src/std/pnpbios.h: -------------------------------------------------------------------------------- 1 | #ifndef __PNPHEADER_H 2 | #define __PNPHEADER_H 3 | 4 | #define PNP_SIGNATURE 0x506e5024 // $PnP 5 | 6 | struct pnpheader { 7 | u32 signature; 8 | u8 version; 9 | u8 length; 10 | u16 control; 11 | u8 checksum; 12 | u32 eventloc; 13 | u16 real_ip; 14 | u16 real_cs; 15 | u16 prot_ip; 16 | u32 prot_base; 17 | u32 oemid; 18 | u16 real_ds; 19 | u32 prot_database; 20 | } PACKED; 21 | 22 | #define FUNCTION_NOT_SUPPORTED 0x82 23 | 24 | #endif // pnpheader.h 25 | -------------------------------------------------------------------------------- /src/std/vga.h: -------------------------------------------------------------------------------- 1 | #ifndef __VGA_H 2 | #define __VGA_H 3 | // Standard structure definitions for vgabios video tables 4 | 5 | #include "types.h" // u8 6 | 7 | // standard BIOS Video Parameter Table 8 | struct video_param_s { 9 | u8 twidth; 10 | u8 theightm1; 11 | u8 cheight; 12 | u16 slength; 13 | u8 sequ_regs[4]; 14 | u8 miscreg; 15 | u8 crtc_regs[25]; 16 | u8 actl_regs[20]; 17 | u8 grdc_regs[9]; 18 | } PACKED; 19 | 20 | // Standard Video Save Pointer Table 21 | struct video_save_pointer_s { 22 | struct segoff_s videoparam; 23 | struct segoff_s paramdynamicsave; 24 | struct segoff_s textcharset; 25 | struct segoff_s graphcharset; 26 | struct segoff_s secsavepointer; 27 | u8 reserved[8]; 28 | } PACKED; 29 | 30 | // Data returned by int101B 31 | struct video_func_static { 32 | u32 modes; 33 | u8 reserved_0x04[3]; 34 | u8 scanlines; 35 | u8 cblocks; 36 | u8 active_cblocks; 37 | u16 misc_flags; 38 | u8 reserved_0x0c[2]; 39 | u8 save_flags; 40 | u8 reserved_0x0f; 41 | } PACKED; 42 | 43 | struct video_func_info { 44 | struct segoff_s static_functionality; 45 | u8 bda_0x49[30]; 46 | u8 bda_0x84[3]; 47 | u8 dcc_index; 48 | u8 dcc_alt; 49 | u16 colors; 50 | u8 pages; 51 | u8 scan_lines; 52 | u8 primary_char; 53 | u8 secondar_char; 54 | u8 misc; 55 | u8 non_vga_mode; 56 | u8 reserved_2f[2]; 57 | u8 video_mem; 58 | u8 save_flags; 59 | u8 disp_info; 60 | u8 reserved_34[12]; 61 | } PACKED; 62 | 63 | #endif // vga.h 64 | -------------------------------------------------------------------------------- /src/stdbool.h: -------------------------------------------------------------------------------- 1 | //***************************************************************************** 2 | // 3 | // 4 | // Copyright (c) 2012 Sage Electronic Engineering. All rights reserved. 5 | // Software License Agreement 6 | // 7 | // THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED 8 | // OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF 9 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. 10 | // Sage Electronic Engineering SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR 11 | // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. 12 | // 13 | //***************************************************************************** 14 | 15 | #ifndef __SEABIOS_STDBOOL_H 16 | #define __SEABIOS_STDBOOL_H 17 | 18 | typedef int bool; 19 | #define true 1 20 | #define false 0 21 | 22 | 23 | 24 | #endif /* __SEABIOS_STDBOOL_H */ 25 | -------------------------------------------------------------------------------- /src/stdint.h: -------------------------------------------------------------------------------- 1 | //***************************************************************************** 2 | // 3 | // 4 | // Copyright (c) 2012 Sage Electronic Engineering. All rights reserved. 5 | // Software License Agreement 6 | // 7 | // THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED 8 | // OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF 9 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. 10 | // Sage Electronic Engineering SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR 11 | // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. 12 | // 13 | //***************************************************************************** 14 | 15 | #ifndef __SEABIOS_STDINT_H 16 | #define __SEABIOS_STDINT_H 17 | 18 | #include "types.h" 19 | 20 | /* minimal stdint types for seabios non-specific portability */ 21 | 22 | typedef u8 uint8_t; 23 | typedef s8 int8_t; 24 | 25 | typedef u16 uint16_t; 26 | typedef s16 int16_t; 27 | 28 | typedef u32 uint32_t; 29 | typedef s32 int32_t; 30 | 31 | typedef u64 uint64_t; 32 | typedef s64 int64_t; 33 | 34 | #endif /* __SEABIOS_STDINT_H */ 35 | -------------------------------------------------------------------------------- /src/string.h: -------------------------------------------------------------------------------- 1 | // String manipulation function defs. 2 | #ifndef __STRING_H 3 | #define __STRING_H 4 | 5 | #include "types.h" // u32 6 | 7 | // string.c 8 | u8 checksum_far(u16 buf_seg, void *buf_far, u32 len); 9 | u8 checksum(void *buf, u32 len); 10 | size_t strlen(const char *s); 11 | int memcmp(const void *s1, const void *s2, size_t n); 12 | int strcmp(const char *s1, const char *s2); 13 | inline void memset_far(u16 d_seg, void *d_far, u8 c, size_t len); 14 | inline void memset16_far(u16 d_seg, void *d_far, u16 c, size_t len); 15 | void *memset(void *s, int c, size_t n); 16 | void memset_fl(void *ptr, u8 val, size_t size); 17 | inline void memcpy_far(u16 d_seg, void *d_far 18 | , u16 s_seg, const void *s_far, size_t len); 19 | void memcpy_fl(void *d_fl, const void *s_fl, size_t len); 20 | void *memcpy(void *d1, const void *s1, size_t len); 21 | #if MODESEGMENT == 0 22 | #define memcpy __builtin_memcpy 23 | #endif 24 | void iomemcpy(void *d, const void *s, u32 len); 25 | void *memmove(void *d, const void *s, size_t len); 26 | char *strtcpy(char *dest, const char *src, size_t len); 27 | char *strchr(const char *s, int c); 28 | char *nullTrailingSpace(char *buf); 29 | 30 | #endif // string.h 31 | -------------------------------------------------------------------------------- /src/x86.c: -------------------------------------------------------------------------------- 1 | // X86 utility functions. 2 | // 3 | // Copyright (C) 2013 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU LGPLv3 license. 6 | 7 | #include "x86.h" // __cpuid 8 | 9 | void 10 | cpuid(u32 index, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx) 11 | { 12 | // Check for cpu id 13 | u32 origflags = save_flags(); 14 | restore_flags(origflags ^ F_ID); 15 | u32 newflags = save_flags(); 16 | restore_flags(origflags); 17 | 18 | if (((origflags ^ newflags) & F_ID) != F_ID) 19 | // no cpuid 20 | *eax = *ebx = *ecx = *edx = 0; 21 | else 22 | __cpuid(index, eax, ebx, ecx, edx); 23 | } 24 | -------------------------------------------------------------------------------- /vgasrc/bochsvga.h: -------------------------------------------------------------------------------- 1 | #ifndef __BOCHSVGA_H 2 | #define __BOCHSVGA_H 3 | 4 | #include "types.h" // u8 5 | 6 | #define VBE_DISPI_BANK_ADDRESS 0xA0000 7 | #define VBE_DISPI_BANK_SIZE_KB 64 8 | 9 | #define VBE_DISPI_MAX_XRES 2560 10 | #define VBE_DISPI_MAX_YRES 1600 11 | 12 | #define VBE_DISPI_IOPORT_INDEX 0x01CE 13 | #define VBE_DISPI_IOPORT_DATA 0x01CF 14 | 15 | #define VBE_DISPI_INDEX_ID 0x0 16 | #define VBE_DISPI_INDEX_XRES 0x1 17 | #define VBE_DISPI_INDEX_YRES 0x2 18 | #define VBE_DISPI_INDEX_BPP 0x3 19 | #define VBE_DISPI_INDEX_ENABLE 0x4 20 | #define VBE_DISPI_INDEX_BANK 0x5 21 | #define VBE_DISPI_INDEX_VIRT_WIDTH 0x6 22 | #define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7 23 | #define VBE_DISPI_INDEX_X_OFFSET 0x8 24 | #define VBE_DISPI_INDEX_Y_OFFSET 0x9 25 | #define VBE_DISPI_INDEX_VIDEO_MEMORY_64K 0xa 26 | 27 | #define VBE_DISPI_ID0 0xB0C0 28 | #define VBE_DISPI_ID1 0xB0C1 29 | #define VBE_DISPI_ID2 0xB0C2 30 | #define VBE_DISPI_ID3 0xB0C3 31 | #define VBE_DISPI_ID4 0xB0C4 32 | #define VBE_DISPI_ID5 0xB0C5 33 | 34 | #define VBE_DISPI_DISABLED 0x00 35 | #define VBE_DISPI_ENABLED 0x01 36 | #define VBE_DISPI_GETCAPS 0x02 37 | #define VBE_DISPI_8BIT_DAC 0x20 38 | #define VBE_DISPI_LFB_ENABLED 0x40 39 | #define VBE_DISPI_NOCLEARMEM 0x80 40 | 41 | #define VBE_DISPI_LFB_PHYSICAL_ADDRESS 0xE0000000 42 | 43 | struct vgamode_s *bochsvga_find_mode(int mode); 44 | void bochsvga_list_modes(u16 seg, u16 *dest, u16 *last); 45 | int bochsvga_get_window(struct vgamode_s *vmode_g, int window); 46 | int bochsvga_set_window(struct vgamode_s *vmode_g, int window, int val); 47 | int bochsvga_get_linelength(struct vgamode_s *vmode_g); 48 | int bochsvga_set_linelength(struct vgamode_s *vmode_g, int val); 49 | int bochsvga_get_displaystart(struct vgamode_s *vmode_g); 50 | int bochsvga_set_displaystart(struct vgamode_s *vmode_g, int val); 51 | int bochsvga_get_dacformat(struct vgamode_s *vmode_g); 52 | int bochsvga_set_dacformat(struct vgamode_s *vmode_g, int val); 53 | int bochsvga_save_restore(int cmd, u16 seg, void *data); 54 | int bochsvga_set_mode(struct vgamode_s *vmode_g, int flags); 55 | int bochsvga_setup(void); 56 | 57 | #endif // bochsvga.h 58 | -------------------------------------------------------------------------------- /vgasrc/cbvga.h: -------------------------------------------------------------------------------- 1 | #ifndef __CBVGA_H 2 | #define __CBVGA_H 3 | 4 | #include "types.h" // u16 5 | 6 | struct vgamode_s *cbvga_find_mode(int mode); 7 | void cbvga_list_modes(u16 seg, u16 *dest, u16 *last); 8 | int cbvga_get_window(struct vgamode_s *vmode_g, int window); 9 | int cbvga_set_window(struct vgamode_s *vmode_g, int window, int val); 10 | int cbvga_get_linelength(struct vgamode_s *vmode_g); 11 | int cbvga_set_linelength(struct vgamode_s *vmode_g, int val); 12 | int cbvga_get_displaystart(struct vgamode_s *vmode_g); 13 | int cbvga_set_displaystart(struct vgamode_s *vmode_g, int val); 14 | int cbvga_get_dacformat(struct vgamode_s *vmode_g); 15 | int cbvga_set_dacformat(struct vgamode_s *vmode_g, int val); 16 | int cbvga_save_restore(int cmd, u16 seg, void *data); 17 | int cbvga_set_mode(struct vgamode_s *vmode_g, int flags); 18 | int cbvga_setup(void); 19 | 20 | #endif // cbvga.h 21 | -------------------------------------------------------------------------------- /vgasrc/clext.h: -------------------------------------------------------------------------------- 1 | #ifndef __CLEXT_H 2 | #define __CLEXT_H 3 | 4 | #include "types.h" // u16 5 | 6 | struct vgamode_s *clext_find_mode(int mode); 7 | void clext_list_modes(u16 seg, u16 *dest, u16 *last); 8 | int clext_get_window(struct vgamode_s *vmode_g, int window); 9 | int clext_set_window(struct vgamode_s *vmode_g, int window, int val); 10 | int clext_get_linelength(struct vgamode_s *vmode_g); 11 | int clext_set_linelength(struct vgamode_s *vmode_g, int val); 12 | int clext_get_displaystart(struct vgamode_s *vmode_g); 13 | int clext_set_displaystart(struct vgamode_s *vmode_g, int val); 14 | int clext_save_restore(int cmd, u16 seg, void *data); 15 | int clext_set_mode(struct vgamode_s *vmode_g, int flags); 16 | struct bregs; 17 | void clext_1012(struct bregs *regs); 18 | int clext_setup(void); 19 | 20 | #endif // clext.h 21 | -------------------------------------------------------------------------------- /vgasrc/geodevga.h: -------------------------------------------------------------------------------- 1 | // Geode GX2/LX VGA functions 2 | // 3 | // Copyright (C) 2009 Chris Kindt 4 | // 5 | // Writen for Google Summer of Code 2009 for the coreboot project 6 | // 7 | // This file may be distributed under the terms of the GNU LGPLv3 license. 8 | 9 | #ifndef GEODEVGA_H 10 | #define GEODEVGA_H 11 | 12 | #define VRC_INDEX 0xAC1C // Index register 13 | #define VRC_DATA 0xAC1E // Data register 14 | #define VR_UNLOCK 0xFC53 // Virtual register unlock code 15 | 16 | // Graphics-specific registers: 17 | #define OEM_BAR0 0x50 18 | #define OEM_BAR1 0x54 19 | #define OEM_BAR2 0x58 20 | #define OEM_BAR3 0x5C 21 | 22 | #define DC_LOCK_LOCK 0x00000000 23 | #define DC_LOCK_UNLOCK 0x00004758 24 | 25 | /* LX MSRs */ 26 | #define MSR_GLIU0 (1 << 28) 27 | #define MSR_GLIU0_BASE4 (MSR_GLIU0 + 0x23) /* LX */ 28 | #define GLIU0_P2D_BM_4 (MSR_GLIU0 + 0x24) /* GX2 */ 29 | #define GLIU0_P2D_RO (MSR_GLIU0 + 0x29) 30 | #define GLIU0_IOD_BM_0 (MSR_GLIU0 + 0xE0) 31 | #define GLIU0_IOD_BM_1 (MSR_GLIU0 + 0xE1) 32 | #define DC_SPARE 0x80000011 33 | #define VP_MSR_CONFIG_GX2 0xc0002001 /* GX2 */ 34 | #define VP_MSR_CONFIG_LX 0x48002001 /* LX */ 35 | #define VP_MSR_PADSEL 0x48002011 36 | 37 | #define VP_MSR_PADSEL_TFT_SEL_LOW 0xDFFFFFFF 38 | #define VP_MSR_PADSEL_TFT_SEL_HIGH 0x0000003F 39 | 40 | /* VP_MSR_CONFIG bits */ 41 | #define VP_MSR_CONFIG_FMT_CRT (0) 42 | #define VP_MSR_CONFIG_FMT_FP (1 << 3) 43 | #define VP_MSR_CONFIG_FPC (1 << 15) 44 | #define VP_MSR_CONFIG_FMT ((1 << 3) | (1 << 4) | (1 << 5)) 45 | 46 | 47 | /* DC REG OFFSET */ 48 | #define DC_UNLOCK 0x0 49 | #define DC_GENERAL_CFG 0x4 50 | #define DC_DISPLAY_CFG 0x8 51 | #define DC_FB_ST_OFFSET 0x10 52 | #define DC_CB_ST_OFFSET 0x14 53 | #define DC_CURS_ST_OFFSET 0x18 54 | #define DC_GLIU0_MEM_OFFSET 0x84 55 | 56 | /* VP REG OFFSET */ 57 | #define VP_VCFG 0x0 58 | #define VP_DCFG 0x8 59 | #define VP_MISC 0x50 60 | 61 | /* FP REG OFFSET */ 62 | #define FP_PT1 0x00 63 | #define FP_PT2 0x08 64 | #define FP_PM 0x10 65 | 66 | 67 | /* DC bits */ 68 | #define DC_GENERAL_CFG_VGAE (1 << 7) 69 | #define DC_DISPLAY_CFG_GDEN (1 << 3) 70 | #define DC_DISPLAY_CFG_TRUP (1 << 6) 71 | 72 | /* VP bits */ 73 | #define VP_DCFG_CRT_EN (1 << 0) 74 | #define VP_DCFG_HSYNC_EN (1 << 1) 75 | #define VP_DCFG_VSYNC_EN (1 << 2) 76 | #define VP_DCFG_DAC_BL_EN (1 << 3) 77 | #define VP_DCFG_CRT_SKEW (1 << 16) 78 | #define VP_DCFG_BYP_BOTH (1 << 0) 79 | 80 | /* FP bits */ 81 | #define FP_PM_P (1 << 24) /* panel power ctl */ 82 | #define FP_PT2_SCRC (1 << 27) /* panel shift clock retrace activity ctl */ 83 | 84 | /* Mask */ 85 | #define DC_CFG_MSK 0xf000a6 86 | 87 | int geodevga_setup(); 88 | 89 | #endif 90 | -------------------------------------------------------------------------------- /vgasrc/stdvgaio.c: -------------------------------------------------------------------------------- 1 | // Standard VGA IO port access 2 | // 3 | // Copyright (C) 2012 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU LGPLv3 license. 6 | 7 | #include "farptr.h" // GET_FARVAR 8 | #include "stdvga.h" // stdvga_pelmask_read 9 | #include "x86.h" // inb 10 | 11 | u8 12 | stdvga_pelmask_read(void) 13 | { 14 | return inb(VGAREG_PEL_MASK); 15 | } 16 | 17 | void 18 | stdvga_pelmask_write(u8 value) 19 | { 20 | outb(value, VGAREG_PEL_MASK); 21 | } 22 | 23 | 24 | u8 25 | stdvga_misc_read(void) 26 | { 27 | return inb(VGAREG_READ_MISC_OUTPUT); 28 | } 29 | 30 | void 31 | stdvga_misc_write(u8 value) 32 | { 33 | outb(value, VGAREG_WRITE_MISC_OUTPUT); 34 | } 35 | 36 | void 37 | stdvga_misc_mask(u8 off, u8 on) 38 | { 39 | stdvga_misc_write((stdvga_misc_read() & ~off) | on); 40 | } 41 | 42 | 43 | u8 44 | stdvga_sequ_read(u8 index) 45 | { 46 | outb(index, VGAREG_SEQU_ADDRESS); 47 | return inb(VGAREG_SEQU_DATA); 48 | } 49 | 50 | void 51 | stdvga_sequ_write(u8 index, u8 value) 52 | { 53 | outw((value<<8) | index, VGAREG_SEQU_ADDRESS); 54 | } 55 | 56 | void 57 | stdvga_sequ_mask(u8 index, u8 off, u8 on) 58 | { 59 | outb(index, VGAREG_SEQU_ADDRESS); 60 | u8 v = inb(VGAREG_SEQU_DATA); 61 | outb((v & ~off) | on, VGAREG_SEQU_DATA); 62 | } 63 | 64 | 65 | u8 66 | stdvga_grdc_read(u8 index) 67 | { 68 | outb(index, VGAREG_GRDC_ADDRESS); 69 | return inb(VGAREG_GRDC_DATA); 70 | } 71 | 72 | void 73 | stdvga_grdc_write(u8 index, u8 value) 74 | { 75 | outw((value<<8) | index, VGAREG_GRDC_ADDRESS); 76 | } 77 | 78 | void 79 | stdvga_grdc_mask(u8 index, u8 off, u8 on) 80 | { 81 | outb(index, VGAREG_GRDC_ADDRESS); 82 | u8 v = inb(VGAREG_GRDC_DATA); 83 | outb((v & ~off) | on, VGAREG_GRDC_DATA); 84 | } 85 | 86 | 87 | u8 88 | stdvga_crtc_read(u16 crtc_addr, u8 index) 89 | { 90 | outb(index, crtc_addr); 91 | return inb(crtc_addr + 1); 92 | } 93 | 94 | void 95 | stdvga_crtc_write(u16 crtc_addr, u8 index, u8 value) 96 | { 97 | outw((value<<8) | index, crtc_addr); 98 | } 99 | 100 | void 101 | stdvga_crtc_mask(u16 crtc_addr, u8 index, u8 off, u8 on) 102 | { 103 | outb(index, crtc_addr); 104 | u8 v = inb(crtc_addr + 1); 105 | outb((v & ~off) | on, crtc_addr + 1); 106 | } 107 | 108 | 109 | u8 110 | stdvga_attr_read(u8 index) 111 | { 112 | inb(VGAREG_ACTL_RESET); 113 | u8 orig = inb(VGAREG_ACTL_ADDRESS); 114 | outb(index, VGAREG_ACTL_ADDRESS); 115 | u8 v = inb(VGAREG_ACTL_READ_DATA); 116 | inb(VGAREG_ACTL_RESET); 117 | outb(orig, VGAREG_ACTL_ADDRESS); 118 | return v; 119 | } 120 | 121 | void 122 | stdvga_attr_write(u8 index, u8 value) 123 | { 124 | inb(VGAREG_ACTL_RESET); 125 | u8 orig = inb(VGAREG_ACTL_ADDRESS); 126 | outb(index, VGAREG_ACTL_ADDRESS); 127 | outb(value, VGAREG_ACTL_WRITE_DATA); 128 | outb(orig, VGAREG_ACTL_ADDRESS); 129 | } 130 | 131 | void 132 | stdvga_attr_mask(u8 index, u8 off, u8 on) 133 | { 134 | inb(VGAREG_ACTL_RESET); 135 | u8 orig = inb(VGAREG_ACTL_ADDRESS); 136 | outb(index, VGAREG_ACTL_ADDRESS); 137 | u8 v = inb(VGAREG_ACTL_READ_DATA); 138 | outb((v & ~off) | on, VGAREG_ACTL_WRITE_DATA); 139 | outb(orig, VGAREG_ACTL_ADDRESS); 140 | } 141 | 142 | u8 143 | stdvga_attrindex_read(void) 144 | { 145 | inb(VGAREG_ACTL_RESET); 146 | return inb(VGAREG_ACTL_ADDRESS); 147 | } 148 | 149 | void 150 | stdvga_attrindex_write(u8 value) 151 | { 152 | inb(VGAREG_ACTL_RESET); 153 | outb(value, VGAREG_ACTL_ADDRESS); 154 | } 155 | 156 | 157 | void 158 | stdvga_dac_read(u16 seg, u8 *data_far, u8 start, int count) 159 | { 160 | outb(start, VGAREG_DAC_READ_ADDRESS); 161 | while (count) { 162 | SET_FARVAR(seg, *data_far, inb(VGAREG_DAC_DATA)); 163 | data_far++; 164 | SET_FARVAR(seg, *data_far, inb(VGAREG_DAC_DATA)); 165 | data_far++; 166 | SET_FARVAR(seg, *data_far, inb(VGAREG_DAC_DATA)); 167 | data_far++; 168 | count--; 169 | } 170 | } 171 | 172 | void 173 | stdvga_dac_write(u16 seg, u8 *data_far, u8 start, int count) 174 | { 175 | outb(start, VGAREG_DAC_WRITE_ADDRESS); 176 | while (count) { 177 | outb(GET_FARVAR(seg, *data_far), VGAREG_DAC_DATA); 178 | data_far++; 179 | outb(GET_FARVAR(seg, *data_far), VGAREG_DAC_DATA); 180 | data_far++; 181 | outb(GET_FARVAR(seg, *data_far), VGAREG_DAC_DATA); 182 | data_far++; 183 | count--; 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /vgasrc/vgalayout.lds.S: -------------------------------------------------------------------------------- 1 | // Linker definitions for an option rom 2 | // 3 | // Copyright (C) 2009 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU LGPLv3 license. 6 | 7 | OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") 8 | OUTPUT_ARCH("i386") 9 | ENTRY(_optionrom_entry) 10 | SECTIONS 11 | { 12 | .text 0 : { 13 | KEEP(*(.rom.header)) 14 | *(.text.*) 15 | _rodata = . ; 16 | *(.rodata*) 17 | *(.data16.*) 18 | } 19 | 20 | // Discard regular data sections to force a link error if 21 | // 16bit code attempts to access data not marked with VAR16. 22 | /DISCARD/ : { *(.text*) *(.rodata*) *(.data*) *(.bss*) *(COMMON) } 23 | } 24 | --------------------------------------------------------------------------------