diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/Kconfig | 15 | ||||
-rw-r--r-- | arch/x86/cpu/interrupts.c | 2 | ||||
-rw-r--r-- | arch/x86/cpu/pci.c | 45 | ||||
-rw-r--r-- | arch/x86/cpu/qemu/Makefile | 1 | ||||
-rw-r--r-- | arch/x86/cpu/qemu/pci.c | 138 | ||||
-rw-r--r-- | arch/x86/cpu/qemu/qemu.c | 82 | ||||
-rw-r--r-- | arch/x86/cpu/queensbay/tnc.c | 26 | ||||
-rw-r--r-- | arch/x86/include/asm/arch-queensbay/tnc.h | 7 | ||||
-rw-r--r-- | arch/x86/include/asm/i8254.h | 43 | ||||
-rw-r--r-- | arch/x86/include/asm/i8259.h | 31 | ||||
-rw-r--r-- | arch/x86/include/asm/interrupt.h | 2 | ||||
-rw-r--r-- | arch/x86/include/asm/pci.h | 21 | ||||
-rw-r--r-- | arch/x86/include/asm/u-boot-x86.h | 2 | ||||
-rw-r--r-- | arch/x86/lib/Makefile | 4 | ||||
-rw-r--r-- | arch/x86/lib/fsp/fsp_common.c | 5 | ||||
-rw-r--r-- | arch/x86/lib/i8254.c | 37 | ||||
-rw-r--r-- | arch/x86/lib/i8259.c (renamed from arch/x86/lib/pcat_interrupts.c) | 47 | ||||
-rw-r--r-- | arch/x86/lib/interrupts.c | 10 | ||||
-rw-r--r-- | arch/x86/lib/pcat_timer.c | 27 | ||||
-rw-r--r-- | arch/x86/lib/tsc_timer.c | 6 |
20 files changed, 221 insertions, 330 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index f92082d..8914be3 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -420,6 +420,21 @@ config PCIE_ECAM_SIZE so a default 0x10000000 size covers all of the 256 buses which is the maximum number of PCI buses as defined by the PCI specification. +config I8259_PIC + bool + default y + help + Intel 8259 ISA compatible chipset incorporates two 8259 (master and + slave) interrupt controllers. Include this to have U-Boot set up + the interrupt correctly. + +config I8254_TIMER + bool + default y + help + Intel 8254 timer contains three counters which have fixed uses. + Include this to have U-Boot set up the timer correctly. + source "arch/x86/lib/efi/Kconfig" endmenu diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c index addd26e..b00ddc0 100644 --- a/arch/x86/cpu/interrupts.c +++ b/arch/x86/cpu/interrupts.c @@ -252,7 +252,7 @@ int interrupt_init(void) /* Just in case... */ disable_interrupts(); -#ifdef CONFIG_SYS_PCAT_INTERRUPTS +#ifdef CONFIG_I8259_PIC /* Initialize the master/slave i8259 pic */ i8259_init(); #endif diff --git a/arch/x86/cpu/pci.c b/arch/x86/cpu/pci.c index d2ec45a..7a31260 100644 --- a/arch/x86/cpu/pci.c +++ b/arch/x86/cpu/pci.c @@ -19,51 +19,6 @@ DECLARE_GLOBAL_DATA_PTR; -static struct pci_controller x86_hose; - -int pci_early_init_hose(struct pci_controller **hosep) -{ - struct pci_controller *hose; - - hose = calloc(1, sizeof(struct pci_controller)); - if (!hose) - return -ENOMEM; - - board_pci_setup_hose(hose); - pci_setup_type1(hose); - hose->last_busno = pci_hose_scan(hose); - gd->hose = hose; - *hosep = hose; - - return 0; -} - -__weak int board_pci_pre_scan(struct pci_controller *hose) -{ - return 0; -} - -__weak int board_pci_post_scan(struct pci_controller *hose) -{ - return 0; -} - -void pci_init_board(void) -{ - struct pci_controller *hose = &x86_hose; - - /* Stop using the early hose */ - gd->hose = NULL; - - board_pci_setup_hose(hose); - pci_setup_type1(hose); - pci_register_hose(hose); - - board_pci_pre_scan(hose); - hose->last_busno = pci_hose_scan(hose); - board_pci_post_scan(hose); -} - static struct pci_controller *get_hose(void) { if (gd->hose) diff --git a/arch/x86/cpu/qemu/Makefile b/arch/x86/cpu/qemu/Makefile index 1c00d1d..3f3958a 100644 --- a/arch/x86/cpu/qemu/Makefile +++ b/arch/x86/cpu/qemu/Makefile @@ -9,4 +9,3 @@ obj-y += car.o dram.o endif obj-y += qemu.o obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi.o dsdt.o -obj-$(CONFIG_PCI) += pci.o diff --git a/arch/x86/cpu/qemu/pci.c b/arch/x86/cpu/qemu/pci.c deleted file mode 100644 index 2e94456..0000000 --- a/arch/x86/cpu/qemu/pci.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <pci.h> -#include <pci_rom.h> -#include <asm/pci.h> -#include <asm/arch/device.h> -#include <asm/arch/qemu.h> - -DECLARE_GLOBAL_DATA_PTR; - -static bool i440fx; - -void board_pci_setup_hose(struct pci_controller *hose) -{ - hose->first_busno = 0; - hose->last_busno = 0; - - /* PCI memory space */ - pci_set_region(hose->regions + 0, - CONFIG_PCI_MEM_BUS, - CONFIG_PCI_MEM_PHYS, - CONFIG_PCI_MEM_SIZE, - PCI_REGION_MEM); - - /* PCI IO space */ - pci_set_region(hose->regions + 1, - CONFIG_PCI_IO_BUS, - CONFIG_PCI_IO_PHYS, - CONFIG_PCI_IO_SIZE, - PCI_REGION_IO); - - pci_set_region(hose->regions + 2, - CONFIG_PCI_PREF_BUS, - CONFIG_PCI_PREF_PHYS, - CONFIG_PCI_PREF_SIZE, - PCI_REGION_PREFETCH); - - pci_set_region(hose->regions + 3, - 0, - 0, - gd->ram_size, - PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); - - hose->region_count = 4; -} - -int board_pci_post_scan(struct pci_controller *hose) -{ - int ret = 0; - u16 device, xbcs; - int pam, i; - pci_dev_t vga; - ulong start; - - /* - * i440FX and Q35 chipset have different PAM register offset, but with - * the same bitfield layout. Here we determine the offset based on its - * PCI device ID. - */ - device = x86_pci_read_config16(PCI_BDF(0, 0, 0), PCI_DEVICE_ID); - i440fx = (device == PCI_DEVICE_ID_INTEL_82441); - pam = i440fx ? I440FX_PAM : Q35_PAM; - - /* - * Initialize Programmable Attribute Map (PAM) Registers - * - * Configure legacy segments C/D/E/F to system RAM - */ - for (i = 0; i < PAM_NUM; i++) - x86_pci_write_config8(PCI_BDF(0, 0, 0), pam + i, PAM_RW); - - if (i440fx) { - /* - * Enable legacy IDE I/O ports decode - * - * Note: QEMU always decode legacy IDE I/O port on PIIX chipset. - * However Linux ata_piix driver does sanity check on these two - * registers to see whether legacy ports decode is turned on. - * This is to make Linux ata_piix driver happy. - */ - x86_pci_write_config16(PIIX_IDE, IDE0_TIM, IDE_DECODE_EN); - x86_pci_write_config16(PIIX_IDE, IDE1_TIM, IDE_DECODE_EN); - - /* Enable I/O APIC */ - xbcs = x86_pci_read_config16(PIIX_ISA, XBCS); - xbcs |= APIC_EN; - x86_pci_write_config16(PIIX_ISA, XBCS, xbcs); - } else { - /* Configure PCIe ECAM base address */ - x86_pci_write_config32(PCI_BDF(0, 0, 0), PCIEX_BAR, - CONFIG_PCIE_ECAM_BASE | BAR_EN); - } - - /* - * QEMU emulated graphic card shows in the PCI configuration space with - * PCI vendor id and device id as an artificial pair 0x1234:0x1111. - * It is on PCI bus 0, function 0, but device number is not consistent - * for the two x86 targets it supports. For i440FX and PIIX chipset - * board, it shows as device 2, while for Q35 and ICH9 chipset board, - * it shows as device 1. - */ - vga = i440fx ? I440FX_VGA : Q35_VGA; - start = get_timer(0); - ret = pci_run_vga_bios(vga, NULL, PCI_ROM_USE_NATIVE); - debug("BIOS ran in %lums\n", get_timer(start)); - - return ret; -} - -#ifdef CONFIG_GENERATE_MP_TABLE -int mp_determine_pci_dstirq(int bus, int dev, int func, int pirq) -{ - u8 irq; - - if (i440fx) { - /* - * Not like most x86 platforms, the PIRQ[A-D] on PIIX3 are not - * connected to I/O APIC INTPIN#16-19. Instead they are routed - * to an irq number controled by the PIRQ routing register. - */ - irq = x86_pci_read_config8(PCI_BDF(bus, dev, func), - PCI_INTERRUPT_LINE); - } else { - /* - * ICH9's PIRQ[A-H] are not consecutive numbers from 0 to 7. - * PIRQ[A-D] still maps to [0-3] but PIRQ[E-H] maps to [8-11]. - */ - irq = pirq < 8 ? pirq + 16 : pirq + 12; - } - - return irq; -} -#endif diff --git a/arch/x86/cpu/qemu/qemu.c b/arch/x86/cpu/qemu/qemu.c index 7c03e02..84fb082 100644 --- a/arch/x86/cpu/qemu/qemu.c +++ b/arch/x86/cpu/qemu/qemu.c @@ -6,8 +6,58 @@ #include <common.h> #include <asm/irq.h> +#include <asm/pci.h> #include <asm/post.h> #include <asm/processor.h> +#include <asm/arch/device.h> +#include <asm/arch/qemu.h> + +static bool i440fx; + +static void qemu_chipset_init(void) +{ + u16 device, xbcs; + int pam, i; + + /* + * i440FX and Q35 chipset have different PAM register offset, but with + * the same bitfield layout. Here we determine the offset based on its + * PCI device ID. + */ + device = x86_pci_read_config16(PCI_BDF(0, 0, 0), PCI_DEVICE_ID); + i440fx = (device == PCI_DEVICE_ID_INTEL_82441); + pam = i440fx ? I440FX_PAM : Q35_PAM; + + /* + * Initialize Programmable Attribute Map (PAM) Registers + * + * Configure legacy segments C/D/E/F to system RAM + */ + for (i = 0; i < PAM_NUM; i++) + x86_pci_write_config8(PCI_BDF(0, 0, 0), pam + i, PAM_RW); + + if (i440fx) { + /* + * Enable legacy IDE I/O ports decode + * + * Note: QEMU always decode legacy IDE I/O port on PIIX chipset. + * However Linux ata_piix driver does sanity check on these two + * registers to see whether legacy ports decode is turned on. + * This is to make Linux ata_piix driver happy. + */ + x86_pci_write_config16(PIIX_IDE, IDE0_TIM, IDE_DECODE_EN); + x86_pci_write_config16(PIIX_IDE, IDE1_TIM, IDE_DECODE_EN); + + /* Enable I/O APIC */ + xbcs = x86_pci_read_config16(PIIX_ISA, XBCS); + xbcs |= APIC_EN; + x86_pci_write_config16(PIIX_ISA, XBCS, xbcs); + } else { + /* Configure PCIe ECAM base address */ + x86_pci_write_config32(PCI_BDF(0, 0, 0), PCIEX_BAR, + CONFIG_PCIE_ECAM_BASE | BAR_EN); + } +} int arch_cpu_init(void) { @@ -39,7 +89,39 @@ void reset_cpu(ulong addr) x86_full_reset(); } +int arch_early_init_r(void) +{ + qemu_chipset_init(); + + return 0; +} + int arch_misc_init(void) { return pirq_init(); } + +#ifdef CONFIG_GENERATE_MP_TABLE +int mp_determine_pci_dstirq(int bus, int dev, int func, int pirq) +{ + u8 irq; + + if (i440fx) { + /* + * Not like most x86 platforms, the PIRQ[A-D] on PIIX3 are not + * connected to I/O APIC INTPIN#16-19. Instead they are routed + * to an irq number controled by the PIRQ routing register. + */ + irq = x86_pci_read_config8(PCI_BDF(bus, dev, func), + PCI_INTERRUPT_LINE); + } else { + /* + * ICH9's PIRQ[A-H] are not consecutive numbers from 0 to 7. + * PIRQ[A-D] still maps to [0-3] but PIRQ[E-H] maps to [8-11]. + */ + irq = pirq < 8 ? pirq + 16 : pirq + 12; + } + + return irq; +} +#endif diff --git a/arch/x86/cpu/queensbay/tnc.c b/arch/x86/cpu/queensbay/tnc.c index 0c02a44..933d189 100644 --- a/arch/x86/cpu/queensbay/tnc.c +++ b/arch/x86/cpu/queensbay/tnc.c @@ -25,12 +25,26 @@ static void unprotect_spi_flash(void) static void __maybe_unused disable_igd(void) { - u32 gc; - - gc = x86_pci_read_config32(TNC_IGD, IGD_GC); - gc &= ~GMS_MASK; - gc |= VGA_DISABLE; - x86_pci_write_config32(TNC_IGD, IGD_GC, gc); + /* + * According to Atom E6xx datasheet, setting VGA Disable (bit17) + * of Graphics Controller register (offset 0x50) prevents IGD + * (D2:F0) from reporting itself as a VGA display controller + * class in the PCI configuration space, and should also prevent + * it from responding to VGA legacy memory range and I/O addresses. + * + * However test result shows that with just VGA Disable bit set and + * a PCIe graphics card connected to one of the PCIe controllers on + * the E6xx, accessing the VGA legacy space still causes system hang. + * After a number of attempts, it turns out besides VGA Disable bit, + * the SDVO (D3:F0) device should be disabled to make it work. + * + * To simplify, use the Function Disable register (offset 0xc4) + * to disable both IGD (D2:F0) and SDVO (D3:F0) devices. Now these + * two devices will be completely disabled (invisible in the PCI + * configuration space) unless a system reset is performed. + */ + x86_pci_write_config32(TNC_IGD, IGD_FD, FUNC_DISABLE); + x86_pci_write_config32(TNC_SDVO, IGD_FD, FUNC_DISABLE); } int arch_cpu_init(void) diff --git a/arch/x86/include/asm/arch-queensbay/tnc.h b/arch/x86/include/asm/arch-queensbay/tnc.h index 2365394..8477d92 100644 --- a/arch/x86/include/asm/arch-queensbay/tnc.h +++ b/arch/x86/include/asm/arch-queensbay/tnc.h @@ -7,10 +7,9 @@ #ifndef _X86_ARCH_TNC_H_ #define _X86_ARCH_TNC_H_ -/* IGD Control Register */ -#define IGD_GC 0x50 -#define VGA_DISABLE 0x00020000 -#define GMS_MASK 0x00700000 +/* IGD Function Disable Register */ +#define IGD_FD 0xc4 +#define FUNC_DISABLE 0x00000001 /* Memory BAR Enable */ #define MEM_BAR_EN 0x00000001 diff --git a/arch/x86/include/asm/i8254.h b/arch/x86/include/asm/i8254.h index 4116de1..48e4df2 100644 --- a/arch/x86/include/asm/i8254.h +++ b/arch/x86/include/asm/i8254.h @@ -5,38 +5,35 @@ * SPDX-License-Identifier: GPL-2.0+ */ - /* i8254.h Intel 8254 PIT registers */ - #ifndef _ASMI386_I8254_H_ -#define _ASMI386_I8954_H_ 1 - +#define _ASMI386_I8954_H_ -#define PIT_T0 0x00 /* PIT channel 0 count/status */ -#define PIT_T1 0x01 /* PIT channel 1 count/status */ -#define PIT_T2 0x02 /* PIT channel 2 count/status */ -#define PIT_COMMAND 0x03 /* PIT mode control, latch and read back */ +#define PIT_T0 0x00 /* PIT channel 0 count/status */ +#define PIT_T1 0x01 /* PIT channel 1 count/status */ +#define PIT_T2 0x02 /* PIT channel 2 count/status */ +#define PIT_COMMAND 0x03 /* PIT mode control, latch and read back */ /* PIT Command Register Bit Definitions */ -#define PIT_CMD_CTR0 0x00 /* Select PIT counter 0 */ -#define PIT_CMD_CTR1 0x40 /* Select PIT counter 1 */ -#define PIT_CMD_CTR2 0x80 /* Select PIT counter 2 */ +#define PIT_CMD_CTR0 0x00 /* Select PIT counter 0 */ +#define PIT_CMD_CTR1 0x40 /* Select PIT counter 1 */ +#define PIT_CMD_CTR2 0x80 /* Select PIT counter 2 */ -#define PIT_CMD_LATCH 0x00 /* Counter Latch Command */ -#define PIT_CMD_LOW 0x10 /* Access counter bits 7-0 */ -#define PIT_CMD_HIGH 0x20 /* Access counter bits 15-8 */ -#define PIT_CMD_BOTH 0x30 /* Access counter bits 15-0 in two accesses */ +#define PIT_CMD_LATCH 0x00 /* Counter Latch Command */ +#define PIT_CMD_LOW 0x10 /* Access counter bits 7-0 */ +#define PIT_CMD_HIGH 0x20 /* Access counter bits 15-8 */ +#define PIT_CMD_BOTH 0x30 /* Access counter bits 15-0 in two accesses */ -#define PIT_CMD_MODE0 0x00 /* Select mode 0 */ -#define PIT_CMD_MODE1 0x02 /* Select mode 1 */ -#define PIT_CMD_MODE2 0x04 /* Select mode 2 */ -#define PIT_CMD_MODE3 0x06 /* Select mode 3 */ -#define PIT_CMD_MODE4 0x08 /* Select mode 4 */ -#define PIT_CMD_MODE5 0x0A /* Select mode 5 */ +#define PIT_CMD_MODE0 0x00 /* Select mode 0 */ +#define PIT_CMD_MODE1 0x02 /* Select mode 1 */ +#define PIT_CMD_MODE2 0x04 /* Select mode 2 */ +#define PIT_CMD_MODE3 0x06 /* Select mode 3 */ +#define PIT_CMD_MODE4 0x08 /* Select mode 4 */ +#define PIT_CMD_MODE5 0x0a /* Select mode 5 */ /* The clock frequency of the i8253/i8254 PIT */ -#define PIT_TICK_RATE 1193182ul +#define PIT_TICK_RATE 1193182 -#endif +#endif /* _ASMI386_I8954_H_ */ diff --git a/arch/x86/include/asm/i8259.h b/arch/x86/include/asm/i8259.h index bc4033b..f216c23 100644 --- a/arch/x86/include/asm/i8259.h +++ b/arch/x86/include/asm/i8259.h @@ -8,11 +8,9 @@ /* i8259.h i8259 PIC Registers */ #ifndef _ASMI386_I8259_H_ -#define _ASMI386_I8959_H_ 1 - +#define _ASMI386_I8959_H_ /* PIC I/O mapped registers */ - #define IRR 0x0 /* Interrupt Request Register */ #define ISR 0x0 /* In-Service Register */ #define ICW1 0x0 /* Initialization Control Word 1 */ @@ -23,7 +21,7 @@ #define ICW4 0x1 /* Initialization Control Word 4 */ #define IMR 0x1 /* Interrupt Mask Register */ -/* bits for IRR, IMR, ISR and ICW3 */ +/* IRR, IMR, ISR and ICW3 bits */ #define IR7 0x80 /* IR7 */ #define IR6 0x40 /* IR6 */ #define IR5 0x20 /* IR5 */ @@ -33,7 +31,7 @@ #define IR1 0x02 /* IR1 */ #define IR0 0x01 /* IR0 */ -/* bits for SEOI */ +/* SEOI bits */ #define SEOI_IR7 0x07 /* IR7 */ #define SEOI_IR6 0x06 /* IR6 */ #define SEOI_IR5 0x05 /* IR5 */ @@ -49,9 +47,9 @@ #define OCW2_NOP 0x40 /* NOP */ #define OCW2_SEOI 0x60 /* Specific EOI */ #define OCW2_RSET 0x80 /* Rotate/set */ -#define OCW2_REOI 0xA0 /* Rotate on non specific EOI */ -#define OCW2_PSET 0xC0 /* Priority Set Command */ -#define OCW2_RSEOI 0xE0 /* Rotate on specific EOI */ +#define OCW2_REOI 0xa0 /* Rotate on non specific EOI */ +#define OCW2_PSET 0xc0 /* Priority Set Command */ +#define OCW2_RSEOI 0xe0 /* Rotate on specific EOI */ /* ICW1 bits */ #define ICW1_SEL 0x10 /* Select ICW1 */ @@ -60,15 +58,20 @@ #define ICW1_SNGL 0x02 /* Single PIC */ #define ICW1_EICW4 0x01 /* Expect initilization ICW4 */ -/* ICW2 is the starting vector number */ - -/* ICW2 is bit-mask of present slaves for a master device, - * or the slave ID for a slave device */ +/* + * ICW2 is the starting vector number + * + * ICW2 is bit-mask of present slaves for a master device, + * or the slave ID for a slave device + */ /* ICW4 bits */ -#define ICW4_AEOI 0x02 /* Automatic EOI Mode */ +#define ICW4_AEOI 0x02 /* Automatic EOI Mode */ #define ICW4_PM 0x01 /* Microprocessor Mode */ +#define ELCR1 0x4d0 +#define ELCR2 0x4d1 + int i8259_init(void); -#endif +#endif /* _ASMI386_I8959_H_ */ diff --git a/arch/x86/include/asm/interrupt.h b/arch/x86/include/asm/interrupt.h index fcd766b..95a4de0 100644 --- a/arch/x86/include/asm/interrupt.h +++ b/arch/x86/include/asm/interrupt.h @@ -13,6 +13,8 @@ #include <asm/types.h> +#define SYS_NUM_IRQS 16 + /* Architecture defined exceptions */ enum x86_exception { EXC_DE = 0, diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h index f7e968e..a2945f1 100644 --- a/arch/x86/include/asm/pci.h +++ b/arch/x86/include/asm/pci.h @@ -25,27 +25,6 @@ struct pci_controller; void pci_setup_type1(struct pci_controller *hose); -/** - * board_pci_setup_hose() - Set up the PCI hose - * - * This is called by the common x86 PCI code to set up the PCI controller - * hose. It may be called when no memory/BSS is available so should just - * store things in 'hose' and not in BSS variables. - */ -void board_pci_setup_hose(struct pci_controller *hose); - -/** - * pci_early_init_hose() - Set up PCI host before relocation - * - * This allocates memory for, sets up and returns the PCI hose. It can be - * called before relocation. The hose will be stored in gd->hose for - * later use, but will become invalid one DRAM is available. - */ -int pci_early_init_hose(struct pci_controller **hosep); - -int board_pci_pre_scan(struct pci_controller *hose); -int board_pci_post_scan(struct pci_controller *hose); - /* * Simple PCI access routines - these work from either the early PCI hose * or the 'real' one, created after U-Boot has memory available diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h index 1c459d5..dbf8e95 100644 --- a/arch/x86/include/asm/u-boot-x86.h +++ b/arch/x86/include/asm/u-boot-x86.h @@ -29,7 +29,7 @@ typedef void (timer_fnc_t) (void); int register_timer_isr (timer_fnc_t *isr_func); unsigned long get_tbclk_mhz(void); void timer_set_base(uint64_t base); -int pcat_timer_init(void); +int i8254_init(void); /* cpu/.../interrupts.c */ int cpu_init_interrupts(void); diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 2f82a21..d676e2c 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -19,8 +19,8 @@ obj-y += lpc-uclass.o obj-y += mpspec.o obj-$(CONFIG_ENABLE_MRC_CACHE) += mrccache.o obj-y += cmd_mtrr.o -obj-$(CONFIG_SYS_PCAT_INTERRUPTS) += pcat_interrupts.o -obj-$(CONFIG_SYS_PCAT_TIMER) += pcat_timer.o +obj-$(CONFIG_I8259_PIC) += i8259.o +obj-$(CONFIG_I8254_TIMER) += i8254.o ifndef CONFIG_DM_PCI obj-$(CONFIG_PCI) += pci_type1.o endif diff --git a/arch/x86/lib/fsp/fsp_common.c b/arch/x86/lib/fsp/fsp_common.c index c78df94..5276ce6 100644 --- a/arch/x86/lib/fsp/fsp_common.c +++ b/arch/x86/lib/fsp/fsp_common.c @@ -35,11 +35,6 @@ int fsp_init_phase_pci(void) return status ? -EPERM : 0; } -int board_pci_post_scan(struct pci_controller *hose) -{ - return fsp_init_phase_pci(); -} - void board_final_cleanup(void) { u32 status; diff --git a/arch/x86/lib/i8254.c b/arch/x86/lib/i8254.c new file mode 100644 index 0000000..46a4245 --- /dev/null +++ b/arch/x86/lib/i8254.c @@ -0,0 +1,37 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/i8254.h> + +#define TIMER1_VALUE 18 /* 15.6us */ +#define TIMER2_VALUE 0x0a8e /* 440Hz */ + +int i8254_init(void) +{ + /* + * Initialize counter 1, used to refresh request signal. + * This is required for legacy purpose as some codes like + * vgabios utilizes counter 1 to provide delay functionality. + */ + outb(PIT_CMD_CTR1 | PIT_CMD_LOW | PIT_CMD_MODE2, + PIT_BASE + PIT_COMMAND); + outb(TIMER1_VALUE, PIT_BASE + PIT_T1); + + /* + * Initialize counter 2, used to drive the speaker. + * To start a beep, set both bit0 and bit1 of port 0x61. + * To stop it, clear both bit0 and bit1 of port 0x61. + */ + outb(PIT_CMD_CTR2 | PIT_CMD_BOTH | PIT_CMD_MODE3, + PIT_BASE + PIT_COMMAND); + outb(TIMER2_VALUE & 0xff, PIT_BASE + PIT_T2); + outb(TIMER2_VALUE >> 8, PIT_BASE + PIT_T2); + + return 0; +} diff --git a/arch/x86/lib/pcat_interrupts.c b/arch/x86/lib/i8259.c index a9af87e..b9d0614 100644 --- a/arch/x86/lib/pcat_interrupts.c +++ b/arch/x86/lib/i8259.c @@ -20,10 +20,6 @@ #include <asm/ibmpc.h> #include <asm/interrupt.h> -#if CONFIG_SYS_NUM_IRQS != 16 -#error "CONFIG_SYS_NUM_IRQS must equal 16 if CONFIG_SYS_NUM_IRQS is defined" -#endif - int i8259_init(void) { u8 i; @@ -32,10 +28,11 @@ int i8259_init(void) outb(0xff, MASTER_PIC + IMR); outb(0xff, SLAVE_PIC + IMR); - /* Master PIC */ - /* Place master PIC interrupts at INT20 */ - /* ICW3, One slave PIC is present */ - outb(ICW1_SEL|ICW1_EICW4, MASTER_PIC + ICW1); + /* + * Master PIC + * Place master PIC interrupts at INT20 + */ + outb(ICW1_SEL | ICW1_EICW4, MASTER_PIC + ICW1); outb(0x20, MASTER_PIC + ICW2); outb(IR2, MASTER_PIC + ICW3); outb(ICW4_PM, MASTER_PIC + ICW4); @@ -43,10 +40,11 @@ int i8259_init(void) for (i = 0; i < 8; i++) outb(OCW2_SEOI | i, MASTER_PIC + OCW2); - /* Slave PIC */ - /* Place slave PIC interrupts at INT28 */ - /* Slave ID */ - outb(ICW1_SEL|ICW1_EICW4, SLAVE_PIC + ICW1); + /* + * Slave PIC + * Place slave PIC interrupts at INT28 + */ + outb(ICW1_SEL | ICW1_EICW4, SLAVE_PIC + ICW1); outb(0x28, SLAVE_PIC + ICW2); outb(0x02, SLAVE_PIC + ICW3); outb(ICW4_PM, SLAVE_PIC + ICW4); @@ -70,7 +68,7 @@ void mask_irq(int irq) { int imr_port; - if (irq >= CONFIG_SYS_NUM_IRQS) + if (irq >= SYS_NUM_IRQS) return; if (irq > 7) @@ -85,7 +83,7 @@ void unmask_irq(int irq) { int imr_port; - if (irq >= CONFIG_SYS_NUM_IRQS) + if (irq >= SYS_NUM_IRQS) return; if (irq > 7) @@ -98,7 +96,7 @@ void unmask_irq(int irq) void specific_eoi(int irq) { - if (irq >= CONFIG_SYS_NUM_IRQS) + if (irq >= SYS_NUM_IRQS) return; if (irq > 7) { @@ -114,9 +112,6 @@ void specific_eoi(int irq) outb(OCW2_SEOI | irq, MASTER_PIC + OCW2); } -#define ELCR1 0x4d0 -#define ELCR2 0x4d1 - void configure_irq_trigger(int int_num, bool is_level_triggered) { u16 int_bits = inb(ELCR1) | (((u16)inb(ELCR2)) << 8); @@ -131,20 +126,4 @@ void configure_irq_trigger(int int_num, bool is_level_triggered) debug("%s: try to set interrupts 0x%x\n", __func__, int_bits); outb((u8)(int_bits & 0xff), ELCR1); outb((u8)(int_bits >> 8), ELCR2); - -#ifdef PARANOID_IRQ_TRIGGERS - /* - * Try reading back the new values. This seems like an error but is - * not - */ - if (inb(ELCR1) != (int_bits & 0xff)) { - printf("%s: lower order bits are wrong: want 0x%x, got 0x%x\n", - __func__, (int_bits & 0xff), inb(ELCR1)); - } - - if (inb(ELCR2) != (int_bits >> 8)) { - printf("%s: higher order bits are wrong: want 0x%x, got 0x%x\n", - __func__, (int_bits>>8), inb(ELCR2)); - } -#endif } diff --git a/arch/x86/lib/interrupts.c b/arch/x86/lib/interrupts.c index 146ad11..dd08402 100644 --- a/arch/x86/lib/interrupts.c +++ b/arch/x86/lib/interrupts.c @@ -39,7 +39,7 @@ struct irq_action { unsigned int count; }; -static struct irq_action irq_handlers[CONFIG_SYS_NUM_IRQS] = { {0} }; +static struct irq_action irq_handlers[SYS_NUM_IRQS] = { {0} }; static int spurious_irq_cnt; static int spurious_irq; @@ -47,7 +47,7 @@ void irq_install_handler(int irq, interrupt_handler_t *handler, void *arg) { int status; - if (irq < 0 || irq >= CONFIG_SYS_NUM_IRQS) { + if (irq < 0 || irq >= SYS_NUM_IRQS) { printf("irq_install_handler: bad irq number %d\n", irq); return; } @@ -75,7 +75,7 @@ void irq_free_handler(int irq) { int status; - if (irq < 0 || irq >= CONFIG_SYS_NUM_IRQS) { + if (irq < 0 || irq >= SYS_NUM_IRQS) { printf("irq_free_handler: bad irq number %d\n", irq); return; } @@ -97,7 +97,7 @@ void do_irq(int hw_irq) { int irq = hw_irq - 0x20; - if (irq < 0 || irq >= CONFIG_SYS_NUM_IRQS) { + if (irq < 0 || irq >= SYS_NUM_IRQS) { printf("do_irq: bad irq number %d\n", irq); return; } @@ -130,7 +130,7 @@ int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) printf("Interrupt-Information:\n"); printf("Nr Routine Arg Count\n"); - for (irq = 0; irq < CONFIG_SYS_NUM_IRQS; irq++) { + for (irq = 0; irq < SYS_NUM_IRQS; irq++) { if (irq_handlers[irq].handler != NULL) { printf("%02d %08lx %08lx %d\n", irq, diff --git a/arch/x86/lib/pcat_timer.c b/arch/x86/lib/pcat_timer.c deleted file mode 100644 index 3545a50..0000000 --- a/arch/x86/lib/pcat_timer.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * (C) Copyright 2002 - * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <asm/io.h> -#include <asm/i8254.h> - -#define TIMER2_VALUE 0x0a8e /* 440Hz */ - -int pcat_timer_init(void) -{ - /* - * initialize 2, used to drive the speaker - * (to start a beep: write 3 to port 0x61, - * to stop it again: write 0) - */ - outb(PIT_CMD_CTR2 | PIT_CMD_BOTH | PIT_CMD_MODE3, - PIT_BASE + PIT_COMMAND); - outb(TIMER2_VALUE & 0xff, PIT_BASE + PIT_T2); - outb(TIMER2_VALUE >> 8, PIT_BASE + PIT_T2); - - return 0; -} diff --git a/arch/x86/lib/tsc_timer.c b/arch/x86/lib/tsc_timer.c index 0df1af2..e02b918 100644 --- a/arch/x86/lib/tsc_timer.c +++ b/arch/x86/lib/tsc_timer.c @@ -368,9 +368,9 @@ void __udelay(unsigned long usec) int timer_init(void) { -#ifdef CONFIG_SYS_PCAT_TIMER - /* Set up the PCAT timer if required */ - pcat_timer_init(); +#ifdef CONFIG_I8254_TIMER + /* Set up the i8254 timer if required */ + i8254_init(); #endif return 0; |