From 3d029417164e9a6dffee491fb061de3de6d85595 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Wed, 5 Mar 2008 20:43:38 -0500 Subject: [PATCH] This patch adds the BIOS support for SMP, ACPI, PCI, SMM, SMBIOS. Signed-off-by: Nguyen Anh Quynh Several compile fixes provided by Kevin O'Connor --- Makefile | 20 ++++++++++++++-- src/config.h | 16 +++++++++++++ src/post.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/system.c | 3 +-- src/types.h | 1 + src/util.h | 15 ++++++++++++ 6 files changed, 118 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index bb078f4..7b9caed 100644 --- a/Makefile +++ b/Makefile @@ -4,13 +4,19 @@ # # This file may be distributed under the terms of the GNU GPLv3 license. +# Don't compile ACPI DSDT by default +# Uncomment the below line in case you want to compile DSDT yourself. +# Note: "iasl" package is required to compile. +#BUILD_ACPI = 1 +BUILD_ACPI = 0 + # Output directory OUT=out/ # Source files SRC16=floppy.c disk.c system.c clock.c serial.c kbd.c mouse.c output.c \ boot.c ata.c cdrom.c apm.c -SRC32=post.c output.c +SRC32=post.c output.c smbios.c acpi.c smm.c smp.c pci.c TABLESRC=font.c cbt.c floppy_dbt.c cc-option = $(shell if test -z "`$(1) $(2) -S -o /dev/null -xc \ @@ -28,6 +34,7 @@ CFLAGS16INC = $(COMMONCFLAGS) -DMODE16 -fno-jump-tables CFLAGS16 = $(CFLAGS16INC) -g TABLETMP=$(addprefix $(OUT), $(patsubst %.c,%.16.s,$(TABLESRC))) + all: $(OUT) $(OUT)rom.bin $(TABLETMP) # Run with "make V=1" to see the actual compile commands @@ -99,7 +106,15 @@ $(OUT)rom16.bin: $(OUT)rom16.o @echo " Extracting binary $@" $(Q)objcopy -O binary $< $@ -$(OUT)romlayout32.o: $(OUT)rom16.offset.auto.h ; $(call whole-compile, $(CFLAGS), $(addprefix src/, $(SRC32)),$@) +$(OUT)romlayout32.o: $(OUT)acpi-dsdt.hex $(OUT)rom16.offset.auto.h ; $(call whole-compile, $(CFLAGS), $(addprefix src/, $(SRC32)),$@) + +ifeq ($(BUILD_ACPI), 1) +$(OUT)acpi-dsdt.hex: src/acpi-dsdt.dsl + iasl -tc -p $@ $< +else +$(OUT)acpi-dsdt.hex: src/acpi-dsdt.hex + cp src/acpi-dsdt.hex $(OUT) +endif $(OUT)rom32.o: $(OUT)romlayout32.o $(OUT)rombios32.lds @echo " Linking $@" @@ -110,6 +125,7 @@ $(OUT)rom.bin: $(OUT)rom16.bin $(OUT)rom32.bin $(OUT)rom16.offset.auto.h $(OUT)r $(Q)./tools/buildrom.py ####### Generic rules +.PHONY : clean clean: rm -rf $(OUT) diff --git a/src/config.h b/src/config.h index 199627e..e896ceb 100644 --- a/src/config.h +++ b/src/config.h @@ -2,6 +2,14 @@ #define __CONFIG_H // Configuration definitions. +//#define QEMU_SUPPORT + +#ifdef QEMU_SUPPORT +#define CONFIG_BIOS_NAME "QEMU" +#else +#define CONFIG_BIOS_NAME "Bochs" +#endif + #define CONFIG_FLOPPY_SUPPORT 1 #define CONFIG_PS2_MOUSE 1 #define CONFIG_ATA 1 @@ -18,4 +26,12 @@ #define CONFIG_SUBMODEL_ID 0x00 #define CONFIG_BIOS_REVISION 0x01 +/* define it if the (emulated) hardware supports SMM mode */ +#define CONFIG_SMM 1 + +/* if true, put the MP float table and ACPI RSDT in EBDA and the MP + table in RAM. Unfortunately, Linux has bugs with that, so we prefer + to modify the BIOS in shadow RAM */ +#define CONFIG_USE_EBDA_TABLES 0 + #endif // config.h diff --git a/src/post.c b/src/post.c index a1c71ee..b157a98 100644 --- a/src/post.c +++ b/src/post.c @@ -12,6 +12,27 @@ #include "util.h" // memset #include "biosvar.h" // struct bios_data_area_s +#include "acpi.h" +#include "smbios.h" +#include "smp.h" +#include "pci.h" + +u32 cpuid_signature; +u32 cpuid_features; +u32 cpuid_ext_features; +unsigned long ram_size; +unsigned long bios_table_cur_addr; +unsigned long bios_table_end_addr; + +#ifdef CONFIG_USE_EBDA_TABLES +unsigned long ebda_cur_addr; +#endif + +#define cpuid(index, eax, ebx, ecx, edx) \ + asm volatile ("cpuid" \ + : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) \ + : "0" (index)) + #define bda ((struct bios_data_area_s *)0) #define ebda ((struct extended_bios_data_area_s *)(EBDA_SEG<<4)) #define ipl ((struct ipl_s *)(IPL_SEG<<4)) @@ -501,6 +522,32 @@ rom_scan(u32 start, u32 end) } } +static void +ram_probe(void) +{ + if (inb_cmos(0x34) | inb_cmos(0x35)) + ram_size = (inb_cmos(0x34) | (inb_cmos(0x35) << 8)) * 65536 + + 16 * 1024 * 1024; + else + ram_size = (inb_cmos(0x17) | (inb_cmos(0x18) << 8)) * 1024; +#ifdef CONFIG_USE_EBDA_TABLES + ebda_cur_addr = ((*(u16 *)(0x40e)) << 4) + 0x380; +#endif + + BX_INFO("ram_size=0x%08lx\n", ram_size); +} + +static void +cpu_probe(void) +{ + u32 eax, ebx, ecx, edx; + + cpuid(1, eax, ebx, ecx, edx); + cpuid_signature = eax; + cpuid_features = edx; + cpuid_ext_features = ecx; +} + static void post() { @@ -533,6 +580,26 @@ post() init_boot_vectors(); rom_scan(0xc8000, 0xe0000); + ram_probe(); + cpu_probe(); + smp_probe(); + //pci_bios_init(); + + if (bios_table_cur_addr != 0) { + mptable_init(); + + smbios_init(); + + if (acpi_enabled) + acpi_bios_init(); + + bios_lock_shadow_ram(); + + BX_INFO("bios_table_cur_addr: 0x%08lx\n", bios_table_cur_addr); + if (bios_table_cur_addr > bios_table_end_addr) + BX_PANIC("bios_table_end_addr overflow!\n"); + } + callrom(SEG_BIOS, OFFSET_begin_boot); } diff --git a/src/system.c b/src/system.c index 29f0052..6f581ef 100644 --- a/src/system.c +++ b/src/system.c @@ -5,6 +5,7 @@ // // This file may be distributed under the terms of the GNU GPLv3 license. +#include "acpi.h" #include "util.h" // irq_restore #include "biosvar.h" // CONFIG_BIOS_TABLE #include "ioport.h" // inb @@ -282,8 +283,6 @@ handle_15e801(struct bregs *regs) set_cf(regs, 0); } -#define ACPI_DATA_SIZE 0x00010000L - static void set_e820_range(u16 DI, u32 start, u32 end, u16 type) { diff --git a/src/types.h b/src/types.h index eb10a7b..10c3dfe 100644 --- a/src/types.h +++ b/src/types.h @@ -13,6 +13,7 @@ typedef signed short s16; typedef unsigned int u32; typedef signed int s32; typedef u32 size_t; +typedef unsigned long long u64; #define VISIBLE __attribute__((externally_visible)) diff --git a/src/util.h b/src/util.h index e84c7d8..488267d 100644 --- a/src/util.h +++ b/src/util.h @@ -52,6 +52,15 @@ memset(void *s, int c, size_t n) ((char *)s)[--n] = c; } +static inline void +memcpy(void *d, void *s, size_t n) +{ + while (n) { + ((char *)d)[n-1] = ((char *)s)[n-1]; + n--; + } +} + static inline void eoi_master_pic() { @@ -138,4 +147,10 @@ handle_ret(struct bregs *regs, u8 code) set_cf(regs, code); } +unsigned long +align(unsigned long addr, unsigned long v) +{ + return (addr + v - 1) & ~(v - 1); +} + #endif // util.h -- 2.25.1