|
|
1.1 ! root 1: // 32bit code to Power On Self Test (POST) a machine. ! 2: // ! 3: // Copyright (C) 2008,2009 Kevin O'Connor <[email protected]> ! 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 "ioport.h" // PORT_* ! 9: #include "config.h" // CONFIG_* ! 10: #include "cmos.h" // CMOS_* ! 11: #include "util.h" // memset ! 12: #include "biosvar.h" // struct bios_data_area_s ! 13: #include "disk.h" // floppy_drive_setup ! 14: #include "ata.h" // ata_setup ! 15: #include "memmap.h" // add_e820 ! 16: #include "pic.h" // pic_setup ! 17: #include "pci.h" // create_pirtable ! 18: #include "acpi.h" // acpi_bios_init ! 19: #include "bregs.h" // struct bregs ! 20: #include "mptable.h" // mptable_init ! 21: #include "boot.h" // IPL ! 22: #include "usb.h" // usb_setup ! 23: #include "smbios.h" // smbios_init ! 24: #include "paravirt.h" // qemu_cfg_port_probe ! 25: #include "ps2port.h" // ps2port_setup ! 26: ! 27: void ! 28: __set_irq(int vector, void *loc) ! 29: { ! 30: SET_IVT(vector, SEGOFF(SEG_BIOS, (u32)loc - BUILD_BIOS_ADDR)); ! 31: } ! 32: ! 33: #define set_irq(vector, func) do { \ ! 34: extern void func (void); \ ! 35: __set_irq(vector, func); \ ! 36: } while (0) ! 37: ! 38: static void ! 39: init_ivt() ! 40: { ! 41: dprintf(3, "init ivt\n"); ! 42: ! 43: // Initialize all vectors to the default handler. ! 44: int i; ! 45: for (i=0; i<256; i++) ! 46: set_irq(i, entry_iret_official); ! 47: ! 48: // Initialize all hw vectors to a default hw handler. ! 49: for (i=0x08; i<=0x0f; i++) ! 50: set_irq(i, entry_hwpic1); ! 51: for (i=0x70; i<=0x77; i++) ! 52: set_irq(i, entry_hwpic2); ! 53: ! 54: // Initialize software handlers. ! 55: set_irq(0x02, entry_02); ! 56: set_irq(0x10, entry_10); ! 57: set_irq(0x11, entry_11); ! 58: set_irq(0x12, entry_12); ! 59: set_irq(0x13, entry_13_official); ! 60: set_irq(0x14, entry_14); ! 61: set_irq(0x15, entry_15); ! 62: set_irq(0x16, entry_16); ! 63: set_irq(0x17, entry_17); ! 64: set_irq(0x18, entry_18); ! 65: set_irq(0x19, entry_19_official); ! 66: set_irq(0x1a, entry_1a); ! 67: set_irq(0x40, entry_40); ! 68: ! 69: // set vector 0x79 to zero ! 70: // this is used by 'gardian angel' protection system ! 71: SET_IVT(0x79, SEGOFF(0, 0)); ! 72: ! 73: __set_irq(0x1E, &diskette_param_table2); ! 74: } ! 75: ! 76: static void ! 77: init_bda() ! 78: { ! 79: dprintf(3, "init bda\n"); ! 80: ! 81: struct bios_data_area_s *bda = MAKE_FLATPTR(SEG_BDA, 0); ! 82: memset(bda, 0, sizeof(*bda)); ! 83: ! 84: int esize = EBDA_SIZE_START; ! 85: SET_BDA(mem_size_kb, BUILD_LOWRAM_END/1024 - esize); ! 86: u16 eseg = EBDA_SEGMENT_START; ! 87: SET_BDA(ebda_seg, eseg); ! 88: ! 89: // Init ebda ! 90: struct extended_bios_data_area_s *ebda = get_ebda_ptr(); ! 91: memset(ebda, 0, sizeof(*ebda)); ! 92: ebda->size = esize; ! 93: } ! 94: ! 95: static void ! 96: ram_probe(void) ! 97: { ! 98: dprintf(3, "Find memory size\n"); ! 99: if (CONFIG_COREBOOT) { ! 100: coreboot_setup(); ! 101: } else { ! 102: // On emulators, get memory size from nvram. ! 103: u32 rs = ((inb_cmos(CMOS_MEM_EXTMEM2_LOW) << 16) ! 104: | (inb_cmos(CMOS_MEM_EXTMEM2_HIGH) << 24)); ! 105: if (rs) ! 106: rs += 16 * 1024 * 1024; ! 107: else ! 108: rs = (((inb_cmos(CMOS_MEM_EXTMEM_LOW) << 10) ! 109: | (inb_cmos(CMOS_MEM_EXTMEM_HIGH) << 18)) ! 110: + 1 * 1024 * 1024); ! 111: RamSize = rs; ! 112: add_e820(0, rs, E820_RAM); ! 113: ! 114: // Check for memory over 4Gig ! 115: u64 high = ((inb_cmos(CMOS_MEM_HIGHMEM_LOW) << 16) ! 116: | (inb_cmos(CMOS_MEM_HIGHMEM_MID) << 24) ! 117: | ((u64)inb_cmos(CMOS_MEM_HIGHMEM_HIGH) << 32)); ! 118: RamSizeOver4G = high; ! 119: add_e820(0x100000000ull, high, E820_RAM); ! 120: ! 121: /* reserve 256KB BIOS area at the end of 4 GB */ ! 122: add_e820(0xfffc0000, 256*1024, E820_RESERVED); ! 123: } ! 124: ! 125: // Don't declare any memory between 0xa0000 and 0x100000 ! 126: add_e820(BUILD_LOWRAM_END, BUILD_BIOS_ADDR-BUILD_LOWRAM_END, E820_HOLE); ! 127: ! 128: // Mark known areas as reserved. ! 129: u16 ebda_seg = get_ebda_seg(); ! 130: add_e820((u32)MAKE_FLATPTR(ebda_seg, 0), GET_EBDA2(ebda_seg, size) * 1024 ! 131: , E820_RESERVED); ! 132: add_e820(BUILD_BIOS_ADDR, BUILD_BIOS_SIZE, E820_RESERVED); ! 133: ! 134: if (kvm_para_available()) ! 135: // 4 pages before the bios, 3 pages for vmx tss pages, the ! 136: // other page for EPT real mode pagetable ! 137: add_e820(0xfffbc000, 4*4096, E820_RESERVED); ! 138: ! 139: dprintf(1, "Ram Size=0x%08x\n", RamSize); ! 140: } ! 141: ! 142: static void ! 143: init_bios_tables(void) ! 144: { ! 145: if (CONFIG_COREBOOT) { ! 146: coreboot_copy_biostable(); ! 147: return; ! 148: } ! 149: ! 150: create_pirtable(); ! 151: ! 152: mptable_init(); ! 153: ! 154: smbios_init(); ! 155: ! 156: acpi_bios_init(); ! 157: } ! 158: ! 159: // Main setup code. ! 160: static void ! 161: post() ! 162: { ! 163: // Detect and init ram. ! 164: init_ivt(); ! 165: init_bda(); ! 166: memmap_setup(); ! 167: ram_probe(); ! 168: malloc_setup(); ! 169: thread_setup(); ! 170: ! 171: // Init base pc hardware. ! 172: pic_setup(); ! 173: timer_setup(); ! 174: mathcp_setup(); ! 175: ! 176: // Initialize smp ! 177: qemu_cfg_port_probe(); ! 178: smp_probe_setup(); ! 179: mtrr_setup(); ! 180: smp_probe(); ! 181: ! 182: // Initialize pci ! 183: pci_setup(); ! 184: smm_init(); ! 185: ! 186: // Setup interfaces that option roms may need ! 187: pmm_setup(); ! 188: pnp_setup(); ! 189: kbd_setup(); ! 190: mouse_setup(); ! 191: init_bios_tables(); ! 192: ! 193: // Run vga option rom (if running synchronously) ! 194: if (!CONFIG_THREADS || !CONFIG_THREAD_OPTIONROMS) ! 195: vga_setup(); ! 196: ! 197: // Initialize hardware devices ! 198: usb_setup(); ! 199: ps2port_setup(); ! 200: lpt_setup(); ! 201: serial_setup(); ! 202: ! 203: boot_setup(); ! 204: drive_setup(); ! 205: cdemu_setup(); ! 206: floppy_setup(); ! 207: ata_setup(); ! 208: ramdisk_setup(); ! 209: ! 210: // Run option roms ! 211: if (CONFIG_THREADS && CONFIG_THREAD_OPTIONROMS) { ! 212: // Run option roms while hw init still in progress. ! 213: vga_setup(); ! 214: optionrom_setup(); ! 215: wait_threads(); ! 216: } else { ! 217: // Wait for hw init to finish and run non-vga option roms. ! 218: wait_threads(); ! 219: optionrom_setup(); ! 220: } ! 221: ! 222: // Run BCVs and show optional boot menu ! 223: boot_prep(); ! 224: ! 225: // Finalize data structures before boot ! 226: pmm_finalize(); ! 227: malloc_finalize(); ! 228: memmap_finalize(); ! 229: } ! 230: ! 231: // 32-bit entry point. ! 232: void VISIBLE32 ! 233: _start() ! 234: { ! 235: init_dma(); ! 236: ! 237: debug_serial_setup(); ! 238: dprintf(1, "Start bios (version %s)\n", VERSION); ! 239: ! 240: // Allow writes to modify bios area (0xf0000) ! 241: make_bios_writable(); ! 242: ! 243: // Perform main setup code. ! 244: post(); ! 245: ! 246: // Setup bios checksum. ! 247: BiosChecksum -= checksum((u8*)BUILD_BIOS_ADDR, BUILD_BIOS_SIZE); ! 248: ! 249: // Write protect bios memory. ! 250: make_bios_readonly(); ! 251: ! 252: // Invoke int 19 to start boot process. ! 253: dprintf(3, "Jump to int19\n"); ! 254: struct bregs br; ! 255: memset(&br, 0, sizeof(br)); ! 256: br.flags = F_IF; ! 257: call16_int(0x19, &br); ! 258: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.