From bc8235f50dcdb5d0425e1bbdb1f8a3a557730610 Mon Sep 17 00:00:00 2001 From: Sam Demeulemeester <38105886+x86fr@users.noreply.github.com> Date: Fri, 20 May 2022 13:23:25 +0200 Subject: [PATCH] Add a way to handle hardware quirks at init or later in the code. Add ASUS TUSL2-C ASB100 Mux as (working) example (#77) --- app/main.c | 3 ++ build32/Makefile | 1 + build64/Makefile | 1 + system/hwquirks.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++ system/hwquirks.h | 37 ++++++++++++++++++++++++ system/pci.c | 24 ++++++++++++++++ system/pci.h | 7 +++++ 7 files changed, 146 insertions(+) create mode 100644 system/hwquirks.c create mode 100644 system/hwquirks.h diff --git a/app/main.c b/app/main.c index 1cdc33b..4a820c3 100644 --- a/app/main.c +++ b/app/main.c @@ -22,6 +22,7 @@ #include "cpuid.h" #include "cpuinfo.h" #include "hwctrl.h" +#include "hwquirks.h" #include "io.h" #include "keyboard.h" #include "pmem.h" @@ -219,6 +220,8 @@ static void global_init(void) smbios_init(); + quirks_init(); + badram_init(); config_init(); diff --git a/build32/Makefile b/build32/Makefile index d04a2b0..862577a 100644 --- a/build32/Makefile +++ b/build32/Makefile @@ -20,6 +20,7 @@ SYS_OBJS = system/cpuid.o \ system/ehci.o \ system/font.o \ system/hwctrl.o \ + system/hwquirks.o \ system/keyboard.o \ system/ohci.o \ system/pci.o \ diff --git a/build64/Makefile b/build64/Makefile index 564329c..3346983 100644 --- a/build64/Makefile +++ b/build64/Makefile @@ -20,6 +20,7 @@ SYS_OBJS = system/cpuid.o \ system/ehci.o \ system/font.o \ system/hwctrl.o \ + system/hwquirks.o \ system/keyboard.o \ system/ohci.o \ system/pci.o \ diff --git a/system/hwquirks.c b/system/hwquirks.c new file mode 100644 index 0000000..0aef869 --- /dev/null +++ b/system/hwquirks.c @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2004-2022 Samuel Demeulemeester +// +// ------------------------ +// This file is used to detect quirks on specific hardware +// that require proprietary init here *OR* different code path +// later in various part of the code. +// +// Please add a quick comment for every quirk added to the list. + +#include "hwquirks.h" +#include "io.h" +#include "pci.h" +#include "unistd.h" + +quirk_t quirk; + +// -------------------------------------- +// -- Private quirk-specific functions -- +// -------------------------------------- + +static void asus_tusl2_configure_mux(void) +{ + uint8_t muxreg; + + // Enter ASB100 Config Mode + outb(0x87, 0x2E); + outb(0x87, 0x2E); + usleep(200); + + // Write LPC Command to access Config Mode Reg + lpc_outb(0x7, 0x8); + + // Read Config Mode Register + muxreg = lpc_inb(0xF1); + + // Change Smbus Mux Channel & Write Config Mode Register + muxreg &= 0xE7; + muxreg |= 0x10; + lpc_outb(0xF1, muxreg); + usleep(200); + + // Leave Config Mode + outb(0xAA, 0x2E); +} + +// --------------------- +// -- Public function -- +// --------------------- + +void quirks_init(void) +{ + quirk.id = QUIRK_NONE; + quirk.type = QUIRK_TYPE_NONE; + quirk.root_vid = pci_config_read16(0, 0, 0, 0); + quirk.root_did = pci_config_read16(0, 0, 0, 2); + + // ------------------------ + // -- ASUS TUSL2-C Quirk -- + // ------------------------ + // This motherboard has an ASB100 ASIC with a SMBUS Mux Integrated. + // To access SPD later in the code, we need to configure the mux. + // PS: Detection via DMI is unreliable, so using Root PCI Registers + if (quirk.root_vid == 0x8086 && quirk.root_did == 0x1130) { // Intel i815 + if (pci_config_read16(0, 0, 0, 0x2C) == 0x1043) { // ASUS + if (pci_config_read16(0, 0, 0, 0x2E) == 0x8027) { // TUSL2-C + quirk.id = QUIRK_TUSL2; + quirk.type |= QUIRK_TYPE_SMBUS; + asus_tusl2_configure_mux(); + } + } + } +} diff --git a/system/hwquirks.h b/system/hwquirks.h new file mode 100644 index 0000000..0982e83 --- /dev/null +++ b/system/hwquirks.h @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2004-2022 Sam Demeulemeester +#ifndef _QUIRK_H_ +#define _QUIRK_H_ +/** + * + * Provides support for hardware quirks + * + */ + +#include +#include + +#define QUIRK_TYPE_NONE 0b00000000 +#define QUIRK_TYPE_USB 0b00000001 +#define QUIRK_TYPE_SMP 0b00000010 +#define QUIRK_TYPE_SMBIOS 0b00000100 +#define QUIRK_TYPE_SMBUS 0b00001000 +#define QUIRK_TYPE_TIMER 0b00010000 + +typedef enum { + QUIRK_NONE, + QUIRK_TUSL2 +} quirk_id_t; + +typedef struct { + quirk_id_t id; + uint8_t type; + uint16_t root_vid; + uint16_t root_did; +} quirk_t; + +extern quirk_t quirk; + +void quirks_init(void); + +#endif /* _QUIRK_H_ */ diff --git a/system/pci.c b/system/pci.c index 1b280a8..812aa16 100644 --- a/system/pci.c +++ b/system/pci.c @@ -244,6 +244,30 @@ void pci_config_write32(int bus, int dev, int func, int reg, uint32_t value) } } + +// ------------- +// LPC Functions +// ------------- + +void lpc_outb(uint8_t cmd, uint8_t data) +{ + outb(cmd, 0x2E); + usleep(100); + outb(data, 0x2F); + usleep(100); +} + +uint8_t lpc_inb(uint8_t reg) +{ + outb(reg, 0x2E); + usleep(100); + return inb(0x2F); +} + +// --------------------------------------- +// AMD System Management Network Functions +// --------------------------------------- + uint32_t amd_smn_read(uint32_t adr) { pci_config_write32(0, 0, 0, 0x60, adr); diff --git a/system/pci.h b/system/pci.h index 7832576..e85d8dc 100644 --- a/system/pci.h +++ b/system/pci.h @@ -60,6 +60,13 @@ void pci_config_write16(int bus, int dev, int func, int reg, uint16_t value); void pci_config_write32(int bus, int dev, int func, int reg, uint32_t value); +/** + * Basic LPC Functions + */ + +void lpc_outb(uint8_t cmd, uint8_t data); +uint8_t lpc_inb(uint8_t reg); + /* * Add some SNM related function (S.DEMEULEMEESTER) */