mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-01 02:48:14 +00:00
firmware/coreboot: Subtree merged blobs
This commit is contained in:
1
firmware/coreboot/3rdparty/blobs
vendored
1
firmware/coreboot/3rdparty/blobs
vendored
Submodule firmware/coreboot/3rdparty/blobs deleted from 78a02a7f9d
BIN
firmware/coreboot/3rdparty/blobs/cpu/amd/family_10h-family_14h/microcode_amd.bin
vendored
Normal file
BIN
firmware/coreboot/3rdparty/blobs/cpu/amd/family_10h-family_14h/microcode_amd.bin
vendored
Normal file
Binary file not shown.
BIN
firmware/coreboot/3rdparty/blobs/cpu/amd/family_15h/microcode_amd_fam15h.bin
vendored
Normal file
BIN
firmware/coreboot/3rdparty/blobs/cpu/amd/family_15h/microcode_amd_fam15h.bin
vendored
Normal file
Binary file not shown.
9
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/README
vendored
Normal file
9
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/README
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
This VSA is taken from
|
||||
http://marcjonesconsulting.com/gplvsa/gpl_vsa_lx_102.bin.gz
|
||||
|
||||
and decompressed for simplicity. The original SHA1 was:
|
||||
96a6097331278d644230eac4fc39bcfebc3c9a16 gpl_vsa_lx_102.bin.gz
|
||||
|
||||
While we have the source code (see gplvsa_ii), it requires a rather
|
||||
esoteric build system. Should this be fixed, we could consider adding
|
||||
VSA to the coreboot tree. Until then, source and binary can reside here.
|
||||
BIN
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gpl_vsa_lx_102.bin
vendored
Normal file
BIN
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gpl_vsa_lx_102.bin
vendored
Normal file
Binary file not shown.
27
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/README.txt
vendored
Executable file
27
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/README.txt
vendored
Executable file
@@ -0,0 +1,27 @@
|
||||
This is the VSA (Virtual Systems Architecture) code used on the AMD
|
||||
Geode series of processors. The Geode, rather than carrying lots of
|
||||
legacy hardware interfaces that are presumed to exist on x86 systems
|
||||
that might be painful to implement on a highly integrated, low power
|
||||
processor, the Geode often emulates such interfaces by use of software that is
|
||||
invoked by special traps that take place when the processor accesses
|
||||
these devices.
|
||||
|
||||
Note that the code here is not currently buildable on open source
|
||||
systems, being only buildable using very obsolete and no longer
|
||||
commercially availble Windows based commercial toolchains. On the
|
||||
OLPC system, these "blobs" of binary code are concatenated together
|
||||
with LinuxBIOS and the bootloader, and set up to be executed by
|
||||
LinuxBIOS early in the Geode's initialization sequence (no linking is
|
||||
involved).
|
||||
|
||||
If you are interested for some reason in making this code buildable on
|
||||
free systems, please let us know of your progress. It is under the
|
||||
GNU LGPL.
|
||||
|
||||
Also note that VESA emulation is *not* included in this (nor does what
|
||||
we use on the OLPC machine use VESA at this date; we use frame
|
||||
buffer code for our console); that code was not owned by AMD and
|
||||
therefore not theirs to make available. Our thanks to AMD to making
|
||||
the VSA code available.
|
||||
|
||||
Jim Gettys, OLPC, September 27, 2006
|
||||
42
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/build/legacy.mak
vendored
Executable file
42
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/build/legacy.mak
vendored
Executable file
@@ -0,0 +1,42 @@
|
||||
#
|
||||
# Copyright (c) 2006 Advanced Micro Devices,Inc. ("AMD").
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation; either version 2.1 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General
|
||||
# Public License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
# Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
VSMNAME = legacy
|
||||
VSMDIR = $(VSA2ROOT)\$(VSMNAME)
|
||||
|
||||
|
||||
all:
|
||||
cd $(VSMDIR)
|
||||
$(MAKE) /nologo all "VSA2ROOT=$(VSA2ROOT)" "USER=$(USER)" "BUILDOBJ=$(OBJECT)" "CPU=$(CPU)"
|
||||
cd $(MAKEDIR)
|
||||
|
||||
clean:
|
||||
cd $(VSMDIR)
|
||||
$(MAKE) /nologo clean
|
||||
cd $(MAKEDIR)
|
||||
|
||||
cleanlocal:
|
||||
cd $(VSMDIR)
|
||||
$(MAKE) /nologo cleanlocal
|
||||
cd $(MAKEDIR)
|
||||
|
||||
cleanall:
|
||||
cd $(VSMDIR)
|
||||
$(MAKE) /nologo cleanall
|
||||
cd $(MAKEDIR)
|
||||
40
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/build/lxvg.mak
vendored
Executable file
40
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/build/lxvg.mak
vendored
Executable file
@@ -0,0 +1,40 @@
|
||||
# Copyright (c) 2007-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation; either version 2.1 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU Lesser General
|
||||
# Public License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
# Boston, MA 02111-1307 USA
|
||||
|
||||
VSMNAME = lxvg
|
||||
VSMDIR = $(VSA2ROOT)\$(VSMNAME)
|
||||
|
||||
all:
|
||||
cd $(VSMDIR)
|
||||
$(MAKE) /nologo all "VSA2ROOT=$(VSA2ROOT)" "USER=$(USER)" "BUILDOBJ=$(OBJECT)" "CPU=$(CPU)"
|
||||
cd $(MAKEDIR)
|
||||
|
||||
|
||||
clean:
|
||||
cd $(VSMDIR)
|
||||
$(MAKE) /nologo clean
|
||||
cd $(MAKEDIR)
|
||||
|
||||
cleanlocal:
|
||||
cd $(VSMDIR)
|
||||
$(MAKE) /nologo cleanlocal
|
||||
cd $(MAKEDIR)
|
||||
|
||||
cleanall:
|
||||
cd $(VSMDIR)
|
||||
$(MAKE) /nologo cleanall
|
||||
cd $(MAKEDIR)
|
||||
99
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/build/makefile
vendored
Executable file
99
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/build/makefile
vendored
Executable file
@@ -0,0 +1,99 @@
|
||||
#
|
||||
# Copyright (c) 2006 Advanced Micro Devices,Inc. ("AMD").
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation; either version 2.1 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General
|
||||
# Public License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
# Boston, MA 02111-1307 USA
|
||||
#
|
||||
# makefile for VSA2
|
||||
|
||||
|
||||
|
||||
!ifndef VSA2ROOT
|
||||
VSA2ROOT = $(MAKEDIR)\..
|
||||
!endif
|
||||
|
||||
USER = $(VSA2ROOT)
|
||||
|
||||
OBJECT = $(MAKEDIR)\obj
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES : .exe .vsm .lib .bin .mak .cln
|
||||
|
||||
!include setvars.mak
|
||||
|
||||
VSMS = \
|
||||
$(OBJECT)\sysmgr.vsm \
|
||||
$(OBJECT)\vsainit.bin \
|
||||
$(OBJECT)\legacy.vsm \
|
||||
$(OBJECT)\lxvg.vsm
|
||||
|
||||
VSM_CLN0 = $(VSMS:.vsm=.cln)
|
||||
VSM_CLN = $(VSM_CLN0:.bin=.cln)
|
||||
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# Targets
|
||||
#
|
||||
#######################################################################
|
||||
all: $(OBJECT) $(VSMS) basic
|
||||
|
||||
basic: setenv
|
||||
@$(ECHO) Make LX VSA Image
|
||||
$(MAKE) /nologo vsa_lx.bin
|
||||
|
||||
$(VSMS): setenv
|
||||
|
||||
vsa_lx.bin $(OBJECT)\amd_vsa_lx.bin: $(OBJECT)\vsainit.bin $(OBJECT)\vsa2.bin
|
||||
@$(ECHO) Concatenate for LX Image ...
|
||||
-$(BINCOPY) $(OBJECT)\vsainit.bin+$(OBJECT)\vsa2.bin+$(OBJECT)\lxvg.vsm $(OBJECT)\amd_vsa_lx.bin
|
||||
|
||||
vsa2.bin $(OBJECT)\vsa2.bin: $(OBJECT)\sysmgr.vsm $(OBJECT)\legacy.vsm
|
||||
@$(ECHO) Concatenate for VSA2.BIN Image ...
|
||||
-$(BINCOPY) $(OBJECT)\sysmgr.vsm+$(OBJECT)\legacy.vsm $(OBJECT)\vsa2.bin
|
||||
|
||||
#This and only this clean target must exist as it is called by cleanall
|
||||
#cleanall and cleanlocal are defined in rules.mak
|
||||
|
||||
clean: cleanlocal cleanlib $(VSM_CLN) tools_clean
|
||||
|
||||
$(OBJECT):
|
||||
-@md $(OBJECT)
|
||||
|
||||
|
||||
############################################
|
||||
# Tools.lib
|
||||
############################################
|
||||
tools_clean:
|
||||
-@cd $(VSA2ROOT)\vsm_lib
|
||||
-@$(MAKE) /nologo cleanall
|
||||
-@cd $(MAKEDIR)
|
||||
|
||||
|
||||
###########################################################################
|
||||
# All VSMs
|
||||
###########################################################################
|
||||
{$(MAKEDIR)}.mak{$(OBJECT)}.vsm:
|
||||
$(MAKE) /nologo -f $(MAKEDIR)\%|fF.mak "VSA2ROOT=$(VSA2ROOT)" "USER=$(VSA2ROOT)" "OBJECT=$(OBJECT)" "CPU=$(CPU)"
|
||||
|
||||
{$(MAKEDIR)}.mak{$(OBJECT)}.bin:
|
||||
$(MAKE) /nologo -f $(MAKEDIR)\%|fF.mak "VSA2ROOT=$(VSA2ROOT)" "USER=$(VSA2ROOT)" "OBJECT=$(OBJECT)" "CPU=$(CPU)"
|
||||
|
||||
{$(MAKEDIR)}.mak{$(OBJECT)}.cln:
|
||||
-@$(MAKE) /nologo -f $(MAKEDIR)\%|fF.mak cleanall "VSA2ROOT=$(VSA2ROOT)" "USER=$(VSA2ROOT)"
|
||||
|
||||
|
||||
!include rules.mak
|
||||
|
||||
138
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/build/rules.mak
vendored
Executable file
138
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/build/rules.mak
vendored
Executable file
@@ -0,0 +1,138 @@
|
||||
#
|
||||
# Copyright (c) 2006 Advanced Micro Devices,Inc. ("AMD").
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation; either version 2.1 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General
|
||||
# Public License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
# Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Common targets
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
|
||||
|
||||
setenv:
|
||||
!if "$(VARS_SET)" != "VSA_II"
|
||||
@$(SETENV) PATH=.\;$(VSA2ROOT)\uti;$(PATH);
|
||||
@$(SETENV) Lib=.\;$(VSA2ROOT)\lib;$(VSA2ROOT)\build;$(LIB);
|
||||
@$(SETENV) VARS_SET=VSA_II
|
||||
!endif
|
||||
@echo INCLUDE=$(INCLUDE)
|
||||
|
||||
$(BUILD_DIR)\obj\$(TOOL_LIB):
|
||||
cd $(VSA2ROOT)\vsm_lib
|
||||
$(MAKE) /nologo all "BUILDOBJ=$(OBJECT)" "CPU=$(CPU)"
|
||||
cd $(MAKEDIR)
|
||||
|
||||
cleanlib:
|
||||
cd $(VSA2ROOT)\vsm_lib
|
||||
$(MAKE) /nologo cleanall
|
||||
cd $(MAKEDIR)
|
||||
|
||||
cleanlocal:
|
||||
-@IF EXIST $(OBJECT)\*.def $(DEL) $(OBJECT)\*.def
|
||||
-@IF EXIST $(OBJECT)\*.lnk $(DEL) $(OBJECT)\*.lnk
|
||||
-@IF EXIST $(OBJECT)\*.map $(DEL) $(OBJECT)\*.map
|
||||
-@IF EXIST $(OBJECT)\*.obj $(DEL) $(OBJECT)\*.obj
|
||||
-@IF EXIST $(OBJECT)\*.exe $(DEL) $(OBJECT)\*.exe
|
||||
-@IF EXIST $(OBJECT)\*.rom $(DEL) $(OBJECT)\*.rom
|
||||
-@IF EXIST $(OBJECT)\*.cpu $(DEL) $(OBJECT)\*.cpu
|
||||
-@IF EXIST $(OBJECT)\*.scc $(DEL) $(OBJECT)\*.scc
|
||||
-@IF EXIST $(OBJECT)\*.inc $(DEL) $(OBJECT)\*.inc
|
||||
-@IF EXIST $(OBJECT)\*.h $(DEL) $(OBJECT)\*.h
|
||||
-@IF EXIST $(OBJECT)\*.lst $(DEL) $(OBJECT)\*.lst
|
||||
-@IF EXIST $(OBJECT)\*.bak $(DEL) $(OBJECT)\*.bak
|
||||
-@IF EXIST $(OBJECT)\*.mac $(DEL) $(OBJECT)\*.mac
|
||||
-@IF EXIST $(OBJECT)\*.asm $(DEL) $(OBJECT)\*.asm
|
||||
-@IF EXIST $(OBJECT)\*.cod $(DEL) $(OBJECT)\*.cod
|
||||
-@IF EXIST $(MAKEDIR)\*.map $(DEL) $(MAKEDIR)\*.map
|
||||
-@IF EXIST $(MAKEDIR)\arccode.h $(DEL) $(MAKEDIR)\arccode.h
|
||||
|
||||
cleanall: clean
|
||||
-@IF EXIST $(MAKEDIR)\*.vsm $(DEL) $(MAKEDIR)\*.vsm
|
||||
-@IF EXIST $(OBJECT)\*.vsm $(DEL) $(OBJECT)\*.vsm
|
||||
-@IF EXIST $(OBJECT)\*.bin $(DEL) $(OBJECT)\*.bin
|
||||
-@IF EXIST $(OBJECT)\*.lib $(DEL) $(OBJECT)\*.lib
|
||||
-@IF EXIST $(OBJECT) rd $(OBJECT)
|
||||
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Common inference rules
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
{$(INC_DIR)}.h{$(OBJECT)}.inc:
|
||||
$(H2) /Fa$(OBJECT)\$(@F) /nologo /C $<
|
||||
|
||||
{$(INC_DIR)\$(CPU)}.h{$(OBJECT)}.inc:
|
||||
$(H2) /Fa$(OBJECT)\$(@F) /nologo /C $<
|
||||
|
||||
{$(SYSMGR_SRC)}.h{$(OBJECT)}.inc:
|
||||
$(H2) /Fa$(OBJECT)\$(@F) /nologo /C $<
|
||||
|
||||
{$(SYSMGR_SRC)\$(CPU)}.h{$(OBJECT)}.inc:
|
||||
$(H2) /Fa$(OBJECT)\$(@F) /nologo /C $<
|
||||
|
||||
{$(MAKEDIR)}.h{$(OBJECT)}.inc:
|
||||
$(H2) /Fa$(OBJECT)\$(@F) /nologo /C $<
|
||||
|
||||
{$(MAKEDIR)\$(CPU)}.h{$(OBJECT)}.inc:
|
||||
$(H2) /Fa$(OBJECT)\$(@F) /nologo /C $<
|
||||
|
||||
{$(INC_DIR)}.h{$(OBJECT)}.h:
|
||||
$(COPY) $< $@
|
||||
|
||||
{$(INC_DIR)\$(CPU)}.h{$(OBJECT)}.h:
|
||||
$(COPY) $< $@
|
||||
|
||||
{$(SYSMGR_SRC)}.h{$(OBJECT)}.h:
|
||||
$(COPY) $< $@
|
||||
|
||||
{$(SYSMGR_SRC)\$(CPU)}.h{$(OBJECT)}.h:
|
||||
$(COPY) $< $@
|
||||
|
||||
{$(MAKEDIR)}.h{$(OBJECT)}.h:
|
||||
$(COPY) $< $@
|
||||
|
||||
{$(MAKEDIR)\$(CPU)}.h{$(OBJECT)}.h:
|
||||
$(COPY) $< $@
|
||||
|
||||
{$(MAKEDIR)}.inc{$(OBJECT)}.inc:
|
||||
$(COPY) $< $@
|
||||
|
||||
{$(MAKEDIR)\$(CPU)}.inc{$(OBJECT)}.inc:
|
||||
$(COPY) $< $@
|
||||
|
||||
{$(MAKEDIR)}.c{$(OBJECT)}.obj:
|
||||
$(CC) /nologo $(CC_OPTS) /Fo$@ $<
|
||||
|
||||
{$(MAKEDIR)\$(CPU)}.c{$(OBJECT)}.obj:
|
||||
$(CC) /nologo $(CC_OPTS) /Fo$@ $<
|
||||
|
||||
{$(MAKEDIR)}.asm{$(OBJECT)}.obj:
|
||||
$(AS) /nologo $(AS_OPTS) /Fo$@ $<
|
||||
|
||||
{$(MAKEDIR)\$(CPU)}.asm{$(OBJECT)}.obj:
|
||||
$(AS) /nologo $(AS_OPTS) /Fo$@ $<
|
||||
|
||||
{$(SYSMGR_SRC)}.mac{$(OBJECT)}.mac:
|
||||
$(COPY) $< $@
|
||||
|
||||
{$(SYSMGR_SRC)\$(CPU)}.mac{$(OBJECT)}.mac:
|
||||
$(COPY) $< $@
|
||||
|
||||
65
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/build/setvars.mak
vendored
Executable file
65
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/build/setvars.mak
vendored
Executable file
@@ -0,0 +1,65 @@
|
||||
#
|
||||
# Copyright (c) 2006 Advanced Micro Devices,Inc. ("AMD").
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation; either version 2.1 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General
|
||||
# Public License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
# Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Directories
|
||||
#
|
||||
##############################################################################
|
||||
BUILD_DIR = $(VSA2ROOT)\build
|
||||
SYSMGR_SRC = $(VSA2ROOT)\sysmgr
|
||||
VSMUTILS_SRC = $(VSA2ROOT)\vsm_lib
|
||||
LEGACY_SRC = $(VSA2ROOT)\legacy
|
||||
INC_DIR = $(VSA2ROOT)\inc
|
||||
H_DIR = $(VSA2ROOT)\sysmgr
|
||||
|
||||
SHELL =
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Tools / Options for tools
|
||||
#
|
||||
##############################################################################
|
||||
ECHO = echo
|
||||
COPY = copy
|
||||
BINCOPY = copy /b
|
||||
MOVE = move
|
||||
DEL = del
|
||||
REN = ren
|
||||
SETENV = set
|
||||
CD = cd
|
||||
AS = ml
|
||||
CC = cl
|
||||
H2 = h2inc
|
||||
LN = link
|
||||
LB = lib
|
||||
X2ROM = exe2bin
|
||||
|
||||
AS_OPTS = /c /Cx /Sa /W3 $(ALIST) /I$(OBJECT)
|
||||
CC_OPTS = /c /AT /Gs /FPi87 /G3fsy /W3 /Fc$(OBJECT)\ /I$(OBJECT) $(COPTS_OPT) $(CLIST)
|
||||
|
||||
COPTS_OPT = /Ow /W3
|
||||
LOPTS_OPT = /NONULLS /nologo /MAP
|
||||
LOPTS_SYS = /MAP /TINY /nologo
|
||||
LOPTS_VSM = /MAP /TINY /nologo
|
||||
|
||||
TOOL_LIB = tools.lib
|
||||
HEAD_LIB = header.lib
|
||||
|
||||
|
||||
42
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/build/sysmgr.mak
vendored
Executable file
42
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/build/sysmgr.mak
vendored
Executable file
@@ -0,0 +1,42 @@
|
||||
#
|
||||
# Copyright (c) 2006 Advanced Micro Devices,Inc. ("AMD").
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation; either version 2.1 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General
|
||||
# Public License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
# Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
VSMNAME = sysmgr
|
||||
VSMDIR = $(VSA2ROOT)\$(VSMNAME)
|
||||
|
||||
all:
|
||||
cd $(VSMDIR)
|
||||
$(MAKE) /nologo all "VSA2ROOT=$(VSA2ROOT)" "USER=$(USER)" "BUILDOBJ=$(OBJECT)" "CPU=$(CPU)"
|
||||
cd $(MAKEDIR)
|
||||
|
||||
|
||||
clean:
|
||||
cd $(VSMDIR)
|
||||
$(MAKE) /nologo clean
|
||||
cd $(MAKEDIR)
|
||||
|
||||
cleanlocal:
|
||||
cd $(VSMDIR)
|
||||
$(MAKE) /nologo cleanlocal
|
||||
cd $(MAKEDIR)
|
||||
|
||||
cleanall:
|
||||
cd $(VSMDIR)
|
||||
$(MAKE) /nologo cleanall
|
||||
cd $(MAKEDIR)
|
||||
42
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/build/vsainit.mak
vendored
Executable file
42
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/build/vsainit.mak
vendored
Executable file
@@ -0,0 +1,42 @@
|
||||
#
|
||||
# Copyright (c) 2006 Advanced Micro Devices,Inc. ("AMD").
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation; either version 2.1 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General
|
||||
# Public License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
# Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
VSMNAME = vsainit
|
||||
VSMDIR = $(VSA2ROOT)\sysmgr
|
||||
|
||||
all:
|
||||
cd $(VSMDIR)
|
||||
$(MAKE) /nologo all "VSA2ROOT=$(VSA2ROOT)" "USER=$(USER)" "BUILDOBJ=$(OBJECT)" "CPU=$(CPU)"
|
||||
cd $(MAKEDIR)
|
||||
|
||||
|
||||
clean:
|
||||
cd $(VSMDIR)
|
||||
$(MAKE) /nologo clean
|
||||
cd $(MAKEDIR)
|
||||
|
||||
cleanlocal:
|
||||
cd $(VSMDIR)
|
||||
$(MAKE) /nologo cleanlocal
|
||||
cd $(MAKEDIR)
|
||||
|
||||
cleanall:
|
||||
cd $(VSMDIR)
|
||||
$(MAKE) /nologo cleanall
|
||||
cd $(MAKEDIR)
|
||||
249
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/acpi.h
vendored
Executable file
249
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/acpi.h
vendored
Executable file
@@ -0,0 +1,249 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
|
||||
//*********************************************************
|
||||
// Private messages used between ACPI VSM and PMCORE VSM **
|
||||
//*********************************************************
|
||||
#define PMSG_GOTO_SLEEP 0x70
|
||||
#define PMSG_BLINK_LED 0x71
|
||||
|
||||
|
||||
/* device power states */
|
||||
#define D0_STATE (0)
|
||||
#define D1_STATE (1)
|
||||
#define D2_STATE (2)
|
||||
#define D3_STATE (3)
|
||||
|
||||
/**************************************************************
|
||||
* smi_cmd Definitions
|
||||
* These values must match the corresponding values in ACPI
|
||||
* FADT. OS writes these values to SMI_CMD I/O location.
|
||||
****************************************************************/
|
||||
#define ACPI_ENABLE (0xA1)
|
||||
#define ACPI_DISABLE (0xA2)
|
||||
#define S4BIOS_REQ (0xA3)
|
||||
|
||||
|
||||
// Bitmap of IRQ's PM VSM can map SCI to
|
||||
#define ALLOWED_SCI_IRQ (0x0E20) // 11,10,9,5
|
||||
#define DEFAULT_SCI_IRQ (9)
|
||||
|
||||
/**************************************************************
|
||||
* PM1_STS bit definitions
|
||||
****************************************************************/
|
||||
#define WAKE_STS (0x8000)
|
||||
#define RTC_STS (0x0400)
|
||||
#define SLPBTN_STS (0x0200)
|
||||
#define PWRBTN_STS (0x0100)
|
||||
#define GBL_STS (0x0020)
|
||||
#define BM_STATUS (0x0010)
|
||||
#define TMR_STS (0x0001)
|
||||
#define PM1_STS_CLR (0x8731)
|
||||
|
||||
/**************************************************************
|
||||
* PM1_EN bit definitions
|
||||
****************************************************************/
|
||||
#define RTC_EN (0x0400)
|
||||
#define SLPBTN_EN (0x0200)
|
||||
#define PWRBTN_EN (0x0100)
|
||||
#define GBL_EN (0x0020)
|
||||
#define TMR_EN (0x0001)
|
||||
|
||||
/**************************************************************
|
||||
* PM1_CNT bit definitions
|
||||
****************************************************************/
|
||||
#define SLP_EN (0x2000)
|
||||
#define SLP_ENB (0x20)
|
||||
#define SLP_TYPx_MASK (0x1C00) // mask for setting SLP_TYPx
|
||||
#define SLP_TYPx_MASKB (0x1C)
|
||||
#define SLP_TYPx_SHFT (10)
|
||||
#define SLP_TYPx_SHFTB (2)
|
||||
#define GBL_RLS (0x0004)
|
||||
#define BM_RLD (0x0002)
|
||||
#define SCI_EN (0x0001)
|
||||
#define ACPI_S0 (0)
|
||||
#define ACPI_S1 (1)
|
||||
#define ACPI_S1_CLKOFF (0x81)
|
||||
#define ACPI_S2 (2)
|
||||
#define ACPI_S3 (3)
|
||||
#define ACPI_S4 (4)
|
||||
#define ACPI_S5 (5)
|
||||
|
||||
/**************************************************************
|
||||
* PM2_CNT bit definitions
|
||||
**************************************************************/
|
||||
#define ARB_DIS (0x0001)
|
||||
|
||||
|
||||
/**************************************************************
|
||||
* P_CNT bit definitions
|
||||
****************************************************************/
|
||||
#define CLK_VAL_MASK (0x0000000F)
|
||||
#define CLK_VAL_OFFSET (0)
|
||||
#define CLK_VAL_WIDTH (4)
|
||||
#define THT_EN (0x00000010)
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* FACS
|
||||
********************************************************************/
|
||||
#define FACS_SIG_OFS (0x00)
|
||||
#define FACS_LEN_OFS (0x04)
|
||||
#define FACS_HWSIG_OFS (0x08)
|
||||
#define FACS_OSWV_OFS (0x0C)
|
||||
#define FACS_GBLOCK_OFS (0x10)
|
||||
#define FACS_GBL_OWNED (0x02)
|
||||
#define FACS_GBL_PENDING (0x01)
|
||||
#define FACS_FLAGS_OFS (0x14)
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* CS5536 PM stuff
|
||||
********************************************************************/
|
||||
#define YIG_SCI (5) // Y Interrupt Group 5 is all SCI sources
|
||||
#define MSR_SYS_RESET (0x0014) // 5536 GLCP SYS_RESET MSR
|
||||
|
||||
// default location of PMC regs
|
||||
#define PMC5536_BASE (0x9D00)
|
||||
|
||||
// default location of ACPI regs (32 bytes)
|
||||
#define ACPI5536_BASE (0x9C00)
|
||||
#define PM1_STS_OFS (0x00)
|
||||
#define PM1_EN_OFS (0x02)
|
||||
#define PM1_CNT_OFS (0x08)
|
||||
#define PM2_CNT_OFS (0x0C)
|
||||
#define PM_TMR_OFS (0x10)
|
||||
#define GPE0_STS_OFS (0x18)
|
||||
#define GPE0_EN_OFS (0x1C)
|
||||
|
||||
// Virtualized ACPI registers, these offsets were picked to provide
|
||||
// minimal overlap of misaligned accesses.
|
||||
// Note: PM1_STS/EN and GPE0_STS/EN must be back-to-back AND
|
||||
// PM1_STS and PM1_EN must be 16-bit only.
|
||||
#define VACPI_TRAP_BASE 0x9C20
|
||||
#define VACPI_TRAP_LEN (32)
|
||||
#define VPM1_STS_OFS (0x00)
|
||||
#define VPM1_EN_OFS (0x02)
|
||||
#define VPM1_CNT_OFS (0x08)
|
||||
#define VGPE0_STS_OFS (0x10)
|
||||
#define VGPE0_EN_OFS (0x14)
|
||||
#define VACPI_ENABLE (0x1C)
|
||||
|
||||
// 5536 GPIO13 AUX1_IN is dedicated to Sleep Button. It's controlled
|
||||
// by SLPB_STS in PM1_STS and SLPB_EN in PM1_EN.
|
||||
// Unfortunately, GPIO13 is in Working Power Domain so it is useless as
|
||||
// a wake event for anything other than S1.
|
||||
#define DFLT_5536_SLPB_GPIO (13)
|
||||
|
||||
// Bit[9] of PM1_CNT, ignored bit in ACPI spec. On 5536 this bit indicates
|
||||
// software has written a 1 to GBL_RLS(bit[2]) of PM1_CNT. Bit[9] can be cleared
|
||||
// by writing a 1 to it.
|
||||
#define GBL_RLS_FLAG (0x0200)
|
||||
|
||||
// Bit[11] of PM1_STS, ignored bit in ACPI spec. On 5536 writing this bit=1 causes
|
||||
// GBL_STS(bit[5]) to be set to 1. Bit[11] always reads as 0.
|
||||
#define SET_GBL_STS (0x0800)
|
||||
|
||||
// 5536 specific bits in ACPI GPE0_STS & GPE0_EN
|
||||
#define GPE0_PIC_INT (0x00000001L)
|
||||
#define GPE0_PIC_ASMI (0x00000002L)
|
||||
#define GPE0_SMB (0x00000004L)
|
||||
#define GPE0_UART1 (0x00000008L)
|
||||
#define GPE0_UART2 (0x00000010L)
|
||||
#define GPE0_USB1 (0x00000020L)
|
||||
#define GPE0_USB2 (0x00000040L)
|
||||
#define GPE0_PME0 (0x00010000L)
|
||||
#define GPE0_PME1 (0x00020000L)
|
||||
#define GPE0_PME2 (0x00040000L)
|
||||
#define GPE0_PME3 (0x00080000L)
|
||||
#define GPE0_PME4 (0x00100000L)
|
||||
#define GPE0_PME5 (0x00200000L)
|
||||
#define GPE0_PME6 (0x40000000L)
|
||||
#define GPE0_PME7 (0x80000000L)
|
||||
|
||||
|
||||
|
||||
/*##
|
||||
*## ACPI Indicator Designations
|
||||
*##
|
||||
*/
|
||||
#define LED_OFF 0x00 // LED turned off
|
||||
#define LED_SLOW 0x01 // 1/4Hz rate (4 second cycle time), 50% duty cycle
|
||||
#define LED_FAST 0x02 // 1Hz rate (1 second cycle time), 50% duty cycle
|
||||
#define LED_ON 0x03 // LED always on
|
||||
|
||||
#define NO_LED 0x00 // No LEDs here
|
||||
//#define MB_LED0 0x01 // The motherboard LED 0 bit mask
|
||||
//#define MB_LED1 0x02 // The motherboard LED 1 bit mask
|
||||
//#define MB_LED2 0x04 // The motherboard LED 2 bit mask
|
||||
//#define MB_LED3 0x08 // The motherboard LED 3 bit mask
|
||||
#define MB_LEDALL 0x0F // The all motherboard LEDs bit mask
|
||||
//#define SIO_LED0 0x10 // The SIO LED 0 bit mask
|
||||
//#define SIO_LED1 0x20 // The SIO LED 1 bit mask
|
||||
//#define SIO_LED2 0x40 // The SIO LED 2 bit mask
|
||||
//#define SIO_LED3 0x80 // The SIO LED 3 bit mask
|
||||
#define SIO_LEDALL 0xF0 // The SIO LEDs are in the upper nibble
|
||||
//The LEDS used to indicate sleep/wake
|
||||
#define INDICATOR_SLEEP 0x11
|
||||
|
||||
|
||||
/*
|
||||
* table indexes for gx2/lx msrs
|
||||
* (This may be moved *)
|
||||
*/
|
||||
// Northbridge
|
||||
#define IDX_GLIU0 (0)
|
||||
#define IDX_MC (1)
|
||||
#define IDX_GLIU1 (2)
|
||||
#define IDX_VG (3)
|
||||
#define IDX_GP (4)
|
||||
#define IDX_DF (5)
|
||||
#define IDX_GLCP (6)
|
||||
#define IDX_GLPCI (7)
|
||||
#define IDX_FG (8)
|
||||
#define IDX_CPU (9)
|
||||
#define IDX_VIP (10)
|
||||
#define IDX_AES (11)
|
||||
|
||||
// Southbridge
|
||||
#define IDX_SB_GLPCI (12)
|
||||
#define IDX_SB_GLIU (13)
|
||||
#define IDX_SB_USB2 (14)
|
||||
#define IDX_SB_ATA (15)
|
||||
#define IDX_SB_MDD (16)
|
||||
#define IDX_SB_AC97 (17)
|
||||
#define IDX_SB_USB1 (18)
|
||||
#define IDX_SB_GLCP (19)
|
||||
|
||||
|
||||
#define NUM_DEVS (IDX_SB_GLCP+1)
|
||||
|
||||
// definitions for callbacks for PM functions
|
||||
#define PM_CALLBACK 0xBD50
|
||||
#define PM_CB_LED 0x00
|
||||
#define PM_CB_PME 0x01
|
||||
#define PM_CB_PME_DISARM 0x00
|
||||
#define PM_CB_PME_ARM 0x01
|
||||
#define PM_CB_SLEEP 0x02
|
||||
#define PM_CB_ENTER_S3 0x00
|
||||
#define PM_CB_ENTER_SLEEP 0x01
|
||||
#define PM_CB_LEAVE_SLEEP 0x02
|
||||
#define PM_CB_DONE_S3 0x03
|
||||
374
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/chipset.h
vendored
Executable file
374
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/chipset.h
vendored
Executable file
@@ -0,0 +1,374 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#define VENDOR_ID_COMPAQ 0x0E11
|
||||
#define VENDOR_ID_CYRIX 0x1078
|
||||
#define VENDOR_ID_NATIONAL 0x100B
|
||||
#define VENDOR_ID_AMD 0x1022
|
||||
|
||||
#define DEVICE_ID_MEDIAGX 0x0001
|
||||
#define DEVICE_ID_5530 0x0100
|
||||
|
||||
#define DEVICE_ID_GX2 0x0028
|
||||
#define DEVICE_ID_GFX2 0x0030
|
||||
|
||||
#define DEVICE_ID_5535 0x002B
|
||||
#define DEVICE_ID_FLASH 0x002C
|
||||
#define DEVICE_ID_ATA 0x002D
|
||||
#define DEVICE_ID_AUDIO 0x002E
|
||||
#define DEVICE_ID_OHCI 0x002F
|
||||
|
||||
#define DEVICE_ID_LX 0x2080
|
||||
#define DEVICE_ID_GFX3 0x2081
|
||||
#define DEVICE_ID_AES 0x2082
|
||||
|
||||
#define DEVICE_ID_5536 0x2090
|
||||
#define DEVICE_ID_AMD_FLASH 0x2091
|
||||
#define DEVICE_ID_AMD_ATA 0x2092
|
||||
#define DEVICE_ID_AMD_AUDIO 0x2093
|
||||
#define DEVICE_ID_AMD_OHCI 0x2094
|
||||
#define DEVICE_ID_AMD_EHCI 0x2095
|
||||
#define DEVICE_ID_AMD_UDC 0x2096
|
||||
#define DEVICE_ID_AMD_OTG 0x2097
|
||||
#define DEVICE_ID_AMD_THOR 0x209A
|
||||
|
||||
|
||||
#define LEGACY_FUNCTION 0x0000
|
||||
#define PM_FUNCTION 0x0100
|
||||
#define IDE_FUNCTION 0x0200
|
||||
#define AUDIO_FUNCTION 0x0300
|
||||
#define VIDEO_FUNCTION 0x0400
|
||||
#define XBUS_FUNCTION 0x0500
|
||||
|
||||
|
||||
|
||||
// SMI sources relative to Function 1 BAR0
|
||||
#define SMI_STATUS_RO 0x0000
|
||||
#define SMI_STATUS 0x0002
|
||||
#define SMI_SRC_PM (1L << 0)
|
||||
#define SMI_SRC_AUDIO_INDEX 1
|
||||
#define SMI_SRC_AUDIO (1L << SMI_SRC_AUDIO_INDEX)
|
||||
#define SMI_SRC_ACPI (1L << 2)
|
||||
#define SMI_SRC_VG (1L << 3)
|
||||
#define SMI_SRC_INT_MEMORY (1L << 4)
|
||||
#define SMI_SRC_RETRACE (1L << 5)
|
||||
#define SMI_SRC_VGA_TIMER (1L << 6)
|
||||
#define SMI_SRC_A20_INDEX 7
|
||||
#define SMI_SRC_A20 (1L << SMI_SRC_A20_INDEX)
|
||||
#define SMI_SRC_SW_INDEX 8
|
||||
#define SMI_SRC_SW (1L << SMI_SRC_SW_INDEX)
|
||||
#define GTT_INDEX 9
|
||||
#define SMI_SRC_GTT (1L << GTT_INDEX)
|
||||
#define SMI_SRC_DEBUG (1L << 10)
|
||||
#define SMI_SRC_MFGPT (1L << 11)
|
||||
#define SMI_SRC_NMI (1L << 12)
|
||||
#define SMI_SRC_RESET (1L << 13)
|
||||
#define SMI_SRC_USB1 (1L << 14)
|
||||
#define SMI_SRC_USB2 (1L << 15)
|
||||
#define SMI_IGNORE 0x7FFF
|
||||
|
||||
|
||||
#define GTT_STATUS 0x0006
|
||||
// NOTE: The following source definitions are shifted left 16 bits because
|
||||
// Get_SMI_Sources passes them that way in the SMI_Sources variable.
|
||||
#define GTT_SRC_GT1 (1L << ( 0+16))
|
||||
#define GTT_SRC_GT2 (1L << ( 1+16))
|
||||
#define GTT_SRC_USR_DEF_TRAP1 (1L << ( 2+16))
|
||||
#define GTT_SRC_USR_DEF_TRAP2 (1L << ( 3+16))
|
||||
#define GTT_SRC_USR_DEF_TRAP3 (1L << ( 4+16))
|
||||
#define SMI_SRC_PCI_TRAP (1L << ( 5+16))
|
||||
#define GTT_SRC_1MS_TMR (1L << ( 6+16))
|
||||
#define GTT_SRC_1SEC_TMR (1L << ( 7+16))
|
||||
#define SMI_SRC_MPCI (1L << ( 8+16)) // Virtualized PCI access
|
||||
#define SMI_SRC_DESCR_HIT (1L << ( 9+16)) // Hit on MBus descriptor
|
||||
#define SMI_SRC_STAT (1L << (10+16)) // Hit on MBus statistics counter
|
||||
#define SMI_SRC_PIC (1L << (11+16)) // PIC event
|
||||
#define SMI_SRC_KEL (1L << (12+16)) // KEL event
|
||||
#define SMI_SRC_PME (1L << (13+16)) // PME event
|
||||
#define SMI_SRC_BLOCKIO (1L << (14+16)) // BLOCKIO event
|
||||
|
||||
#define SMI_SPEEDUP_DISABLE 0x0008
|
||||
|
||||
#define AUDIO_STATUS 0x0010 // relative to F3 BAR0
|
||||
|
||||
|
||||
|
||||
//############################################################################################
|
||||
|
||||
|
||||
#define PCI_CFG_CONTROL 0x40
|
||||
#define LEGACY_CFG_SMI (1L << 8)
|
||||
#define PM_CFG_SMI (1L << 11)
|
||||
#define IDE_CFG_SMI (1L << 14)
|
||||
#define AUDIO_CFG_SMI (1L << 16)
|
||||
#define VIDEO_CFG_SMI (1L << 17)
|
||||
#define USB_PM_SMI (1L << 22)
|
||||
#define USB_CFG_SMI (1L << 23)
|
||||
#define USB_ENABLE (1L << 24)
|
||||
|
||||
#define PM_CFG_SMI_SCxxxx (1L << 9)
|
||||
#define IDE_CFG_SMI_SCxxxx (1L << 10)
|
||||
#define AUDIO_CFG_SMI_SCxxxx (1L << 11)
|
||||
#define VIDEO_CFG_SMI_SCxxxx (1L << 12)
|
||||
#define XBUS_CFG_SMI_SCxxxx (1L << 13)
|
||||
|
||||
#define RESET_CONTROL 0x44
|
||||
#define X_BUS_WARM_START (1L << 0)
|
||||
#define PCI_RESET (1L << 1)
|
||||
#define IDE_RESET (1L << 2)
|
||||
#define IDE_CONTROLLER_RESET (1L << 3)
|
||||
#define AC97_RESET (1L << 7)
|
||||
|
||||
|
||||
#define ROM_AT_LOGIC 0x52
|
||||
#define LOWER_ROM_ENABLE (1 << 0)
|
||||
#define ROM_WRITE_ENABLE (1 << 1)
|
||||
#define ROM_1MB_WRITE_ENABLE (1 << 2)
|
||||
#define PORT_92_ENABLE (1 << 3)
|
||||
#define A20M_DEASSERT (1 << 4)
|
||||
#define GAMEPORT_CS_ON_READS (1 << 5)
|
||||
#define GAMEPORT_CS_ON_WRITES (1 << 6)
|
||||
#define FAST_KEYBOARD_DISABLE (1 << 7)
|
||||
|
||||
|
||||
#define CPU_SUPPORT 0x53
|
||||
#define A20M_ENABLE (1 << 0)
|
||||
#define RTC_ENABLE (1 << 2)
|
||||
#define GAMEPORT_ENABLE (1 << 3)
|
||||
|
||||
#define DECODE_CONTROL 0x5A
|
||||
#define RTC_POSITIVE_DECODE (1 << 0)
|
||||
#define KBD_POSITIVE_DECODE (1 << 1)
|
||||
#define COM1_POSITIVE_DECODE (1 << 2)
|
||||
#define COM2_POSITIVE_DECODE (1 << 3)
|
||||
#define COM3_POSITIVE_DECODE (1 << 4)
|
||||
#define COM4_POSITIVE_DECODE (1 << 5)
|
||||
#define FLPY1_POSITIVE_DECODE (1 << 6)
|
||||
#define FLPY2_POSITIVE_DECODE (1 << 7)
|
||||
#define LPT1_POSITIVE_DECODE (1 << 8)
|
||||
#define LPT2_POSITIVE_DECODE (1 << 9)
|
||||
#define LPT3_POSITIVE_DECODE (1 << 10)
|
||||
#define IDE1_POSITIVE_DECODE (1 << 11)
|
||||
#define IDE2_POSITIVE_DECODE (1 << 12)
|
||||
#define ROM_POSITIVE_DECODE (1 << 13)
|
||||
#define KBD_6X_DECODE (1 << 15)
|
||||
|
||||
#define PCI_STEERING 0x5C
|
||||
|
||||
|
||||
// Top-level SMI enables (registers 0x80-0x83)
|
||||
#define ENABLE_TRAPS_TIMERS 0x80
|
||||
#define ENABLE_PM (1L << 0)
|
||||
#define ENABLE_TIMERS (1L << 1)
|
||||
#define ENABLE_TRAPS (1L << 2)
|
||||
#define ENABLE_IRQ_SPEEDUP (1L << 3)
|
||||
#define ENABLE_VIDEO_SPEEDUP (1L << 4)
|
||||
#define ENABLE_CODEC_SMI (1L << 5)
|
||||
#define ENABLE_RESERVED1 (1L << 6)
|
||||
#define ENABLE_RESERVED2 (1L << 7)
|
||||
#define ENABLE_HDD0_TIMER (1L << 8)
|
||||
#define ENABLE_FDD_TIMER (1L << 9)
|
||||
#define ENABLE_PAR_SER_TIMER (1L << 10)
|
||||
#define ENABLE_KYBD_MOUSE_TIMER (1L << 11)
|
||||
#define ENABLE_USR_DEF_TIMER1 (1L << 12)
|
||||
#define ENABLE_USR_DEF_TIMER2 (1L << 13)
|
||||
#define ENABLE_USR_DEF_TIMER3 (1L << 14)
|
||||
#define ENABLE_VIDEO_TIMER (1L << 15)
|
||||
#define ENABLE_HDD0_TRAP (1L << 16)
|
||||
#define ENABLE_FDD_TRAP (1L << 17)
|
||||
#define ENABLE_PAR_SER_TRAP (1L << 18)
|
||||
#define ENABLE_KYBD_MOUSE_TRAP (1L << 19)
|
||||
#define ENABLE_USR_DEF_TRAP1 (1L << 20)
|
||||
#define ENABLE_USR_DEF_TRAP2 (1L << 21)
|
||||
#define ENABLE_USR_DEF_TRAP3 (1L << 22)
|
||||
#define ENABLE_VIDEO_TRAP (1L << 23)
|
||||
#define ENABLE_GT1 (1L << 24)
|
||||
#define ENABLE_GT2 (1L << 25)
|
||||
#define ENABLE_RETRACE (1L << 26)
|
||||
#define ENABLE_VGA_TIMER (1L << 27)
|
||||
#define ENABLE_THERMAL (1L << 28) // SCxxxx only
|
||||
#define ENABLE_ACPI_TIMER (1L << 29)
|
||||
#define ENABLE_HDD1_TRAP (1L << 30)
|
||||
#define ENABLE_HDD1_TIMER (1L << 31)
|
||||
|
||||
|
||||
#define GT1_COUNT 0x88
|
||||
#define GT1_CONTROL 0x89
|
||||
#define GT1_RESET_HDD (1 << 0)
|
||||
#define GT1_RESET_FDD (1 << 1)
|
||||
#define GT1_RESET_PARALLEL_SERIAL (1 << 2)
|
||||
#define GT1_RESET_KEYBD_MOUSE (1 << 3)
|
||||
#define GT1_RESET_USR_DEF1 (1 << 4)
|
||||
#define GT1_RESET_USR_DEF2 (1 << 5)
|
||||
#define GT1_RESET_USR_DEF3 (1 << 6)
|
||||
#define GT1_TIMEBASE (1 << 7)
|
||||
|
||||
|
||||
#define GT2_COUNT 0x8A
|
||||
#define GT2_CONTROL 0x8B
|
||||
#define GT2_RESET_GPIO7 (1 << 2)
|
||||
#define GT2_TIMEBASE (1 << 3) // 0=second 1=ms
|
||||
#define GT1_SHIFT (1 << 4) // 0=8 bit 1=16 bit
|
||||
#define GT2_SHIFT (1 << 5) // 0=8 bit 1=16 bit
|
||||
#define VGA_TIMEBASE (1 << 6) // 0=ms 1=32 us
|
||||
#define GT1_RESET_SEC_HDD (1 << 7) // 0=disable 1=enable
|
||||
|
||||
#define IRQ_SPEEDUP_COUNT 0x8C
|
||||
#define VIDEO_SPEEDUP_COUNT 0x8D
|
||||
#define VGA_TIMER_LOAD_COUNT 0x8E
|
||||
|
||||
|
||||
|
||||
|
||||
#define GPIO_DIRECTION 0x90
|
||||
#define GPIO_DATA 0x91
|
||||
#define GPIO_CONTROL 0x92
|
||||
#define GPIO0_ENABLE (1 << 0)
|
||||
#define GPIO1_ENABLE (1 << 1)
|
||||
#define GPIO2_ENABLE (1 << 2)
|
||||
#define GPIO0_EDGE (1 << 3)
|
||||
#define GPIO1_EDGE (1 << 4)
|
||||
#define GPIO2_EDGE (1 << 5)
|
||||
#define GPIO6_ENABLE (1 << 6)
|
||||
#define GPIO6_EDGE (0 << 6)
|
||||
#define GPIO7_EDGE (1 << 7)
|
||||
|
||||
|
||||
|
||||
#define MISCELLANEOUS 0x93
|
||||
#define SERIAL_MOUSE_SELECT (1 << 0)
|
||||
#define SERIAL_MOUSE (1 << 1)
|
||||
#define HDD1_PARTIAL_DECODE (1 << 4)
|
||||
#define HDD0_PARTIAL_DECODE (1 << 5)
|
||||
#define HDD_SELECT (1 << 6)
|
||||
#define FDD_SELECT (1 << 7)
|
||||
|
||||
#define SUSPEND_MODULATION_OFF 0x94
|
||||
#define SUSPEND_MODULATION_ON 0x95
|
||||
#define SUSPEND_CONFIGURATION 0x96
|
||||
#define SUSPEND_MOD_ENABLE (1 << 0)
|
||||
#define SMI_SPEEDUP (1 << 1)
|
||||
#define SUSPEND_MODE (1 << 2)
|
||||
|
||||
|
||||
#define GPIO_CONTROL2 0x97
|
||||
#define GPIO3_ENABLE (1 << 0)
|
||||
#define GPIO4_ENABLE (1 << 1)
|
||||
#define GPIO5_ENABLE (1 << 2)
|
||||
#define GPIO7_ENABLE (1 << 3)
|
||||
#define GPIO3_EDGE (1 << 4)
|
||||
#define GPIO4_EDGE (1 << 5)
|
||||
#define GPIO5_EDGE (1 << 6)
|
||||
#define GPIO7_EDGE (1 << 7)
|
||||
|
||||
|
||||
#define HDD_IDLE_TIMEOUT 0x98
|
||||
#define FDD_IDLE_TIMEOUT 0x9A
|
||||
#define PAR_SER_IDLE_TIMEOUT 0x9C
|
||||
#define KYBD_MOUSE_IDLE_TIMEOUT 0x9E
|
||||
#define USR_DEF1_IDLE_TIMEOUT 0xA0
|
||||
#define USR_DEF2_IDLE_TIMEOUT 0xA2
|
||||
#define USR_DEF3_IDLE_TIMEOUT 0xA4
|
||||
#define VIDEO_IDLE_TIMEOUT 0xA6
|
||||
|
||||
#define SEC_HDD_TIMEOUT 0xAC
|
||||
#define CPU_SUSPEND_COMMAND 0xAE
|
||||
#define CPU_STOP_CLOCK_COMMAND 0xAF
|
||||
#define CPU_CACHE_MISS_ACTIVITY 0xB0
|
||||
#define CPU_CACHE_MISS_INACTIVITY 0xB1
|
||||
#define CPU_CACHE_MISS_THRESHOLD 0xB2
|
||||
|
||||
#define FLOPPY_SHADOW 0xB4
|
||||
#define FLOPPY_3F2 0xB4
|
||||
#define FLOPPY_3F7 0xB5
|
||||
#define FLOPPY_372 0xB6
|
||||
#define FLOPPY_377 0xB7
|
||||
|
||||
#define DMA_SHADOW 0xB8
|
||||
#define DMA_SHADOW_CNT 10
|
||||
|
||||
#define PIC_SHADOW 0xB9
|
||||
#define PIC_SHADOW_CNT 12
|
||||
|
||||
#define PIT_SHADOW 0xBA
|
||||
#define PIT_SHADOW_CNT 9
|
||||
|
||||
#define RTC_SHADOW 0xBB
|
||||
#define RTC_SHADOW_CNT 1
|
||||
|
||||
#define PIC_SHADOW 0xB9
|
||||
#define PIT_SHADOW 0xBA
|
||||
#define RTC_SHADOW 0xBB
|
||||
|
||||
#define CLOCK_STOP_CONTROL 0xBC
|
||||
|
||||
#define USR_DEF_1_BASE 0xC0
|
||||
#define USR_DEF_2_BASE 0xC4
|
||||
#define USR_DEF_3_BASE 0xC8
|
||||
#define USR_DEF_1_CONTROL 0xCC
|
||||
#define USR_DEF_2_CONTROL 0xCD
|
||||
#define USR_DEF_3_CONTROL 0xCE
|
||||
#define USR_DEF_MEMORY (1 << 7) // Bit 7 = 1
|
||||
#define USR_DEF_IO (0 << 7) // Bit 7 = 0
|
||||
#define USR_DEF_WRITE (1 << 6) // Bit 6 = 1 (only for I/O)
|
||||
#define USR_DEF_READ (1 << 5) // Bit 5 = 1 (only for I/O)
|
||||
|
||||
|
||||
#define SW_SMI 0xD0
|
||||
|
||||
|
||||
|
||||
// Relative to PCI Function 0
|
||||
#define PM_STATUS 0xF4
|
||||
#define PM_SRC_GPIO3 (1L << 0)
|
||||
#define PM_SRC_GPIO4 (1L << 1)
|
||||
#define PM_SRC_GPIO5 (1L << 2)
|
||||
#define PM_SRC_GPIO7 (1L << 3)
|
||||
#define PM_SRC_GAMEPORT (1L << 4)
|
||||
#define PM_SRC_HDD_IDLE (1L << 8) // Primary
|
||||
#define PM_SRC_FDD_IDLE (1L << 9)
|
||||
#define PM_SRC_PARSER_IDLE (1L << 10)
|
||||
#define PM_SRC_KEYBMS_IDLE (1L << 11)
|
||||
#define PM_SRC_USER_DEF1_IDLE (1L << 12)
|
||||
#define PM_SRC_USER_DEF2_IDLE (1L << 13)
|
||||
#define PM_SRC_USER_DEF3_IDLE (1L << 14)
|
||||
#define PM_SRC_VIDEO_IDLE (1L << 15)
|
||||
#define PM_SRC_HDD_TRAP (1L << 16) // Primary
|
||||
#define PM_SRC_FDD_TRAP (1L << 17)
|
||||
#define PM_SRC_PAR_SER_TRAP (1L << 18)
|
||||
#define PM_SRC_KYBD_MOUSE_TRAP (1L << 19)
|
||||
#define PM_SRC_SECONDARY_IDLE (1L << 20)
|
||||
#define PM_SRC_SECONDARY_TRAP (1L << 21)
|
||||
#define PM_SRC_reserved (1L << 22)
|
||||
#define PM_SRC_VIDEO_TRAP (1L << 23)
|
||||
#define PM_SRC_ACPI_TIMER (1L << 24)
|
||||
#define PM_SRC_RTC_ALARM (1L << 25)
|
||||
#define PM_SRC_AC97_CODEC (1L << 26)
|
||||
#define PM_SRC_LID_SWITCH (1L << 27)
|
||||
#define PM_SRC_LID_POSITION (1L << 28) // Not an SMI source
|
||||
#define PM_SRC_GPIO0 (1L << 29)
|
||||
#define PM_SRC_GPIO1 (1L << 30) // CS55x0 only
|
||||
#define PM_SRC_THERMAL (1L << 30) // SCxxxx only
|
||||
#define PM_SRC_GPIO2 ((ULONG)(1L << 31))
|
||||
|
||||
|
||||
#define GPIO_PINS (PM_SRC_GPIO0 | PM_SRC_GPIO1 | PM_SRC_GPIO2 | PM_SRC_GPIO3 | PM_SRC_GPIO4 | PM_SRC_GPIO5 | PM_SRC_LID_SWITCH | PM_SRC_GPIO7)
|
||||
|
||||
|
||||
|
||||
230
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/cs5536.h
vendored
Executable file
230
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/cs5536.h
vendored
Executable file
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//************************** CS5536 related defines ***************************
|
||||
|
||||
|
||||
|
||||
// Southbridge MPCI CTRL:
|
||||
#define ME (1 << 0) // Enable in-bound memory accesses
|
||||
#define IE (1 << 1) // Enable in-bound I/O accesses
|
||||
#define CIS_MASK (3 << 3) // CIS Mode
|
||||
#define CIS_A (1 << 3)
|
||||
#define CIS_B (2 << 3)
|
||||
#define CIS_C (3 << 3)
|
||||
|
||||
|
||||
|
||||
#define MPCI_SOUTH 0x51000000 // 2.4.2.0
|
||||
|
||||
#define MDD_PORT 4 // Port that MDD is at
|
||||
|
||||
|
||||
|
||||
#define REGION_R0 0x20
|
||||
#define REGION_R15 (REGION_R0 + 15)
|
||||
|
||||
|
||||
|
||||
|
||||
/****** 5536 GPIO definitions ******/
|
||||
|
||||
// offsets from GPIO base
|
||||
#define GPIO5536_BASE (0x6100)
|
||||
|
||||
#define NUM_5536_GPIO (28)
|
||||
|
||||
#define GPIOH_OFFSET (0x80)
|
||||
|
||||
#define GPIO_OUT_VAL (0x00)
|
||||
#define GPIO_OUT_EN (0x04)
|
||||
#define GPIO_OUT_OD_EN (0x08)
|
||||
#define GPIO_OUT_INV_EN (0x0C)
|
||||
#define GPIO_OUT_AUX1_SEL (0x10)
|
||||
#define GPIO_OUT_AUX2_SEL (0x14)
|
||||
#define GPIO_PU_EN (0x18)
|
||||
#define GPIO_PD_EN (0x1C)
|
||||
#define GPIO_IN_EN (0x20)
|
||||
#define GPIO_IN_INV_EN (0x24)
|
||||
#define GPIO_IN_FIL_EN (0x28)
|
||||
#define GPIO_IN_EVC_EN (0x2C)
|
||||
#define GPIO_READBACK (0x30)
|
||||
#define GPIO_IN_AUX_SEL (0x34)
|
||||
#define GPIO_EVENT_EN (0x38)
|
||||
#define GPIO_LOCK_EN (0x3C)
|
||||
#define GPIO_IN_PEDG_EN (0x40)
|
||||
#define GPIO_IN_NEDG_EN (0x44)
|
||||
#define GPIO_IN_PEDG_STS (0x48)
|
||||
#define GPIO_IN_NEDG_STS (0x4C)
|
||||
|
||||
#define GPIO00_FILA (0x50)
|
||||
#define GPIO00_FILC (0x52)
|
||||
#define GPIO00_EVCNT (0x54)
|
||||
#define GPIO00_EVCMP (0x56)
|
||||
#define GPIO01_FILA (0x58)
|
||||
#define GPIO01_FILC (0x5A)
|
||||
#define GPIO01_EVCNT (0x5C)
|
||||
#define GPIO01_EVCMP (0x5E)
|
||||
#define GPIO02_FILA (0x60)
|
||||
#define GPIO02_FILC (0x62)
|
||||
#define GPIO02_EVCNT (0x64)
|
||||
#define GPIO02_EVCMP (0x66)
|
||||
#define GPIO03_FILA (0x68)
|
||||
#define GPIO03_FILC (0x6A)
|
||||
#define GPIO03_EVCNT (0x6C)
|
||||
#define GPIO03_EVCMP (0x6E)
|
||||
#define GPIO04_FILA (0x70)
|
||||
#define GPIO04_FILC (0x72)
|
||||
#define GPIO04_EVCNT (0x74)
|
||||
#define GPIO04_EVCMP (0x76)
|
||||
#define GPIO05_FILA (0x78)
|
||||
#define GPIO05_FILC (0x7A)
|
||||
#define GPIO05_EVCNT (0x7C)
|
||||
#define GPIO05_EVCMP (0x7E)
|
||||
#define GPIO06_FILA (0xD0)
|
||||
#define GPIO06_FILC (0xD2)
|
||||
#define GPIO06_EVCNT (0xD4)
|
||||
#define GPIO06_EVCMP (0xD6)
|
||||
#define GPIO07_FILA (0xD8)
|
||||
#define GPIO07_FILC (0xDA)
|
||||
#define GPIO07_EVCNT (0xDC)
|
||||
#define GPIO07_EVCMP (0xDE)
|
||||
|
||||
#define GPIO_MAPX (0xE0)
|
||||
#define GPIO_MAPY (0xE4)
|
||||
#define GPIO_MAPZ (0xE8)
|
||||
#define GPIO_MAPW (0xEC)
|
||||
|
||||
#define GPIO_FE0 (0xF0)
|
||||
#define GPIO_FE1 (0xF1)
|
||||
#define GPIO_FE2 (0xF2)
|
||||
#define GPIO_FE3 (0xF3)
|
||||
#define GPIO_FE4 (0xF4)
|
||||
#define GPIO_FE5 (0xF5)
|
||||
#define GPIO_FE6 (0xF6)
|
||||
#define GPIO_FE7 (0xF7)
|
||||
|
||||
#define GPIOL_IN_EVENT_DECR (0xF8)
|
||||
#define GPIOH_IN_EVENT_DECR (0xFC)
|
||||
|
||||
// GPIO atomic register values
|
||||
#define GPIO00_SET (0x00000001L)
|
||||
#define GPIO00_CLR (0x00010000L)
|
||||
#define GPIO01_SET (0x00000002L)
|
||||
#define GPIO01_CLR (0x00020000L)
|
||||
#define GPIO02_SET (0x00000004L)
|
||||
#define GPIO02_CLR (0x00040000L)
|
||||
#define GPIO03_SET (0x00000008L)
|
||||
#define GPIO03_CLR (0x00080000L)
|
||||
#define GPIO04_SET (0x00000010L)
|
||||
#define GPIO04_CLR (0x00100000L)
|
||||
#define GPIO05_SET (0x00000020L)
|
||||
#define GPIO05_CLR (0x00200000L)
|
||||
#define GPIO06_SET (0x00000040L)
|
||||
#define GPIO06_CLR (0x00400000L)
|
||||
#define GPIO07_SET (0x00000080L)
|
||||
#define GPIO07_CLR (0x00800000L)
|
||||
#define GPIO08_SET (0x00000100L)
|
||||
#define GPIO08_CLR (0x01000000L)
|
||||
#define GPIO09_SET (0x00000200L)
|
||||
#define GPIO09_CLR (0x02000000L)
|
||||
#define GPIO10_SET (0x00000400L)
|
||||
#define GPIO10_CLR (0x04000000L)
|
||||
#define GPIO11_SET (0x00000800L)
|
||||
#define GPIO11_CLR (0x08000000L)
|
||||
#define GPIO12_SET (0x00001000L)
|
||||
#define GPIO12_CLR (0x10000000L)
|
||||
#define GPIO13_SET (0x00002000L)
|
||||
#define GPIO13_CLR (0x20000000L)
|
||||
#define GPIO14_SET (0x00004000L)
|
||||
#define GPIO14_CLR (0x40000000L)
|
||||
#define GPIO15_SET (0x00008000L)
|
||||
#define GPIO15_CLR (0x80000000L)
|
||||
|
||||
#define GPIO16_SET (0x00000001L)
|
||||
#define GPIO16_CLR (0x00010000L)
|
||||
#define GPIO17_SET (0x00000002L)
|
||||
#define GPIO17_CLR (0x00020000L)
|
||||
#define GPIO18_SET (0x00000004L)
|
||||
#define GPIO18_CLR (0x00040000L)
|
||||
#define GPIO19_SET (0x00000008L)
|
||||
#define GPIO19_CLR (0x00080000L)
|
||||
#define GPIO20_SET (0x00000010L)
|
||||
#define GPIO20_CLR (0x00100000L)
|
||||
#define GPIO21_SET (0x00000020L)
|
||||
#define GPIO21_CLR (0x00200000L)
|
||||
#define GPIO22_SET (0x00000040L)
|
||||
#define GPIO22_CLR (0x00400000L)
|
||||
#define GPIO23_SET (0x00000080L)
|
||||
#define GPIO23_CLR (0x00800000L)
|
||||
#define GPIO24_SET (0x00000100L)
|
||||
#define GPIO24_CLR (0x01000000L)
|
||||
#define GPIO25_SET (0x00000200L)
|
||||
#define GPIO25_CLR (0x02000000L)
|
||||
#define GPIO26_SET (0x00000400L)
|
||||
#define GPIO26_CLR (0x04000000L)
|
||||
#define GPIO27_SET (0x00000800L)
|
||||
#define GPIO27_CLR (0x08000000L)
|
||||
#define GPIO28_SET (0x00001000L)
|
||||
#define GPIO28_CLR (0x10000000L)
|
||||
#define GPIO29_SET (0x00002000L)
|
||||
#define GPIO29_CLR (0x20000000L)
|
||||
#define GPIO30_SET (0x00004000L)
|
||||
#define GPIO30_CLR (0x40000000L)
|
||||
#define GPIO31_SET (0x00008000L)
|
||||
#define GPIO31_CLR (0x80000000L)
|
||||
|
||||
// Hawk platform has Sleep Button connected to GPIO25
|
||||
#define DEFAULT_SLPB_GPIO (25)
|
||||
|
||||
// GPIO13 AUX_IN is dedicated 5536 Sleep Button but it is only connected
|
||||
// to Working Power Domain and can't wake the system from Standby.
|
||||
// #define DEFAULT_SLPB_GPIO (13)
|
||||
|
||||
|
||||
// 5536 Power Management Controller
|
||||
|
||||
// offsets from base PMC I/O address, all are 32-bit regs
|
||||
#define PM_SSD (0x00) // Sleep start delay
|
||||
#define PM_SCXA (0x04) // Sleep control X Assert Delay and Enable
|
||||
#define PM_SCYA (0x08) // Sleep control Y Assert Delay and Enable
|
||||
#define PM_SODA (0x0C) // Sleep Output Disable Assert Delay and Enable
|
||||
#define PM_SCLK (0x10) // Sleep Clock Delay and Enable
|
||||
#define PM_SED (0x14) // Sleep End Delay
|
||||
#define PM_SCXD (0x18) // Sleep Control X De-assert Delay and Enable
|
||||
#define PM_SCYD (0x1C) // Sleep Control Y De-assert Delay and Enable
|
||||
#define PM_SIDD (0x20) // Sleep Input Disable De-assert Delay and Enable
|
||||
#define PM_WKD (0x30) // Working De-assert Delay and Enable
|
||||
#define PM_WKXD (0x34) // Work_AUX De-assert Delay and Enable
|
||||
#define PM_RD (0x38) // De-assert Delay from Standby
|
||||
#define PM_WKXA (0x3C) // Work_AUX Assert Delay from Standby Wakeup
|
||||
#define PM_FSD (0x40) // Fail-Safe Delay and Enable
|
||||
#define PM_TSD (0x44) // Thermal-Safe Delay and Enable
|
||||
#define PM_PSD (0x48) // Power-Safe Delay and Enable
|
||||
#define PM_NWKD (0x4C) // Normal Work Delay and Enable
|
||||
#define PM_AWKD (0x50) // Abnormal Work Delay and Enable
|
||||
#define PM_SSC (0x54) // Standby Status and Control
|
||||
|
||||
|
||||
|
||||
#define USBMSROHCB 0x0008
|
||||
#define USBMSREHCB 0x0009
|
||||
#define USBMSRUDCB 0x000A
|
||||
#define USBMSRUOCB 0x000B
|
||||
#define PMEEN (1L << 3)
|
||||
443
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/gx2.h
vendored
Executable file
443
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/gx2.h
vendored
Executable file
@@ -0,0 +1,443 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
// Vail MSRs
|
||||
#define MSR_SMM_CTRL 0x1301
|
||||
#define SMM_NMI_EN (1L << 0) // Enables NMIs during SMM
|
||||
#define SMM_SUSP_EN (1L << 1) // Enables SUSP# pin during SMM
|
||||
#define NEST_SMI_EN (1L << 2) // Enables SSMIs during SMM
|
||||
#define SMM_INST_EN (1L << 3) // Enables SMM instructions
|
||||
#define INTL_SMI_EN (1L << 4) // Enables SSMIs
|
||||
#define EXTL_SMI_EN (1L << 5) // Enables SMI# pin
|
||||
|
||||
#define MSR_SMM_HDR 0x132B
|
||||
#define MSR_SMM_LOC 0x133B
|
||||
#define MSR_EFLAGS 0x1418
|
||||
#define MSR_CR0 0x1420
|
||||
#define MSR_DR7 0x1343
|
||||
|
||||
|
||||
//
|
||||
// Region Control Registers (see page 10-188 of Vail spec)
|
||||
//
|
||||
#define REGION_CD (1L << 0) // Cache disabled
|
||||
#define REGION_WA (1L << 1) // Write-allocate
|
||||
#define REGION_WP (1L << 2) // Write-protect
|
||||
#define REGION_WT (1L << 3) // Write-through
|
||||
#define REGION_WC (1L << 4) // Write-combine
|
||||
#define REGION_WS (1L << 5) // Write-serialize
|
||||
#define REGION_EN (1L << 8) // Region enable
|
||||
|
||||
#define MSR_RCONF_DEFAULT 0x1808
|
||||
#define MSR_RCONF_BYPASS 0x180A
|
||||
#define MSR_RCONF_A0_BF 0x180B
|
||||
#define MSR_RCONF_C0_DF 0x180C
|
||||
#define MSR_RCONF_E0_FF 0x180D
|
||||
#define MSR_RCONF_SMM 0x180E
|
||||
#define MSR_RCONF_DMM 0x180F
|
||||
|
||||
|
||||
// Bit(s) Field
|
||||
// ------ -----------------------------------------------
|
||||
// 7:0 Region Properties
|
||||
// 8 Enable
|
||||
// 11:9 reserved
|
||||
// 31:12 Start of region (4 KB granularity; inclusive)
|
||||
// 43:32 reserved
|
||||
// 63:44 Top of region (4 KB granularity; inclusive)
|
||||
#define MSR_RCONF0 0x1810
|
||||
#define MSR_RCONF1 0x1811
|
||||
#define MSR_RCONF2 0x1812
|
||||
#define MSR_RCONF3 0x1813
|
||||
#define MSR_RCONF4 0x1814
|
||||
#define MSR_RCONF5 0x1815
|
||||
#define MSR_RCONF6 0x1816
|
||||
#define MSR_RCONF7 0x1817
|
||||
|
||||
|
||||
//========================================================================================
|
||||
#define BIZARRO (1L << 28)
|
||||
#define ROUTING 0xFFFFC000 // Mask for routing field
|
||||
|
||||
|
||||
|
||||
// Ports under Redcloud MBIU0
|
||||
#define PORT_MBIU0 0x10000000L // By convention
|
||||
|
||||
|
||||
// Standard MBus Device MSRs:
|
||||
#define MBD_MSR_CAP 0x2000
|
||||
#define MBD_MSR_CONFIG 0x2001 // 3 LSBs = subtractive port
|
||||
// MBIU0: 0x00000002
|
||||
// MBIU1: 0x00000004
|
||||
// MBIU2: 0x00000004
|
||||
|
||||
#define MBD_MSR_SMI 0x2002
|
||||
#define MBD_MSR_ERROR 0x2003
|
||||
#define MBD_MSR_PM 0x2004
|
||||
#define MBD_MSR_DIAG 0x2005
|
||||
|
||||
// Northbridge MPCI
|
||||
#define MPCI_CTRL 0x2010
|
||||
#define LDE (1 << 9) // Enable latency disconnect timer
|
||||
#define MPCI_ARB 0x2011
|
||||
#define MPCI_PBUS 0x2012
|
||||
#define MPCI_REN 0x2014 // Fixed Region Enables
|
||||
#define MPCI_A0_BF 0x2015 // Fixed Regions Properties A0000-BFFFF
|
||||
#define MPCI_C0_DF 0x2016 // Fixed Regions Properties C0000-DFFFF
|
||||
#define MPCI_E0_FF 0x2017 // Fixed Regions Properties E0000-FFFFF
|
||||
#define MPCI_R0 0x2018 // Base memory
|
||||
#define MPCI_R1 0x2019 // Extended memory
|
||||
#define MPCI_R2 0x201A // SMM memory
|
||||
#define MPCI_R3 0x201B
|
||||
#define MPCI_R4 0x201C
|
||||
#define MPCI_R5 0x201D
|
||||
// MPCI Region Control Registers (see page 89 of MPCI spec)
|
||||
#define REGION_CD (1L << 0) // Cache disabled
|
||||
#define REGION_DD (1L << 1) // Discard data
|
||||
#define REGION_WP (1L << 2) // Write protect
|
||||
#define REGION_WT (1L << 3) // Write through
|
||||
#define REGION_WC (1L << 4) // Write combine
|
||||
#define REGION_PF (1L << 5) // Prefetchable
|
||||
|
||||
#define MPCI_ExtMSR 0x201E
|
||||
|
||||
|
||||
|
||||
// Revision IDs
|
||||
#define CPU_REV_1_0 0x11
|
||||
#define CPU_REV_1_1 0x12
|
||||
#define CPU_REV_2_0 0x20
|
||||
|
||||
|
||||
// MBus Device IDs:
|
||||
#define ID_SHIFT 12
|
||||
#define ID_MBIU 0x01
|
||||
#define ID_MC 0x20
|
||||
#define ID_VAIL 0x86
|
||||
#define ID_AES 0x30
|
||||
#define ID_VIP 0x3C
|
||||
#define ID_GP 0x3D
|
||||
#define ID_VG 0x3E
|
||||
#define ID_DF 0x3F
|
||||
#define ID_MCP 0x02
|
||||
#define ID_MPCI 0x05
|
||||
#define ID_FG 0xF0
|
||||
#define ID_OHCI 0x42
|
||||
#define ID_USB_20 0x43
|
||||
#define ID_ATA 0x47
|
||||
#define ID_ATA100 0x48
|
||||
#define ID_MDD 0xDF
|
||||
#define ID_AC97 0x33
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Northbridge
|
||||
/////////////////////////////////////////////////////////////
|
||||
// MBIU0
|
||||
//
|
||||
// Capabilities: 22711830 010C1086
|
||||
// P2D_BM = 6; 0x20-0x25
|
||||
// P2D_BMO = 2; 0x26-0x27
|
||||
// P2D_R = 1; 0x28
|
||||
// P2D_RO = 3; 0x29-0x2B
|
||||
// P2D_SC = 1; 0x2C
|
||||
// P2D_SCO = 0;
|
||||
// IOD_BM = 3; 0xE0-0xE2
|
||||
// IOD_SC = 6; 0xE3-0xE8
|
||||
// NPORTS = 5;
|
||||
// STATS = 2;
|
||||
//
|
||||
// Port Dev_ID Routing FS/2 Device Description
|
||||
// ----- -------- ------------------- -------- ------------------
|
||||
// 0 01h 10000000 0.1.0.0.0 20000000 MBIU0
|
||||
// 1 20h 20000000 1.0.0.0.0 24000000 Memory Controller
|
||||
// 2 01h 40000000 2.0.0.0.0 MBIU1 (subtractive)
|
||||
// 3 86h 60000000 3.0.0.0.0 2C000000 Vail (self-reference)
|
||||
// 4 3Eh 80000000 4.0.0.0.0 30000000 Video Generator
|
||||
// 5 3Dh A0000000 5.0.0.0.0 34000000 Graphics Processor
|
||||
// 6 3Fh C0000000 6.0.0.0.0 38000000 Display Filter
|
||||
// 7 <empty>
|
||||
|
||||
#define VG_PORT 4L
|
||||
#define GP_PORT 5L
|
||||
#define VG_SMI_MSR (VG_PORT << 29) + MBD_MSR_SMI
|
||||
#define GP_SMI_MSR (GP_PORT << 29) + MBD_MSR_SMI
|
||||
|
||||
|
||||
//
|
||||
// MBIU1
|
||||
//
|
||||
// Capabilities: 20281830 01004009
|
||||
// P2D_BM = 9; 0x20-0x28
|
||||
// P2D_BMO = 0;
|
||||
// P2D_R = 4; 0x29-0x2C
|
||||
// P2D_RO = 0;
|
||||
// P2D_SC = 1; 0x2D
|
||||
// P2D_SCO = 0;
|
||||
// IOD_BM = 3; 0xE0-0xE2
|
||||
// IOD_SC = 6; 0xE3-0xE8
|
||||
// NPORTS = 5;
|
||||
// STATS = 2;
|
||||
//
|
||||
// Port Dev_ID Routing FS/2 Device Description
|
||||
// ----- -------- ------------------- -------- ------------------
|
||||
// 0 <empty>
|
||||
// 1 01h 44000000 2.1.0.0.0 01000000 MBIU1 (self-reference)
|
||||
// 2 <empty>
|
||||
// 3 02h 4C000000 2.3.0.0.0 00000000 MCP
|
||||
// 4 05h 50000000 2.4.0.0.0 80000000 MPCI Northbridge (subtractive)
|
||||
// 5 F0h 54000000 2.5.0.0.0 A0000000 FooGlue
|
||||
// 6 <empty>
|
||||
// 7 <empty>
|
||||
|
||||
#define MBIU0_PORT 1 // From MBIU1's point of view
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// CS5535
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Capabilities: 327920A0 80000003 (simulator: 303820a0)
|
||||
// P2D_BM = 3; 0x20-0x22
|
||||
// P2D_BMK = 2; 0x23-0x24
|
||||
// IOD_BM = 10; 0xE0-0xE9
|
||||
// IOD_SC = 8; 0xEA-0xF1
|
||||
// NPORTS = 7;
|
||||
// STATS = 3;
|
||||
//
|
||||
//
|
||||
// Port Dev_ID Routing FS/2 Device Description
|
||||
// ----- -------- ------------------- -------- -----------------
|
||||
// 05h 51000000 2.4.2.0.0 88000000 MPCI Southbridge
|
||||
// 0 01h 51020000 2.4.2.0.1 88100000 MBIU2
|
||||
// 1 51100000 2.4.2.1.0 MPCI (self-reference)
|
||||
// 2 42h 51200000 2.4.2.2.0 89000000 OHCI #2
|
||||
// 3 47h 51300000 2.4.2.3.0 89800000 ATA-5
|
||||
// 4 DFh 51400000 2.4.2.4.0 8A000000 MDD (subtractive)
|
||||
// 5 33h 51500000 2.4.2.5.0 8A800000 AC97 codec
|
||||
// 6 42h 51600000 2.4.2.6.0 8B000000 OHCI #1
|
||||
// 7 02h 51700000 2.4.2.7.0 8B800000 MCP
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// CS5536
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Capabilities: 327920A0 80000003
|
||||
// P2D_BM = 3; 0x20-0x22
|
||||
// P2D_BMK = 2; 0x23-0x24
|
||||
// IOD_BM = 10; 0xE0-0xE9
|
||||
// IOD_SC = 8; 0xEA-0xF1
|
||||
// NPORTS = 7;
|
||||
// STATS = 3;
|
||||
//
|
||||
//
|
||||
// Port Dev_ID Routing FS/2 Device Description
|
||||
// ----- -------- ------------------- -------- -----------------
|
||||
// 05h 51000000 2.4.2.0.0 88000000 MPCI Southbridge
|
||||
// 0 01h 51020000 2.4.2.0.1 88100000 MBIU2
|
||||
// 1 51100000 2.4.2.1.0 MPCI (self-reference)
|
||||
// 2 42h 51200000 2.4.2.2.0 89000000 <empty>
|
||||
// 3 47h 51300000 2.4.2.3.0 89800000 ATA-5
|
||||
// 4 DFh 51400000 2.4.2.4.0 8A000000 MDD (subtractive)
|
||||
// 5 33h 51500000 2.4.2.5.0 8A800000 AC97 codec
|
||||
// 6 43h 51600000 2.4.2.6.0 8B000000 USB 2.0
|
||||
// 7 02h 51700000 2.4.2.7.0 8B800000 MCP
|
||||
|
||||
|
||||
//
|
||||
// Arcturus
|
||||
//
|
||||
// Device AD PIN Physical Device
|
||||
// ------ ------ ---------------------------------------------------
|
||||
// 13 23 MacPhyter
|
||||
// 14 24 PCI Slot 1
|
||||
// 15 25 PCI Slot 2
|
||||
// 16 26 Chipset Register Space - pin H26 High
|
||||
// 17 27 USB Register Space - pin H26 High
|
||||
// 18 28 Chipset Register Space - pin H26 Low
|
||||
// 19 29 USB Register Space - pin H26 Low
|
||||
|
||||
|
||||
//
|
||||
// MPCI
|
||||
//
|
||||
|
||||
// Fields for both MPCI_MSR_SMI and MPCI_MSR_ERROR
|
||||
#define MARM (1L << 0)
|
||||
#define TARM (1L << 1)
|
||||
#define BMM (1L << 2)
|
||||
#define SSMM (1L << 2) // only in MPCI SB MSR_SMI
|
||||
#define VPHM (1L << 3) // only in MPCI NB MSR_SMI
|
||||
#define SYSM (1L << 4)
|
||||
#define PARM (1L << 5)
|
||||
#define MARE (1L << 16)
|
||||
#define TARE (1L << 17)
|
||||
#define BME (1L << 18) // Northbridge only ?
|
||||
#define VPHE (1L << 19) // only in MPCI NB MSR_SMI
|
||||
#define SYSE (1L << 20)
|
||||
#define PARE (1L << 21)
|
||||
#define TASE (1L << 22)
|
||||
|
||||
|
||||
|
||||
// FooGlue MSRs:
|
||||
#define FG_IIOC 0x0010
|
||||
#define MODE_5530 0
|
||||
#define MODE_5535A 1
|
||||
#define MODE_5535B 2
|
||||
#define FG_A20M 0x0011
|
||||
#define A20M (1 << 0)
|
||||
#define FG_NMI 0x0012
|
||||
#define NMI (1 << 0)
|
||||
|
||||
#define FG_INIT 0x0013
|
||||
#define INIT (1 << 0)
|
||||
|
||||
|
||||
|
||||
#define MBIU_COH 0x0080
|
||||
#define MBIU_PAE 0x0081
|
||||
#define MBIU_ARB 0x0082
|
||||
#define MBIU_ASMI 0x0083
|
||||
#define MBIU_ERR 0x0084
|
||||
#define MBIU_DEBUG 0x0085
|
||||
#define MBIU_CAP 0x0086
|
||||
#define MBIU_NOUT_RESP 0x0087
|
||||
#define MBIU_NOUT_WDATA 0x0088
|
||||
#define MBIU_WHOAMI 0x008B
|
||||
// MBIU_WHOAMI tells self-reference:
|
||||
// MBIU0: 0x00000003
|
||||
// MBIU1: 0x00000001
|
||||
// MBIU2: 0x00000001
|
||||
#define MBIU_SLV 0x008C
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Descriptor MSRs
|
||||
//
|
||||
#define MSR_MEM_DESCR 0x0020
|
||||
#define MSR_IO_DESCR 0x00E0
|
||||
// Defines for IOD_SC
|
||||
#define REN (1L << 20)
|
||||
#define WEN (1L << 21)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Descriptor Statistics MSRs
|
||||
//
|
||||
#define MSR_STATISTICS_CNT 0x00A0 // and A4, A8, AC
|
||||
// High dword is Load Value; Low dword is Count
|
||||
#define MSR_STATISTICS_MASK 0x00A1 // and A5, A9, AD
|
||||
// High dword is IOD mask; Low dword is P2D mask
|
||||
#define MSR_STATISTICS_ACTION 0x00A2 // and A6, AA, AE
|
||||
#define HIT_LDEN (1L << 0) // Load CNT on descriptor hit
|
||||
#define HIT_DEC (1L << 1) // Decrement CNT on descriptor hit
|
||||
#define HIT_SMI (1L << 2) // Assert ASMI on descriptor hit
|
||||
#define HIT_ERR (1L << 3) // Assert AERR on descriptor hit
|
||||
#define ALWAYS_DEC (1L << 4) // Always decrement CNT (unless loading or (CNT = 0 & !RELOAD))
|
||||
#define ZERO_SMI (1L << 5) // Assert ASMI on CNT = 0
|
||||
#define ZERO_ERR (1L << 6) // Assert AERR on CNT = 0
|
||||
#define WRAP (1L << 7) // Reload CNT from LOAD_VAL on CNT = 0
|
||||
|
||||
// Vail PM stuff
|
||||
#define BC_MSR0 0x1900
|
||||
#define SUSP_EN (0x1000L)
|
||||
|
||||
#define XC_CONFIG 0x1210
|
||||
#define XC_CLK_SUSP (0x01L)
|
||||
|
||||
// GX2 Memory Controller PM stuff
|
||||
|
||||
// MC PMode1 Up Delay
|
||||
#define MC_CF1017_DATA 0x001A
|
||||
#define PM1_UP_DLY_MASK (0xFF00L)
|
||||
// 240ns delay, DDR spec. state minimum delay is 200ns
|
||||
#define PM1_UP_DLY_VAL (0xF000L)
|
||||
|
||||
// MC PMode Sensitivity
|
||||
// bits[63:32]=PMode1, bits[31:0]=PMode0
|
||||
#define MC_CF_PMCTR 0x0020
|
||||
// number of MC clocks that MC must be inactive
|
||||
// before entering PMode1
|
||||
#define PM1_SENS_VAL (0x020L)
|
||||
|
||||
|
||||
// GX2 GLCP PM stuff
|
||||
|
||||
// Clock Disable Delay
|
||||
#define MCP_CLK_DIS_DLY 0x0008
|
||||
#define CLKDIS_MASK (0x00FFFFFFL)
|
||||
|
||||
// PM Clock Disable
|
||||
#define MCP_PMCLKDISABLE (0x0009)
|
||||
|
||||
#define MCP_PMCLKOFF (0x0010)
|
||||
|
||||
// PM CLK4ACK MSR
|
||||
#define MCP_CLK4ACK 0x0013
|
||||
#define S3_CLK4ACK (0x07BE7FC3L)
|
||||
#define S1_CLK4ACK S3_CLK4ACK
|
||||
|
||||
// Throttling PM I/O regs default location
|
||||
#define MCP_GLB_PM 0x000B
|
||||
#define MCP_GLB_THEN (0x01L)
|
||||
|
||||
#define MCP_DOTPLL 0x0015
|
||||
#define MCP_DBGCLKCTL 0x0016
|
||||
|
||||
// default location to map GLCP P_CNT I/O space regs
|
||||
#define PMGX2_BASE (0x9E00)
|
||||
/* offset from PMGX2_BASE */
|
||||
#define P_CNT_OFS (0)
|
||||
#define P_LVL2_OFS (4)
|
||||
#define P_LVL3_OFS (8)
|
||||
|
||||
// GLCP MSR offsets for clock throttling
|
||||
#define MCP_CNT (0x0018)
|
||||
#define CNT_THEN (0x10L)
|
||||
#define CNT_MASK (0x0FL)
|
||||
#define CNT_MAX (0x01L)
|
||||
#define CNT_NONE (0x0FL)
|
||||
#define MCP_LVL2 (0x0019)
|
||||
#define MCP_TH_SD (0x001C)
|
||||
#define SD_MASK (0x0FFFL)
|
||||
#define PLVL2_IN (0x1000L)
|
||||
#define MCP_TH_SF (0x001D)
|
||||
#define SF_MASK (0x0FFL)
|
||||
#define MCP_TH_OD (0x001E)
|
||||
#define OD_IRQ (0x8000L)
|
||||
#define OD_SMI (0x4000L)
|
||||
#define OD_MASK (0x3FFFL)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
97
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/hce.h
vendored
Executable file
97
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/hce.h
vendored
Executable file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
unsigned long HceUlong;
|
||||
unsigned short HceUshort;
|
||||
struct {
|
||||
unsigned short EmulationEnable: 1;
|
||||
unsigned short EmulationInterrupt: 1;
|
||||
unsigned short CharacterPending: 1;
|
||||
unsigned short IRQEn: 1;
|
||||
unsigned short ExternalIRQEn: 1;
|
||||
unsigned short GateA20Sequence: 1;
|
||||
unsigned short IRQ1Active: 1;
|
||||
unsigned short IRQ12Active: 1;
|
||||
unsigned short A20State: 1;
|
||||
};
|
||||
};
|
||||
} HCE_CONTROL;
|
||||
|
||||
|
||||
// Host Controller Operational Registers
|
||||
typedef struct {
|
||||
unsigned long HcRevision;
|
||||
unsigned long HcControl;
|
||||
unsigned long HcCommandStatus;
|
||||
unsigned long HcInterruptStatus;
|
||||
unsigned long HcInterruptEnable;
|
||||
unsigned long HcInterruptDisable;
|
||||
unsigned long HcHCCA;
|
||||
unsigned long HcPeriodCurrentED;
|
||||
unsigned long HcControlHeadED;
|
||||
unsigned long HcControlCurrentED;
|
||||
unsigned long HcBulkHeadED;
|
||||
unsigned long HcBulkCurrentED;
|
||||
unsigned long HcDoneHead;
|
||||
unsigned long HcFmInterval;
|
||||
unsigned long HcFmRemaining;
|
||||
unsigned long HcFmNumber;
|
||||
unsigned long HcPeriodicStart;
|
||||
unsigned long HcLSThreshold;
|
||||
unsigned long HcRhDescriptorA;
|
||||
unsigned long HcRhDescriptorB;
|
||||
unsigned long HcRhStatus;
|
||||
unsigned long HcRhPortStatus[2];
|
||||
|
||||
unsigned char Reserved[0x100-0x54-2*4]; // Reserved for use by HC
|
||||
HCE_CONTROL HceControl; // 0x100
|
||||
unsigned long HceInput; // 0x104
|
||||
unsigned long HceOutput; // 0x108
|
||||
unsigned long HceStatus; // 0x10C
|
||||
} HCOR;
|
||||
|
||||
|
||||
// HcInterruptStatus & HcInterruptDisable fields:
|
||||
#define SO 0x00000001L // Scheduling Overrun
|
||||
#define WDH 0x00000002L // HcDoneHead Writeback
|
||||
#define SF 0x00000004L // Start of Frame
|
||||
#define RD 0x00000008L // Resume Detect
|
||||
#define UE 0x00000010L // Unrecoverable Error
|
||||
#define FNO 0x00000020L // Frame Number Overflow
|
||||
#define RHSC 0x00000040L // Root Hub Status Change
|
||||
#define OC 0x40000000L // Ownership Change
|
||||
#define MIE 0x80000000L // Master Interrupt Enable
|
||||
|
||||
|
||||
// HceControl fields:
|
||||
#define EMULATION_ENABLE 0x01
|
||||
#define EMULATION_INTERRUPT 0x02
|
||||
#define CHARACTER_PENDING 0x04
|
||||
#define IRQ_ENABLE 0x08
|
||||
#define EXTERNAL_IRQ_ENABLE 0x10
|
||||
#define GATE_A20_SEQUENCE 0x20
|
||||
#define IRQ1_ACTIVE 0x40
|
||||
#define IRQ12_ACTIVE 0x80
|
||||
#define A20_STATE 0x100
|
||||
|
||||
// HceStatus fields:
|
||||
#define CMD_DATA 0x08
|
||||
|
||||
183
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/isa.h
vendored
Executable file
183
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/isa.h
vendored
Executable file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
// Real Time Clock (RTC) definitions
|
||||
#define CMOS_INDEX 0x70
|
||||
#define CMOS_DATA CMOS_INDEX+1
|
||||
#define CMOS_SECONDS 0x00
|
||||
#define CMOS_MINUTES 0x02
|
||||
#define CMOS_HOURS 0x04
|
||||
#define CMOS_DAY 0x07
|
||||
#define CMOS_MONTH 0x08
|
||||
#define CMOS_YEAR 0x09
|
||||
#define CMOS_STATUS_A 0x0A
|
||||
#define UIP 0x80
|
||||
#define CMOS_STATUS_B 0x0B
|
||||
#define SET 0x80
|
||||
#define PI 0x40
|
||||
#define AI 0x20
|
||||
#define UI 0x10
|
||||
#define SQUARE 0x08
|
||||
#define DM 0x04
|
||||
#define HOUR24 0x02
|
||||
#define DLS 0x01
|
||||
#define CMOS_STATUS_C 0x0C
|
||||
#define IRQ 0x80
|
||||
#define PS 0x40
|
||||
#define AS 0x20
|
||||
#define US 0x10
|
||||
#define CMOS_CENTURY 0x32
|
||||
|
||||
|
||||
|
||||
// Programmable Interrupt Controller (PIC) definitions
|
||||
#define PIC1_BASE 0x20
|
||||
#define PIC1_MASK PIC1_BASE+1
|
||||
#define PIC2_BASE 0xA0
|
||||
#define PIC2_MASK PIC2_BASE+1
|
||||
#define NONSPECIFIC_EOI 0x20
|
||||
#define SPECIFIC_EOI 0x60
|
||||
#define PIC1_EDGE 0x4D0
|
||||
#define PIC2_EDGE 0x4D1
|
||||
|
||||
|
||||
|
||||
|
||||
#define PIC1_ICW1 0x20
|
||||
#define PIC1_ICW2 0x21
|
||||
#define PIC1_ICW3 0x21
|
||||
#define PIC1_ICW4 0x21
|
||||
#define PIC1_OCW1 0x21
|
||||
#define PIC1_OCW2 0x20
|
||||
#define PIC1_OCW3 0x20
|
||||
#define PIC2_ICW1 0xA0
|
||||
#define PIC2_ICW2 0xA1
|
||||
#define PIC2_ICW3 0xA1
|
||||
#define PIC2_ICW4 0xA1
|
||||
#define PIC2_OCW1 0xA1
|
||||
#define PIC2_OCW2 0xA0
|
||||
#define PIC2_OCW3 0xA0
|
||||
|
||||
|
||||
// DMA definitions
|
||||
#define TRANSFER_MASK (0x0C)
|
||||
#define DMA_VERIFY (0x00)
|
||||
#define DMA_WRITE (0x04)
|
||||
#define DMA_READ (0x08)
|
||||
#define MODE_MASK (0xC0)
|
||||
#define MODE_DEMAND (0x00)
|
||||
#define MODE_SINGLE (0x40)
|
||||
#define MODE_BLOCK (0x80)
|
||||
#define MODE_CASCADE (0xC0)
|
||||
|
||||
#define DMA1_ADDR0 0x00
|
||||
#define DMA1_CNT0 0x01
|
||||
#define DMA1_ADDR1 0x02
|
||||
#define DMA1_CNT1 0x03
|
||||
#define DMA1_ADDR2 0x04
|
||||
#define DMA1_CNT2 0x05
|
||||
#define DMA1_ADDR3 0x06
|
||||
#define DMA1_CNT3 0x07
|
||||
#define DMA1_MODE 0x0B
|
||||
#define DMA1_CPTR 0x0C
|
||||
#define DMA1_MASK 0x0F
|
||||
#define DMA2_ADDR0 0xC0
|
||||
#define DMA2_CNT0 0xC2
|
||||
#define DMA2_ADDR1 0xC4
|
||||
#define DMA2_CNT1 0xC6
|
||||
#define DMA2_ADDR2 0xC8
|
||||
#define DMA2_CNT2 0xCA
|
||||
#define DMA2_ADDR3 0xCC
|
||||
#define DMA2_CNT3 0xCE
|
||||
#define DMA2_MODE 0xD6
|
||||
#define DMA2_CPTR 0xD8
|
||||
#define DMA2_MASK 0xDE
|
||||
#define DMA_PAGE 0x80
|
||||
#define DMA_HPAGE 0x480
|
||||
|
||||
|
||||
|
||||
// Programmable Interval Timer (PIT) definitions
|
||||
#define PIT_CTR0 0x40
|
||||
#define PIT_CTR1 0x41
|
||||
#define PIT_CTR2 0x42
|
||||
#define PIT_CMD 0x43
|
||||
#define PIT_CMD_BOTH_BYTES 0x30 // Sets CMD word to read/write both bytes
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define READ_IRR 0x0A
|
||||
#define READ_ISR 0x0B
|
||||
|
||||
// Keyboard controller registers
|
||||
#define KYBD_DATA 0x60
|
||||
#define KYBD_STATUS 0x64
|
||||
#define STAT_OBF 0x01
|
||||
#define STAT_IBF 0x02
|
||||
#define STAT_FLAG 0x04
|
||||
#define STAT_CMD 0x08
|
||||
#define STAT_INHIBIT 0x10
|
||||
#define STAT_AUX_OBF 0x20
|
||||
#define STAT_TIMEOUT 0x40
|
||||
#define STAT_PARITY 0x80
|
||||
#define KYBD_COMMAND 0x64
|
||||
|
||||
// Keyboard controller output port bits
|
||||
#define KYBD_SYSR 0x01 // Processor reset
|
||||
#define KYBD_GA20 0x02 // Gate A20 (1=on)
|
||||
#define KYBD_ADAT 0x04 // AUX data
|
||||
#define KYBD_ACLK 0x08 // AUX clock
|
||||
#define KYBD_KOBF 0x10 // Keyboard OBF
|
||||
#define KYBD_AOBF 0x20 // AUX OBF
|
||||
#define KYBD_KCLK 0x40 // Keyboard clock
|
||||
#define KYBD_KDAT 0x80 // Keyboard data
|
||||
|
||||
// Keyboard controller commands
|
||||
#define KYBD_RD_OUT 0xD0
|
||||
#define KYBD_WR_OUT 0xD1
|
||||
|
||||
// Keyboard controller command byte
|
||||
#define OBF_INTERRUPT 0x01
|
||||
#define AUX_INTERRUPT 0x02
|
||||
#define SYSTEM_STATUS 0x04
|
||||
#define KBD_DISABLED 0x10
|
||||
#define AUX_DISABLED 0x20
|
||||
#define XT_SCANSET 0x40
|
||||
|
||||
|
||||
#define PORT_B 0x92
|
||||
#define GAMEPORT 0x200
|
||||
#define PRIMARY_IDE 0x1F6
|
||||
#define SECONDARY_IDE 0x176
|
||||
#define PRIMARY_FLOPPY 0x3F5
|
||||
#define SECONDARY_FLOPPY 0x375
|
||||
|
||||
#define COM1 0x3F8
|
||||
#define COM2 0x2F8
|
||||
#define COM3 0x3E8
|
||||
#define COM4 0x2E8
|
||||
|
||||
#define LPT1 0x378
|
||||
#define LPT2 0x278
|
||||
|
||||
|
||||
|
||||
|
||||
111
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/pci.h
vendored
Executable file
111
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/pci.h
vendored
Executable file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
// PCI related definitions
|
||||
#define PCI_CONFIG_ADDRESS 0xCF8
|
||||
#define PCI_CONFIG_DATA 0xCFC
|
||||
|
||||
#define VENDOR_ID 0x00
|
||||
#define COMMAND 0x04
|
||||
#define IO_SPACE (1 << 0)
|
||||
#define MEM_SPACE (1 << 1)
|
||||
#define BUS_MASTER (1 << 2)
|
||||
#define SPECIAL_CYCLES (1 << 3)
|
||||
#define MEM_WR_INVALIDATE (1 << 4)
|
||||
#define VGA_PALETTE_SNOOP (1 << 5)
|
||||
#define PARITY_RESPONSE (1 << 6)
|
||||
#define WAIT_CYCLE_CONTROL (1 << 7)
|
||||
#define SERR_ENABLE (1 << 8)
|
||||
#define FAST_BACK_TO_BACK (1 << 9)
|
||||
|
||||
#define STATUS 0x06
|
||||
#define CAPABILITIES_LIST (1L << 20)
|
||||
#define PCI_66MHZ_CAPABLE (1L << 21)
|
||||
#define BACK2BACK_CAPABLE (1L << 23)
|
||||
#define MASTER_PARITY_ERROR (1L << 24)
|
||||
#define DEVSEL_FAST (0L << 25)
|
||||
#define DEVSEL_MEDIUM (1L << 25)
|
||||
#define DEVSEL_SLOW (2L << 25)
|
||||
#define SIGNALED_TARGET_ABORT (1L << 27)
|
||||
#define RECEIVED_TARGET_ABORT (1L << 28)
|
||||
#define RECEIVED_MASTER_ABORT (1L << 29)
|
||||
#define SIGNALED_SYSTEM_ERROR (1L << 30)
|
||||
#define DETECTED_PARITY_ERROR (1L << 31)
|
||||
|
||||
|
||||
|
||||
#define REVISION_ID 0x08
|
||||
#define CACHE_LINE 0x0C
|
||||
#define LATENCY_TIMER 0x0D
|
||||
#define HEADER_TYPE 0x0E
|
||||
#define BIST 0x0F
|
||||
|
||||
|
||||
// Capability List IDs
|
||||
#define CAP_ID_PM 0x01
|
||||
#define CAP_ID_AGP 0x02
|
||||
#define CAP_ID_VPD 0x03
|
||||
#define CAP_ID_SLOT 0x04
|
||||
#define CAP_ID_MSI 0x05
|
||||
#define CAP_ID_HOT_SWAP 0x06
|
||||
|
||||
|
||||
#define SUBSYSTEM_VENDOR_ID 0x2C
|
||||
|
||||
#define INTERRUPT_LINE 0x3C
|
||||
#define INTERRUPT_PIN 0x3D
|
||||
#define MIN_GNT 0x3E
|
||||
#define MAX_LAT 0x3F
|
||||
|
||||
|
||||
#define BAR0 0x10
|
||||
#define BAR1 0x14
|
||||
#define BAR2 0x18
|
||||
#define BAR3 0x1C
|
||||
#define BAR4 0x20
|
||||
#define BAR5 0x24
|
||||
|
||||
// PCI Power Management:
|
||||
#define PCI_PM_REG 0x40
|
||||
|
||||
// Graphics-specific registers:
|
||||
#define OEM_BAR0 0x50
|
||||
#define OEM_BAR1 0x54
|
||||
#define OEM_BAR2 0x58
|
||||
#define OEM_BAR3 0x5C
|
||||
|
||||
// EHCI-specific registers
|
||||
#define EECP 0x50
|
||||
#define USBLEGSUP (EECP)
|
||||
#define OS_OWNED_SEMAPHORE 0x01000000
|
||||
#define BIOS_OWNED_SEMAPHORE 0x00010000
|
||||
#define USBLEGCTLSTS (EECP+4)
|
||||
#define SMI_ON_BAR 0x80000000
|
||||
#define SMI_ON_COMMAND 0x40000000
|
||||
#define SMI_ON_OC 0x20000000
|
||||
|
||||
#define SRBN_REG 0x60
|
||||
|
||||
// 5536 B0 ATA-specific registers:
|
||||
#define IDE_CFG 0x40
|
||||
#define IDE_DTC 0x48
|
||||
#define IDE_CAST 0x4C
|
||||
#define IDE_ETC 0x50
|
||||
#define IDE_PM 0x54
|
||||
|
||||
485
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/vr.h
vendored
Executable file
485
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/vr.h
vendored
Executable file
@@ -0,0 +1,485 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#define VRC_INDEX 0xAC1C // Index register
|
||||
#define VRC_DATA 0xAC1E // Data register
|
||||
#define VR_UNLOCK 0xFC53 // Virtual register unlock code
|
||||
#define NO_VR -1 // No virtual registers
|
||||
|
||||
#define VRC_MISCELLANEOUS 0x00 // Miscellaneous Class
|
||||
#define VSA_VERSION_NUM 0x00
|
||||
#define HIGH_MEM_ACCESS 0x01
|
||||
#define GET_VSM_INFO 0x02 // Used by INFO
|
||||
#define GET_BASICS 0x00
|
||||
#define GET_EVENT 0x01
|
||||
#define GET_STATISTICS 0x02
|
||||
#define GET_HISTORY 0x03
|
||||
#define GET_HARDWARE 0x04
|
||||
#define GET_ERROR 0x05
|
||||
#define SET_VSM_TYPE 0x06
|
||||
#define SIGNATURE 0x03
|
||||
#define VSA2_SIGNATURE 0x56534132 // 'VSA2' returned in EAX
|
||||
|
||||
#define GET_HW_INFO 0x04
|
||||
#define VSM_VERSION 0x05
|
||||
#define CTRL_ALT_DEL 0x06
|
||||
#define MSR_ACCESS 0x07
|
||||
#define GET_DESCR_INFO 0x08
|
||||
#define PCI_INT_AB 0x09 // GPIO pins for INTA# and INTB#
|
||||
#define PCI_INT_CD 0x0A // GPIO pins for INTC# and INTD#
|
||||
#define WATCHDOG 0x0B // Watchdog timer
|
||||
|
||||
#define MAX_MISC WATCHDOG
|
||||
|
||||
|
||||
// NOTE: Do not change the order of the following registers:
|
||||
#define VRC_AUDIO 0x01 // XpressAudio Class
|
||||
#define AUDIO_VERSION 0x00
|
||||
#define PM_STATE 0x01
|
||||
#define SB_16_IO_BASE 0x02
|
||||
#define MIDI_BASE 0x03
|
||||
#define CPU_USAGE 0x04
|
||||
#define CODEC_TYPE 0x05
|
||||
#define STATE_INDEX 0x06
|
||||
#define STATE_DATA 0x07
|
||||
#define AUDIO_IRQ 0x08 // For use by native audio drivers
|
||||
#define STATUS_PTR 0x09 // For use by native audio drivers
|
||||
#define MAX_AUDIO STATUS_PTR
|
||||
|
||||
#define VRC_VG 0x02 // SoftVG Class
|
||||
#define VRC_VGA 0x02 // SoftVGA Class
|
||||
#define VG_MEM_SIZE 0x00 // bits 7:0 - 512K unit size, bit 8 controller priority
|
||||
#define VG_CONFIG 0x00 // Main configuration register
|
||||
#define VG_CFG_BYPASS 0x0001 // DOTPLL bypass bit
|
||||
#define VG_MEM_MASK 0x00FE // Memory size mask bits, 2MB increment
|
||||
#define VG_CFG_DSMASK 0x0700 // Active display mask bits
|
||||
#define VG_CFG_DSCRT 0x0000 // Active display is CRT
|
||||
#define VG_CFG_DSPAN 0x0100 // Active display is panel
|
||||
#define VG_CFG_DSTV 0x0200 // Active display is TV
|
||||
#define VG_CFG_DSSIM 0x0400 // Simultaneous CRT
|
||||
#define VG_CFG_PRIORITY 0x0800 // Controller priority bit
|
||||
#define VG_CFG_MONO 0x1000 // External monochrome card support bit
|
||||
#define VG_CFG_DRIVER 0x2000 // Driver active bit
|
||||
#define VG_CRTC_DIAG 0x8000 // Enable CRTC emulation
|
||||
|
||||
// Defined for LX/LXVG
|
||||
#define VG_REFRESH 0x01 // Mode refresh, a mode switch without changing modes
|
||||
#define VG_FRSH_REF_MASK 0xE000 // Refresh rate mask
|
||||
#define VG_FRSH_REF_GO 0x1000 // Refresh rate GO bit
|
||||
// Uses CFP_REF_xxx values from below
|
||||
#define VG_FRSH_BPP_MASK 0x0E00 // Color depth mask
|
||||
#define VG_FRSH_BPP_GO 0x0100 // Color depth GO bit
|
||||
#define FRSH_BPP_8RGB 0x0200 // 8 bits per pixel, RGB
|
||||
#define FRSH_BPP_16ARGB 0x0400 // 16BPP, ARGB (4:4:4:4)
|
||||
#define FRSH_BPP_15RGB 0x0600 // 15BPP, RGB (1:5:5:5)
|
||||
#define FRSH_BPP_16RGB 0x0800 // 16BPP, RGB (5:6:5)
|
||||
#define FRSH_BPP_24RGB 0x0A00 // 24BPP, RGB (0:8:8:8)
|
||||
#define FRSH_BPP_32ARGB 0x0C00 // 32BPP, ARGB (8:8:8:8)
|
||||
#define VG_CFG_DPMS 0x00C0 // DPMS mask bits
|
||||
#define VG_CFG_DPMS_H 0x0040 // HSYNC mask bit
|
||||
#define VG_CFG_DPMS_V 0x0080 // VSYNC mask bit
|
||||
#define VG_VESA_SV_RST 0x0020 // VESA Save/Restore state flag
|
||||
#define VG_VESA_RST 0x0000 // VESA Restore state
|
||||
#define VG_VESA_SV 0x0020 // VESA Save state
|
||||
#define VG_FRSH_MODE 0x0002 // Mode refresh flag
|
||||
#define VG_FRSH_TIMINGS 0x0001 // Timings only refresh flag
|
||||
|
||||
// Defined for GX2/SoftVG
|
||||
#define VG_PLL_REF 0x01 // PLL reference frequency selection register
|
||||
#define PLL_14MHZ 0x0000 // 14.31818MHz PLL reference frequency (Default)
|
||||
#define PLL_48MHZ 0x0100 // 48MHz PLL reference frequency
|
||||
|
||||
// Defined for GX1/SoftVGA
|
||||
#define VGA_MEM_SIZE 0x01 // bits 7:1 - 128K unit size, bit 0 controller enable
|
||||
|
||||
#define VG_FP_TYPE 0x02 // Flat panel type data
|
||||
// VG_FP_TYPE definitions for GX2/SoftVG
|
||||
#define FP_TYPE_SSTN 0x0000 // SSTN panel type value
|
||||
#define FP_TYPE_DSTN 0x0001 // DSTN panel type value
|
||||
#define FP_TYPE_TFT 0x0002 // TFT panel type value
|
||||
#define FP_TYPE_LVDS 0x0003 // LVDS panel type value
|
||||
#define FP_RES_6X4 0x0000 // 640x480 resolution value
|
||||
#define FP_RES_8X6 0x0008 // 800x600 resolution value
|
||||
#define FP_RES_10X7 0x0010 // 1024x768 resolution value
|
||||
#define FP_RES_11X8 0x0018 // 1152x864 resolution value
|
||||
#define FP_RES_12X10 0x0020 // 1280x1024 resolution value
|
||||
#define FP_RES_16X12 0x0028 // 1600x1200 resolution value
|
||||
#define FP_WIDTH_8 0x0000 // 8 bit data bus width
|
||||
#define FP_WIDTH_9 0x0040 // 9 bit data bus width
|
||||
#define FP_WIDTH_12 0x0080 // 12 bit data bus width
|
||||
#define FP_WIDTH_18 0x00C0 // 18 bit data bus width
|
||||
#define FP_WIDTH_24 0x0100 // 24 bit data bus width
|
||||
#define FP_WIDTH_16 0x0140 // 16 bit data bus width - 16 bit Mono DSTN only
|
||||
#define FP_COLOR_COLOR 0x0000 // Color panel
|
||||
#define FP_COLOR_MONO 0x0200 // Mono Panel
|
||||
#define FP_PPC_1PPC 0x0000 // One pixel per clock
|
||||
#define FP_PPC_2PPC 0x0400 // Two pixels per clock
|
||||
#define FP_H_POL_LGH 0x0000 // HSync at panel, normally low, active high
|
||||
#define FP_H_POL_HGL 0x0800 // HSync at panel, normally high, active low
|
||||
#define FP_V_POL_LGH 0x0000 // VSync at panel, normally low, active high
|
||||
#define FP_V_POL_HGL 0x1000 // VSync at panel, normally high, active low
|
||||
#define FP_REF_60 0x0000 // 60Hz refresh rate
|
||||
#define FP_REF_65 0x2000 // 65Hz refresh rate
|
||||
#define FP_REF_70 0x4000 // 70Hz refresh rate
|
||||
#define FP_REF_72 0x6000 // 72Hz refresh rate
|
||||
#define FP_REF_75 0x8000 // 75Hz refresh rate
|
||||
#define FP_REF_85 0xA000 // 85Hz refresh rate
|
||||
|
||||
// VG_FP_TYPE definitions for LX/LXVG
|
||||
#define FP_TYPE_TYPE 0x0003 // Flat panel type bits mask
|
||||
#define CFP_TYPE_TFT 0x0000 // TFT panel type value
|
||||
#define CFP_TYPE_LVDS 0x0001 // LVDS panel type value
|
||||
#define FP_TYPE_RES 0x0038 // Panel resolution bits mask
|
||||
#define CFP_RES_3X2 0x0000 // 320x240 resolution value
|
||||
#define CFP_RES_6X4 0x0008 // 640x480 resolution value
|
||||
#define CFP_RES_8X6 0x0010 // 800x600 resolution value
|
||||
#define CFP_RES_10X7 0x0018 // 1024x768 resolution value
|
||||
#define CFP_RES_11X8 0x0020 // 1152x864 resolution value
|
||||
#define CFP_RES_12X10 0x0028 // 1280x1024 resolution value
|
||||
#define CFP_RES_16X12 0x0030 // 1600x1200 resolution value
|
||||
#define FP_TYPE_BUS 0x00C0 // Data bus width and pixels/clock mask
|
||||
#define CFP_BUS_1PPC 0x0040 // 9, 12, 18 or 24 bit data bus, 1 pixel per clock
|
||||
#define CFP_BUS_2PPC 0x0080 // 18 or 24 bit data bus, 2 pixels per clock
|
||||
#define FP_TYPE_HPOL 0x0800 // HSYNC polarity into the panel
|
||||
#define CFP_HPOL_HGL 0x0000 // HSync at panel, normally high, active low
|
||||
#define CFP_HPOL_LGH 0x0800 // HSync at panel, normally low, active high
|
||||
#define FP_TYPE_VPOL 0x1000 // VSYNC polarity into the panel
|
||||
#define CFP_VPOL_HGL 0x0000 // VSync at panel, normally high, active low
|
||||
#define CFP_VPOL_LGH 0x1000 // VSync at panel, normally low, active high
|
||||
#define FP_TYPE_REF 0xE000 // Panel refresh rate
|
||||
#define CFP_REF_60 0x0000 // 60Hz refresh rate
|
||||
#define CFP_REF_70 0x2000 // 70Hz refresh rate
|
||||
#define CFP_REF_75 0x4000 // 75Hz refresh rate
|
||||
#define CFP_REF_85 0x6000 // 85Hz refresh rate
|
||||
#define CFP_REF_100 0x8000 // 100Hz refresh rate
|
||||
|
||||
#define VG_FP_OPTION 0x03 // Flat panel option data
|
||||
#define FP_OPT_SCLK_NORMAL 0x0000 // SHFTClk not inverted to panel
|
||||
#define FP_OPT_SCLK_INVERTED 0x0010 // SHFTClk inverted to panel
|
||||
#define FP_OPT_SCLK_ACT_ACTIVE 0x0000 // SHFTClk active during "active" only
|
||||
#define FP_OPT_SCLK_ACT_FREE 0x0020 // SHFTClk free-running
|
||||
#define FP_OPT_LP_ACT_FREE 0x0000 // LP free-running
|
||||
#define FP_OPT_LP_ACT_ACTIVE 0x0040 // LP active during "active" only
|
||||
#define FP_OPT_LDE_POL_LGH 0x0000 // LDE/MOD, normally low, active high
|
||||
#define FP_OPT_LDE_POL_HGL 0x0080 // LDE/MOD, normally high, active low
|
||||
#define FP_OPT_PWR_DLY_32MS 0x0000 // 32MS delay for each step of pwr seq.
|
||||
#define FP_OPT_PWR_DLY_128MS 0x0100 // 128MS delay for each step of pwr seq.
|
||||
|
||||
#define VG_TV_CONFIG 0x04 // TV configuration register
|
||||
#define VG_TV_ENC 0x000F // TV encoder select mask
|
||||
#define VG_TV_ADV7171 0x0000 // ADV7171 Encoder
|
||||
#define VG_TV_SAA7127 0x0001 // ADV7171 Encoder
|
||||
#define VG_TV_ADV7300 0x0002 // ADV7300 Encoder
|
||||
#define VG_TV_FS454 0x0003 // FS454 Encoder
|
||||
#define VG_TV_FMT 0x0070 // TV encoder output format mask
|
||||
#define VG_TV_FMT_SHIFT 0x0004 // Right shift value
|
||||
#define VG_TV_NTSC 0x0000 // NTSC output format
|
||||
#define VG_TV_PAL 0x0010 // PAL output format
|
||||
#define VG_TV_HDTV 0x0020 // HDTV output format
|
||||
|
||||
// The meaning of the VG_TV_RES field is dependent on the selected
|
||||
// encoder and output format. The translations are:
|
||||
// ADV7171 - Not Used
|
||||
// SAA7127 - Not Used
|
||||
// ADV7300 - HDTV resolutions only
|
||||
// LO -> 720x480p
|
||||
// MED -> 1280x720p
|
||||
// HI -> 1920x1080i
|
||||
// FS454 - Both SD and HD resolutions
|
||||
// SD Resolutions - NTSC and PAL
|
||||
// LO -> 640x480
|
||||
// MED -> 800x600
|
||||
// HI -> 1024x768
|
||||
// HD Resolutions
|
||||
// LO -> 720x480p
|
||||
// MED -> 1280x720p
|
||||
// HI -> 1920x1080i
|
||||
#define VG_TV_RES 0x0780 // TV resolution select mask
|
||||
#define VG_TV_RES_SHIFT 0x0007 // Right shift value
|
||||
#define VG_TV_RES_LO 0x0000 // Low resolution
|
||||
#define VG_TV_RES_MED 0x0080 // Medium resolution
|
||||
#define VG_TV_RES_HI 0x0100 // High resolution
|
||||
#define VG_TV_PASSTHRU 0x0800 // TV passthru mode
|
||||
|
||||
#define VG_TV_SCALE_ADJ 0x05 // Modifies scaling factors for TV resolutions
|
||||
#define VG_TV_HACT_ADJ 0x00FF // Horizontal active scale adjust value mask
|
||||
#define VG_TV_VACT_ADJ 0xFF00 // Vertical active scale adjust value mask
|
||||
|
||||
#define VG_DEBUG 0x0F // A debug register
|
||||
|
||||
#define VG_FT_HTOT 0x10 // Fixed timings, horizontal total
|
||||
#define VG_FT_HACT 0x11 // Fixed timings, horizontal active
|
||||
#define VG_FT_HBST 0x12 // Fixed timings, horizontal blank start
|
||||
#define VG_FT_HBND 0x13 // Fixed timings, horizontal blank end
|
||||
#define VG_FT_HSST 0x14 // Fixed timings, horizontal sync start
|
||||
#define VG_FT_HSND 0x15 // Fixed timings, horizontal sync end
|
||||
|
||||
#define VG_FT_VTOT 0x16 // Fixed timings, vertical total
|
||||
#define VG_FT_VACT 0x17 // Fixed timings, vertical active
|
||||
#define VG_FT_VBST 0x18 // Fixed timings, vertical blank start
|
||||
#define VG_FT_VBND 0x19 // Fixed timings, vertical blank end
|
||||
#define VG_FT_VSST 0x1A // Fixed timings, vertical sync start
|
||||
#define VG_FT_VSND 0x1B // Fixed timings, vertical sync end
|
||||
|
||||
#define VG_START_OFFS_LO 0x20 // Framebuffer start offset bits 15:0
|
||||
#define VG_START_OFFS_HI 0x21 // Framebuffer start offset bits 27:16
|
||||
|
||||
#define VG_FT_VEACT 0x28 // Fixed timings, vertical active
|
||||
#define VG_FT_VETOT 0x29 // Fixed timings, vertical total
|
||||
#define VG_FT_VEBST 0x2A // Fixed timings, vertical blank start
|
||||
#define VG_FT_VEBND 0x2B // Fixed timings, vertical blank end
|
||||
#define VG_FT_VESST 0x2C // Fixed timings, vertical sync start
|
||||
#define VG_FT_VESND 0x2D // Fixed timings, vertical sync end
|
||||
|
||||
#define MAX_VGA VGA_MEM_SIZE
|
||||
// #define MAX_VG VG_FP_OPTION
|
||||
// #define MAX_VG VG_START_OFFS_HI
|
||||
#define MAX_VG VG_FT_VESND
|
||||
|
||||
#define VRC_APM 0x03
|
||||
#define REPORT_EVENT 0x00
|
||||
#define CAPABILITIES 0x01
|
||||
#define APM_PRESENT 0x02
|
||||
#define MAX_APM APM_PRESENT
|
||||
|
||||
|
||||
#define VRC_PM 0x04 // Legacy PM Class
|
||||
#define POWER_MODE 0x00
|
||||
#define POWER_STATE 0x01
|
||||
#define DOZE_TIMEOUT 0x02
|
||||
#define STANDBY_TIMEOUT 0x03
|
||||
#define SUSPEND_TIMEOUT 0x04
|
||||
#define PS2_TIMEOUT 0x05
|
||||
#define RESUME_ON_RING 0x06
|
||||
#define VIDEO_TIMEOUT 0x07
|
||||
#define DISK_TIMEOUT 0x08
|
||||
#define FLOPPY_TIMEOUT 0x09
|
||||
#define SERIAL_TIMEOUT 0x0A
|
||||
#define PARALLEL_TIMEOUT 0x0B
|
||||
#define IRQ_WAKEUP_MASK 0x0C
|
||||
// #define SUSPEND_MODULATION 0x0D
|
||||
#define SLEEP_PIN 0x0E
|
||||
#define SLEEP_PIN_ATTR 0x0F
|
||||
// #define SMI_WAKEUP_MASK 0x10
|
||||
#define INACTIVITY_CONTROL 0x11
|
||||
#define PM_S1_CLOCKS 0x12
|
||||
#define S1_CLOCKS_ON 0x00
|
||||
#define S1_CLOCKS_OFF 0x01
|
||||
// #define PM_S2_CLOCKS 0x13
|
||||
// #define PM_S3_CLOCKS 0x14
|
||||
// #define PM_S4_CLOCKS 0x15
|
||||
// #define PM_S5_CLOCKS 0x16
|
||||
#define PM_S0_LED 0x17
|
||||
#define PM_S1_LED 0x18
|
||||
#define PM_S2_LED 0x19
|
||||
#define PM_S3_LED 0x1A
|
||||
#define PM_S4_LED 0x1B
|
||||
#define PM_S5_LED 0x1C
|
||||
#define PM_LED_GPIO 0x1D
|
||||
#define PM_IMM_LED 0x1E
|
||||
#define PM_PWR_LEDS 0x1F
|
||||
#define MB_LED0 0x01
|
||||
#define MB_LED1 0x02
|
||||
#define MB_LED2 0x04
|
||||
#define MB_LED3 0x08
|
||||
#define SIO_LED0 0x10
|
||||
#define SIO_LED1 0x20
|
||||
#define SIO_LED2 0x40
|
||||
#define SIO_LED3 0x80
|
||||
#define PM_PME_MASK 0x20
|
||||
#define MAX_PM PM_PME_MASK
|
||||
|
||||
#define VRC_INFRARED 0x05
|
||||
#define MAX_INFRARED NO_VR
|
||||
|
||||
#define VRC_TV 0x06 // TV Encoder Class
|
||||
#define TV_ENCODER_TYPE 0x00
|
||||
#define TV_CALLBACK_MASK 0x01
|
||||
#define TV_MODE 0x02
|
||||
#define TV_POSITION 0x03
|
||||
#define TV_BRIGHTNESS 0x04
|
||||
#define TV_CONTRAST 0x05
|
||||
#define TV_OUTPUT 0x06
|
||||
#define TV_TIMING 0x10 // 0x10...0x1D are all timings
|
||||
#define MAX_TV TV_TIMING
|
||||
|
||||
|
||||
|
||||
#define VRC_EXTERNAL_AMP 0x07
|
||||
#define EAPD_VERSION 0x00
|
||||
#define AMP_POWER 0x01
|
||||
#define AMP_OFF 0x00
|
||||
#define AMP_ON 0x01
|
||||
#define AMP_TYPE 0x02
|
||||
#define MAX_EXTERNAL_AMP AMP_TYPE
|
||||
|
||||
|
||||
#define VRC_ACPI 0x08
|
||||
#define ENABLE_ACPI 0x00 // Enable ACPI Mode
|
||||
#define SCI_IRQ 0x01 // Set the IRQ the SCI is mapped to, sysbios use.
|
||||
#define ACPINVS_LO 0x02 // new calls to send 32bit physAddress of
|
||||
#define ACPINVS_HI 0x03 // ACPI NVS region to VSA
|
||||
#define GLOBAL_LOCK 0x04 // read requests semaphore, write clears
|
||||
#define ACPI_UNUSED1 0x05
|
||||
#define RW_PIRQ 0x06 // read/write PCI IRQ router regs in SB Func0 cfg space
|
||||
#define SLPB_CLEAR 0x07 // clear sleep button GPIO status's
|
||||
#define PIRQ_ROUTING 0x08 // read the PCI IRQ routing based on BIOS setup
|
||||
#define ACPI_UNUSED2 0x09
|
||||
#define ACPI_UNUSED3 0x0A
|
||||
#define PIC_INTERRUPT 0x0B
|
||||
#define ACPI_PRESENT 0x0C
|
||||
#define ACPI_GEN_COMMAND 0x0D
|
||||
#define ACPI_GEN_PARAM1 0x0E
|
||||
#define ACPI_GEN_PARAM2 0x0F
|
||||
#define ACPI_GEN_PARAM3 0x10
|
||||
#define ACPI_GEN_RETVAL 0x11
|
||||
#define MAX_ACPI ACPI_GEN_RETVAL
|
||||
|
||||
#define VRC_ACPI_OEM 0x09
|
||||
#define MAX_ACPI_OEM NO_VR
|
||||
|
||||
#define VRC_POWER 0x0A
|
||||
#define BATTERY_UNITS 0x00 // No. battery units
|
||||
#define BATTERY_SELECT 0x01
|
||||
#define AC_STATUS 0x02
|
||||
#define BATTERY_STATUS 0x03
|
||||
#define BATTERY_FLAG 0x04
|
||||
#define BATTERY_PERCENTAGE 0x05
|
||||
#define BATTERY_TIME 0x06
|
||||
#define MAX_POWER BATTERY_TIME
|
||||
|
||||
|
||||
|
||||
#define VRC_OHCI 0x0B // OHCI Class
|
||||
#define SET_LED 0x00
|
||||
#define INIT_OHCI 0x01
|
||||
#define MAX_OHCI INIT_OHCI
|
||||
|
||||
#define VRC_KEYBOARD 0x0C // Kbd Controller Class
|
||||
#define KEYBOARD_PRESENT 0x00
|
||||
#define SCANCODE 0x01
|
||||
#define MOUSE_PRESENT 0x02
|
||||
#define MOUSE_BUTTONS 0x03
|
||||
#define MOUSE_XY 0x04
|
||||
#define TYPEMATIC_DISABLE 0x05
|
||||
#define MAX_KEYBOARD TYPEMATIC_DISABLE
|
||||
|
||||
|
||||
#define VRC_DDC 0x0D // Video DDC Class
|
||||
#define VRC_DDC_ENABLE 0x00 // Enable/disable register
|
||||
#define DDC_DISABLE 0x00
|
||||
#define DDC_ENABLE 0x01
|
||||
#define VRC_DDC_IO 0x01 // A non-zero value for safety
|
||||
#define MAX_DDC VRC_DDC_IO
|
||||
|
||||
#define VRC_DEBUGGER 0x0E
|
||||
#define MAX_DEBUGGER NO_VR
|
||||
|
||||
|
||||
#define VRC_STR 0x0F // Virtual Register class
|
||||
#define RESTORE_ADDR 0x00 // Physical address of MSR restore table
|
||||
|
||||
|
||||
#define VRC_COP8 0x10 // Virtual Register class
|
||||
#define VRC_HIB_ENABLE 0x00 // HIB enable/disable index
|
||||
#define HIB_ENABLE 0x00 // HIB enable command
|
||||
#define HIB_DISABLE 0x01 // HIB disable command
|
||||
#define VRC_HIB_SEND 0x01 // Send packet to COP8
|
||||
#define VRC_HIB_READUART 0x02 // Read byte from COP8 UART
|
||||
#define VRC_HIB_VERSION 0x03 // Read COP8 version
|
||||
#define VRC_HIB_SERIAL 0x04 // Read 8 byte serial number
|
||||
#define VRC_HIB_USRBTN 0x05 // Read POST button pressed status
|
||||
#define MAX_COP8 NO_VR
|
||||
|
||||
#define VRC_OWL 0x11 // Virtual Register class
|
||||
#define VRC_OWL_DAC 0x00 // DAC (Backlight) Control
|
||||
#define VRC_OWL_GPIO 0x01 // GPIO Control
|
||||
#define MAX_OWL VRC_OWL_GPIO
|
||||
|
||||
#define VRC_SYSINFO 0x12 // Virtual Register class
|
||||
#define VRC_SI_VERSION 0x00 // Sysinfo VSM version
|
||||
#define VRC_SI_CPU_MHZ 0x01 // CPU speed in MHZ
|
||||
#define VRC_SI_CHIPSET_BASE_LOW 0x02
|
||||
#define VRC_SI_CHIPSET_BASE_HI 0x03
|
||||
#define VRC_SI_CHIPSET_ID 0x04
|
||||
#define VRC_SI_CHIPSET_REV 0x05
|
||||
#define VRC_SI_CPU_ID 0x06
|
||||
#define VRC_SI_CPU_REV 0x07
|
||||
#define MAX_SYSINFO VRC_SI_CPU_REV
|
||||
|
||||
#define VRC_SUPERIO 0x13
|
||||
#define VRC_SIO_CHIPID 0x00
|
||||
#define VRC_SIO_NUMLD 0x01
|
||||
#define VRC_SIO_FDCEN 0x02
|
||||
#define VRC_SIO_FDCIO 0x03
|
||||
#define VRC_SIO_FDCIRQ 0x04
|
||||
#define VRC_SIO_FDCDMA 0x05
|
||||
#define VRC_SIO_FDCCFG1 0x06
|
||||
#define VRC_SIO_FDCCFG2 0x07
|
||||
#define VRC_SIO_PP1EN 0x08
|
||||
#define VRC_SIO_PP1IO 0x09
|
||||
#define VRC_SIO_PP1IRQ 0x0A
|
||||
#define VRC_SIO_PP1DMA 0x0B
|
||||
#define VRC_SIO_PP1CFG1 0x0C
|
||||
#define VRC_SIO_SP1EN 0x0D
|
||||
#define VRC_SIO_SP1IO 0x0E
|
||||
#define VRC_SIO_SP1IRQ 0x0F
|
||||
#define VRC_SIO_SP1CFG1 0x10
|
||||
#define VRC_SIO_SP2EN 0x11
|
||||
#define VRC_SIO_SP2IO 0x12
|
||||
#define VRC_SIO_SP2IRQ 0x13
|
||||
#define VRC_SIO_SP2CFG1 0x14
|
||||
#define VRC_SIO_KBEN 0x15
|
||||
#define VRC_SIO_KBIO1 0x16
|
||||
#define VRC_SIO_KBIO2 0x17
|
||||
#define VRC_SIO_KBIRQ 0x18
|
||||
#define VRC_SIO_KBCFG1 0x19
|
||||
#define VRC_SIO_MSEN 0x1A
|
||||
#define VRC_SIO_MSIO 0x1B
|
||||
#define VRC_SIO_MSIRQ 0x1C
|
||||
#define VRC_SIO_RTCEN 0x1D
|
||||
#define VRC_SIO_RTCIO1 0x1E
|
||||
#define VRC_SIO_RTCIO2 0x1F
|
||||
#define VRC_SIO_RTCIRQ 0x20
|
||||
#define VRC_SIO_RTCCFG1 0x21
|
||||
#define VRC_SIO_RTCCFG2 0x22
|
||||
#define VRC_SIO_RTCCFG3 0x23
|
||||
#define VRC_SIO_RTCCFG4 0x24
|
||||
#define MAX_SUPERIO VRC_SIO_RTCCFG4
|
||||
|
||||
#define VRC_CHIPSET 0x14
|
||||
#define VRC_CS_PWRBTN 0x00
|
||||
#define VRC_CS_UART1 0x01
|
||||
#define VRC_CS_UART2 0x02
|
||||
#define MAX_CHIPSET VRC_CS_UART2
|
||||
|
||||
#define VRC_THERMAL 0x15
|
||||
#define VRC_THERMAL_CURR_RTEMP 0x00 // read only
|
||||
#define VRC_THERMAL_CURR_LTEMP 0x01 // read only
|
||||
#define VRC_THERMAL_FAN 0x02
|
||||
#define VRC_THERMAL_LOW_THRESHOLD 0x03
|
||||
#define VRC_THERMAL_HIGH_THRESHOLD 0x04
|
||||
#define VRC_THERMAL_INDEX 0x05
|
||||
#define VRC_THERMAL_DATA 0x06
|
||||
#define VRC_THERMAL_SMB_ADDRESS 0x07
|
||||
#define VRC_THERMAL_SMB_INDEX 0x08
|
||||
#define VRC_THERMAL_SMB_DATA 0x09
|
||||
#define MAX_THERMAL VRC_THERMAL_SMB_DATA
|
||||
|
||||
#define MAX_VR_CLASS VRC_THERMAL
|
||||
700
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/vsa2.h
vendored
Executable file
700
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/vsa2.h
vendored
Executable file
@@ -0,0 +1,700 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#define VSM_SIGNATURE 0x204D5356 // 'VSM '
|
||||
#define VSA_VERSION 0x03B0 // SysMgr Version
|
||||
|
||||
|
||||
#define BYTE_IO 0x01
|
||||
#define WORD_IO 0x03
|
||||
#define DWORD_IO 0x0F
|
||||
#define IO_WRITE 0x80
|
||||
|
||||
|
||||
|
||||
typedef unsigned char UCHAR;
|
||||
typedef unsigned long ULONG;
|
||||
typedef unsigned short USHORT;
|
||||
|
||||
|
||||
|
||||
#define HIWORD(p) ((USHORT) ((p) >> 16))
|
||||
|
||||
typedef struct {
|
||||
unsigned short Alignment: 5; // 2^(n+5) (e.g. 00000 = 32-byte boundary)
|
||||
unsigned short LoadHi: 1; // 1 = must load VSM above top of memory
|
||||
unsigned short LoadLo: 1; // 1 = must load VSM below 1 MB
|
||||
unsigned short SkipMe: 1; // 1 = Skip this VSM
|
||||
unsigned short Reserved: 8;
|
||||
} Requirements;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//*********************************************************************
|
||||
// Structures
|
||||
//*********************************************************************
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
ULONG Reg_EAX;
|
||||
USHORT Reg_AX;
|
||||
struct {
|
||||
UCHAR Reg_AL;
|
||||
UCHAR Reg_AH;
|
||||
};
|
||||
};
|
||||
union {
|
||||
ULONG Reg_EBX;
|
||||
USHORT Reg_BX;
|
||||
struct {
|
||||
UCHAR Reg_BL;
|
||||
UCHAR Reg_BH;
|
||||
};
|
||||
};
|
||||
union {
|
||||
ULONG Reg_ECX;
|
||||
USHORT Reg_CX;
|
||||
struct {
|
||||
UCHAR Reg_CL;
|
||||
UCHAR Reg_CH;
|
||||
};
|
||||
};
|
||||
union {
|
||||
ULONG Reg_EDX;
|
||||
USHORT Reg_DX;
|
||||
struct {
|
||||
UCHAR Reg_DL;
|
||||
UCHAR Reg_DH;
|
||||
};
|
||||
};
|
||||
union {
|
||||
ULONG Reg_EBP;
|
||||
USHORT Reg_BP;
|
||||
};
|
||||
union {
|
||||
ULONG Reg_ESI;
|
||||
USHORT Reg_SI;
|
||||
};
|
||||
union {
|
||||
ULONG Reg_EDI;
|
||||
USHORT Reg_DI;
|
||||
};
|
||||
USHORT Reg_DS;
|
||||
USHORT Reg_ES;
|
||||
USHORT Flags;
|
||||
UCHAR PIC0_Mask;
|
||||
UCHAR PIC1_Mask;
|
||||
} INT_REGS;
|
||||
|
||||
|
||||
|
||||
typedef struct { // Used by SVDC & RSDC instructions
|
||||
USHORT limit_15_0;
|
||||
USHORT base_15_0;
|
||||
UCHAR base_23_16;
|
||||
UCHAR attr;
|
||||
#define G_BIT 0x80
|
||||
#define D_BIT 0x40
|
||||
|
||||
UCHAR limit_19_16;
|
||||
UCHAR base_31_24;
|
||||
USHORT selector;
|
||||
} Descriptor;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ULONG Reserved;
|
||||
ULONG SMM_CTL_MSR;
|
||||
ULONG write_data;
|
||||
USHORT IO_addr;
|
||||
USHORT data_size;
|
||||
union {
|
||||
struct {
|
||||
USHORT CS_Writable: 1;
|
||||
USHORT IO_Write: 1;
|
||||
USHORT REP_Prefix: 1;
|
||||
USHORT SMINT: 1;
|
||||
|
||||
USHORT HALT: 1;
|
||||
USHORT Ext_IO_Trap: 1;
|
||||
USHORT External: 1;
|
||||
USHORT IO_Trap: 1;
|
||||
|
||||
USHORT Nested: 1;
|
||||
USHORT Reserved: 6;
|
||||
USHORT CS_Readable: 1;
|
||||
} SMI_Flags;
|
||||
USHORT SMI_Flags_Ushort;
|
||||
};
|
||||
|
||||
USHORT SS_Flags;
|
||||
|
||||
struct {
|
||||
ULONG limit;
|
||||
ULONG base;
|
||||
USHORT selector;
|
||||
USHORT attr;
|
||||
} _CS;
|
||||
|
||||
union {
|
||||
USHORT Next_IP;
|
||||
ULONG Next_EIP;
|
||||
};
|
||||
union {
|
||||
USHORT Current_IP;
|
||||
ULONG Current_EIP;
|
||||
};
|
||||
ULONG r_CR0;
|
||||
ULONG EFLAGS;
|
||||
ULONG r_DR7;
|
||||
} SmiHeader;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef USHORT MSG;
|
||||
typedef USHORT PRIORITY;
|
||||
typedef USHORT EVENT;
|
||||
typedef ULONG VSM;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define MAX_MSG_PARAM 4 // Parameter count
|
||||
#define MAX_MSG_CNT 10 // # entries in message queue
|
||||
|
||||
typedef struct {
|
||||
MSG Msg; // Message code
|
||||
PRIORITY Priority; // Priority
|
||||
ULONG From_VSM; // VSM that sent the message
|
||||
ULONG Param[MAX_MSG_PARAM]; // Parameters
|
||||
ULONG Timestamp; // Timestamp when message was entered
|
||||
} Message;
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
// VSM's state
|
||||
SmiHeader State; // SMM header for this VSM
|
||||
|
||||
// NOTE: Flink field must be immediately after State structure
|
||||
ULONG Flink; // Forward link to next VSM
|
||||
ULONG Blink; // Backward link to previous VSM
|
||||
ULONG SavedESP; // VSM's stack pointer
|
||||
ULONG SysMgr_Ptr; // Ptr to SysMgr's InfoStuff structure
|
||||
ULONG Southbridge; // PCI address of Southbridge
|
||||
|
||||
|
||||
// Statistics
|
||||
ULONG Adjustment; // Clocks used by SMM entry/exit
|
||||
ULONG Clocks[2]; // Total clocks used by this VSM
|
||||
ULONG NumSMIs[2]; // Total SMI count for this VSM
|
||||
ULONG FrozenClocks[2]; // Copied from Clocks[]
|
||||
ULONG FrozenNumSMIs[2]; // Copied from NumSMIs[]
|
||||
ULONG StartTime[2]; // Timestamp @ start of timeslice
|
||||
ULONG StartClocks[2]; // Timestamp of last INFO /S
|
||||
|
||||
// Floating Point
|
||||
UCHAR FPU_State[108]; // Saved FPU state
|
||||
UCHAR FPU_Flag; // Non-zero if FPU in use
|
||||
|
||||
UCHAR RunFlag; // VSM's scheduler state
|
||||
|
||||
USHORT ResumeVector; // Used by SaveToRAM
|
||||
USHORT Pad[5];
|
||||
|
||||
// Message Queue
|
||||
USHORT EndMsgQ; // Offset of *end* of message queue
|
||||
USHORT Qhead; // Message queue head offset
|
||||
USHORT Qtail; // Message queue tail offset
|
||||
|
||||
// MsgQueue is variable length, so it must be the last field
|
||||
Message MsgQueue[MAX_MSG_CNT]; // The VSM's message queue
|
||||
|
||||
} System;
|
||||
|
||||
|
||||
|
||||
//*********************************************************************
|
||||
// VSM Header
|
||||
//*********************************************************************
|
||||
|
||||
typedef struct {
|
||||
ULONG Signature; // 'VSM '
|
||||
UCHAR VSM_Type; // Type of VSM
|
||||
UCHAR ForCPU; // Required CPU (FFFFh for any)
|
||||
USHORT ForChipset; // Required companion I/O (FFFFh for any)
|
||||
USHORT VSM_Version; // Version of VSM
|
||||
ULONG VSM_Length; // Length of VSM module in bytes
|
||||
USHORT EntryPoint; // Offset of entry point
|
||||
ULONG DS_Limit;
|
||||
Requirements Flag; // Special requirements/capabilities
|
||||
USHORT VSA_Version;
|
||||
Descriptor _SS; // SS: descriptor for this VSM
|
||||
Descriptor _DS; // DS: descriptor for this VSM
|
||||
Descriptor _ES; // ES: descriptor for this VSM
|
||||
USHORT AlignSystem; // SysStuff must be DWORD aligned
|
||||
System SysStuff; // Reserved for use by System Manager
|
||||
|
||||
} VSM_Header;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//*********************************************************************
|
||||
// VSM Types
|
||||
//*********************************************************************
|
||||
#define VSM_SYS_MGR 0x00 // System Manager
|
||||
#define VSM_AUDIO 0x01 // Xpress Audio
|
||||
#define VSM_VGA 0x02 // SoftVGA
|
||||
#define VSM_LEGACY 0x03 // Standard AT peripherals
|
||||
#define VSM_PM 0x04 // Legacy Power Management
|
||||
#define VSM_OHCI 0x05 // OHCI
|
||||
#define VSM_i8042 0x06 // 8042 emulator
|
||||
#define VSM_DEBUGGER 0x07 // SMI based debugger
|
||||
#define VSM_ACPI 0x08 // Virtual ACPI
|
||||
#define VSM_APM 0x09 // APM 1.2
|
||||
#define VSM_OEM_ACPI 0x0A // OEM ACPI customizations
|
||||
#define VSM_SMB 0x0B // System Management Bus
|
||||
#define VSM_BATTERY 0x0C // Battery controller
|
||||
#define VSM_RTC 0x0D // Virtual RTC
|
||||
#define VSM_S2D 0x0E // SaveToDisk
|
||||
#define VSM_EXT_AMP 0x0F // External audio amplifier
|
||||
#define VSM_PCMCIA 0x10 // PCMCIA
|
||||
#define VSM_SPY 0x11 // Spy. Receives ALL messages first.
|
||||
#define VSM_NETWORK 0x12 // Network
|
||||
#define VSM_GPIO 0x13 // GPIO handler
|
||||
#define VSM_KEYBOARD 0x14 // USB keyboard to PC/AT emulation
|
||||
#define VSM_MOUSE 0x15 // USB mouse to PS/2 emulation
|
||||
#define VSM_USB 0x16 // Universal Serial Bus
|
||||
#define VSM_FLASH 0x17 // FLASH
|
||||
#define VSM_INFRARED 0x18 // Infrared
|
||||
#define VSM_THERMAL 0x19 // Thermal monitor
|
||||
#define VSM_NULL 0x1A // Unspecified
|
||||
#define VSM_MPEG 0x1B // MPEG video decoder (EMMA)
|
||||
#define VSM_VIP 0x1C // Video processor (VIDEC)
|
||||
#define VSM_LPC 0x1D // Low Pin Count bus
|
||||
#define VSM_VUART 0x1E // Virtual UART
|
||||
#define VSM_MICRO 0x1F // MicroController
|
||||
#define VSM_USER1 0x20 // USER 1
|
||||
#define VSM_USER2 0x21 // USER 2
|
||||
#define VSM_USER3 0x22 // USER 3
|
||||
#define VSM_SYSINFO 0x23 // System Information
|
||||
#define VSM_SUPERIO 0x24 // PM for SuperIO
|
||||
#define VSM_EHCI 0x25 // EHCI
|
||||
#define VSM_MAX_TYPE VSM_EHCI // Highest valid VSM type
|
||||
|
||||
#define VSM_ANY 0xFF // Wildcard for SYS_BROADCAST
|
||||
#define VSM_NOT_SELF 0x4000 // Flag used by SYS_BROADCAST
|
||||
#define VSM_ALL_EXCEPT 0x8000 // Flag used by SYS_BROADCAST
|
||||
|
||||
|
||||
//*********************************************************************
|
||||
// SMINT codes used by non-VSA components (BIOS, INIT, etc.)
|
||||
//*********************************************************************
|
||||
#define SYS_BIOS_INIT 0x00F0 // VSA installation from POST
|
||||
#define SYS_DOS_INSTALL 0x00F2 // VSA installation from DOS prompt
|
||||
#define SYS_VSM_INSTALL 0x00F3 // Install VSM dynamically
|
||||
#define SYS_REMOVE 0x00F4 // Unregister events belonging to VSM
|
||||
#define SYS_INT_RETURN 0x00F5 // Return from call to INT vector
|
||||
#define SYS_RESUME_FROM_RAM 0x6789 // Resume from RAM
|
||||
#define SYS_END_OF_POST 0x5000 // Issued by GeodeROM at end of POST
|
||||
#define SYS_INT13_SMI 0x5001 // Issued by Int 13 module (USB floppy)
|
||||
#define SYS_INT13CDR_SMI 0x5003 // Issued by Int 13 module (USB CD-ROM)
|
||||
#define SYS_USB_DEVICE_SMI 0x7777 // Issued by USBBOOT.ROM to access device table
|
||||
|
||||
//*********************************************************************
|
||||
// Event Priorities
|
||||
//*********************************************************************
|
||||
#define NORMAL_PRIORITY 0x0000
|
||||
#define MAX_PRIORITY 0x7FFF
|
||||
#define BROADCAST_PRIORITY 0x9000
|
||||
#define UNREGISTER_PRIORITY 0xFFF0
|
||||
|
||||
//*********************************************************************
|
||||
// Messages
|
||||
//*********************************************************************
|
||||
|
||||
#define MSG_INITIALIZE 0 // Perform VSM initialization
|
||||
#define EARLY_INIT 0
|
||||
#define END_OF_POST_INIT 1
|
||||
|
||||
#define MSG_SHUTDOWN 1 // Prepare for system shutdown (cold boot)
|
||||
#define MSG_SAVE_STATE 2 // Save entire state of device(s) controlled by VSM
|
||||
#define MSG_RESTORE_STATE 3 // Restore saved state of device(s) controlled by VSM
|
||||
#define MSG_SET_POWER_STATE 4 // Set device(s) to specified power state
|
||||
#define MSG_EVENT 5 // A registered event has occurred
|
||||
#define MSG_QUEUE_OVERFLOW 6 // The message queue is full.
|
||||
#define MSG_WARM_BOOT 7 // Prepare for a warm boot
|
||||
#define MSG_SET_POWER_MODE 9 // Restore saved state of device(s) controlled by VSM
|
||||
#define MSG_ABORT_POWER_STATE 10 // Power state is to be aborted
|
||||
|
||||
//*********************************************************************
|
||||
// Events
|
||||
//*********************************************************************
|
||||
|
||||
#define EVENT_GRAPHICS 1 // Video event
|
||||
#define EVENT_AUDIO 2 // Audio event
|
||||
#define EVENT_USB 3 // USB event
|
||||
#define EVENT_ACPI 4 // ACPI register access
|
||||
#define EVENT_ACPI_TIMER 5 // The ACPI timer expired
|
||||
#define EVENT_IO_TRAP 6 // I/O trap
|
||||
#define EVENT_IO_TIMEOUT 7 // I/O timeout
|
||||
#define EVENT_PME 8 // Power Management
|
||||
#define EVENT_KEL 9 // KEL
|
||||
#define EVENT_VIDEO_INACTIVITY 0x0A // Not supported in GX2
|
||||
#define EVENT_GPIO 0x0B // GPIO transition
|
||||
#define FALLING_EDGE (1 << 0)
|
||||
#define RISING_EDGE (1 << 1)
|
||||
#define BOTH_EDGES (FALLING_EDGE | RISING_EDGE)
|
||||
#define PME (1 << 2)
|
||||
#define DEBOUNCE (1 << 3)
|
||||
#define PULLDOWN (1 << 4)
|
||||
#define PULLUP (1 << 5)
|
||||
#define INVERT (1 << 6)
|
||||
#define OUTPUT (1 << 7)
|
||||
#define OPEN_DRAIN (1 << 8)
|
||||
// INPUT may be removed as if it is not OUTPUT it is assumed to be INPUT
|
||||
// this will have almost no impact on the code
|
||||
// Do Not use INPUT
|
||||
#define INPUT (1 << 9)
|
||||
#define AUX1 (1 << 10)
|
||||
#define AUX2 (1 << 11)
|
||||
#define NO_ASMI (1 << 12)
|
||||
#define PM1 (1 << 13)
|
||||
#define GPE (1 << 14)
|
||||
#define NO_ENABLE (1L << 15) // do not enable in GPE0_EN or PM1_EN
|
||||
// when using EVENT_PME
|
||||
#define EVENT_SOFTWARE_SMI 0x0C // Software SMI
|
||||
#define EVENT_PCI_TRAP 0x0D // PCI trap
|
||||
#define EVENT_VIRTUAL_REGISTER 0x0E // Virtual register access
|
||||
#define EVENT_NMI 0x0F // NMI
|
||||
#define EVENT_TIMER 0x10 // Millisecond timer
|
||||
#define EVENT_DEVICE_TIMEOUT 0x11 // Device timeout
|
||||
#define EVENT_SEMAPHORE 0x12 // ACPI global lock
|
||||
#define EVENT_VBLANK 0x13 // Vertical blank
|
||||
#define EVENT_A20 0x14 // A20 mask toggled
|
||||
#define EVENT_SMB 0x15 // SMB Controller
|
||||
#define EVENT_RTC 0x16 // RTC Alarm
|
||||
#define EVENT_THERMAL 0x17 // THRM pin
|
||||
#define EVENT_LPC 0x18 // Low Pin Count bus
|
||||
#define EVENT_UART 0x19
|
||||
#define EVENT_BLOCKIO 0x1A
|
||||
#define EVENT_PWM 0x1B
|
||||
#define MAX_EVENT EVENT_PWM
|
||||
|
||||
// Flags for event registration
|
||||
#define WRITES_ONLY (1L << 16)
|
||||
#define READS_ONLY (1L << 17)
|
||||
#define GLIU_ID (1L << 19)
|
||||
#define NOT_GLIU0 (1L << 20)
|
||||
#define NOT_GLIU1 (1L << 21)
|
||||
#define NOT_GLIU2 (1L << 22)
|
||||
#define ALL_GLIUS (NOT_GLIU0 | NOT_GLIU1 | NOT_GLIU2)
|
||||
// Flags used for EVENT_TIMER must be >= bit 24
|
||||
#define ONE_SHOT (1L << 24)
|
||||
#define FOR_STANDBY (1L << 25)
|
||||
|
||||
|
||||
//*********************************************************************
|
||||
// Resources
|
||||
//*********************************************************************
|
||||
#define RESOURCE_MEMORY 0 // Physical Memory
|
||||
#define RESOURCE_MMIO 1 // Memory mapped I/O
|
||||
#define RESOURCE_IO 2 // I/O space
|
||||
#define RESOURCE_SCIO 3 // Swiss-cheese I/O
|
||||
#define RESOURCE_GPIO 4 // General-purpose I/O pin
|
||||
#define RESOURCE_IRQ 5 // IRQ
|
||||
|
||||
|
||||
|
||||
//*********************************************************************
|
||||
// Macros
|
||||
//*********************************************************************
|
||||
|
||||
#define SYS_GET_NEXT_MSG(p) sys_get_next_msg(p)
|
||||
#define SYS_QUERY_MSG_QUEUE(p) sys_query_msg_queue(p)
|
||||
#define SYS_UNREGISTER_EVENT(e, p1, p2) sys_register_event(e, p1, p2, UNREGISTER_PRIORITY)
|
||||
#define SYS_REGISTER_EVENT(e, p1, p2, p) sys_register_event(e, p1, p2, p)
|
||||
#define SYS_PASS_EVENT(e, p1, p2, p3) // no longer needed
|
||||
#define SYS_VSM_PRESENT(vsm) sys_vsm_present(vsm)
|
||||
#define SYS_YIELD_CONTROL(p1) sys_yield_control(p1)
|
||||
#define SYS_SW_INTERRUPT(interrupt, regs) sys_software_interrupt(interrupt, regs)
|
||||
#define SYS_BROADCAST_MSG(msg, p, vsm) sys_broadcast_msg(msg, p, vsm)
|
||||
#define SYS_GET_SYSTEM_INFO(buffer) sys_get_system_info(buffer)
|
||||
#define SYS_REPORT_ERROR(err, info1, info2) sys_report_error(err, info1, info2)
|
||||
#define SYS_GENERATE_IRQ(irq) sys_generate_IRQ(irq)
|
||||
#define SYS_UNLOAD_VSM() sys_unload_vsm()
|
||||
#define SYS_LOGICAL_TO_PHYSICAL(addr) sys_logical_to_physical(addr)
|
||||
#define SYS_ALLOCATE_RESOURCE(f,p,q,r,s) sys_resource(f, p, q, r, s)
|
||||
#define SYS_DEALLOCATE_RESOURCE(f,p,q,r,s) sys_resource((UCHAR)(f|0x80), p, q, r, s)
|
||||
#define SYS_MBUS_DESCRIPTOR(addr, p) sys_mbus_descriptor(addr, p, 0)
|
||||
#define SYS_IO_DESCRIPTOR(addr, p) sys_mbus_descriptor(addr, p, 3)
|
||||
#define SYS_LOOKUP_DEVICE(id, i) sys_lookup_device(id, i)
|
||||
#define SYS_SAVE_STATE(buffer) sys_state(0, buffer)
|
||||
#define SYS_RESTORE_STATE(buffer) sys_state(1, buffer)
|
||||
#define SYS_SET_DECODE(addr, flag) sys_address_decode(addr, flag)
|
||||
#define SYS_MAP_IRQ(Source, Irq) sys_map_irq(Source, Irq)
|
||||
#define SYS_RETURN_RESULT(Data) sys_return_result(Data)
|
||||
#define SYS_DUPLICATE_VSM(MemModel) sys_duplicate_vsm(MemModel)
|
||||
|
||||
#define READ_PCI_BYTE(addr) read_PCI_byte(addr)
|
||||
#define READ_PCI_WORD(addr) read_PCI_word(addr)
|
||||
#define READ_PCI_DWORD(addr) read_PCI_dword(addr)
|
||||
#define WRITE_PCI_BYTE(addr, data) write_PCI_byte(addr, data)
|
||||
#define WRITE_PCI_WORD(addr, data) write_PCI_word(addr, data)
|
||||
#define WRITE_PCI_DWORD(addr, data) write_PCI_dword(addr, data)
|
||||
|
||||
#define WRITE_PCI_BYTE_NO_TRAP(addr, data) write_PCI_no_trap(addr, (ULONG)data, BYTE_IO)
|
||||
#define WRITE_PCI_WORD_NO_TRAP(addr, data) write_PCI_no_trap(addr, (ULONG)data, WORD_IO)
|
||||
#define WRITE_PCI_DWORD_NO_TRAP(addr, data) write_PCI_no_trap(addr, data, DWORD_IO)
|
||||
#define READ_PCI_BYTE_NO_TRAP(addr) ((UCHAR)read_PCI_no_trap(addr, BYTE_IO))
|
||||
#define READ_PCI_WORD_NO_TRAP(addr) ((USHORT)read_PCI_no_trap(addr, WORD_IO))
|
||||
#define READ_PCI_DWORD_NO_TRAP(addr) read_PCI_no_trap(addr, DWORD_IO)
|
||||
|
||||
#define WRITE_MEMORY(addr, data) write_flat(addr, data)
|
||||
#define READ_MEMORY(addr) read_flat(addr)
|
||||
|
||||
#define ENTER_CRITICAL_SECTION EnterCriticalSection();
|
||||
#define EXIT_CRITICAL_SECTION ExitCriticalSection();
|
||||
|
||||
|
||||
|
||||
void __pascal sys_register_event(EVENT, ULONG, ULONG, USHORT);
|
||||
void __pascal sys_software_interrupt(USHORT, INT_REGS *);
|
||||
void __pascal sys_broadcast_msg(MSG, void *, USHORT);
|
||||
void __pascal sys_yield_control(ULONG);
|
||||
void __pascal sys_get_system_info(void *);
|
||||
void __pascal sys_generate_IRQ(USHORT);
|
||||
void __pascal sys_state(USHORT, void *);
|
||||
void __pascal sys_address_decode(USHORT, USHORT);
|
||||
void __pascal sys_map_irq(UCHAR, UCHAR);
|
||||
void __pascal sys_return_result(ULONG);
|
||||
void __pascal sys_get_descriptor(USHORT, void *);
|
||||
void __pascal sys_set_descriptor(USHORT, void *);
|
||||
void __pascal sys_set_header_data(USHORT, ULONG);
|
||||
void __pascal sys_set_register(USHORT, ULONG);
|
||||
void __pascal sys_set_virtual_register(USHORT, USHORT);
|
||||
void __pascal sys_report_error(USHORT, ULONG, ULONG);
|
||||
|
||||
void __pascal write_PCI_byte(ULONG, UCHAR);
|
||||
void __pascal write_PCI_word(ULONG, USHORT);
|
||||
void __pascal write_PCI_dword(ULONG, ULONG);
|
||||
void __pascal write_PCI_no_trap(ULONG, ULONG, USHORT);
|
||||
|
||||
void EnterCriticalSection(void);
|
||||
void ExitCriticalSection(void);
|
||||
void sys_fast_path_return(void);
|
||||
void sys_unload_vsm(void);
|
||||
void __pascal sys_duplicate_vsm(USHORT);
|
||||
|
||||
void __pascal write_flat(ULONG, ULONG);
|
||||
ULONG __pascal read_flat(ULONG);
|
||||
UCHAR __pascal sys_vsm_present(UCHAR);
|
||||
USHORT __pascal sys_get_virtual_register(USHORT);
|
||||
ULONG __pascal sys_get_header_data(USHORT);
|
||||
ULONG __pascal sys_get_register(USHORT);
|
||||
UCHAR __pascal read_PCI_byte(ULONG);
|
||||
USHORT __pascal read_PCI_word(ULONG);
|
||||
ULONG __pascal read_PCI_dword(ULONG);
|
||||
ULONG __pascal read_PCI_no_trap(ULONG, USHORT);
|
||||
ULONG __pascal sys_logical_to_physical(void *);
|
||||
ULONG __pascal sys_resource(UCHAR, USHORT, ULONG, USHORT, USHORT);
|
||||
ULONG __pascal sys_mbus_descriptor(USHORT, ULONG *, USHORT);
|
||||
ULONG __pascal sys_lookup_device(USHORT, USHORT);
|
||||
MSG sys_get_next_msg(void *);
|
||||
MSG sys_query_msg_queue(void *);
|
||||
|
||||
// Macros for use by VSMs to access the non-SMM context
|
||||
#define SET_HEADER_DATA(reg, data) sys_set_header_data(reg, data)
|
||||
#define GET_HEADER_DATA(reg) (ULONG)sys_get_header_data(reg)
|
||||
#define GET_DESCRIPTOR(reg, buffer) sys_get_descriptor(reg, buffer);
|
||||
#define SET_DESCRIPTOR(reg, buffer) sys_set_descriptor(reg, buffer);
|
||||
#define GET_REGISTER(reg) (ULONG)sys_get_register(reg)
|
||||
#define SET_REGISTER(reg, data) sys_set_register(reg, data)
|
||||
#define SET_EAX(data) SET_REGISTER(R_EAX, (ULONG) (data))
|
||||
#define SET_AX(data) SET_REGISTER(R_AX, (USHORT)(data))
|
||||
#define SET_AL(data) SET_REGISTER(R_AL, (UCHAR) (data))
|
||||
#define SET_AH(data) SET_REGISTER(R_AH, (UCHAR) (data))
|
||||
#define SET_EFLAGS(data) SET_HEADER_DATA(R_EFLAGS, data)
|
||||
#define GET_EAX() ((ULONG) GET_REGISTER(R_EAX))
|
||||
#define GET_AX() ((USHORT)GET_REGISTER(R_AX))
|
||||
#define GET_AL() ((UCHAR) GET_REGISTER(R_AL))
|
||||
#define GET_AH() ((UCHAR) GET_REGISTER(R_AH))
|
||||
#define GET_EFLAGS() (GET_HEADER_DATA(R_EFLAGS))
|
||||
|
||||
|
||||
// Macros for accessing virtual registers
|
||||
#define GET_VIRTUAL_REGISTER(reg) (USHORT)sys_get_virtual_register(reg)
|
||||
#define SET_VIRTUAL_REGISTER(reg, data) sys_set_virtual_register(reg, data)
|
||||
|
||||
|
||||
//*********************************************************************
|
||||
// Error Codes
|
||||
//*********************************************************************
|
||||
|
||||
#define ERR_UNDEF_EVENT 1 // Attempt to register an undefined event
|
||||
//#define ERR_SCHEDULER 2 // Scheduler error
|
||||
#define ERR_BAD_PARAMETER 3 // Illegal system call parameter
|
||||
#define ERR_RESOURCE_CONFLICT 4 // Multiple VSMs requested conflicting resources
|
||||
#define ERR_UNHANDLED_EVENT 5 // An event occurred that no VSM handled
|
||||
#define ERR_INVALID_EVENT 6 // SysMgr attempted to send an invalid event
|
||||
//#define ERR_TIME_LIMIT 7 // A VSM exceeded its allotted runtime
|
||||
#define ERR_REGISTRATION_LOST 8 // A registered event is lost due to too many event registrations
|
||||
#define ERR_HW_MISMATCH 9 // A VSM could not find the correct hardware (e.g. OHCI)
|
||||
#define ERR_BAD_DESCRIPTOR 0x0A // A descriptor in a VSM header is not valid
|
||||
//#define ERR_MSG_QUEUE_FULL 0x0B // A VSM's message queue is full
|
||||
//#define ERR_MULTIPLE_EVENT 0x0C // A VSM attempted to register the same event twice
|
||||
#define ERR_UNREGISTRATION 0x0D // A VSM attempted to unregister an event for which it was not registered
|
||||
#define ERR_UNREGISTERED_EVENT 0x0E // An event occurred for which no VSM is registered
|
||||
#define ERR_MISALIGNED_IO 0x0F // An misaligned I/O access occurred
|
||||
//#define ERR_UNEXPECTED_EVENT 0x10 // A handler routine was passed an unexpected SMI event
|
||||
//#define ERR_BAD_VSM 0x11 // A VSM header doesn't look right (no signature, etc.)
|
||||
#define ERR_NESTED_ACCESS 0x12 // A VSM directly accessed a ACPI or virtual register
|
||||
//#define ERR_BAD_MSG 0x13 // An attempt was made to send an illegal message code
|
||||
//#define ERR_UNHANDLED_VIRTUAL 0x14 // An access was made by a VSM to an unhandled virtual register
|
||||
#define ERR_BAD_INTERRUPT 0x15 // A VSM attempted to call an illegal INT vector
|
||||
#define ERR_ILLEGAL_MACRO 0x16 // Illegal use of GET/SET_REGISTER or GET/SET_HEADER_DATA macros
|
||||
#define ERR_UNDEF_SYS_CALL 0x17 // Undefined system call
|
||||
//#define ERR_BAD_POWER_STATE 0x18 // Invalid power state
|
||||
#define ERR_BAD_VR_ACCESS 0x19 // Access to undefined VR class by an application
|
||||
#define ERR_UNDEF_VIRTUAL_REG 0x1A // Access to undefined VR class by a VSM
|
||||
//#define ERR_UNSUPPORTED_CHIPSET 0x1B // This chipset is not supported
|
||||
#define ERR_PCI_TRAP 0x1C // A VSM requested an unsupported PCI trap
|
||||
#define ERR_RESOURCE_NOT_FOUND 0x1D // A VSM requested an unsupported resource
|
||||
#define ERR_NO_MORE_DESCRIPTORS 0x1E // Out of MBIU descriptors
|
||||
//#define ERR_INTERNAL_ERROR 0x1F // System error, e.g. inconsistent data structure
|
||||
#define ERR_DATA_STRUCTURE 0x20 // A system structure is too small
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Used as 2nd parameter to SYS_SET_DECODE macro:
|
||||
#define POSITIVE_DECODE 1
|
||||
#define SUBTRACTIVE_DECODE 0
|
||||
|
||||
|
||||
|
||||
|
||||
//****************************************************************************************************
|
||||
#define FROM_HEADER 0x2000
|
||||
#define WORD_SIZE 0x4000
|
||||
#define DWORD_SIZE 0x8000
|
||||
|
||||
|
||||
|
||||
|
||||
// Field names for GET_REGISTER and SET_REGISTER macros
|
||||
// These offsets must match the register order on the stack (PUSHAD)
|
||||
|
||||
#define R_DI 0 + WORD_SIZE
|
||||
#define R_EDI 0 + DWORD_SIZE
|
||||
|
||||
#define R_SI 4 + WORD_SIZE
|
||||
#define R_ESI 4 + DWORD_SIZE
|
||||
|
||||
#define R_BP 8 + WORD_SIZE
|
||||
#define R_EBP 8 + DWORD_SIZE
|
||||
|
||||
#define R_BL 16
|
||||
#define R_BH R_BL + 1
|
||||
#define R_BX R_BL + WORD_SIZE
|
||||
#define R_EBX R_BL + DWORD_SIZE
|
||||
|
||||
#define R_DL 20
|
||||
#define R_DH R_DL + 1
|
||||
#define R_DX R_DL + WORD_SIZE
|
||||
#define R_EDX R_DL + DWORD_SIZE
|
||||
|
||||
#define R_CL 24
|
||||
#define R_CH R_CL + 1
|
||||
#define R_CX R_CL + WORD_SIZE
|
||||
#define R_ECX R_CL + DWORD_SIZE
|
||||
|
||||
#define R_AL 28
|
||||
#define R_AH R_AL + 1
|
||||
#define R_AX R_AL + WORD_SIZE
|
||||
#define R_EAX R_AL + DWORD_SIZE
|
||||
|
||||
#define R_SP 32 + WORD_SIZE
|
||||
#define R_ESP 32 + DWORD_SIZE
|
||||
|
||||
|
||||
// Segment registers
|
||||
// NOTE: offset points to .selector field
|
||||
#define DESCRIPTOR_SIZE 10 // sizeof(Descriptor)
|
||||
#define R_SS 36-2 + DESCRIPTOR_SIZE + WORD_SIZE
|
||||
#define R_DS R_SS + DESCRIPTOR_SIZE
|
||||
#define R_ES R_DS + DESCRIPTOR_SIZE
|
||||
#define R_FS R_ES + DESCRIPTOR_SIZE
|
||||
#define R_GS R_FS + DESCRIPTOR_SIZE
|
||||
|
||||
// Fields from SMM header
|
||||
#define WRITE_DATA 0x08 + DWORD_SIZE + FROM_HEADER
|
||||
#define IO_ADDRESS 0x0C + WORD_SIZE + FROM_HEADER
|
||||
#define DATA_SIZE 0x0E + FROM_HEADER
|
||||
#define SMM_FLAGS 0x10 + WORD_SIZE + FROM_HEADER
|
||||
#define CS_LIMIT 0x14 + DWORD_SIZE + FROM_HEADER
|
||||
#define CS_BASE 0x18 + DWORD_SIZE + FROM_HEADER
|
||||
#define CS_SELECTOR 0x1C + WORD_SIZE + FROM_HEADER
|
||||
#define CS_ATTR 0x1E + WORD_SIZE + FROM_HEADER
|
||||
#define R_CS 0x1C + WORD_SIZE + FROM_HEADER
|
||||
#define R_IP 0x20 + WORD_SIZE + FROM_HEADER
|
||||
#define R_EIP 0x20 + DWORD_SIZE + FROM_HEADER
|
||||
#define CURRENT_EIP 0x24 + DWORD_SIZE + FROM_HEADER
|
||||
#define R_CR0 0x28 + DWORD_SIZE + FROM_HEADER
|
||||
#define R_EFLAGS 0x2C + DWORD_SIZE + FROM_HEADER
|
||||
#define EFLAGS_CF 0x0001
|
||||
#define EFLAGS_ZF 0x0040
|
||||
#define EFLAGS_IF 0x0200
|
||||
#define EFLAGS_DF 0x0400
|
||||
#define R_DR7 0x30 + DWORD_SIZE + FROM_HEADER
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
ULONG Chipset_Base;
|
||||
USHORT Chipset_ID;
|
||||
USHORT Chipset_Rev;
|
||||
USHORT CPU_ID;
|
||||
USHORT CPU_Revision;
|
||||
USHORT CPU_MHz;
|
||||
ULONG SystemMemory; // Units = bytes
|
||||
ULONG VSA_Location; // Physical location
|
||||
USHORT VSA_Size; // Units = KB
|
||||
USHORT PCI_MHz;
|
||||
USHORT DRAM_MHz;
|
||||
} Hardware;
|
||||
|
||||
|
||||
|
||||
|
||||
88
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/blockio.c
vendored
Executable file
88
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/blockio.c
vendored
Executable file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//* Function: *
|
||||
//* Handler for blocked PIO during UDMA
|
||||
|
||||
#include "vsa2.h"
|
||||
#include "protos.h"
|
||||
|
||||
|
||||
#define RESET_DRIVE 0x08
|
||||
|
||||
|
||||
USHORT UDMA_IO_Base;
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Enables/disables BLOCKIO
|
||||
//***********************************************************************
|
||||
void pascal BlockIO(UCHAR EnableFlag)
|
||||
{ USHORT Priority=UNREGISTER_PRIORITY;
|
||||
|
||||
if (EnableFlag) {
|
||||
Priority = MAX_PRIORITY;
|
||||
}
|
||||
|
||||
SYS_REGISTER_EVENT(EVENT_BLOCKIO, 0, 0, Priority);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Handler for EVENT_BLOCKIO
|
||||
//***********************************************************************
|
||||
void Handle_BLOCKIO(USHORT IO_Address, ULONG Data, UCHAR DataSize)
|
||||
{ UCHAR Command;
|
||||
|
||||
switch (IO_Address) {
|
||||
|
||||
case 0x1F7:
|
||||
// Check for drive reset command
|
||||
if ((UCHAR)Data == RESET_DRIVE) {
|
||||
break;
|
||||
}
|
||||
return;
|
||||
|
||||
case 0x3F6:
|
||||
if ((UCHAR)Data & 4) {
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
// Ignore I/O to all other IDE registers
|
||||
return;
|
||||
}
|
||||
|
||||
// Disable BLOCKIO
|
||||
BlockIO(0);
|
||||
|
||||
// Terminate bus mastering
|
||||
Command = in_8(UDMA_IO_Base);
|
||||
out_8(UDMA_IO_Base, (UCHAR)(Command & ~1));
|
||||
|
||||
// Re-issue the I/O
|
||||
out_8(IO_Address, (UCHAR)Data);
|
||||
|
||||
// Re-enable BLOCKIO
|
||||
BlockIO(1);
|
||||
|
||||
}
|
||||
479
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/cs5536.c
vendored
Executable file
479
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/cs5536.c
vendored
Executable file
@@ -0,0 +1,479 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//* Function: *
|
||||
//* This file contains routines specific to the CS5536.
|
||||
|
||||
#include "vsa2.h"
|
||||
#include "chipset.h"
|
||||
#include "pci.h"
|
||||
#include "vr.h"
|
||||
#include "mapper.h"
|
||||
#include "gx2.h"
|
||||
#include "legacy.h"
|
||||
#include "protos.h"
|
||||
#include "isa.h"
|
||||
|
||||
|
||||
|
||||
// External Function prototypes
|
||||
extern void GetDrivesPresent(void);
|
||||
extern void Allocate_Flash_BARs(void);
|
||||
extern void pascal Flash_IDE_Switch(USHORT, ULONG);
|
||||
extern void BlockIO(UCHAR);
|
||||
extern void Register_DMA_Fix(void);
|
||||
extern UCHAR FlashIsEnabled(void);
|
||||
|
||||
// Local function prototypes:
|
||||
void Handle_5536_PCI_Traps(USHORT, USHORT, ULONG);
|
||||
void Register_PCI_Trap(USHORT, UCHAR);
|
||||
|
||||
// External variables:
|
||||
extern Hardware SystemInfo;
|
||||
extern ULONG ChipsetBase;
|
||||
extern ULONG Param[];
|
||||
extern USHORT UDMA_IO_Base;
|
||||
extern ULONG OHCI_Address[];
|
||||
|
||||
// Local variables:
|
||||
typedef void (* PCI_HANDLER)(USHORT, USHORT, ULONG);
|
||||
extern PCI_HANDLER Handle_PCI_Traps;
|
||||
|
||||
USHORT uart1 = 0;
|
||||
USHORT uart2 = 0;
|
||||
USHORT Flash_Function=0x00FF, IDE_Function = 0x00FF;
|
||||
USHORT PCI_Int_AB = ((USHORT)((INTB_PIN << 8) | INTA_PIN));
|
||||
USHORT PCI_Int_CD = ((USHORT)((INTD_PIN << 8) | INTC_PIN));
|
||||
USHORT Y_Sources[8];
|
||||
USHORT Flash_PME;
|
||||
USHORT Steering = 0x0000;
|
||||
USHORT Hidden_Function = 0x0000;
|
||||
UCHAR IDE_Allocated = 0;
|
||||
UCHAR Flash_Allocated = 0;
|
||||
ULONG MDD_Base;
|
||||
USHORT pmc_base = 0;
|
||||
USHORT gpio_base = 0;
|
||||
USHORT acpi_base = 0;
|
||||
|
||||
typedef struct {
|
||||
UCHAR Pin;
|
||||
UCHAR Z_Source;
|
||||
UCHAR Lbar;
|
||||
} PCI_INTERRUPT;
|
||||
|
||||
PCI_INTERRUPT PCI_Interrupt[] = {
|
||||
// Pin Z_Source
|
||||
{INTA_PIN, Z_IRQ_INTA},
|
||||
{INTB_PIN, Z_IRQ_INTB},
|
||||
{INTC_PIN, Z_IRQ_INTC},
|
||||
{INTD_PIN, Z_IRQ_INTD}
|
||||
};
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Hides the PCI header of the specified function
|
||||
//***********************************************************************
|
||||
void Hide_Hdr(USHORT Function)
|
||||
{
|
||||
|
||||
// If a function is currently being hidden, un-hide it
|
||||
if (Hidden_Function) {
|
||||
SYS_UNREGISTER_EVENT(EVENT_PCI_TRAP, ChipsetBase+Hidden_Function, 0x000000FF);
|
||||
SYS_UNREGISTER_EVENT(EVENT_PCI_TRAP, ChipsetBase+Function+0x40, WRITES_ONLY);
|
||||
}
|
||||
|
||||
// Register for IDE/Flash config space (to make invisible)
|
||||
Register_PCI_Trap(Function, 0xFF);
|
||||
|
||||
// Record which function is hidden
|
||||
Hidden_Function = Function;
|
||||
|
||||
// Get the 'other' function
|
||||
if (Function == IDE_Function) {
|
||||
Function = Flash_Function;
|
||||
} else {
|
||||
Function = IDE_Function;
|
||||
}
|
||||
|
||||
// Trap IDE/Flash register 0x40 (used for Flash<->IDE switch)
|
||||
SYS_REGISTER_EVENT(EVENT_PCI_TRAP, ChipsetBase+Function+0x40, WRITES_ONLY, 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Maps the NAND Flash PMEs to the specified IRQ
|
||||
//***********************************************************************
|
||||
void Map_Flash_IRQ(UCHAR Irq)
|
||||
{
|
||||
SYS_MAP_IRQ((UCHAR)(Flash_PME+0), Irq);
|
||||
SYS_MAP_IRQ((UCHAR)(Flash_PME+1), Irq);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Hides the IDE function and un-hides the Flash function
|
||||
//***********************************************************************
|
||||
void Hide_IDE_Hdr(void)
|
||||
{ UCHAR Shift, Irq;
|
||||
|
||||
// Map NAND Flash interrupts
|
||||
Shift = (UCHAR)(((Flash_PME >> 8)-1) * 4);
|
||||
Irq = (UCHAR)(Steering >> Shift) & 0x0F;
|
||||
Map_Flash_IRQ(Irq);
|
||||
|
||||
// Hide the IDE header
|
||||
Hide_Hdr(IDE_Function);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Hides the Flash function and un-hides the IDE function
|
||||
//***********************************************************************
|
||||
void Hide_Flash_Hdr(void)
|
||||
{ USHORT Bar;
|
||||
|
||||
// Unmap NAND Flash interrupts
|
||||
Map_Flash_IRQ(0);
|
||||
|
||||
// If Flash BARs have been allocated, then zero them to disable linked MSRs
|
||||
if (Flash_Allocated) {
|
||||
for (Bar = BAR0; Bar <= BAR3; Bar += 0x10) {
|
||||
WRITE_PCI_DWORD(ChipsetBase+IDE_Function+Bar, 0x00000000);
|
||||
}
|
||||
}
|
||||
Hide_Hdr(Flash_Function);
|
||||
|
||||
if (!IDE_Allocated) {
|
||||
|
||||
// Allocate UDMA BAR
|
||||
SYS_ALLOCATE_RESOURCE(RESOURCE_IO, BAR4, 16, DEVICE_ID_AMD_THOR, ID_ATA);
|
||||
|
||||
IDE_Allocated = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Performs early initialization for CS5536
|
||||
//***********************************************************************
|
||||
void CS5536_Early_Init(void)
|
||||
{ USHORT Function;
|
||||
ULONG PciAddr, PciData;
|
||||
|
||||
Handle_PCI_Traps = Handle_5536_PCI_Traps;
|
||||
|
||||
MDD_Base = SYS_LOOKUP_DEVICE(ID_MDD, 1);
|
||||
// Get I/O base of PMC, ACPI & GPIO
|
||||
pmc_base = READ_PCI_WORD(ChipsetBase + BAR4) & 0xFFFE;
|
||||
gpio_base = READ_PCI_WORD(ChipsetBase + BAR1) & 0xFFFE;
|
||||
acpi_base = READ_PCI_WORD(ChipsetBase + BAR5) & 0xFFFE;
|
||||
|
||||
|
||||
// Scan Southbridge functions to:
|
||||
// - Get Unrestricted Sources Y IRQ.
|
||||
// - Find Flash & IDE functions.
|
||||
for (Function = 0; Function < 8; Function++) {
|
||||
|
||||
// Generate PCI configuration address
|
||||
PciAddr = ChipsetBase | (Function << 8);
|
||||
|
||||
// For functions that have PCI interrupts, Interrupt Line
|
||||
// contains Y Sources field number.
|
||||
(UCHAR)PciAddr = INTERRUPT_LINE;
|
||||
|
||||
// If PCI interrupt is defined, record linked Unrestricted Y Source
|
||||
Y_Sources[Function] = READ_PCI_WORD(PciAddr);
|
||||
if (Y_Sources[Function]) {
|
||||
// clear Interrupt Line
|
||||
WRITE_PCI_WORD(PciAddr, 0x0000);
|
||||
}
|
||||
|
||||
// Read Class Code
|
||||
(UCHAR)PciAddr = REVISION_ID;
|
||||
PciData = READ_PCI_DWORD(PciAddr);
|
||||
// Ignore Revision ID
|
||||
PciData &= 0xFFFFFF00;
|
||||
|
||||
// Record function # of Flash header
|
||||
if (PciData == 0x05010000) {
|
||||
Flash_Function = (USHORT)PciAddr & 0x0700;
|
||||
Flash_PME = Y_Sources[Function];
|
||||
}
|
||||
// Record function # of IDE header
|
||||
if (PciData == 0x01018000) {
|
||||
IDE_Function = (USHORT)PciAddr & 0x0700;
|
||||
Y_Sources[Function] = Flash_PME+1;
|
||||
}
|
||||
}
|
||||
|
||||
switch (SystemInfo.Chipset_ID) {
|
||||
case DEVICE_ID_5536:
|
||||
SYS_REGISTER_EVENT(EVENT_PCI_TRAP, ChipsetBase+IDE_Function+BAR4, WRITES_ONLY, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// Is Flash controller enabled ?
|
||||
if (FlashIsEnabled()) {
|
||||
|
||||
// Allocate Flash BARs
|
||||
Allocate_Flash_BARs();
|
||||
|
||||
// Hide the IDE header
|
||||
Hide_IDE_Hdr();
|
||||
|
||||
} else {
|
||||
|
||||
// Hide the Flash header
|
||||
Hide_Flash_Hdr();
|
||||
}
|
||||
|
||||
// Register for virtual registers VRC_MISCELLANEOUS::PCI_INT_AB->WATCHDOG
|
||||
SYS_REGISTER_EVENT(EVENT_VIRTUAL_REGISTER, VRC_MISCELLANEOUS, (PCI_INT_AB<<8) | WATCHDOG, MAX_PRIORITY);
|
||||
|
||||
// Register for SB PCI register 0x5C-0x5D (emulation of 5530 PCI steering register)
|
||||
Register_PCI_Trap(0x005C, 0x01);
|
||||
|
||||
/*MEJ
|
||||
// If Power Management VSM is present...
|
||||
if (SYS_VSM_PRESENT(VSM_PM)) {
|
||||
// Register for virtual register timeouts on legacy devices
|
||||
SYS_REGISTER_EVENT(EVENT_VIRTUAL_REGISTER, VRC_PM, (DISK_TIMEOUT<<8) | PARALLEL_TIMEOUT, 0);
|
||||
}
|
||||
*/
|
||||
|
||||
// Register for virtual register class VRC_CHIPSET
|
||||
SYS_REGISTER_EVENT(EVENT_VIRTUAL_REGISTER, VRC_CHIPSET, 0, NORMAL_PRIORITY);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Performs End-of-POST initialization for CS5536
|
||||
//***********************************************************************
|
||||
void CS5536_Late_Init(void)
|
||||
{
|
||||
// Determine how many ATA drives are present
|
||||
GetDrivesPresent();
|
||||
|
||||
// Set ISA bridge Latency Timer to 0x40
|
||||
WRITE_PCI_BYTE(ChipsetBase + LATENCY_TIMER, 0x40);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Handler for writes to VRC_MISCELLANEOUS PCI_INT_AB & PCI_INT_CD
|
||||
// These registers define what GPIOs are to be used for PCI interrupts.
|
||||
//***********************************************************************
|
||||
void Handle_Misc_VR(UCHAR Index, USHORT Data)
|
||||
{ int i, j;
|
||||
ULONG Param2;
|
||||
static UCHAR Flag = 0x00;
|
||||
|
||||
|
||||
if (Index == PCI_INT_AB) {
|
||||
// PCI interrupt GPIOs can only be allocated once
|
||||
if (Flag & 1) {
|
||||
return;
|
||||
}
|
||||
// Record data for readback
|
||||
PCI_Int_AB = Data;
|
||||
Flag |= 1;
|
||||
i = 0;
|
||||
} else {
|
||||
// PCI interrupt GPIOs can only be allocated once
|
||||
if (Flag & 2) {
|
||||
return;
|
||||
}
|
||||
// Record data for readback
|
||||
PCI_Int_CD = Data;
|
||||
Flag |= 2;
|
||||
i = 2;
|
||||
}
|
||||
|
||||
// Set GPIOs as level-sensitive (no ASMI!), inverted inputs
|
||||
j = i + 2;
|
||||
while (i < j) {
|
||||
|
||||
// Record the GPIO pin
|
||||
PCI_Interrupt[i].Pin = (UCHAR)Data;
|
||||
|
||||
if (PCI_Interrupt[i].Pin < 32) {
|
||||
Param2 = ((ULONG)PCI_Interrupt[i].Z_Source << 16) | PCI_Interrupt[i].Pin;
|
||||
SYS_REGISTER_EVENT(EVENT_GPIO, Param2, INVERT, MAX_PRIORITY);
|
||||
}
|
||||
|
||||
// Shift the next pin # into the 8 LSBs
|
||||
Data >>= 8;
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Emulates CS5530's PCI Interrupt steering registers 0x5C & 0x5D
|
||||
// Register 0x5C:
|
||||
// 3:0 INTA#
|
||||
// 7:4 INTB#
|
||||
// Register 0x5D:
|
||||
// 3:0 INTC#
|
||||
// 7:4 INTD#
|
||||
// Maps PCI INT pins to Unrestricted Z sources
|
||||
//***********************************************************************
|
||||
void PCI_Interrupt_Steering(USHORT Data)
|
||||
{ UCHAR i, j, Irq;
|
||||
|
||||
// Register for PCI interrupt GPIOs in case BIOS never wrote to the VR
|
||||
Handle_Misc_VR(PCI_INT_AB, PCI_Int_AB);
|
||||
Handle_Misc_VR(PCI_INT_CD, PCI_Int_CD);
|
||||
|
||||
for (i=0; i < 4; i++) {
|
||||
|
||||
// Extract IRQ from next nibble
|
||||
Irq = (UCHAR)(Data & 0x0F);
|
||||
|
||||
// Don't allow IRQ2 (SMI)
|
||||
if (Irq != 2) {
|
||||
// Map the Unrestricted Z Source to the requested IRQ
|
||||
SYS_MAP_IRQ((UCHAR)(PCI_Interrupt[i].Z_Source+16), Irq);
|
||||
|
||||
// Map the Unrestricted Y Source (if any) to the requested IRQ
|
||||
for (j=0; j < 8; j++) {
|
||||
UCHAR InterruptPin;
|
||||
|
||||
InterruptPin = (UCHAR)(Y_Sources[j] >> 8);
|
||||
if (InterruptPin == i+1) {
|
||||
SYS_MAP_IRQ((UCHAR)Y_Sources[j], Irq);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Shift the next nibble into the 4 LSBs
|
||||
Data >>= 4;
|
||||
}
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
// Handler for emulation of 5530 PCI steering registers on a 5536 system
|
||||
//***********************************************************************
|
||||
void Handle_5536_PCI_Traps(USHORT PCI_Addr, USHORT IO_Params, ULONG Data)
|
||||
{ UCHAR PCI_Reg, Shift, IO_Size;
|
||||
USHORT Function;
|
||||
|
||||
|
||||
PCI_Reg = (UCHAR) PCI_Addr;
|
||||
IO_Size = (UCHAR) IO_Params;
|
||||
Function = PCI_Addr & 0x0700;
|
||||
Shift = (PCI_Reg & 3) << 3;
|
||||
|
||||
// Record OHCI BAR values
|
||||
if (PCI_Addr == 0x7C10 || PCI_Addr == 0x7D10) {
|
||||
if (IO_Params & IO_WRITE) {
|
||||
Function = (Function >> 8) - 4;
|
||||
OHCI_Address[Function] = Data & 0xFFFFF000;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// PCI Interrupt Steering register
|
||||
if (Function == 0x0000) {
|
||||
|
||||
if (IO_Params & IO_WRITE) {
|
||||
// Handle mis-aligned accesses
|
||||
if (Shift) {
|
||||
Steering &= 0x00FF;
|
||||
Steering |= (USHORT)Data << 8;
|
||||
} else {
|
||||
Steering = (USHORT)Data;
|
||||
}
|
||||
PCI_Interrupt_Steering(Steering);
|
||||
return;
|
||||
|
||||
} else {
|
||||
if (PCI_Reg < 0x5C) {
|
||||
Data = (ULONG)Steering << (32-Shift);
|
||||
Shift = 0;
|
||||
} else {
|
||||
Data = Steering;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// Flash/IDE configuration space
|
||||
if (Function == Flash_Function || Function == IDE_Function) {
|
||||
|
||||
if (IO_Params & IO_WRITE) {
|
||||
|
||||
// PCI writes to IDE/Flash function
|
||||
switch (PCI_Reg) {
|
||||
case BAR4:
|
||||
if (Function == IDE_Function && (USHORT)Data != 0xFFFF) {
|
||||
// Record UDMA I/O base for BLOCK_IO logic
|
||||
UDMA_IO_Base = (USHORT)Data & 0xFFF0;
|
||||
}
|
||||
break;
|
||||
|
||||
// Write to IDE<->Flash switch
|
||||
case 0x40:
|
||||
if (Data == 0xDEADBEEF || Data == 0xBEEFDEAD) {
|
||||
// Switch Flash<->IDE
|
||||
Flash_IDE_Switch(Function, Data);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
} else {
|
||||
|
||||
// PCI reads of hidden function
|
||||
if (Function == Hidden_Function) {
|
||||
Data = 0xFFFFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Handle non-dword aligned accesses
|
||||
Data >>= Shift;
|
||||
Data |= 0xFFFFFFFFL << (32-Shift);
|
||||
|
||||
// Return the PCI register value
|
||||
SYS_RETURN_RESULT(Data);
|
||||
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
// Registers a PCI trap for the specified Addr/Mask
|
||||
//***********************************************************************
|
||||
void Register_PCI_Trap(USHORT Addr, UCHAR Mask)
|
||||
{
|
||||
SYS_REGISTER_EVENT(EVENT_PCI_TRAP, ChipsetBase+Addr, (ULONG)Mask, 0);
|
||||
}
|
||||
|
||||
145
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/events.c
vendored
Executable file
145
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/events.c
vendored
Executable file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (c) 2006 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//* Function: *
|
||||
//* This file handles the Legacy VSM's event messages.
|
||||
|
||||
#include "vsa2.h"
|
||||
#include "chipset.h"
|
||||
#include "vr.h"
|
||||
#include "legacy.h"
|
||||
#include "protos.h"
|
||||
#include "pci.h"
|
||||
#include "isa.h"
|
||||
|
||||
// Function prototypes
|
||||
extern void Handle_BLOCKIO(USHORT, ULONG, UCHAR);
|
||||
extern void Handle_VirtualRegs(UCHAR, UCHAR, UCHAR, USHORT);
|
||||
extern void Do_OHCI_SWAPSiF(void);
|
||||
|
||||
// External variables:
|
||||
extern ULONG ChipsetBase;
|
||||
extern USHORT DiskTimeout, SerialTimeout, ParallelTimeout, FloppyTimeout;
|
||||
|
||||
// Local variables:
|
||||
USHORT IDE_Interface = MASTER_IDE; // Default to "bus master capable"
|
||||
|
||||
typedef void (* PCI_HANDLER)(USHORT, USHORT, ULONG);
|
||||
PCI_HANDLER Handle_PCI_Traps;
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Register I/O trap to fix 118.409 - Block/Demand mode fails
|
||||
//***********************************************************************
|
||||
void Register_DMA_Fix(void)
|
||||
{
|
||||
#define DMA_FLAGS (WRITES_ONLY | ONE_SHOT)
|
||||
|
||||
SYS_REGISTER_EVENT(EVENT_IO_TRAP, DMA1_MODE, DMA_FLAGS | 1, 0);
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Handler for MSG_EVENT
|
||||
//***********************************************************************
|
||||
void Handle_Events(ULONG * Param)
|
||||
{ USHORT Event, IO_Address;
|
||||
ULONG Data;
|
||||
UCHAR WrFlag, DataSize, Class, Index;
|
||||
|
||||
Event = (USHORT)Param[0];
|
||||
IO_Address = (USHORT)Param[2];
|
||||
DataSize = (UCHAR)(Param[2] >> 16);
|
||||
Data = Param[3];
|
||||
|
||||
switch (Event) {
|
||||
|
||||
case EVENT_IO_TRAP:
|
||||
// If it is an I/O to the 8237 DMA controller...
|
||||
if (IO_Address == DMA1_MODE) {
|
||||
static UCHAR Mode = 0x00;
|
||||
UCHAR ByteData;
|
||||
|
||||
// and it is a I/O write...
|
||||
if (Param[1] & 2) {
|
||||
ByteData = (UCHAR)Data;
|
||||
// and the Mode is either Block or Demand...
|
||||
Mode = ByteData & MODE_MASK;
|
||||
if (Mode == MODE_DEMAND || Mode == MODE_BLOCK) {
|
||||
// then change the mode to Single
|
||||
ByteData &= ~MODE_MASK;
|
||||
ByteData |= MODE_SINGLE;
|
||||
}
|
||||
|
||||
// Re-issue the I/O (trapping is disabled since it was a ONE_SHOT)
|
||||
out_8(DMA1_MODE, ByteData);
|
||||
}
|
||||
// Re-register for the I/O trap
|
||||
Register_DMA_Fix();
|
||||
break;
|
||||
}
|
||||
|
||||
// Handle PM traps here...
|
||||
break;
|
||||
|
||||
case EVENT_IO_TIMEOUT:
|
||||
// Handle PM timeout here...
|
||||
break;
|
||||
|
||||
case EVENT_SOFTWARE_SMI:
|
||||
if (Param[1] == SYS_DMA_DRIVER) {
|
||||
// Allow the UDMA driver to see that IDE is bus master capable.
|
||||
IDE_Interface = MASTER_IDE;
|
||||
} else if (Param[1] == SYS_DMA_DRIVER+1) {
|
||||
// Prevent the UDMA driver from seeing that IDE is bus master capable.
|
||||
IDE_Interface = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case EVENT_PCI_TRAP:
|
||||
Handle_PCI_Traps((USHORT)Param[1], (USHORT)Param[2], Data);
|
||||
break;
|
||||
|
||||
case EVENT_VIRTUAL_REGISTER:
|
||||
// Extract virtual register parameters from message
|
||||
Class = (UCHAR)(Param[1] >> 8);
|
||||
Index = (UCHAR)Param[1];
|
||||
WrFlag = (UCHAR)Param[2];
|
||||
Handle_VirtualRegs(Class, Index, WrFlag, (USHORT)Data);
|
||||
break;
|
||||
|
||||
case EVENT_BLOCKIO:
|
||||
Handle_BLOCKIO(IO_Address, Data, DataSize);
|
||||
break;
|
||||
|
||||
case EVENT_TIMER:
|
||||
// Fix for attach/detach hardware bug
|
||||
if (Param[2] == USBF_HANDLE) {
|
||||
Do_OHCI_SWAPSiF();
|
||||
break;
|
||||
}
|
||||
|
||||
/*MEJ // Broadcast to all VSM's
|
||||
Param[0] = S5_STATE;
|
||||
Param[1] = CLASS_ALL;
|
||||
SYS_BROADCAST_MSG(MSG_SET_POWER_STATE, &Param[0], VSM_ANY);
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
174
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/flash.bak
vendored
Executable file
174
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/flash.bak
vendored
Executable file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//******************************************************************************
|
||||
//* Routines related to the Flash device.
|
||||
//******************************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "VSA2.H"
|
||||
#include "CHIPSET.H"
|
||||
#include "SYSMGR.H"
|
||||
#include "MDD.H"
|
||||
#include "PCI.H"
|
||||
#include "GX2.H"
|
||||
#include "LEGACY.H"
|
||||
#include "PROTOS.H"
|
||||
|
||||
// Function prototypes:
|
||||
extern void Hide_IDE_Hdr(void);
|
||||
extern void Hide_Flash_Hdr(void);
|
||||
|
||||
|
||||
// External variables:
|
||||
extern ULONG MDD_Base;
|
||||
extern USHORT Flash_Function, IDE_Function;
|
||||
extern UCHAR Flash_Allocated;
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Returns non-zero if Flash device is enabled
|
||||
//***********************************************************************
|
||||
UCHAR FlashIsEnabled(void)
|
||||
{ UCHAR Pin;
|
||||
|
||||
Pin = (UCHAR)Read_MSR_LO(MDD_Base + MSR_PIN_OPTS) & PIN_OPT_IDE;
|
||||
Pin ^= PIN_OPT_IDE;
|
||||
return Pin;
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Allocates Flash BARs
|
||||
//***********************************************************************
|
||||
void Allocate_Flash_BARs(void)
|
||||
{ ULONG MsrAddr, MsrData[2], Size;
|
||||
USHORT Bar;
|
||||
UCHAR Resource;
|
||||
static UCHAR Flash_LBARs[4] = {
|
||||
MSR_LBAR_FLSH0,
|
||||
MSR_LBAR_FLSH1,
|
||||
MSR_LBAR_FLSH2,
|
||||
MSR_LBAR_FLSH3,
|
||||
};
|
||||
|
||||
|
||||
// BARs are only to be allocated once
|
||||
if (Flash_Allocated == 0) {
|
||||
|
||||
Flash_Allocated = 1;
|
||||
// Determine type/size of PCI BAR for each Flash device
|
||||
MsrAddr = MDD_Base;
|
||||
for (Bar = BAR0; Bar <= BAR3; Bar += 4) {
|
||||
// Read the Flash LBAR
|
||||
(UCHAR)MsrAddr = Flash_LBARs[(Bar-BAR0)/4];
|
||||
Read_MSR(MsrAddr, MsrData);
|
||||
|
||||
// If LBAR size has not been programmed, then don't configure the PCI BAR
|
||||
Size = MsrData[1] & ~(MEM_IO | NOR_NAND | LBAR_EN);
|
||||
if (Size == 0x00000000) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// NAND or NOR Flash ?
|
||||
if (MsrData[1] & NOR_NAND) {
|
||||
// NAND Flash
|
||||
// Required for proper byte count calculation
|
||||
Size |= 0xFFFF0000;
|
||||
Resource = RESOURCE_IO;
|
||||
} else {
|
||||
// NOR Flash
|
||||
Size &= LBAR_MEM_MASK;
|
||||
Resource = RESOURCE_MMIO;
|
||||
}
|
||||
// Convert mask to byte count
|
||||
Size = ~Size + 1;
|
||||
// Allocate BAR
|
||||
SYS_ALLOCATE_RESOURCE(Resource, Bar, Size, DEVICE_ID_AMD_FLASH, ID_MDD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Switches between Flash and IDE headers
|
||||
//***********************************************************************
|
||||
void pascal Flash_IDE_Switch(USHORT Function, ULONG Data)
|
||||
{ ULONG PinOptions, PinMsr, FlashMsr, LBar[2], SavedLBar[2];
|
||||
|
||||
// Switch pins to Flash mode
|
||||
PinMsr = MDD_Base + MSR_PIN_OPTS;
|
||||
PinOptions = Read_MSR_LO(PinMsr);
|
||||
|
||||
if (Function == Flash_Function) {
|
||||
// Currently in Flash mode
|
||||
|
||||
// Switching to IDE mode ?
|
||||
if (Data == 0xBEEFDEAD) {
|
||||
|
||||
// Hide the Flash header
|
||||
Hide_Flash_Hdr();
|
||||
|
||||
// Switch pins to IDE mode
|
||||
PinOptions |= PIN_OPT_IDE;
|
||||
Write_MSR_LO(PinMsr, PinOptions);
|
||||
|
||||
// Disconnect the ROM from the DMA pins
|
||||
in_8(0x3F6);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// Currently in IDE mode
|
||||
|
||||
// Switching to Flash mode ?
|
||||
if (Data == 0xDEADBEEF) {
|
||||
|
||||
// Hide the IDE header
|
||||
Hide_IDE_Hdr();
|
||||
|
||||
// Allocate Flash BARs
|
||||
Allocate_Flash_BARs();
|
||||
|
||||
// Enable Flash mode
|
||||
PinOptions &= ~PIN_OPT_IDE;
|
||||
Write_MSR_LO(PinMsr, PinOptions);
|
||||
|
||||
// Handle Canary circuit
|
||||
|
||||
// Set CS1# to respond to I/O address 22h
|
||||
FlashMsr = MDD_Base + MSR_LBAR_FLSH1;
|
||||
Read_MSR(FlashMsr, SavedLBar);
|
||||
LBar[0] = 0x00000022;
|
||||
LBar[1] = 0x0000FFF0 | LBAR_EN;
|
||||
Write_MSR(FlashMsr, LBar);
|
||||
|
||||
// Turn Canary circuit on
|
||||
in_8(0x22);
|
||||
|
||||
// Restore CS1 LBAR
|
||||
Write_MSR(FlashMsr, SavedLBar);
|
||||
}
|
||||
}
|
||||
}
|
||||
174
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/flash.c
vendored
Executable file
174
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/flash.c
vendored
Executable file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//******************************************************************************
|
||||
//* Routines related to the Flash device.
|
||||
//******************************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "VSA2.H"
|
||||
#include "CHIPSET.H"
|
||||
#include "SYSMGR.H"
|
||||
#include "MDD.H"
|
||||
#include "PCI.H"
|
||||
#include "GX2.H"
|
||||
#include "LEGACY.H"
|
||||
#include "PROTOS.H"
|
||||
|
||||
// Function prototypes:
|
||||
extern void Hide_IDE_Hdr(void);
|
||||
extern void Hide_Flash_Hdr(void);
|
||||
|
||||
|
||||
// External variables:
|
||||
extern ULONG MDD_Base;
|
||||
extern USHORT Flash_Function, IDE_Function;
|
||||
extern UCHAR Flash_Allocated;
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Returns non-zero if Flash device is enabled
|
||||
//***********************************************************************
|
||||
UCHAR FlashIsEnabled(void)
|
||||
{ UCHAR Pin;
|
||||
|
||||
Pin = (UCHAR)Read_MSR_LO(MDD_Base + MSR_PIN_OPTS) & PIN_OPT_IDE;
|
||||
Pin ^= PIN_OPT_IDE;
|
||||
return Pin;
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Allocates Flash BARs
|
||||
//***********************************************************************
|
||||
void Allocate_Flash_BARs(void)
|
||||
{ ULONG MsrAddr, MsrData[2], Size;
|
||||
USHORT Bar;
|
||||
UCHAR Resource;
|
||||
static UCHAR Flash_LBARs[4] = {
|
||||
MSR_LBAR_FLSH0,
|
||||
MSR_LBAR_FLSH1,
|
||||
MSR_LBAR_FLSH2,
|
||||
MSR_LBAR_FLSH3,
|
||||
};
|
||||
|
||||
|
||||
// BARs are only to be allocated once
|
||||
if (Flash_Allocated == 0) {
|
||||
|
||||
Flash_Allocated = 1;
|
||||
// Determine type/size of PCI BAR for each Flash device
|
||||
MsrAddr = MDD_Base;
|
||||
for (Bar = BAR0; Bar <= BAR3; Bar += 4) {
|
||||
// Read the Flash LBAR
|
||||
(UCHAR)MsrAddr = Flash_LBARs[(Bar-BAR0)/4];
|
||||
Read_MSR(MsrAddr, MsrData);
|
||||
|
||||
// If LBAR size has not been programmed, then don't configure the PCI BAR
|
||||
Size = MsrData[1] & ~(MEM_IO | NOR_NAND | LBAR_EN);
|
||||
if (Size == 0x00000000) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// MMIO or IO resource
|
||||
if (MsrData[1] & MEM_IO ) {
|
||||
// MMIO mode
|
||||
Size &= LBAR_MEM_MASK;
|
||||
Resource = RESOURCE_MMIO;
|
||||
} else {
|
||||
// IO mode
|
||||
// Required for proper byte count calculation
|
||||
Size |= 0xFFFF0000;
|
||||
Resource = RESOURCE_IO;
|
||||
}
|
||||
// Convert mask to byte count
|
||||
Size = ~Size + 1;
|
||||
// Allocate BAR
|
||||
SYS_ALLOCATE_RESOURCE(Resource, Bar, Size, DEVICE_ID_AMD_FLASH, ID_MDD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Switches between Flash and IDE headers
|
||||
//***********************************************************************
|
||||
void pascal Flash_IDE_Switch(USHORT Function, ULONG Data)
|
||||
{ ULONG PinOptions, PinMsr, FlashMsr, LBar[2], SavedLBar[2];
|
||||
|
||||
// Switch pins to Flash mode
|
||||
PinMsr = MDD_Base + MSR_PIN_OPTS;
|
||||
PinOptions = Read_MSR_LO(PinMsr);
|
||||
|
||||
if (Function == Flash_Function) {
|
||||
// Currently in Flash mode
|
||||
|
||||
// Switching to IDE mode ?
|
||||
if (Data == 0xBEEFDEAD) {
|
||||
|
||||
// Hide the Flash header
|
||||
Hide_Flash_Hdr();
|
||||
|
||||
// Switch pins to IDE mode
|
||||
PinOptions |= PIN_OPT_IDE;
|
||||
Write_MSR_LO(PinMsr, PinOptions);
|
||||
|
||||
// Disconnect the ROM from the DMA pins
|
||||
in_8(0x3F6);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// Currently in IDE mode
|
||||
|
||||
// Switching to Flash mode ?
|
||||
if (Data == 0xDEADBEEF) {
|
||||
|
||||
// Hide the IDE header
|
||||
Hide_IDE_Hdr();
|
||||
|
||||
// Allocate Flash BARs
|
||||
Allocate_Flash_BARs();
|
||||
|
||||
// Enable Flash mode
|
||||
PinOptions &= ~PIN_OPT_IDE;
|
||||
Write_MSR_LO(PinMsr, PinOptions);
|
||||
|
||||
// Handle Canary circuit
|
||||
|
||||
// Set CS1# to respond to I/O address 22h
|
||||
FlashMsr = MDD_Base + MSR_LBAR_FLSH1;
|
||||
Read_MSR(FlashMsr, SavedLBar);
|
||||
LBar[0] = 0x00000022;
|
||||
LBar[1] = 0x0000FFF0 | LBAR_EN;
|
||||
Write_MSR(FlashMsr, LBar);
|
||||
|
||||
// Turn Canary circuit on
|
||||
in_8(0x22);
|
||||
|
||||
// Restore CS1 LBAR
|
||||
Write_MSR(FlashMsr, SavedLBar);
|
||||
}
|
||||
}
|
||||
}
|
||||
53
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/header.asm
vendored
Executable file
53
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/header.asm
vendored
Executable file
@@ -0,0 +1,53 @@
|
||||
;
|
||||
; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
;
|
||||
; This library is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU Lesser General Public License as
|
||||
; published by the Free Software Foundation; either version 2.1 of the
|
||||
; License, or (at your option) any later version.
|
||||
;
|
||||
; This code is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
; Lesser General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU Lesser General
|
||||
; Public License along with this library; if not, write to the
|
||||
; Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
; Boston, MA 02111-1307 USA
|
||||
;
|
||||
|
||||
;* Function: *
|
||||
;* This file contains the VSM header for the legacy VSM
|
||||
|
||||
|
||||
.model tiny,c
|
||||
.586
|
||||
.CODE
|
||||
|
||||
include VSA2.INC
|
||||
|
||||
externdef edata:proc
|
||||
externdef _end:proc
|
||||
externdef VSM_msg_loop:proc
|
||||
public VSM_Hdr
|
||||
|
||||
|
||||
|
||||
VSM_Hdr:
|
||||
dd VSM_SIGNATURE ; VSM signature
|
||||
db VSM_LEGACY ; VSM type
|
||||
db 0FFh ; Any CPU
|
||||
dw 0FFFFh ; Any Chipset
|
||||
dw 0106h ; VSM version
|
||||
dd OFFSET edata ; Size of VSM module
|
||||
dw OFFSET VSM_msg_loop ; EntryPoint
|
||||
dd OFFSET _end ; DS Limit
|
||||
dw 0000h ; Requirements
|
||||
dw VSA_VERSION ; VSA version
|
||||
|
||||
db sizeof(VSM_Header) - ($-VSM_Hdr) dup (0)
|
||||
|
||||
|
||||
END
|
||||
|
||||
158
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/ide.c
vendored
Executable file
158
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/ide.c
vendored
Executable file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//* Function: *
|
||||
//* This file contains code for power-managing the ATA drives.
|
||||
|
||||
|
||||
#include "vsa2.h"
|
||||
#include "isa.h"
|
||||
|
||||
extern UCHAR pascal in_8(USHORT);
|
||||
extern void pascal out_8(USHORT, UCHAR);
|
||||
|
||||
|
||||
// NOTE: Win95 touches CD-ROMs every 4.2 seconds for AutoDetect
|
||||
|
||||
#define HDD0 1
|
||||
#define HDD1 2
|
||||
#define HDD2 4
|
||||
#define HDD3 8
|
||||
|
||||
#define IDE_BSY 0x80 // Status register
|
||||
#define IDE_RDY 0x40 // Status register
|
||||
#define IDE_MSK IDE_BSY+IDE_RDY
|
||||
|
||||
#define IDE_CMD_SPINDOWN 0xE0 // Spindown Command
|
||||
#define IDE_CMD_SPINUP 0xE1 // Spinup Command
|
||||
#define IDE_CMD_CHECK_POWER_MODE 0xE5 // Get Power Management State Command
|
||||
#define IDE_CMD_SLEEP 0xE6
|
||||
|
||||
UCHAR DrivesPresent = 0, DrvHd;
|
||||
|
||||
|
||||
//*************************************************************************
|
||||
// Issues specified command to one or more drive units
|
||||
//*************************************************************************
|
||||
void pascal IDE_Command(UCHAR DriveUnit, UCHAR Command)
|
||||
{ UCHAR DriveSelect, Mask = 1;
|
||||
USHORT IO_Port;
|
||||
ULONG Timeout;
|
||||
|
||||
// Only spindown drives that are present
|
||||
DriveUnit &= DrivesPresent;
|
||||
|
||||
while (DriveUnit) {
|
||||
|
||||
// Is drive present ?
|
||||
if (DriveUnit & Mask) {
|
||||
|
||||
// Yes, determine I/O port
|
||||
IO_Port = PRIMARY_IDE;
|
||||
if (Mask & (HDD2+HDD3)) {
|
||||
IO_Port = SECONDARY_IDE;
|
||||
}
|
||||
|
||||
// Determine master/slave
|
||||
DriveSelect = 0xA0; // Master drive
|
||||
if (Mask & (HDD1+HDD3)) {
|
||||
DriveSelect = 0xB0; // Slave drive
|
||||
}
|
||||
|
||||
// Wait for IDE channel READY
|
||||
for (Timeout=0xFFFFF; Timeout; Timeout--) {
|
||||
if ((IDE_MSK & in_8(IO_Port+1)) == IDE_RDY)
|
||||
break;
|
||||
}
|
||||
|
||||
DrvHd = in_8(IO_Port); // Save Drive/Head register
|
||||
|
||||
out_8(IO_Port, DriveSelect); // Select drive to spin down
|
||||
out_8(IO_Port+1, Command); // Issue command to the the drive
|
||||
|
||||
for (Timeout=0xFFFFF; Timeout; Timeout--) {
|
||||
if (!(in_8(IO_Port+1) & IDE_BSY))
|
||||
break;
|
||||
}
|
||||
|
||||
in_8(IO_Port+1); // Clear IRQ
|
||||
|
||||
DriveUnit &= ~Mask;
|
||||
}
|
||||
|
||||
// Next drive
|
||||
Mask <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
// Spins down specified drive(s)
|
||||
//*************************************************************************
|
||||
void pascal SpinDownHardDrive(UCHAR DriveUnit)
|
||||
{
|
||||
IDE_Command(DriveUnit, IDE_CMD_SPINDOWN);
|
||||
}
|
||||
|
||||
|
||||
//*************************************************************************
|
||||
// Puts drive(s) into sleep mode
|
||||
//*************************************************************************
|
||||
void pascal DriveSleep(UCHAR DriveUnit)
|
||||
{
|
||||
// IDE_Command(DriveUnit, IDE_CMD_SLEEP);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
// Determines what hard drives are present
|
||||
// Input: I/O address of IDE Drive/Head register
|
||||
//*************************************************************************
|
||||
UCHAR Check_IDE_Channel(USHORT IDE_DrvHd)
|
||||
{ UCHAR HDD_Status, DrivesPresent=0;
|
||||
|
||||
DrvHd = in_8(IDE_DrvHd); // Save Drive/Head register
|
||||
|
||||
out_8(IDE_DrvHd, (UCHAR)(DrvHd & ~0x10)); // Select master drive
|
||||
HDD_Status = in_8(IDE_DrvHd);
|
||||
if (in_8(IDE_DrvHd+1) == 0x50) { // Is drive present ?
|
||||
DrivesPresent |= HDD0;
|
||||
|
||||
out_8(IDE_DrvHd, (UCHAR)(DrvHd | 0x10)); // Select slave drive
|
||||
HDD_Status = in_8(IDE_DrvHd);
|
||||
if (in_8(IDE_DrvHd+1) == 0x50) { // Is drive present ?
|
||||
DrivesPresent |= HDD1;
|
||||
}
|
||||
}
|
||||
|
||||
// Restore Drive/Head register
|
||||
out_8(IDE_DrvHd, DrvHd);
|
||||
return DrivesPresent;
|
||||
}
|
||||
|
||||
|
||||
//*************************************************************************
|
||||
// Determines what hard drives are present
|
||||
// Input: I/O address of IDE Drive/Head register
|
||||
//*************************************************************************
|
||||
UCHAR GetDrivesPresent(void)
|
||||
{
|
||||
DrivesPresent = Check_IDE_Channel(PRIMARY_IDE);
|
||||
DrivesPresent |= Check_IDE_Channel(SECONDARY_IDE) << 2;
|
||||
|
||||
return DrivesPresent;
|
||||
}
|
||||
83
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/init.c
vendored
Executable file
83
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/init.c
vendored
Executable file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//*****************************************************************************
|
||||
//* This file performs Legacy VSM initialization.
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
#include "vsa2.h"
|
||||
#include "chipset.h"
|
||||
#include "sysmgr.h"
|
||||
#include "vr.h"
|
||||
|
||||
|
||||
|
||||
// External variables:
|
||||
extern Hardware SystemInfo;
|
||||
|
||||
// Function prototypes:
|
||||
extern void pascal out_8(USHORT, UCHAR);
|
||||
extern void CS5536_Early_Init(void);
|
||||
extern void CS5536_Late_Init(void);
|
||||
extern void Init_OHCI_SWAPSiF(UCHAR);
|
||||
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Performs early initialization
|
||||
//***********************************************************************
|
||||
void Legacy_Early_Init(void)
|
||||
{
|
||||
|
||||
// Register for VRC_SYSINFO virtual registers
|
||||
SYS_REGISTER_EVENT(EVENT_VIRTUAL_REGISTER, VRC_SYSINFO, 0, NORMAL_PRIORITY);
|
||||
|
||||
|
||||
switch (SystemInfo.Chipset_ID) {
|
||||
|
||||
case DEVICE_ID_5536:
|
||||
CS5536_Early_Init();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Performs End-of-POST initialization
|
||||
//***********************************************************************
|
||||
void Legacy_Late_Init(void)
|
||||
{
|
||||
|
||||
switch (SystemInfo.Chipset_ID) {
|
||||
|
||||
case DEVICE_ID_5536:
|
||||
CS5536_Late_Init();
|
||||
break;
|
||||
}
|
||||
|
||||
// Initialize A20 to '1MB wrap'
|
||||
// SDG - removed for OLPC
|
||||
// out_8(0x92, 0);
|
||||
|
||||
}
|
||||
92
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/legacy.c
vendored
Executable file
92
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/legacy.c
vendored
Executable file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//* Function: *
|
||||
//* This file implements miscellaneous VSA functionality: *
|
||||
//* *
|
||||
//* All chipsets: *
|
||||
//* 1) SYSINFO virtual registers *
|
||||
//* *
|
||||
//* CS5536 : *
|
||||
//* 1) Emulation of CS5530 PCI interrupt steering registers. *
|
||||
//* 2) Flash-IDE switching *
|
||||
//* 3) Power management *
|
||||
|
||||
|
||||
#include "vsa2.h"
|
||||
#include "chipset.h"
|
||||
#include "protos.h"
|
||||
|
||||
// Function prototypes
|
||||
extern void Legacy_Early_Init(void);
|
||||
extern void Legacy_Late_Init(void);
|
||||
extern void Handle_Events(ULONG *);
|
||||
|
||||
|
||||
// Local variables
|
||||
Hardware SystemInfo;
|
||||
ULONG ChipsetBase;
|
||||
ULONG Param[MAX_MSG_PARAM];
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Message handler for the Legacy VSM
|
||||
//***********************************************************************
|
||||
void VSM_msg_loop()
|
||||
{ MSG Msg;
|
||||
|
||||
// Get information about the system I'm executing on.
|
||||
SYS_GET_SYSTEM_INFO(&SystemInfo);
|
||||
ChipsetBase = SystemInfo.Chipset_Base;
|
||||
|
||||
//
|
||||
// Message Handling Loop
|
||||
//
|
||||
do {
|
||||
|
||||
// Get the next message
|
||||
Msg = SYS_GET_NEXT_MSG(&Param);
|
||||
|
||||
switch (Msg) {
|
||||
|
||||
case MSG_INITIALIZE:
|
||||
switch (Param[0]) {
|
||||
case EARLY_INIT:
|
||||
Legacy_Early_Init();
|
||||
break;
|
||||
|
||||
case END_OF_POST_INIT:
|
||||
Legacy_Late_Init();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case MSG_EVENT:
|
||||
Handle_Events(Param);
|
||||
break;
|
||||
|
||||
case MSG_SET_POWER_MODE:
|
||||
case MSG_SET_POWER_STATE:
|
||||
case MSG_SAVE_STATE:
|
||||
case MSG_RESTORE_STATE:
|
||||
break;
|
||||
} // end switch(Msg)
|
||||
} while (1);
|
||||
}
|
||||
37
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/legacy.h
vendored
Executable file
37
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/legacy.h
vendored
Executable file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#define SYS_DMA_DRIVER 0x5006
|
||||
#define MASTER_IDE 0x8000
|
||||
|
||||
|
||||
|
||||
// Default GPIOs for PCI interrupts on the Hawk reference design
|
||||
#define INTA_PIN 0
|
||||
#define INTB_PIN 7
|
||||
#define INTC_PIN 12
|
||||
#define INTD_PIN 13
|
||||
|
||||
|
||||
|
||||
#define USBF_PERIOD 2000 // 2 seconds
|
||||
#define USBF_HANDLE 0x3333
|
||||
|
||||
|
||||
|
||||
165
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/makefile
vendored
Executable file
165
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/makefile
vendored
Executable file
@@ -0,0 +1,165 @@
|
||||
#
|
||||
# Copyright (c) 2006 Advanced Micro Devices,Inc. ("AMD").
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation; either version 2.1 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General
|
||||
# Public License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
# Boston, MA 02111-1307 USA
|
||||
#
|
||||
#
|
||||
######################################################################
|
||||
#
|
||||
# Init variables
|
||||
#
|
||||
######################################################################
|
||||
.SUFFIXES: .asm .c .h .inc .map .obj .mac
|
||||
|
||||
!ifndef VSA2ROOT
|
||||
VSA2ROOT = ..
|
||||
!endif
|
||||
|
||||
BUILD_DIR = $(VSA2ROOT)\build
|
||||
OBJECT = obj
|
||||
!include $(BUILD_DIR)\setvars.mak
|
||||
|
||||
INCLUDE = $(OBJECT);$(INCLUDE)
|
||||
|
||||
VSMNAME = legacy
|
||||
|
||||
|
||||
######################################################################
|
||||
#
|
||||
# Build Macros
|
||||
#
|
||||
######################################################################
|
||||
|
||||
LEGACY_ASM_OBJS = \
|
||||
$(OBJECT)\header.obj \
|
||||
$(OBJECT)\msr.obj \
|
||||
|
||||
LEGACY_C_OBJS = \
|
||||
$(OBJECT)\legacy.obj \
|
||||
$(OBJECT)\init.obj \
|
||||
$(OBJECT)\events.obj \
|
||||
$(OBJECT)\flash.obj \
|
||||
$(OBJECT)\cs5536.obj \
|
||||
$(OBJECT)\ide.obj \
|
||||
$(OBJECT)\blockio.obj \
|
||||
$(OBJECT)\uarts.obj \
|
||||
$(OBJECT)\virtregs.obj \
|
||||
$(OBJECT)\swapsif.obj \
|
||||
$(OBJECT)\sysinfo.obj \
|
||||
|
||||
LEGACY_LNK_OBJS = \
|
||||
header.obj \
|
||||
legacy.obj \
|
||||
msr.obj \
|
||||
init.obj \
|
||||
events.obj \
|
||||
flash.obj \
|
||||
cs5536.obj \
|
||||
ide.obj \
|
||||
blockio.obj \
|
||||
uarts.obj \
|
||||
virtregs.obj \
|
||||
swapsif.obj \
|
||||
sysinfo.obj \
|
||||
|
||||
|
||||
LEGACY_OBJS = $(LEGACY_ASM_OBJS) $(LEGACY_C_OBJS)
|
||||
LEGACY_VSM = legacy.vsm
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# Targets
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
all: $(OBJECT) setenv legacy.vsm
|
||||
$(COPY) $(LEGACY_VSM) $(BUILDOBJ)
|
||||
|
||||
legacy.vsm: $(LEGACY_OBJS)
|
||||
cd $(OBJECT)
|
||||
$(LN) $(LOPTS_VSM) $(LEGACY_LNK_OBJS), ..\$(LEGACY_VSM),, ..\..\build\obj\$(TOOL_LIB);
|
||||
cd ..
|
||||
|
||||
#This and only this clean target must exist as it is called by cleanall
|
||||
#cleanall and cleanlocal are defined in rules.mak
|
||||
|
||||
clean: cleanlocal cleanlib
|
||||
|
||||
$(OBJECT):
|
||||
-@md $(OBJECT)
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# Dependencies
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
$(LEGACY_ASM_OBJS): $(MAKEDIR)\makefile \
|
||||
$(OBJECT)\sysmgr.inc \
|
||||
$(OBJECT)\smimac.mac \
|
||||
$(OBJECT)\vsa2.inc \
|
||||
$(OBJECT)\isa.inc \
|
||||
$(OBJECT)\chipset.inc \
|
||||
$(OBJECT)\vr.inc \
|
||||
$(OBJECT)\pci.inc \
|
||||
$(OBJECT)\acpi.inc \
|
||||
$(OBJECT)\gx2.inc \
|
||||
$(OBJECT)\cs5536.inc \
|
||||
$(OBJECT)\pci.inc \
|
||||
$(OBJECT)\mdd.inc \
|
||||
|
||||
$(LEGACY_C_OBJS): $(MAKEDIR)\makefile \
|
||||
$(BUILD_DIR)\obj\$(TOOL_LIB) \
|
||||
$(OBJECT)\sysmgr.h \
|
||||
$(OBJECT)\vsa2.h \
|
||||
$(OBJECT)\isa.h \
|
||||
$(OBJECT)\chipset.h \
|
||||
$(OBJECT)\vr.h \
|
||||
$(OBJECT)\pci.h \
|
||||
$(OBJECT)\legacy.h \
|
||||
$(OBJECT)\mapper.h \
|
||||
$(OBJECT)\protos.h \
|
||||
$(OBJECT)\mdd.h \
|
||||
$(OBJECT)\acpi.h \
|
||||
$(OBJECT)\gx2.h \
|
||||
$(OBJECT)\cs5536.h \
|
||||
|
||||
######################################################################
|
||||
#
|
||||
# Common Targets
|
||||
#
|
||||
######################################################################
|
||||
# include common targets and inference rules
|
||||
!include $(BUILD_DIR)\rules.mak
|
||||
|
||||
######################################################################
|
||||
#
|
||||
# Inference Rules
|
||||
#
|
||||
######################################################################
|
||||
# Override common inference rules here
|
||||
|
||||
{$(INC_DIR)}.h{$(OBJECT)}.inc:
|
||||
$(H2) /Fa$(OBJECT)\$(@F) /nologo /Zni /C $<
|
||||
|
||||
{$(INC_DIR)\$(CPU)}.h{$(OBJECT)}.inc:
|
||||
$(H2) /Fa$(OBJECT)\$(@F) /nologo /Zni /C $<
|
||||
|
||||
{$(SYSMGR_SRC)}.h{$(OBJECT)}.inc:
|
||||
$(H2) /Fa$(OBJECT)\$(@F) /nologo /Zns /C $<
|
||||
|
||||
{$(SYSMGR_SRC)\$(CPU)}.h{$(OBJECT)}.inc:
|
||||
$(H2) /Fa$(OBJECT)\$(@F) /nologo /Zns /C $<
|
||||
97
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/msr.asm
vendored
Executable file
97
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/msr.asm
vendored
Executable file
@@ -0,0 +1,97 @@
|
||||
;
|
||||
; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
;
|
||||
; This library is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU Lesser General Public License as
|
||||
; published by the Free Software Foundation; either version 2.1 of the
|
||||
; License, or (at your option) any later version.
|
||||
;
|
||||
; This code is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
; Lesser General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU Lesser General
|
||||
; Public License along with this library; if not, write to the
|
||||
; Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
; Boston, MA 02111-1307 USA
|
||||
;
|
||||
|
||||
.model tiny,c
|
||||
.586p
|
||||
.CODE
|
||||
|
||||
;***********************************************************************
|
||||
; Returns the low DWORD of an MSR.
|
||||
; Usage: LowMsrValue = Read_MSR_LO(Msr_Address);
|
||||
;***********************************************************************
|
||||
Read_MSR_LO proc pascal \
|
||||
Msr: dword
|
||||
|
||||
mov ecx, [Msr]
|
||||
rdmsr
|
||||
mov edx, eax
|
||||
shr edx, 16
|
||||
ret
|
||||
|
||||
Read_MSR_LO endp
|
||||
|
||||
;***********************************************************************
|
||||
; Writes the low DWORD of an MSR. The high DWORD is preserved.
|
||||
; Usage: Write_MSR_LO(Msr_Address, Data);
|
||||
;***********************************************************************
|
||||
Write_MSR_LO proc pascal \
|
||||
Msr: dword, \
|
||||
Data: dword
|
||||
|
||||
mov ecx, [Msr]
|
||||
rdmsr ; Get high 32 bits
|
||||
mov eax, [Data]
|
||||
wrmsr
|
||||
ret
|
||||
|
||||
Write_MSR_LO endp
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Returns an MSR value in a buffer.
|
||||
; Usage: Read_MSR(ULONG Msr, ULONG * Buffer);
|
||||
;***********************************************************************
|
||||
Read_MSR proc pascal \
|
||||
Msr: dword, \
|
||||
Buffer: PTR
|
||||
|
||||
mov ecx, [Msr]
|
||||
rdmsr
|
||||
|
||||
mov bx, [Buffer]
|
||||
mov [bx+0], eax
|
||||
mov [bx+4], edx
|
||||
ret
|
||||
|
||||
Read_MSR endp
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Writes an MSR.
|
||||
; Usage: Write_MSR(ULONG Msr, ULONG * Buffer);
|
||||
;***********************************************************************
|
||||
Write_MSR proc pascal \
|
||||
Msr: dword, \
|
||||
Buffer: PTR
|
||||
|
||||
mov ecx, [Msr]
|
||||
mov bx, [Buffer]
|
||||
mov eax, [bx+0]
|
||||
mov edx, [bx+4]
|
||||
wrmsr
|
||||
ret
|
||||
|
||||
Write_MSR endp
|
||||
|
||||
|
||||
END
|
||||
|
||||
|
||||
|
||||
130
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/swapsif.c
vendored
Executable file
130
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/swapsif.c
vendored
Executable file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//******************************************************************************
|
||||
//* This file contains SWAPSiFs
|
||||
//******************************************************************************
|
||||
|
||||
|
||||
|
||||
#include "vsa2.h"
|
||||
#include "protos.h"
|
||||
#include "chipset.h"
|
||||
#include "legacy.h"
|
||||
#include "pci.h"
|
||||
|
||||
|
||||
// External variables
|
||||
extern Hardware SystemInfo;
|
||||
|
||||
// Local variables
|
||||
ULONG OHCI_Address[2];
|
||||
UCHAR WinCE_Flag = 1;
|
||||
|
||||
|
||||
//*****************************************************************
|
||||
// Fixes 118.438 - OHCI May Not Recognize Device Attach/Removal
|
||||
//*****************************************************************
|
||||
void pascal OHCI_SWAPSiF(UCHAR Flag)
|
||||
{ PRIORITY Priority = 0;
|
||||
static PRIORITY LastPriority = 0x5555;
|
||||
|
||||
switch (SystemInfo.Chipset_ID) {
|
||||
case DEVICE_ID_5536:
|
||||
break;
|
||||
|
||||
default:
|
||||
if (Flag == 0) {
|
||||
Priority = UNREGISTER_PRIORITY;
|
||||
}
|
||||
if (Priority != LastPriority) {
|
||||
LastPriority = Priority;
|
||||
SYS_REGISTER_EVENT(EVENT_TIMER, USBF_PERIOD, USBF_HANDLE, Priority);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define HcControl 0x0004
|
||||
#define HCFS 0x000000C0L
|
||||
#define USB_RESET 0x00000000L
|
||||
#define USB_RESUME 0x00000040L
|
||||
#define USB_OPERATIONAL 0x00000080L
|
||||
#define USB_SUSPEND 0x000000C0L
|
||||
#define IR 0x00000100L
|
||||
#define HceControl 0x0100
|
||||
|
||||
//***********************************************************************
|
||||
void Do_OHCI_SWAPSif(void)
|
||||
{ ULONG i, PCI_Addr, HC_Addr, OldValue;
|
||||
|
||||
for (i=0; i<=1; i++) {
|
||||
|
||||
// Get base of Host Controller's registers
|
||||
HC_Addr = OHCI_Address[i];
|
||||
|
||||
// Ignore this tick if BAR is being sized
|
||||
if (HC_Addr == 0xFFFFF000 || HC_Addr == 0x00000000) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if Host Controller registers are accessible
|
||||
PCI_Addr = 0x80007C00L + (i<<8);
|
||||
if (READ_PCI_BYTE(PCI_Addr + COMMAND) & MEM_SPACE) {
|
||||
|
||||
OldValue = READ_MEMORY(HC_Addr + HcControl);
|
||||
|
||||
// WinCE doesn't perform a valid Ownership Change.
|
||||
// It disables MIE then performs the Ownership Change request.
|
||||
// This code detects that situation and turns emulation off.
|
||||
// Otherwise, neither the USB keyboard or PS/2 keyboard works.
|
||||
if ((i == 0) && (OldValue & IR) == 0 && WinCE_Flag) {
|
||||
WinCE_Flag = 0; // Only do this once
|
||||
WRITE_MEMORY(HC_Addr + HceControl, 0x00);
|
||||
}
|
||||
|
||||
// Transition through Operational to clear possible attach/detach glitch
|
||||
if ((OldValue & USB_SUSPEND) == USB_SUSPEND) {
|
||||
WRITE_MEMORY(HC_Addr + HcControl, USB_OPERATIONAL);
|
||||
WRITE_MEMORY(HC_Addr + HcControl, OldValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Initialization for the OHCI attach/detach hardware bug
|
||||
//***********************************************************************
|
||||
void Init_OHCI_SWAPSiF(UCHAR InitStage)
|
||||
{
|
||||
switch (InitStage) {
|
||||
case EARLY_INIT:
|
||||
// Trap writes to SB F4 & F5 BAR0 in order keep current OHCI BAR values
|
||||
SYS_REGISTER_EVENT(EVENT_PCI_TRAP, 0x7C10, WRITES_ONLY | 0x100, 0);
|
||||
break;
|
||||
|
||||
case END_OF_POST_INIT:
|
||||
// Turn on the timer
|
||||
OHCI_SWAPSiF(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
78
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/sysinfo.c
vendored
Executable file
78
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/sysinfo.c
vendored
Executable file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//* Function: *
|
||||
//* This file implementes the SYSINFO virtual registers.
|
||||
|
||||
#include "vsa2.h"
|
||||
#include "vr.h"
|
||||
|
||||
void pascal Hex_8(UCHAR);
|
||||
void pascal Hex_16(USHORT);
|
||||
void pascal Hex_32(ULONG);
|
||||
|
||||
|
||||
// Local variables
|
||||
extern Hardware SystemInfo;
|
||||
|
||||
|
||||
void Handle_SysInfo_VR(UCHAR i)
|
||||
{ USHORT Data;
|
||||
|
||||
|
||||
switch (i) {
|
||||
case VRC_SI_VERSION:
|
||||
Data = 0x100; // Version 1.0
|
||||
break;
|
||||
|
||||
case VRC_SI_CPU_MHZ:
|
||||
Data = SystemInfo.CPU_MHz;
|
||||
break;
|
||||
|
||||
case VRC_SI_CHIPSET_BASE_LOW:
|
||||
Data = (USHORT) SystemInfo.Chipset_Base;
|
||||
break;
|
||||
|
||||
case VRC_SI_CHIPSET_BASE_HI:
|
||||
Data = (USHORT) (SystemInfo.Chipset_Base >> 16);
|
||||
break;
|
||||
|
||||
case VRC_SI_CHIPSET_ID:
|
||||
Data = SystemInfo.Chipset_ID;
|
||||
break;
|
||||
|
||||
case VRC_SI_CHIPSET_REV:
|
||||
Data = SystemInfo.Chipset_Rev;
|
||||
break;
|
||||
|
||||
case VRC_SI_CPU_ID:
|
||||
Data = SystemInfo.CPU_ID;
|
||||
break;
|
||||
|
||||
case VRC_SI_CPU_REV:
|
||||
Data = SystemInfo.CPU_Revision;
|
||||
break;
|
||||
|
||||
default:
|
||||
Data = 0xFFFF;
|
||||
break;
|
||||
}
|
||||
|
||||
SET_AX(Data);
|
||||
}
|
||||
210
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/uarts.c
vendored
Executable file
210
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/uarts.c
vendored
Executable file
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
//* Function: *
|
||||
//* This file contains routines specific to the CS5536 UARTs.
|
||||
|
||||
#include "vsa2.h"
|
||||
#include "vr.h"
|
||||
#include "mdd.h"
|
||||
#include "protos.h"
|
||||
|
||||
|
||||
// Function prototypes:
|
||||
void Handle_5536_UART(UCHAR, UCHAR, USHORT);
|
||||
USHORT Get_5536_UART(USHORT);
|
||||
void Prog_5536_UART(USHORT, USHORT);
|
||||
|
||||
// External variables:
|
||||
extern ULONG MDD_Base;
|
||||
extern USHORT gpio_base;
|
||||
|
||||
|
||||
// 5536 implements two UART's. The resources for both are controlled
|
||||
// by MDD MSR_LEG_IO, MSR_IRQM_YHIGH.
|
||||
// IRQ Enable, Clock freeze and soft reset controlled by MSR_UARTx_CONF
|
||||
//
|
||||
// One Virtual Register is implemented for each UART.
|
||||
// bit15 = 1 Soft-Reset
|
||||
// bits[14:13] = unused
|
||||
// bit12 = 1 UART GPIO's have been setup by BIOS, RO bit
|
||||
// bit11 = 1 enable UART I/O space extended register banks
|
||||
// bit10 = 1 enable test mode
|
||||
// bit9 = 1 Freeze device clocks, IRQ still enabled
|
||||
// bit8 = 1 enable interrupt & functionality, doesn't affect I/O
|
||||
// bits[7:4] = IRQ number
|
||||
// bit3 = unused
|
||||
// bit2 = 1 I/O decode enabled
|
||||
// bits[1:0] = I/O location
|
||||
//
|
||||
void Handle_5536_UART(UCHAR vrIndex, UCHAR wFlag, USHORT wData)
|
||||
{
|
||||
if (wFlag) { // write
|
||||
Prog_5536_UART(vrIndex, wData);
|
||||
} else {
|
||||
SYS_RETURN_RESULT((ULONG)Get_5536_UART(vrIndex));
|
||||
}
|
||||
}
|
||||
|
||||
USHORT Get_5536_UART(USHORT vri)
|
||||
{
|
||||
ULONG d;
|
||||
USHORT u;
|
||||
|
||||
u = 0;
|
||||
|
||||
(USHORT)MDD_Base = MSR_LEG_IO;
|
||||
d = Read_MSR_LO(MDD_Base);
|
||||
switch (vri) {
|
||||
case VRC_CS_UART1:
|
||||
d >>= UART1_SHIFT;
|
||||
break;
|
||||
|
||||
case VRC_CS_UART2:
|
||||
d >>= UART2_SHIFT;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
u = (USHORT)d & UART_MASK;
|
||||
|
||||
// get the IRQ number
|
||||
(USHORT)MDD_Base = MSR_IRQM_YHIGH;
|
||||
d = Read_MSR_LO(MDD_Base);
|
||||
if (vri == VRC_CS_UART1) {
|
||||
d >>= 20;
|
||||
} else {
|
||||
d >>= 24;
|
||||
}
|
||||
u |= ((USHORT)d & 0x00F0);
|
||||
|
||||
// fill in the other flags from MSR_UARTx_CONF
|
||||
if (vri == VRC_CS_UART1) {
|
||||
(USHORT)MDD_Base = MSR_UART1_CONF;
|
||||
} else {
|
||||
(USHORT)MDD_Base = MSR_UART2_CONF;
|
||||
}
|
||||
d = Read_MSR_LO(MDD_Base);
|
||||
// MSR bit0 = soft-reset -> bit15
|
||||
// MSR bit1 = deven -> bit8
|
||||
// MSR bit2 = freeze -> bit9
|
||||
// MSR bit3 = test mode -> bit10
|
||||
// MSR bit4 = upper banks -> bit11
|
||||
if ((USHORT)d & 0x0001) {
|
||||
u |= 0x8000;
|
||||
}
|
||||
d <<= 7;
|
||||
u |= ((USHORT)d & 0x0F00);
|
||||
|
||||
// check if GPIO's for this UART have been setup
|
||||
// This is used as an indicator the UART is 'hidden' from OS
|
||||
d = in_32(gpio_base + GPIO_IN_AUX1_SELECT);
|
||||
if (vri == VRC_CS_UART1) {
|
||||
// UART1 GPIO9 should be IN_AUX
|
||||
if (d & 0x0200L) {
|
||||
u |= 0x1000; // set bit12
|
||||
}
|
||||
} else {
|
||||
// UART2 GPIO3 should be IN_AUX
|
||||
if (d & 0x0008L) {
|
||||
u |= 0x1000; // set bit12
|
||||
}
|
||||
}
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
|
||||
void Prog_5536_UART(USHORT vri, USHORT vrval)
|
||||
{
|
||||
ULONG d, r;
|
||||
USHORT curval, uartmsr, shift, irqshift;
|
||||
|
||||
r = 0L;
|
||||
|
||||
// clear reserved/unused bits
|
||||
vrval &= 0x8FF7;
|
||||
|
||||
switch (vri) {
|
||||
case VRC_CS_UART1:
|
||||
uartmsr = MSR_UART1_CONF;
|
||||
shift = UART1_SHIFT;
|
||||
irqshift = 24;
|
||||
break;
|
||||
|
||||
case VRC_CS_UART2:
|
||||
uartmsr = MSR_UART2_CONF;
|
||||
shift = UART2_SHIFT;
|
||||
irqshift = 28;
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
// get current settings
|
||||
curval = Get_5536_UART(vri);
|
||||
|
||||
// change?
|
||||
if (curval ^ vrval) { // Yes
|
||||
// I/O change?
|
||||
if ((curval & 0x0007) ^ (vrval & 0x0007)) {
|
||||
// Program I/O
|
||||
(USHORT)MDD_Base = MSR_LEG_IO;
|
||||
d = Read_MSR_LO(MDD_Base);
|
||||
// don't trust C compiler when expanding a 'define' to
|
||||
// long unless 'define' is a long constant.
|
||||
(USHORT)r = UART_MASK;
|
||||
d &= ~(r << shift);
|
||||
d |= ((ULONG)(vrval & 0x0007)) << shift;
|
||||
Write_MSR_LO(MDD_Base, d);
|
||||
}
|
||||
|
||||
// IRQ change?
|
||||
if ((curval & 0x00F0) ^ (vrval & 0x00F0)) {
|
||||
// Program IRQ
|
||||
(USHORT)MDD_Base = MSR_IRQM_YHIGH;
|
||||
d = Read_MSR_LO(MDD_Base);
|
||||
d &= ~(0x0FL << irqshift);
|
||||
d |= ((ULONG)(vrval & 0x00F0)) << (irqshift-4);
|
||||
Write_MSR_LO(MDD_Base, d);
|
||||
}
|
||||
|
||||
// control bit(s) changed?
|
||||
if ((curval & 0x8F00) ^ (vrval & 0x8F00)) {
|
||||
// Program control bits in MSR_UARTx_CONF
|
||||
// bits[11:8] of vr map to bits[4:1] of MSR
|
||||
// bit[15] of vr maps to bit[0] of MSR
|
||||
(USHORT)MDD_Base = uartmsr;
|
||||
d = Read_MSR_LO(MDD_Base);
|
||||
// clear bits[4:0]
|
||||
d &= ~(0x1FL);
|
||||
(USHORT)d |= ((vrval & 0x0F00) >> 7);
|
||||
if (vrval & 0x8000) {
|
||||
(USHORT)d |= 0x0001;
|
||||
}
|
||||
Write_MSR_LO(MDD_Base, d);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
131
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/virtregs.c
vendored
Executable file
131
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/virtregs.c
vendored
Executable file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//* Function: *
|
||||
//* This file handles virtual registers.
|
||||
|
||||
#include "vsa2.h"
|
||||
#include "chipset.h"
|
||||
#include "vr.h"
|
||||
#include "protos.h"
|
||||
#include "acpi.h"
|
||||
|
||||
extern void Handle_Misc_VR(UCHAR, USHORT);
|
||||
extern void Handle_SysInfo_VR(UCHAR);
|
||||
extern void Handle_5536_UART(UCHAR, UCHAR, USHORT);
|
||||
|
||||
extern USHORT PCI_Int_AB, PCI_Int_CD;
|
||||
extern USHORT DiskTimeout, SerialTimeout, ParallelTimeout, FloppyTimeout;
|
||||
USHORT WatchDogDelay;
|
||||
|
||||
void Handle_VirtualRegs(UCHAR Class, UCHAR Index, UCHAR WrFlag, USHORT Data)
|
||||
{
|
||||
ULONG Param[MAX_MSG_PARAM]; // Select on virtual register class
|
||||
switch (Class) {
|
||||
|
||||
case VRC_MISCELLANEOUS:
|
||||
if (WrFlag) {
|
||||
if (Index == WATCHDOG) {
|
||||
static ULONG WatchDogKey=0;
|
||||
ULONG Key;
|
||||
|
||||
Key = GET_REGISTER(R_ECX);
|
||||
if (WatchDogKey) {
|
||||
// The key has already been set...check it
|
||||
if (WatchDogKey != Key) {
|
||||
/*MEJ // Broadcast to all VSM's
|
||||
Param[0] = S5_STATE;
|
||||
Param[1] = CLASS_ALL;
|
||||
SYS_BROADCAST_MSG(MSG_SET_POWER_STATE, &Param[0], VSM_ANY);
|
||||
*/
|
||||
}
|
||||
} else {
|
||||
// Set the key (only once)
|
||||
WatchDogKey = Key;
|
||||
}
|
||||
WatchDogDelay = Data;
|
||||
SYS_REGISTER_EVENT(EVENT_TIMER, WatchDogDelay*1000L, ONE_SHOT, 0);
|
||||
break;
|
||||
}
|
||||
Handle_Misc_VR(Index, Data);
|
||||
} else {
|
||||
switch (Index) {
|
||||
case PCI_INT_AB:
|
||||
SET_AX(PCI_Int_AB);
|
||||
break;
|
||||
|
||||
case PCI_INT_CD:
|
||||
SET_AX(PCI_Int_CD);
|
||||
break;
|
||||
|
||||
case WATCHDOG:
|
||||
SET_AX(WatchDogDelay);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case VRC_PM:
|
||||
// Ignore READs
|
||||
if (WrFlag) {
|
||||
/*MEJ switch (Index) {
|
||||
case DISK_TIMEOUT:
|
||||
DiskTimeout = Data;
|
||||
break;
|
||||
|
||||
case SERIAL_TIMEOUT:
|
||||
SerialTimeout = Data;
|
||||
break;
|
||||
|
||||
case PARALLEL_TIMEOUT:
|
||||
ParallelTimeout = Data;
|
||||
break;
|
||||
|
||||
case FLOPPY_TIMEOUT:
|
||||
FloppyTimeout = Data;
|
||||
break;
|
||||
}
|
||||
*/
|
||||
}
|
||||
break;
|
||||
|
||||
case VRC_SYSINFO:
|
||||
if (!WrFlag) {
|
||||
Handle_SysInfo_VR(Index);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case VRC_CHIPSET:
|
||||
switch (Index) {
|
||||
case VRC_CS_UART1:
|
||||
case VRC_CS_UART2:
|
||||
Handle_5536_UART(Index, WrFlag, Data);
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
194
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/decode.c
vendored
Executable file
194
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/decode.c
vendored
Executable file
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright (c) 2007-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
// This module decodes the SoftVG SMI sources.
|
||||
|
||||
|
||||
#include "lxvg.h"
|
||||
#include "vsa2.h"
|
||||
#include "vr.h"
|
||||
#include "pci.h"
|
||||
|
||||
extern void pascal out_8(USHORT, UCHAR);
|
||||
extern void pascal out_16(USHORT, USHORT);
|
||||
extern UCHAR pascal in_8(USHORT);
|
||||
extern USHORT pascal in_16(USHORT);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// virtual_register_event
|
||||
//
|
||||
// This routine is called when LXVG receives a VRC_VG virtual register
|
||||
// access event.
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void virtual_register_event(unsigned char reg, unsigned long rwFlag, unsigned long vrData)
|
||||
{
|
||||
|
||||
// Look for virtual register read case first
|
||||
if (!(rwFlag & SMM_VR_WRITE))
|
||||
{
|
||||
// Determine if we are initialized
|
||||
if (!(VGState & SF_SECONDARY))
|
||||
{
|
||||
SET_AX(0xFFFF);
|
||||
}else{
|
||||
SET_AX(vReg[reg]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// If we get here, we know its a write, so handle the requests
|
||||
switch (reg)
|
||||
{
|
||||
case VG_CONFIG:
|
||||
// We only need to initialize once!
|
||||
if (!(VGState & SF_SECONDARY))
|
||||
{
|
||||
// Initialize the secondary controller portion of the engine.
|
||||
lxvg_initialize((unsigned short)vrData);
|
||||
|
||||
// REGISTER PCI EVENTS - DO NOT ENABLE PCI EVENTS IF DISABLED.
|
||||
|
||||
if (VGState & SF_SECONDARY)
|
||||
{
|
||||
// If we've initialized to the secondary state, we need to support
|
||||
// PCI config accesses. If we are disabled, the SysMgr will handle
|
||||
// the support. We may be initialized to the primary state, but the
|
||||
// minimum level is secondary.
|
||||
SYS_REGISTER_EVENT(EVENT_PCI_TRAP, vga_config_addr, 0xFF, NORMAL_PRIORITY);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Finally, store the data...
|
||||
vReg[reg] = (unsigned short)vrData;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// pci_trap_event
|
||||
//
|
||||
// This routine is called when the VSA2 system manager receives an SMI for
|
||||
// a PCI configuration cycle that we have registered for.
|
||||
//
|
||||
// The "flags" parameter indicates the size in bits [3:0] (0x1 = byte,
|
||||
// 0x3 = word, and 0xF = dword). Bit 7 indicates a write.
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void pci_trap_event(unsigned long address, unsigned long flags, unsigned long data)
|
||||
{
|
||||
unsigned char reg = (unsigned char) address & 0x000000FF;
|
||||
unsigned char size = (unsigned char) flags & 0x0000000F;
|
||||
unsigned long pciSave;
|
||||
|
||||
if ((address & PCI_CONFIG_MASK) == vga_config_addr)
|
||||
{
|
||||
|
||||
// CHECK IF PCI WRITE
|
||||
if (flags & PCI_TRAP_WRITE)
|
||||
{
|
||||
// Handle the trapped register writes
|
||||
if (reg == PCI_CMD_REG)
|
||||
{
|
||||
if ((unsigned char)data & PCI_MEM_SPACE)
|
||||
// Change the frame buffer base realated stuff.
|
||||
hw_fb_map_init(framebuffer_base);
|
||||
}
|
||||
else if ((reg >= BAR0) && (reg <= BAR4))
|
||||
{
|
||||
// NOTE: SysMgr now delivers DWORD aligned values with all reserved bits zeroed.
|
||||
if ((data < VGdata.pci_fb_mask) && (data != 0L))
|
||||
{
|
||||
// We have to assume that the changing agent won't put the framebuffer
|
||||
// on top of program memory. The check for zero above was added when
|
||||
// Windows was observed clearing out the BARS by writing 0's to them.
|
||||
// This is still susceptible to failure due to bad address choices by
|
||||
// the changing agent.
|
||||
switch (reg)
|
||||
{
|
||||
case BAR0:
|
||||
if ((data != framebuffer_base) && (data >= 0x1000000))
|
||||
{
|
||||
// Set the frame buffer base.
|
||||
framebuffer_base = data;
|
||||
|
||||
// If the PCI memory is on, change the framebuffer base
|
||||
// related stuff.
|
||||
pciSave = READ_PCI_DWORD_NO_TRAP(PCI_CMD_REG);
|
||||
if (pciSave & PCI_MEM_SPACE)
|
||||
// Change the frame buffer base realated stuff.
|
||||
hw_fb_map_init(framebuffer_base);
|
||||
}
|
||||
break;
|
||||
|
||||
case BAR1:
|
||||
// Set the GP register base
|
||||
GPregister_base = data;
|
||||
break;
|
||||
|
||||
case BAR2:
|
||||
// Set the VG register base
|
||||
VGregister_base = data;
|
||||
break;
|
||||
|
||||
case BAR3:
|
||||
// Set the DF register base
|
||||
DFregister_base = data;
|
||||
break;
|
||||
|
||||
case BAR4:
|
||||
// Set the VIP register base
|
||||
VIPregister_base = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Always mask off the invalid bits, but preserve the
|
||||
// bottom 4 bits.
|
||||
if (size == DWORD_IO)
|
||||
{
|
||||
pciSave = GET_EAX();
|
||||
switch (reg)
|
||||
{
|
||||
case BAR0:
|
||||
pciSave &= VGdata.pci_fb_mask | 0x0000000F;
|
||||
break;
|
||||
|
||||
case BAR1:
|
||||
case BAR2:
|
||||
case BAR3:
|
||||
case BAR4:
|
||||
pciSave &= MASK16K;
|
||||
break;
|
||||
}
|
||||
SET_EAX(pciSave);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// END OF FILE
|
||||
74
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/init.c
vendored
Executable file
74
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/init.c
vendored
Executable file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2007-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
// This module performs LXVG initialization.
|
||||
|
||||
|
||||
#include "lxvg.h"
|
||||
#include "vsa2.h"
|
||||
#include "pci.h"
|
||||
#include "vr.h"
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// lxvg_initialize
|
||||
//
|
||||
// This routine initializes LXVG. This is the routine called when
|
||||
// VG_CONFIG virtual register is written the first time.
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void lxvg_initialize(unsigned short init_parms)
|
||||
{
|
||||
int index;
|
||||
unsigned char *ptr;
|
||||
|
||||
// CLEAR THE ENTIRE LXVG DATA STRUCTURE TO ZERO - This is a tedious loop
|
||||
|
||||
ptr = (unsigned char *) &VGdata;
|
||||
for (index = 0; index < sizeof(VGdata); index++)
|
||||
*ptr++ = 0;
|
||||
|
||||
// Start with virtual registers = 0
|
||||
for (index = 0; index < MAX_VG+1; index++)
|
||||
{
|
||||
if (index != VG_CONFIG)
|
||||
{
|
||||
vReg[index] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// DEVICE DEPENDENT INITIALIZATION
|
||||
// -------------------------------
|
||||
// This MUST be done first. The routine handles all of the MBUS related
|
||||
// initialization and determines various register and base address values
|
||||
// that get used during later initialization.
|
||||
hw_initialize(init_parms);
|
||||
|
||||
// If we haven't initialized because of error, just leave...
|
||||
if (VGState & SF_DISABLED) return;
|
||||
|
||||
|
||||
// LXVG is operating strictly as a secondary controller
|
||||
VGState |= SF_DRIVER_ENABLED;
|
||||
|
||||
// Disable the graphics system in the PCI header command register
|
||||
WRITE_PCI_BYTE(vga_config_addr+0x04, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// END OF FILE
|
||||
298
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/lxhwctl.c
vendored
Executable file
298
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/lxhwctl.c
vendored
Executable file
@@ -0,0 +1,298 @@
|
||||
/*
|
||||
* Copyright (c) 2007-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
// This module contains the routines that access the LX hardware.
|
||||
|
||||
|
||||
#include "lxvg.h"
|
||||
#include "vsa2.h"
|
||||
#include "vr.h"
|
||||
#include "pci.h"
|
||||
|
||||
// This is required here because of inclusion problems in LXVG.h
|
||||
extern Hardware SystemInfo;
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// hw_initialize
|
||||
//
|
||||
// This routine performs the device dependent initialization.
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void hw_initialize(unsigned short config)
|
||||
{
|
||||
unsigned long base,tbase;
|
||||
struct mValue mVal;
|
||||
unsigned short i;
|
||||
|
||||
// Find the list of devices so we can get to their MSRs. If any one
|
||||
// device is missing, bail out because we don't know how to handle
|
||||
// partial systems.
|
||||
|
||||
if (FALSE == msrInit())
|
||||
{
|
||||
VGState = SF_DISABLED;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Initialize the MSRs for the graphics processor
|
||||
hw_gp_msr_init();
|
||||
|
||||
// Initialize the MSRs for the video generator
|
||||
hw_vg_msr_init();
|
||||
|
||||
// Initialize the MSRs for the display filter
|
||||
hw_df_msr_init();
|
||||
|
||||
// Initialize the MSRs for the display filter
|
||||
hw_vip_msr_init();
|
||||
|
||||
// Initialize the DOT PLL MSR in the MCP
|
||||
hw_mcp_msr_init();
|
||||
|
||||
// Compute graphics memory requirement from config. The following strips
|
||||
// off the PLL bypass bit and shifts the number of 1MB hunks up
|
||||
// to the point where it is a size in bytes. Base is used as a temp.
|
||||
base = (unsigned long)(config & MEM_SIZE_MASK) << 20;
|
||||
|
||||
// Now compute the memory size mask we will use when we return the contents of
|
||||
// BAR0
|
||||
VGdata.pci_fb_mask = 0;
|
||||
tbase = base;
|
||||
for (i=0;i<32,tbase!=0L;i++)
|
||||
{
|
||||
VGdata.pci_fb_mask |= (1L << i);
|
||||
tbase = tbase >> 1;
|
||||
}
|
||||
VGdata.pci_fb_mask = ~(VGdata.pci_fb_mask);
|
||||
|
||||
// ALLOCATE DESCRIPTORS
|
||||
vga_config_addr = SYS_ALLOCATE_RESOURCE(RESOURCE_MEMORY, BAR0, base, PCI_DEV_ID, ID_MC); // Graphics memory
|
||||
SYS_ALLOCATE_RESOURCE(RESOURCE_MMIO, BAR1, SIZE16K, PCI_DEV_ID, ID_GP); // GP registers
|
||||
SYS_ALLOCATE_RESOURCE(RESOURCE_MMIO, BAR2, SIZE16K, PCI_DEV_ID, ID_VG); // VG registers
|
||||
SYS_ALLOCATE_RESOURCE(RESOURCE_MMIO, BAR3, SIZE16K, PCI_DEV_ID, ID_DF); // DF registers
|
||||
SYS_ALLOCATE_RESOURCE(RESOURCE_MMIO, BAR4, SIZE16K, PCI_DEV_ID, ID_VIP); // VIP registers
|
||||
|
||||
// Modify vga_config_addr to point to the beginning of the header, because all the accesses
|
||||
// to the header are based on the beginning of the header rather than BAR0.
|
||||
vga_config_addr -= BAR0;
|
||||
|
||||
// SET BASE ADDRESS VALUES.
|
||||
|
||||
// The base addresses are all relative to the framebuffer base address which
|
||||
// is defined to be on the next 256MB boundary above the SYSMGR. Initially,
|
||||
// it was hard coded to be at 0x50000000, and now it should show up at 0x90000000.
|
||||
framebuffer_base = (SYS_LOGICAL_TO_PHYSICAL(0) & 0xF0000000) + 0x10000000;
|
||||
WRITE_PCI_DWORD_NO_TRAP(vga_config_addr+BAR0, framebuffer_base); // Frame buffer address
|
||||
|
||||
GPregister_base = framebuffer_base - 0x00004000;
|
||||
WRITE_PCI_DWORD_NO_TRAP(vga_config_addr+BAR1, GPregister_base); // Graphics processor register space
|
||||
|
||||
VGregister_base = GPregister_base - 0x00004000;
|
||||
WRITE_PCI_DWORD_NO_TRAP(vga_config_addr+BAR2, VGregister_base); // Video generator register space
|
||||
|
||||
DFregister_base = VGregister_base - 0x00004000;
|
||||
WRITE_PCI_DWORD_NO_TRAP(vga_config_addr+BAR3, DFregister_base); // Display filter register space
|
||||
|
||||
VIPregister_base = DFregister_base - 0x00004000;
|
||||
WRITE_PCI_DWORD_NO_TRAP(vga_config_addr+BAR4, VIPregister_base); // Display filter register space
|
||||
|
||||
// Turn on the descriptors
|
||||
WRITE_PCI_BYTE(vga_config_addr+0x04,PCI_MEM_SPACE);
|
||||
|
||||
// Unlock the display controller registers
|
||||
saveLock = read_vg_32(DC_UNLOCK);
|
||||
write_vg_32(DC_UNLOCK, DC_UNLOCK_VALUE);
|
||||
|
||||
// Set up the DV Address offset in the DC_DV_CTL register to the offset from frame
|
||||
// buffer descriptor. First, get the frame buffer descriptor so we can set the
|
||||
// DV Address Offset in the DV_CTL register. Because this is a pointer to real
|
||||
// silicon memory, we don't need to do this whenever we change the framebuffer BAR,
|
||||
// so it isn't included in the hw_fb_map_init routine.
|
||||
SYS_MBUS_DESCRIPTOR((unsigned short)(vga_config_addr+BAR0),(void *)&mVal);
|
||||
mVal.high &= DESC_OFFSET_MASK;
|
||||
mVal.high <<= 4;
|
||||
mVal.high += framebuffer_base; // Watch for overflow issues here...
|
||||
write_vg_32(DC_DV_CTL, mVal.high);
|
||||
|
||||
// Initialize the frame buffer base realated stuff.
|
||||
hw_fb_map_init(framebuffer_base);
|
||||
|
||||
// CLEAR Video Generator START ADDRESS VALUES
|
||||
write_vg_32(DC_FB_ST_OFFSET, 0L);
|
||||
write_vg_32(DC_CB_ST_OFFSET, 0L);
|
||||
write_vg_32(DC_CURS_ST_OFFSET, 0L);
|
||||
write_vg_32(DC_UNLOCK, saveLock);
|
||||
|
||||
|
||||
// Put VIP input and output sections into reset state with default values.
|
||||
write_vip_32(VIP_CTRL1, 0x42000001);
|
||||
|
||||
// Set flags indicating the hardware registers are available and that we are not
|
||||
// disabled. Among other things, the SF_SECONDARY flag controls the hardware
|
||||
// register locking and unlocking at the top of the message handling loop.
|
||||
VGState |= SF_SECONDARY;
|
||||
VGState &= ~SF_DISABLED;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Initialize the graphics processor MSR registers.
|
||||
void hw_gp_msr_init(void)
|
||||
{
|
||||
// Initialize the configuration MSR - 0x00000000 00000010
|
||||
msrModify(msrIdx_GP, MBD_MSR_CONFIG, MSR_CLR_ALL, MSR_CLR_ALL_BUT_PID, 0, GP_DEF_PRI);
|
||||
|
||||
// Initialize the SMI MSR. Clear and disable all SMIs - 0x00000001 00000001
|
||||
msrModify(msrIdx_GP, MBD_MSR_SMI, MSR_CLR_ALL, MSR_CLR_ALL, GP_SMI_CLR, GP_SMI_DIS);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize the video input port MSR registers.
|
||||
void hw_vip_msr_init(void)
|
||||
{
|
||||
msrModify(msrIdx_VIP, MBD_MSR_CONFIG, MSR_CLR_ALL, MSR_CLR_ALL_BUT_PID, 0L, VIP_DEF_PRI);
|
||||
|
||||
// Initialize the SMI MSR. Clear and disable all SMIs - 0x00000000 7FFF7FFF
|
||||
msrModify(msrIdx_VIP, MBD_MSR_SMI, MSR_CLR_ALL, MSR_CLR_ALL, 0L, 0x7FFF7FFF);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize the video generator MSR registers.
|
||||
void hw_vg_msr_init(void)
|
||||
{
|
||||
// Initialize the configuration MSR - 0x00000000 00000320
|
||||
msrModify(msrIdx_VG, MBD_MSR_CONFIG, MSR_CLR_ALL, MSR_CLR_ALL_BUT_PID, 0, VG_DEF_PRI);
|
||||
|
||||
// Initialize the SMI MSR. Clear and disable all SMIs - 0x0000001f 0000001f
|
||||
msrModify(msrIdx_VG, MBD_MSR_SMI, MSR_CLR_ALL, MSR_CLR_ALL, VG_SMI_DIS, VG_SMI_DIS);
|
||||
|
||||
// Initialize the DELAY MSR.
|
||||
msrModify(msrIdx_VG, MBD_MSR_DELAY, MSR_CLR_ALL, MSR_CLR_ALL, 0L, 0x00000302);
|
||||
|
||||
// Turn off the bad VG fetch state machine hardware fix and the video FIFO watermarks
|
||||
msrModify(msrIdx_VG, MBD_MSR_SPARE, MSR_CLR_ALL, MSR_CLR_ALL, 0L, 0x00000042);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize the display filter MSR registers.
|
||||
void hw_mcp_msr_init(void)
|
||||
{
|
||||
unsigned long orValLo, orValHi;
|
||||
struct mValue mVal;
|
||||
unsigned char i;
|
||||
|
||||
// Initialize the DOT PLL MSR. We need to default to a known clock so
|
||||
// the PLL doesn't exceed its limits, and if the bypass bit is set, we
|
||||
// need to also set the power down bit.
|
||||
if (vReg[VG_CONFIG] & VG_CFG_BYPASS)
|
||||
{
|
||||
// Bypassed, so just set the bypass and power down bits.
|
||||
orValLo = DOTPLL_BYPASS | DOTPLL_PDBIT;
|
||||
orValHi = 0L;
|
||||
}
|
||||
else
|
||||
{
|
||||
orValLo = DOTPLL_RESET;
|
||||
orValHi = 0x0000216C; // 28.322MHz
|
||||
}
|
||||
|
||||
msrModify(msrIdx_MCP, MCP_DOTPLL, MSR_CLR_ALL, MSR_CLR_ALL, orValHi, orValLo);
|
||||
|
||||
// LEDA has indicated that there may be up to a 42 clock delay from the time the
|
||||
// DOTPLL comes out of powerdown until the lock bit is guaranteed to go low. In
|
||||
// order to make sure we don't read an errant value, we need to delay a bit.
|
||||
for (i=0;i<8;i++)
|
||||
outp(0xed,0xf5);
|
||||
|
||||
// Wait for lock (maybe)
|
||||
msrRead(msrIdx_MCP, MCP_DOTPLL, &mVal);
|
||||
while (!(mVal.low & DOTPLL_LOCKBIT))
|
||||
{
|
||||
// Read the current contents...
|
||||
msrRead(msrIdx_MCP, MCP_DOTPLL, &mVal);
|
||||
};
|
||||
|
||||
msrModify(msrIdx_MCP, MCP_DOTPLL, 0, MSR_CLR_ALL, 0, 0); // Clear the reset bit
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize the display filter MSR registers.
|
||||
void hw_df_msr_init(void)
|
||||
{
|
||||
unsigned long orVal;
|
||||
unsigned long mDiv, mMul, pSpd, mSpd, mbClk;
|
||||
struct mValue mVal;
|
||||
|
||||
// Get a colletion of information necessary to compute the divisor for the
|
||||
// CONFIG MSR. This includes the processor speed, the CPU multiplier and
|
||||
// divisor and the MBus multiplier and divisor. There are two different
|
||||
// versions of the computation. The commented out version doesn't depend
|
||||
// on the bootstrap pin, and the other starts with a known PCI speed based
|
||||
// on that pin.
|
||||
msrRead(msrIdx_MCP, MCP_SYSPLL, &mVal); // Returns the divisors...
|
||||
|
||||
pSpd = (mVal.low & 0x00000008)?66:33;
|
||||
|
||||
mDiv = ((mVal.high & 0x00000040) >> 6) + 1;
|
||||
mMul = ((mVal.high & 0x00000F80) >> 7) + 1;
|
||||
|
||||
mbClk = (pSpd * mMul) / mDiv;
|
||||
|
||||
mSpd = (mbClk / 14) & 0x0000003F;
|
||||
|
||||
// Initialize the configuration MSR
|
||||
orVal = DF_DEF_PRI;
|
||||
orVal |= (mSpd << 8);
|
||||
msrModify(msrIdx_DF, MBD_MSR_CONFIG, MSR_CLR_ALL, MSR_CLR_ALL_BUT_PID, 0, orVal);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// hw_fb_map_init
|
||||
//
|
||||
// This routine initializes the hardware pointers that are specifically
|
||||
// related to the framebuffer address.
|
||||
//---------------------------------------------------------------------------
|
||||
void hw_fb_map_init(unsigned long fbLoc)
|
||||
{
|
||||
unsigned long ltemp;
|
||||
|
||||
// Insist upon a certain alignment...
|
||||
fbLoc &= VGdata.pci_fb_mask;
|
||||
|
||||
// Set the MBus Memory Offset register.
|
||||
write_vg_32(PHY_MEM_OFFSET, fbLoc);
|
||||
|
||||
// Set GP2 base offset - different from Redcloud. There are both source
|
||||
// and destination fields the need to be set.
|
||||
ltemp = fbLoc | (fbLoc >> 10);
|
||||
write_gp_32(GP2_BASE_OFFSET, ltemp);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
915
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/lxvg.h
vendored
Executable file
915
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/lxvg.h
vendored
Executable file
@@ -0,0 +1,915 @@
|
||||
/*
|
||||
* Copyright (c) 2007-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
// This is the main header file for LXVG.
|
||||
|
||||
// VERSION NUMBERS
|
||||
|
||||
#define LXVG_MAJOR_VER 0x00
|
||||
#define LXVG_MINOR_VER 0x11
|
||||
|
||||
// PROCESSOR IDS
|
||||
// Keep as bitwise flags to make "either" comparisons easier.
|
||||
|
||||
#define PROCESSOR_GXM 0x01
|
||||
#define PROCESSOR_REDC 0x02
|
||||
#define PROCESSOR_CSTL 0x03
|
||||
|
||||
// A pair of LONG generic masks
|
||||
#define CLR_HIWORD 0x0000FFFF
|
||||
#define CLR_LOWORD 0xFFFF0000
|
||||
|
||||
|
||||
// Some LXVG configuration flags and masks
|
||||
#define MEM_SIZE_MASK 0x00FE // Bits 7:1 (size in 2MB hunks)
|
||||
#define ADAPTER_PRIMARY 0x0100 // Bit 8
|
||||
|
||||
#define PLL_REF_MASK 0x0600 // Bits 10:9
|
||||
#define PLL_BYPASS 0x0800 // Bit 11
|
||||
#define VGDATA_PLL_14MHZ 0x00 // VGdata PLL reference frequency flag value
|
||||
#define VGDATA_PLL_48MHZ 0x01 // VGdata PLL reference frequency flag value
|
||||
#define VGDATA_PLL_ERROR 0xFF // Bad PLL or hardware error
|
||||
#define MONOCHROME_CARD 0x1000 // Bit 12
|
||||
|
||||
// SOME REDCLOUD DEFINITIONS
|
||||
|
||||
#define FAKE_ADDRESS 0xFFFFFFFF
|
||||
#define CLASS_MASK 0x000FF000
|
||||
#define DEVID_MASK 0x00FFFF00
|
||||
|
||||
// A memory space enable value for the PCI command register
|
||||
#define PCI_CMD_REG 0x04
|
||||
#define PCI_IO_SPACE (1 << 0)
|
||||
#define PCI_MEM_SPACE (1 << 1)
|
||||
|
||||
// Some commonly used size definitions
|
||||
#define SIZE4K 0x00001000 // A 4K range indicator
|
||||
#define SIZE16K 0x00004000 // A 16K range indicator
|
||||
#define MASK16K 0xFFFFC00F // A 16K range mask
|
||||
#define SIZE32K 0x00008000 // A 32K range indicator
|
||||
#define SIZE64K 0x00010000 // A 64K range indicator
|
||||
#define SIZE128K 0x00020000 // A 128K range indicator
|
||||
|
||||
// PCI device ID assigned to LX graphics system
|
||||
#define PCI_DEV_ID 0x2081
|
||||
|
||||
// MBus device IDs. These IDs will have to be shifted into place by the System
|
||||
// manager when it goes to access the devices.
|
||||
#define ID_MBIU 0x01 // Default MBIU device ID
|
||||
#define ID_MCP 0x02 // MBus Control Processor device ID
|
||||
#define ID_MC 0x20 // Default Memory Controller device ID
|
||||
#define ID_GP 0x3D // Graphics Processor device ID
|
||||
#define ID_VG 0x3E // Video Generator device ID
|
||||
#define ID_DF 0x3F // Display Filter device ID
|
||||
#define ID_VIP 0x3C // Display Filter device ID
|
||||
|
||||
// MSR Register Offsets
|
||||
#define MBD_MSR_CAP 0x2000
|
||||
#define MBD_MSR_CONFIG 0x2001
|
||||
#define MBD_MSR_SMI 0x2002
|
||||
#define MBD_MSR_ERROR 0x2003
|
||||
#define MBD_MSR_PM 0x2004
|
||||
#define MBD_MSR_DIAG 0x2005
|
||||
#define MBD_MSR_SPARE 0x2011
|
||||
#define MBD_MSR_DELAY 0x2012
|
||||
|
||||
// DF specific MSRs
|
||||
#define DF_MSR_DIAG_DF 0x2010
|
||||
#define DF_MSR_PAD_SEL 0x2011
|
||||
|
||||
// MSR stuff specific to the MCP_DOTPLL
|
||||
#define MCP_SYSPLL 0x0014
|
||||
#define MCP_DOTPLL 0x0015
|
||||
#define DOTPLL_DIV_MASK 0x00007FFF
|
||||
#define DOTPLL_DIV4 0x00010000
|
||||
|
||||
#define DOTPLL_RESET 0x00000001
|
||||
#define DOTPLL_CAPEN 0x00002000
|
||||
#define DOTPLL_PDBIT 0x00004000
|
||||
#define DOTPLL_BYPASS 0x00008000
|
||||
#define DOTPLL_HALFPIX 0x01000000
|
||||
#define DOTPLL_LOCKBIT 0x02000000
|
||||
|
||||
// MCP Error and SMI MSR error bits related to the DOTPLL reset during power-on bug PBz#3344.
|
||||
#define MCP_SMI_ERRBIT 0x00010000
|
||||
#define MCP_DOTPLL_ERRBIT 0x00000004
|
||||
|
||||
#define MCP_CHIPREV 0x0017
|
||||
|
||||
//
|
||||
// msrDev indices for the devices that we care about/know about
|
||||
//
|
||||
#define msrIdx_MCP 0
|
||||
#define msrIdx_MC 1
|
||||
#define msrIdx_GP 2
|
||||
#define msrIdx_VG 3
|
||||
#define msrIdx_DF 4
|
||||
#define msrIdx_VIP 5
|
||||
#define msrIdx_MBIU 6
|
||||
|
||||
// A mask to isolate the offset field of the frame buffer descriptor.
|
||||
#define DESC_OFFSET_MASK 0x0FFFFF00
|
||||
#define DV_OFFSET_MASK 0xFFFFF000
|
||||
#define DV_LINE_1K 0x00000000
|
||||
#define DV_LINE_2K 0x00000400
|
||||
#define DV_LINE_4K 0x00000800
|
||||
#define DV_LINE_8K 0x00000C00
|
||||
|
||||
// Structures of MSRs.
|
||||
//
|
||||
// Proper usage is as follows:
|
||||
//
|
||||
// MSR access routines (MSRAR) should first check the 'Present' field and :
|
||||
//
|
||||
// 1) If the field is set to 'REQ_NOT_FOUND' :
|
||||
// - The device was not detected on the MBUS but a request was made to
|
||||
// find it at some point since/during initization [ see msrInit() ].
|
||||
// Therefore, MSRAR should not attempt to access the device.
|
||||
//
|
||||
// 2) If the field is set to 'FOUND' :
|
||||
// - The device was detected on the MBUS, the rest of the structure
|
||||
// has been filled in and MSRAR should use the address provided.
|
||||
//
|
||||
// 3) If the field is set to 'UNKNOWN' :
|
||||
// - There has never been a request to find this device. MSRAR returns
|
||||
// to caller. Caller should first call msrInit().
|
||||
//
|
||||
// The address field is set to FAKE_ADDRESS just in case "renegade software" doesn't
|
||||
// check the 'Present' field and just grabs the 'address' field.
|
||||
// FAKE_ADDRESS has been set to a value that should never appear in
|
||||
// a real system. It is only meant to protect the system 99%
|
||||
// of the time from badly written software....
|
||||
|
||||
typedef struct tagMSR {
|
||||
unsigned short Present; // Present - Read above under "Structures of MSRs"
|
||||
unsigned short Id; // Id - Device ID number (from MSR specs)
|
||||
unsigned long Routing; // Routing - 32-bit address at which 'Id' was found
|
||||
} MSR;
|
||||
|
||||
//
|
||||
// mValue is used to hold the 64-bit msr data value.
|
||||
//
|
||||
typedef struct mValue {
|
||||
unsigned long low;
|
||||
unsigned long high;
|
||||
};
|
||||
|
||||
// Capabilities bits
|
||||
#define DF_BOND_MASK 0x000000C0 // CRT bond value
|
||||
#define BOND_CRT 0x00 // CRT bond value
|
||||
#define BOND_FP 0x40 // flat panel bond value
|
||||
|
||||
#define HALF_MEG 0x00080000 // 512K
|
||||
#define QRTR_MEG 0x00040000 // 256K
|
||||
#define MAX_ICON 0x4C00 // 19K
|
||||
|
||||
// MSR AND masks used by rc_msrModify. These masks define bits that are
|
||||
// always cleared in the register.
|
||||
#define MSR_CLR_ALL 0xFFFFFFFF // Clear all bits
|
||||
#define MSR_CLR_NONE 0L // Clear no bits
|
||||
#define MSR_CLR_OUT 0x00008038 // Clear bits 15, 5:3
|
||||
#define MSR_CLR_ALL_BUT_PID 0xFFFFFFF8 // Clear all bits except [2:0]
|
||||
|
||||
|
||||
// GP
|
||||
#define GP_SMI_MSK_HI 0xFFFFFFFF // SMI MSR
|
||||
#define GP_SMI_MSK_LO 0xFFE0FFE0
|
||||
#define GP_ERR_MSK_HI 0xFFFFFFFF // Error MSR
|
||||
#define GP_ERR_MSK_LO 0xFFF0FFF0
|
||||
#define GP_PM_MSK_HI 0xFFFFFFFC // PM MSR
|
||||
#define GP_PM_MSK_LO 0xFFFFFFF0
|
||||
|
||||
// VG
|
||||
#define VG_SMI_MSK_HI 0xFFFFFFFF // SMI MSR
|
||||
#define VG_SMI_MSK_LO 0xFFE0FFE0
|
||||
#define VG_ERR_MSK_HI 0xFFFFFFFF // Error MSR
|
||||
#define VG_ERR_MSK_LO 0xFFF0FFF0
|
||||
#define VG_PM_MSK_HI 0xFFFFFFFC // PM MSR
|
||||
#define VG_PM_MSK_LO 0xFFFFFFF0
|
||||
|
||||
// DF
|
||||
#define DF_SMI_MSK_HI 0xFFFFFFFF // SMI MSR
|
||||
#define DF_SMI_MSK_LO 0xFFFCFFFC
|
||||
#define DF_ERR_MSK_HI 0xFFFFFFFE // Error MSR
|
||||
#define DF_ERR_MSK_LO 0xFFFFFFFE
|
||||
#define DF_PM_MSK_HI 0xFFFFFFE0 // PM MSR
|
||||
#define DF_PM_MSK_LO 0xF0FFFC00
|
||||
|
||||
|
||||
// MSR bit field AND masks. These are added to the above masks to
|
||||
// clear particular fields
|
||||
|
||||
// GP
|
||||
#define GP_CFG_PRI 0x00000070 // Both priority fields
|
||||
#define GP_CFG_PID 0x00000007 // PID field
|
||||
#define GP_DEF_PRI 0x00000010 // Default priorities
|
||||
|
||||
#define GP_SMI_CLR 0x00000001 // SMI clear bits
|
||||
#define GP_SMI_DIS 0x00000001 // SMI disable bits
|
||||
|
||||
#define GP_CLK_RQ 0x00000001 // Software clock PM request bits field
|
||||
#define GP_PM_MODE 0x00000003 // Clock PM mode fields
|
||||
#define GP_CLK_ON 0x00000000 // Both clocks always on
|
||||
#define GP_CLK_HW 0x00000001 // Both clocks hardware gated
|
||||
#define GP_CLK_SW 0x00000002 // Both clocks software gated
|
||||
#define GP_CLK_BOTH 0x00000003 // Both clocks software and hardware gated
|
||||
|
||||
// VG
|
||||
#define VG_CFG_PRI 0x00000770 // Both priority fields
|
||||
#define VG_CFG_PID 0x00000007 // PID field
|
||||
#define VG_DEF_PRI 0x00000720 // Default priorities
|
||||
#define VG_DEF_PRI_10 0x00000620 // Default priorities for 1.0 parts
|
||||
|
||||
// LX 2.0 changes
|
||||
#define VG_SMI_DIS 0x1001FFFF // SMI disable and clear bits
|
||||
#define VG_SMI_ALLNB 0x10000016 // All "Standard" SMIs but VBLANKs
|
||||
|
||||
#define VG_SMI_INV_CRTC 0x00000010 // Invalid CRTC SMI disable mask
|
||||
#define VG_SMI_VBLANK 0x00000009 // Vertical blanks SMI disable mask
|
||||
#define VG_SMI_ISR0 0x00000004 // Input status register SMI disable mask
|
||||
#define VG_SMI_MISC_W 0x00000002 // Miscellaneous output register SMI disable mask
|
||||
|
||||
#define VG_SMI_ALLCRTC 0x00000060 // All CRTC reads and writes
|
||||
#define VG_SMI_ALLSEQ 0x00000180 // All SEQ reads and writes
|
||||
#define VG_SMI_ALLGDC 0x00000600 // All GFX reads and writes
|
||||
#define VG_SMI_ALLATC 0x00001800 // All ATC reads and writes
|
||||
#define VG_SMI_ALLDAC 0x00006000 // All DAC reads and writes
|
||||
|
||||
#define VG_SMI_CRTC_W 0x00000020 // All CRTC writes
|
||||
#define VG_SMI_CRTC_R 0x00000040 // All CRTC reads
|
||||
#define VG_SMI_SEQ_W 0x00000080 // All SEQ writes
|
||||
#define VG_SMI_SEQ_R 0x00000100 // All SEQ reads
|
||||
#define VG_SMI_GDC_W 0x00000200 // All GDC writes
|
||||
#define VG_SMI_GDC_R 0x00000400 // All GDC reads
|
||||
#define VG_SMI_ATC_W 0x00000800 // All ATC writes
|
||||
#define VG_SMI_ATC_R 0x00001000 // All ATC reads
|
||||
#define VG_SMI_DAC_W 0x00002000 // All DAC writes
|
||||
#define VG_SMI_DAC_R 0x00004000 // All DAC reads
|
||||
#define VG_SMI_MISC_R 0x00008000 // Miscellaneous output register reads
|
||||
#define VG_SMI_ISR1_R 0x00010000 // Input status register 1 reads
|
||||
|
||||
// VG_DEBUG trap request bits
|
||||
#define TRAP_ALL_CRTC 0x0100
|
||||
#define TRAP_ALL_SEQ 0x0200
|
||||
#define TRAP_ALL_GDC 0x0400
|
||||
#define TRAP_ALL_ATC 0x0800
|
||||
#define TRAP_ALL_DAC 0x1000
|
||||
#define TRAP_MISC_RDS 0x2000
|
||||
#define TRAP_ISR1_RDS 0x4000
|
||||
// LX 2.0 changes
|
||||
|
||||
#define VG_CLK_RQ 0x00000003 // Software clock PM request bits field
|
||||
#define VG_PM_MODE 0x0000000F // Clock PM mode fields
|
||||
#define VG_CLK_ON 0x00000000 // Both clocks always on
|
||||
#define VG_CLK_HW 0x00000005 // Both clocks hardware gated
|
||||
#define VG_CLK_SW 0x0000000A // Both clocks software gated
|
||||
#define VG_CLK_BOTH 0x0000000F // Both clocks software and hardware gated
|
||||
|
||||
|
||||
// DF
|
||||
#define DF_CFG_PID 0x00000007 // PID field
|
||||
#define DF_CFG_FMT 0x00000038 // Output format select field
|
||||
#define DF_CFG_FMBO 0x000000C0 // Output format byte order field
|
||||
#define DF_CFG_DIV 0x00003F00 // Clock divider field
|
||||
#define DF_CFG_IUV 0x00004000 // Interchange UV field
|
||||
#define DF_CFG_FPC 0x00008000 // Simultaneous CRT and panel/VOP bit
|
||||
#define DF_CFG_PRI 0x00070000 // MBus master priority field
|
||||
#define DF_DEF_PRI 0x00040000 // Default priority
|
||||
#define DF_DEF_DIV 0x00003F00 // Default clock divider
|
||||
|
||||
//#define DF_SMI_CLR 0x00030000 // SMI clear bits
|
||||
#define DF_SMI_CLR 0x00000000 // SMI clear bits
|
||||
#define DF_SMI_DIS 0x00000003 // SMI disable bits
|
||||
|
||||
#define DF_CLK_RQ 0x0000001F // Software clock PM request bits field
|
||||
#define DF_PM_MODE 0x000003FF // Clock PM mode fields
|
||||
#define DF_CLK_ON 0x00000000 // All clocks always on
|
||||
#define DF_CLK_HW 0x00000155 // All clocks hardware gated
|
||||
#define DF_CLK_SW 0x000002AA // All clocks software gated
|
||||
#define DF_CLK_BOTH 0x000003FF // All clocks software and hardware gated
|
||||
|
||||
#define DF_CLR_CRC 0x80000000 // Clear the CRC select bit
|
||||
|
||||
// VIP
|
||||
#define VIP_CFG_PID 0x00000007 // PID field
|
||||
#define VIP_PRI_PRI 0x00000070 // MBus master priority field
|
||||
#define VIP_SEC_PRI 0x00000700 // Default priority
|
||||
#define VIP_DEF_PRI_10 0x00000630 // Default priority
|
||||
#define VIP_DEF_PRI 0x00000620 // Default priority
|
||||
|
||||
#define VIP_SMI_CLR 0x3FFF0000 // SMI clear bits
|
||||
#define VIP_SMI_DIS 0x00003FFF // SMI disable bits
|
||||
|
||||
#define VIP_CLK_RQ 0x0000001F // Software clock PM request bits field
|
||||
#define VIP_PM_MODE 0x000003FF // Clock PM mode fields
|
||||
#define VIP_CLK_ON 0x00000000 // All clocks always on
|
||||
#define VIP_CLK_HW 0x00000155 // All clocks hardware gated
|
||||
#define VIP_CLK_SW 0x000002AA // All clocks software gated
|
||||
#define VIP_CLK_BOTH 0x000003FF // All clocks software and hardware gated
|
||||
|
||||
//
|
||||
// SMI event id bits
|
||||
//
|
||||
#define EVT_VG_VBLANK 0x00000001
|
||||
#define EVT_VG_MISC_WR 0x00000002
|
||||
#define EVT_VG_ISR0_RD 0x00000004
|
||||
#define EVT_VGA_VBLANK 0x00000008
|
||||
#define EVT_VG_INV_CRTC 0x00000010
|
||||
#define EVT_VG_CRTC_W 0x00000020
|
||||
#define EVT_VG_CRTC_R 0x00000040
|
||||
#define EVT_VG_SEQ_W 0x00000080
|
||||
#define EVT_VG_SEQ_R 0x00000100
|
||||
#define EVT_VG_GFX_W 0x00000200
|
||||
#define EVT_VG_GFX_R 0x00000400
|
||||
#define EVT_VG_ATC_W 0x00000800
|
||||
#define EVT_VG_ATC_R 0x00001000
|
||||
#define EVT_VG_DAC_W 0x00002000
|
||||
#define EVT_VG_DAC_R 0x00004000
|
||||
#define EVT_VG_MISC_R 0x00008000
|
||||
#define EVT_VG_ISR1_R 0x00010000
|
||||
#define EVT_VGA_RES_CHG 0x10000000
|
||||
|
||||
#define EVT_WRITES 0x00000AB2 // The register write bits
|
||||
#define EVT_READS 0x0001D554 // The register read bits + ISR0 & Inv CRTC
|
||||
//#define EVT_GP_SMI0 0x20000000
|
||||
//#define EVT_DF_SMI0 0x40000000
|
||||
//#define EVT_DF_SMI1 0x80000000
|
||||
// Castle 2.0 Defs
|
||||
|
||||
|
||||
//
|
||||
// GP2 Memory Mapped Register Set
|
||||
//
|
||||
#define GP2_DST_OFFSET 0x0000
|
||||
#define GP2_SRC_OFFSET 0x0004
|
||||
#define GP2_VEC_ERR 0x0004
|
||||
#define GP2_STRIDE 0x0008
|
||||
#define GP2_WID_HEIGHT 0x000C
|
||||
#define GP2_SRC_COLOR_FG 0x0010
|
||||
#define GP2_SRC_COLOR_BG 0x0014
|
||||
#define GP2_PAT_COLOR_0 0x0018
|
||||
#define GP2_PAT_COLOR_1 0x001C
|
||||
#define GP2_PAT_COLOR_2 0x0020
|
||||
#define GP2_PAT_COLOR_3 0x0024
|
||||
#define GP2_PAT_COLOR_4 0x0028
|
||||
#define GP2_PAT_COLOR_5 0x002C
|
||||
#define GP2_PAT_DATA_0 0x0030
|
||||
#define GP2_PAT_DATA_1 0x0034
|
||||
#define GP2_RASTER_MODE 0x0038
|
||||
#define GP2_VECTOR_MODE 0x003C
|
||||
#define GP2_BLT_MODE 0x0040
|
||||
#define GP2_BLT_STATUS 0x0044
|
||||
#define GP2_RESET 0x0044
|
||||
#define GP2_HST_SRC 0x0048
|
||||
#define GP2_BASE_OFFSET 0x004C
|
||||
|
||||
//
|
||||
// VG Memory Mapped Register Set
|
||||
//
|
||||
#define DC_UNLOCK 0x0000
|
||||
#define DC_GENERAL_CFG 0x0004
|
||||
#define DC_DISPLAY_CFG 0x0008
|
||||
#define DC_ARB_CFG 0x000C
|
||||
//#define DC_GFX_SCL 0x000C
|
||||
#define DC_FB_ST_OFFSET 0x0010
|
||||
#define DC_CB_ST_OFFSET 0x0014
|
||||
#define DC_CURS_ST_OFFSET 0x0018
|
||||
//#define DC_ICON_ST_OFFSET 0x001C
|
||||
#define DC_VID_Y_ST_OFFSET 0x0020
|
||||
#define DC_VID_U_ST_OFFSET 0x0024
|
||||
#define DC_VID_V_ST_OFFSET 0x0028
|
||||
#define DC_DV_TOP 0x002C
|
||||
//#define DC_VID_SP_ST_OFFSET 0x002C
|
||||
#define DC_LINE_SIZE 0x0030
|
||||
#define DC_GFX_PITCH 0x0034
|
||||
#define DC_VID_YUV_PITCH 0x0038
|
||||
//#define DC_VID_SP_PITCH 0x003C
|
||||
#define DC_H_ACTIVE_TIMING 0x0040
|
||||
#define DC_H_BLANK_TIMING 0x0044
|
||||
#define DC_H_SYNC_TIMING 0x0048
|
||||
//#define DC_FP_HSYNC_TIMING 0x004C
|
||||
#define DC_V_ACTIVE_TIMING 0x0050
|
||||
#define DC_V_BLANK_TIMING 0x0054
|
||||
#define DC_V_SYNC_TIMING 0x0058
|
||||
#define DC_FB_ACTIVE 0x005C
|
||||
//#define DC_FP_VSYNC_TIMING 0x005C
|
||||
#define DC_CURSOR_X 0x0060
|
||||
#define DC_CURSOR_Y 0x0064
|
||||
//#define DC_ICON_X 0x0068
|
||||
#define DC_LINE_CNT 0x006C
|
||||
#define DC_PAL_ADDRESS 0x0070
|
||||
#define DC_PAL_DATA 0x0074
|
||||
#define DC_DFIFO_DIAG 0x0078
|
||||
#define DC_CFIFO_DIAG 0x007C
|
||||
#define DC_VID_DS_DELTA 0x0080
|
||||
#define PHY_MEM_OFFSET 0x0084
|
||||
#define DC_DV_CTL 0x0088
|
||||
#define DC_ACCESS 0x008C
|
||||
|
||||
#define DC_GFX_SCALE 0x0090
|
||||
#define DC_IRQ_FLT_CTL 0x0094
|
||||
#define DC_FLT_COEFF1 0x0098
|
||||
#define DC_FLT_COEFF2 0x009C
|
||||
|
||||
#define DC_VBI_EVN_CTL 0x00A0
|
||||
#define DC_VBI_ODD_CTL 0x00A4
|
||||
#define DC_VBI_HOR_CTL 0x00A8
|
||||
#define DC_VBI_LN_ODD 0x00AC
|
||||
#define DC_VBI_LN_EVN 0x00B0
|
||||
#define DC_VBI_PITCH 0x00B4
|
||||
#define DC_VBI_CLR_KEY 0x00B8
|
||||
#define DC_VBI_CK_MASK 0x00BC
|
||||
#define DC_VBI_CK_X 0x00C0
|
||||
#define DC_VBI_CK_Y 0x00C4
|
||||
|
||||
#define DC_IRQ 0x00C8
|
||||
#define DC_GENLK_CTL 0x00D4
|
||||
|
||||
#define DC_VID_EVN_Y_ST 0x00D8
|
||||
#define DC_VID_EVN_U_ST 0x00DC
|
||||
#define DC_VID_EVN_V_ST 0x00E0
|
||||
|
||||
#define DC_VID_EVN_ACT 0x00E4
|
||||
#define DC_VID_EVN_BLANK 0x00E8
|
||||
#define DC_VID_EVN_SYNC 0x00EC
|
||||
|
||||
#define DC_VGA_CONFIG 0x0100
|
||||
#define DC_VGA_STATUS 0x0104
|
||||
//#define DC_VGA_EXTADDR 0x0108
|
||||
|
||||
#define DC_UNLOCK_VALUE 0x00004758
|
||||
#define DC_LOCK_VALUE 0x00000000
|
||||
|
||||
//-----------------------------------//
|
||||
// DC_GENERAL_CFG Bit Definitions //
|
||||
//-----------------------------------//
|
||||
// DC_GCFG_CLR_MASK turns off everything but VGA fixed timing enable, VGA enable,
|
||||
// compression and decompression enables and Display-FIFO Load Enable
|
||||
#define DC_GCFG_CLR_MASK 0x0004FF00
|
||||
|
||||
#define DC_GCFG_DFLE 0x00000001
|
||||
#define DC_GCFG_CURE 0x00000002
|
||||
#define DC_GCFG_ICNE 0x00000004
|
||||
#define DC_GCFG_VIDE 0x00000008
|
||||
//#define DC_GCFG_VSPE 0x00000010
|
||||
#define DC_GCFG_FSSEL 0x00000010
|
||||
#define DC_GCFG_CMPE 0x00000020
|
||||
#define DC_GCFG_DECE 0x00000040
|
||||
#define DC_GCFG_VGAE 0x00000080
|
||||
|
||||
#define DC_GCFG_DFIFO_ST 0x00000F00
|
||||
#define DC_GCFG_DFIFO_END 0x0000F000
|
||||
#define DC_GCFG_WATERMARKS 0x00007200
|
||||
#define DC_GCFG_STFM 0x00010000
|
||||
#define DC_GCFG_FDTY 0x00020000
|
||||
#define DC_GCFG_VGAFT 0x00040000
|
||||
#define DC_GCFG_VDSE 0x00080000
|
||||
#define DC_GCFG_YUVM 0x00100000
|
||||
//#define DC_GCFG_FTSTR 0x00200000
|
||||
#define DC_GCFG_FRC8PIX 0x00400000
|
||||
#define DC_GCFG_SIGSEL 0x00800000
|
||||
#define DC_GCFG_CLR_CRC 0xF8FFFFFF
|
||||
//#define DC_GCFG_CLR_CRC_ALL 0xF07FFFFF
|
||||
#define DC_GCFG_CLR_CRC_ALL 0xF07FFFEF
|
||||
#define DC_GCFG_SIGE 0x01000000
|
||||
#define DC_GCFG_SGRE 0x02000000
|
||||
#define DC_GCFG_SGFR 0x04000000
|
||||
#define DC_GCFG_CRCMODE 0x08000000
|
||||
//#define DC_GCFG_GXRFS4 0x08000000
|
||||
|
||||
|
||||
//-----------------------------------//
|
||||
// DC_DISPLAY_CFG Bit Definitions //
|
||||
//-----------------------------------//
|
||||
// DC_DCFG_CLR_MASK turns off everything but display center, color depth fields,
|
||||
// and scale enable.
|
||||
#define DC_DCFG_CLR_MASK 0xC0000F00
|
||||
#define DC_DCFG_BLANK_MASK 0xFFFFFFC0
|
||||
|
||||
#define DC_DCFG_TGEN 0x00000001
|
||||
//#define DC_DCFG_PCKE 0x00000002
|
||||
//#define DC_DCFG_VCKE 0x00000004
|
||||
#define DC_DCFG_GDEN 0x00000008
|
||||
//#define DC_DCFG_VDEN 0x00000010
|
||||
#define DC_DCFG_VIEN 0x00000020
|
||||
#define DC_DCFG_TRUP 0x00000040
|
||||
#define DC_DCFG_SCLE 0x00000080
|
||||
|
||||
// Color depth related masks and values
|
||||
#define DC_DCFG_MODE_MASK 0x00000F00
|
||||
#define DC_DCFG_16BPP_MODE 0x00000C00
|
||||
#define DC_DCFG_DISP_MODE 0x00000300
|
||||
|
||||
#define DC_DCFG_BPP16 0x00000100
|
||||
#define DC_DCFG_BPP15 0x00000500
|
||||
#define DC_DCFG_BPP12 0x00000900
|
||||
#define DC_DCFG_BPP32 0x00000200
|
||||
|
||||
#define DC_DCFG_VFHPSL 0x0000F000
|
||||
//#define DC_DCFG_PLNR 0x00001000
|
||||
//#define DC_DCFG_SSLC 0x00002000
|
||||
//#define DC_DCFG_PXDB 0x00004000
|
||||
//#define DC_DCFG_LNDB 0x00008000
|
||||
|
||||
#define DC_DCFG_VFHPEL 0x000F0000
|
||||
//#define DC_DCFG_BLNK 0x00010000
|
||||
//#define DC_DCFG_BKRT 0x00020000
|
||||
//#define DC_DCFG_RFS4 0x00040000
|
||||
//#define DC_DCFG_DCEN 0x00080000
|
||||
|
||||
//#define DC_DCFG_PIX_PAN 0x00F00000
|
||||
//#define DC_DCFG_PPC 0x01000000
|
||||
#define DC_DCFG_DCEN 0x01000000
|
||||
#define DC_DCFG_PALB 0x02000000
|
||||
//#define DC_DCFG_FRLK 0x04000000
|
||||
#define DC_DCFG_VISL 0x08000000
|
||||
//#define DC_DCFG_A18M 0x40000000
|
||||
//#define DC_DCFG_A20M 0x80000000
|
||||
|
||||
//-----------------------------------//
|
||||
// DC_IRQ_FLT_CTL Bit Definitions //
|
||||
//-----------------------------------//
|
||||
#define IF_FLT_ADDR_MASK 0x000000FF
|
||||
#define IF_HFILT_SEL 0x00000400
|
||||
#define IF_INTL_EN 0x00000800
|
||||
#define IF_HFILT_EN 0x00001000
|
||||
#define IF_VFILT_EN 0x00002000
|
||||
#define IF_HALPH_FILT_EN 0x00004000
|
||||
#define IF_VALPH_FILT_EN 0x00008000
|
||||
#define IF_LIN_CNT_MASK 0x07FF0000
|
||||
#define IF_IRQ_EN 0x08000000
|
||||
#define IF_INTL_ADDR 0x10000000
|
||||
|
||||
|
||||
|
||||
//
|
||||
// DF Memory Mapped Register Set
|
||||
//
|
||||
#define DF_VCFG 0x0000
|
||||
#define DF_DCFG 0x0008
|
||||
#define DF_VID_X 0x0010
|
||||
#define DF_VID_Y 0x0018
|
||||
#define DF_VID_SCL 0x0020
|
||||
#define DF_VID_CK 0x0028
|
||||
#define DF_VID_CM 0x0030
|
||||
#define DF_PAL_ADDR 0x0038
|
||||
#define DF_PAL_DATA 0x0040
|
||||
|
||||
#define DF_SLR 0x0048
|
||||
|
||||
#define DF_MISC 0x0050
|
||||
#define DF_CRT_CS 0x0058
|
||||
|
||||
#define DF_VYS 0x0060
|
||||
#define DF_VXS 0x0068
|
||||
|
||||
#define DF_VID_DSC 0x0078
|
||||
//#define DF_VID_DCO 0x0080
|
||||
|
||||
#define DF_CRC_SIG 0x0088
|
||||
#define DF_CRCS_CLR_CRC 0xFFFFFFF8
|
||||
#define DF_CRCS_SIGE 0x00000001
|
||||
#define DF_CRCS_SGFR 0x00000004
|
||||
#define DF_CRC32_SIG 0x0090
|
||||
|
||||
#define DF_VID_VDE 0x0098
|
||||
#define DF_VID_CCK 0x00A0
|
||||
#define DF_VID_CCM 0x00A8
|
||||
#define DF_VID_CC1 0x00B0
|
||||
#define DF_VID_CC2 0x00B8
|
||||
#define DF_VID_A1X 0x00C0
|
||||
#define DF_VID_A1Y 0x00C8
|
||||
#define DF_VID_A1C 0x00D0
|
||||
#define DF_VID_A1T 0x00D8
|
||||
#define DF_VID_A2X 0x00E0
|
||||
#define DF_VID_A2Y 0x00E8
|
||||
#define DF_VID_A2C 0x00F0
|
||||
#define DF_VID_A2T 0x00F8
|
||||
#define DF_VID_A3X 0x0100
|
||||
#define DF_VID_A3Y 0x0108
|
||||
#define DF_VID_A3C 0x0110
|
||||
#define DF_VID_A3T 0x0118
|
||||
#define DF_VID_VRR 0x0120
|
||||
#define DF_VID_AWT 0x0128
|
||||
|
||||
// Flat panel specific
|
||||
#define DF_FP_PT1 0x0400
|
||||
#define DF_FP_PT2 0x0408
|
||||
#define DF_FP_PM 0x0410
|
||||
#define DF_FP_DFC 0x0418
|
||||
#define DF_DFC_NO_DITHER 0x00000070
|
||||
//#define DF_FP_BLFSR 0x0420
|
||||
//#define DF_FP_RLFSR 0x0428
|
||||
//#define DF_FP_FMI 0x0430
|
||||
//#define DF_FP_FMD 0x0438
|
||||
//#define DF_FP_RSVD 0x0440
|
||||
#define DF_FP_DCA 0x0448
|
||||
#define DF_FP_DMD 0x0450
|
||||
#define DF_FP_CRC 0x0458
|
||||
//#define DF_FP_FBB 0x0460
|
||||
#define DF_FP_CRC32 0x0468
|
||||
|
||||
// VOP specific
|
||||
#define DF_VOP_CFG 0x0800
|
||||
#define DF_VOP_SIG 0x0808
|
||||
|
||||
#define DF_VID_VCR 0x1000
|
||||
|
||||
#define DF_DCFG_VID_EN 0x00000001
|
||||
|
||||
//-----------------------------------//
|
||||
// DF_DCFG Bit Definitions //
|
||||
//-----------------------------------//
|
||||
// DF_DCFG_CLR_MASK turns off everything but CRT sync skew. The blank mask turns off
|
||||
// CRT DACs, the CRT sync enables and resets the display logic.
|
||||
#define DF_DCFG_CLR_MASK 0x0001C000
|
||||
#define DF_DCFG_BLANK_MASK 0xFFFFFFF0 // 0xF431FF30
|
||||
#define DF_DCFG_ENABLE_MASK 0x0000000F
|
||||
#define DF_DCFG_DPMS_STBY 0x00000005
|
||||
#define DF_DCFG_DPMS_SUSP 0x00000003
|
||||
|
||||
#define DF_DCFG_DIS_EN 0x00000001
|
||||
#define DF_DCFG_HSYNC_EN 0x00000002
|
||||
#define DF_DCFG_VSYNC_EN 0x00000004
|
||||
#define DF_DCFG_DAC_BL_EN 0x00000008
|
||||
//#define DF_DCFG_DAC_PWDNX 0x00000020
|
||||
//#define DF_DCFG_FP_PWR_EN 0x00000040
|
||||
//#define DF_DCFG_FP_DATA_EN 0x00000080
|
||||
#define DF_DCFG_CRT_HSYNC_POL 0x00000100
|
||||
#define DF_DCFG_CRT_VSYNC_POL 0x00000200
|
||||
//#define DF_DCFG_FP_HSYNC_POL 0x00000400
|
||||
//#define DF_DCFG_FP_VSYNC_POL 0x00000800
|
||||
//#define DF_DCFG_XGA_FP 0x00001000
|
||||
//#define DF_DCFG_FP_DITH_EN 0x00002000
|
||||
#define DF_DCFG_CRT_SYNC_SKW_MASK 0x0001C000
|
||||
#define DF_DCFG_CRT_SYNC_SKW_POS 14
|
||||
//#define DF_DCFG_PWR_SEQ_DLY_MASK 0x000E0000
|
||||
//#define DF_DCFG_PWR_SEQ_DLY_POS 17
|
||||
//#define DF_DCFG_PWR_SEQ_DLY_VAL 0x00080000
|
||||
#define DF_DCFG_VG_CK 0x00100000
|
||||
#define DF_DCFG_GV_PAL_BYP 0x00200000
|
||||
//#define DF_DCFG_DDC_SCL 0x00400000
|
||||
//#define DF_DCFG_DDC_SDA 0x00800000
|
||||
//#define DF_DCFG_DDC_OE 0x01000000
|
||||
#define DF_DCFG_DAC_VREF 0x04000000
|
||||
//#define DF_DCFG_FP_PWR_ON 0x08000000
|
||||
|
||||
|
||||
//-----------------------------------//
|
||||
// DF_FP_PT1 Bit Definitions //
|
||||
//-----------------------------------//
|
||||
#define DF_PT1_HPULSE_MASK 0x0000001F
|
||||
#define DF_PT1_HDELAY_MASK 0x000000E0 // Not used in LXVG
|
||||
#define DF_PT1_HDELAY_SHIFT 5
|
||||
#define DF_PT1_O 0x00004000
|
||||
#define DF_PT1_U 0x00008000
|
||||
#define DF_PT1_VSIZE_MASK 0x07FF0000
|
||||
#define DF_PT1_VSIZE_SHIFT 16
|
||||
#define DF_PT1_HSRC 0x08000000
|
||||
#define DF_PT1_HSIP 0x20000000
|
||||
#define DF_PT1_VSIP 0x40000000
|
||||
|
||||
|
||||
//-----------------------------------//
|
||||
// DF_FP_PT2 Bit Definitions //
|
||||
//-----------------------------------//
|
||||
#define DF_PT2_CLP 0x00002000
|
||||
#define DF_PT2_PIXF_MASK 0x00070000
|
||||
#define DF_PT2_PIXF_SHIFT 16
|
||||
#define DF_PT2_PIXF_000 0x00000000
|
||||
#define DF_PT2_PIXF_001 0x00010000
|
||||
#define DF_PT2_PIXF_002 0x00020000
|
||||
#define DF_PT2_PIXF_003 0x00030000
|
||||
#define DF_PT2_MCS 0x00080000
|
||||
#define DF_PT2_PSEL_MASK 0x00300000
|
||||
#define DF_PT2_PSEL_STN 0x00000000
|
||||
#define DF_PT2_PSEL_TFT 0x00100000
|
||||
#define DF_PT2_HSP 0x00400000
|
||||
#define DF_PT2_VSP 0x00800000
|
||||
#define DF_PT2_VFS 0x01000000
|
||||
#define DF_PT2_LMS 0x02000000
|
||||
#define DF_PT2_LHS 0x04000000
|
||||
#define DF_PT2_SCRC 0x08000000
|
||||
#define DF_PT2_LPOL 0x20000000
|
||||
#define DF_PT2_TPASS 0x40000000
|
||||
|
||||
//-----------------------------------//
|
||||
// DF_FP_PM Bit Definitions //
|
||||
//-----------------------------------//
|
||||
#define DF_PM_SINV 0x00002000
|
||||
#define DF_PM_VDEL_MASK 0x0000C000
|
||||
#define DF_PM_VDEL_SHIFT 14
|
||||
#define DF_PM_HDEL_MASK 0x00030000
|
||||
#define DF_PM_HDEL_SHIFT 16
|
||||
#define DF_PM_PD0 0x00040000
|
||||
#define DF_PM_PD1 0x00080000
|
||||
#define DF_PM_PD2 0x00100000
|
||||
#define DF_PM_PUB0 0x00200000
|
||||
#define DF_PM_PUB1 0x00400000
|
||||
#define DF_PM_PUB2 0x00800000
|
||||
#define DF_PM_P 0x01000000
|
||||
#define DF_PM_D 0x02000000
|
||||
#define DF_PM_PWR_SEQ 0x08000000
|
||||
|
||||
//-----------------------------------//
|
||||
// DF_VOP_CFG Bit Definitions //
|
||||
//-----------------------------------//
|
||||
#define DF_VOP_ENABLE_MASK 0x00000003
|
||||
#define DF_VOP_VIP11 0x00000001
|
||||
#define DF_VOP_VIP2 0x00000002
|
||||
#define DF_VOP_CCIR656 0x00000003
|
||||
#define DF_VOP_LVL2 0x00000004
|
||||
#define DF_VOP_EXTSAV 0x00000008
|
||||
#define DF_VOP_422CO 0x00000000
|
||||
#define DF_VOP_422RCO 0x00000010
|
||||
#define DF_VOP_422ASS 0x00000020
|
||||
#define DF_VOP_SC120X 0x00000040
|
||||
#define DF_VOP_SIGE 0x00000080
|
||||
#define DF_VOP_SIGFR 0x00000100
|
||||
|
||||
|
||||
//
|
||||
// VIP Memory Mapped Register Set
|
||||
//
|
||||
#define VIP_CTRL1 0x0000
|
||||
#define VIP_CTRL2 0x0004
|
||||
#define VIP_STATUS 0x0008
|
||||
#define VIP_INTS 0x000C
|
||||
#define VIP_CURTGT 0x0010
|
||||
#define VIP_MAX_ADDR 0x0014
|
||||
|
||||
#define VIP_AVID_EBASE 0x0018
|
||||
#define VIP_AVID_OBASE 0x001C
|
||||
#define VIP_AVBI_EBASE 0x0020
|
||||
#define VIP_AVBI_OBASE 0x0024
|
||||
#define VIP_A_PITCH 0x0028
|
||||
#define VIP_CTRL3 0x002C
|
||||
#define VIP_A_VOBUF 0x0030
|
||||
#define VIP_A_UOBUF 0x0034
|
||||
|
||||
#define VIP_BVID_EBASE 0x0038
|
||||
#define VIP_BVID_OBASE 0x003C
|
||||
#define VIP_BVBI_EBASE 0x0040
|
||||
#define VIP_BVBI_OBASE 0x0044
|
||||
#define VIP_B_PITCH 0x0048
|
||||
#define VIP_B_VBUF 0x0050
|
||||
#define VIP_B_UBUF 0x0054
|
||||
|
||||
#define VIP_AMSG_1BASE 0x0058
|
||||
#define VIP_AMSG_2BASE 0x005C
|
||||
#define VIP_AMSG_SIZE 0x0060
|
||||
|
||||
#define VIP_PAGE_OFFS 0x0068
|
||||
#define VIP_VERT_ST 0x006C
|
||||
#define VIP_FIFO_ADDR 0x0070
|
||||
#define VIP_FIFO_RW 0x0074
|
||||
#define VIP_FRM_DCNT 0x0078
|
||||
#define VIP_A_VEBUF 0x007C
|
||||
#define VIP_A_UEBUF 0x0080
|
||||
|
||||
|
||||
|
||||
// CHIPSET IDS
|
||||
// Keep as bitwise flags to make "either" comparisons easier.
|
||||
|
||||
#define CHIPSET_CX5530 0x01
|
||||
#define CHIPSET_REDC 0x02
|
||||
#define CHIPSET_DHRUVA 0x10
|
||||
#define CHIPSET_BHARGAVA 0x20
|
||||
#define CX5530_DISPLAY_CONFIG 0x00000004
|
||||
|
||||
// TRAPPED PCI DEVICES
|
||||
|
||||
#define PCI_CONFIG_MASK 0xFFFFFF00 // bits for comparison
|
||||
#define PCI_NSM_FLAGS_REG0 0x44 // register for flags
|
||||
#define PCI_NSM_FLAGS_REG1 0x45 // register for flags
|
||||
#define PCI_NSM_FLAGS_REG2 0x46 // register for flags
|
||||
#define PCI_NSM_FLAGS_REG3 0x47 // register for flags
|
||||
#define PCI_NSM_FLAG_DISABLE 0x01 // flag to disable LXVG
|
||||
|
||||
// SYSTEM FLAGS (stored in VGState)
|
||||
|
||||
#define SF_DISABLED 0x00000001 // LXVG is disabled
|
||||
#define SF_SECONDARY 0x00000002 // Init to secondary controller capability
|
||||
#define SF_PRIMARY 0x00000004 // Init to primary controller capability
|
||||
// The next flag indicates a mode switch has occurred. Generally only the first mode
|
||||
// switch is interesting.
|
||||
#define SF_MODE_SET 0x00000008
|
||||
#define SF_END_POST 0x00000010 // POST is complete
|
||||
#define SF_DRIVER_ENABLED 0x00000020 // Graphics driver is controlling system
|
||||
#define SF_DIAG_SMI 0x00000040 // Use diagnostic SMI settings
|
||||
|
||||
#define SF_MONOCHROME 0x00000100 // monochrome mode
|
||||
#define SF_3D0_RANGE 0x00000200 // remembers state of ioaddr bit in misc output
|
||||
#define SF_SCALE_DISABLED 0x00000400 // Disable graphics scaling during fixed timings
|
||||
#define SF_FORCE_VALIDATION 0x00000800 // force all HW validation
|
||||
|
||||
|
||||
// SMM HEADER FLAGS
|
||||
|
||||
#define SMM_IO_WRITE 0x0002
|
||||
#define SMM_VR_WRITE 0x0001
|
||||
|
||||
// FLAGS FOR PCI TRAP EVENTS
|
||||
|
||||
#define PCI_TRAP_WRITE 0x80
|
||||
|
||||
#include "VGdata.h"
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
|
||||
extern VGDATA VGdata;
|
||||
extern unsigned long VGState;
|
||||
extern unsigned long lockNest; // Nested SMI recognition scheme
|
||||
extern unsigned long saveLock; // Nested SMI recognition scheme
|
||||
extern unsigned short vReg[];
|
||||
extern unsigned long vga_config_addr;
|
||||
extern unsigned long GPregister_base;
|
||||
extern unsigned long VGregister_base;
|
||||
extern unsigned long DFregister_base;
|
||||
extern unsigned long VIPregister_base;
|
||||
extern unsigned long framebuffer_base;
|
||||
extern unsigned long VG_SMI_Mask;
|
||||
extern unsigned char crc_time;
|
||||
|
||||
|
||||
//------------//
|
||||
// ROUTINES //
|
||||
//------------//
|
||||
|
||||
// ROUTINES IN MSR.C
|
||||
|
||||
unsigned char msrInit(void);
|
||||
unsigned short msrFindDevice(struct tagMSR *);
|
||||
unsigned short msrIdDevice(unsigned long);
|
||||
unsigned short msrRead(unsigned short msrIdx, unsigned short msrReg, struct mValue *);
|
||||
unsigned short msrWrite(unsigned short msrIdx, unsigned short msrReg, unsigned long outHi, unsigned long outLo);
|
||||
void msrModify(unsigned short msrIdx, unsigned short msrReg,
|
||||
unsigned long andHi, unsigned long andLo, unsigned long orHi, unsigned long orLo);
|
||||
void msrSave(unsigned short msrIdx, unsigned short *, struct mValue *);
|
||||
void msrRestore(unsigned short msrIdx, unsigned short *, struct mValue *);
|
||||
void msrDump(unsigned short msrIdx, unsigned short msrReg);
|
||||
|
||||
|
||||
// ROUTINES IN VSA2.C
|
||||
|
||||
void decode_vsa2_event(void);
|
||||
void vsa2_io_read(unsigned short size, unsigned long data);
|
||||
|
||||
|
||||
// ROUTINES IN DECODE.C
|
||||
|
||||
void virtual_register_event(unsigned char reg, unsigned long rwFlag, unsigned long vrData);
|
||||
void pci_trap_event(unsigned long address, unsigned long size, unsigned long data);
|
||||
|
||||
|
||||
// ROUTINES IN GXHWCTL.C
|
||||
|
||||
void hw_initialize(unsigned short config);
|
||||
void hw_gp_msr_init(void);
|
||||
void hw_vip_msr_init(void);
|
||||
void hw_vg_msr_init(void);
|
||||
void hw_df_msr_init(void);
|
||||
void hw_mcp_msr_init(void);
|
||||
void hw_fb_map_init(unsigned long fbLoc);
|
||||
|
||||
// ROUTINES IN INIT.C
|
||||
|
||||
void lxvg_initialize(unsigned short init_parms);
|
||||
|
||||
|
||||
// ROUTINES IN UTILS.ASM
|
||||
|
||||
unsigned long read_fb_32(unsigned long offset);
|
||||
void write_fb_32(unsigned long offset, unsigned long data);
|
||||
unsigned long read_gp_32(unsigned long offset);
|
||||
void write_gp_32(unsigned long offset, unsigned long data);
|
||||
unsigned char read_vg_8(unsigned long offset);
|
||||
void write_vg_8(unsigned long offset, unsigned char data);
|
||||
unsigned long read_vg_32(unsigned long offset);
|
||||
void write_vg_32(unsigned long offset, unsigned long data);
|
||||
unsigned long read_df_32(unsigned long offset);
|
||||
void write_df_32(unsigned long offset, unsigned long data);
|
||||
unsigned long read_vip_32(unsigned long offset);
|
||||
void write_vip_32(unsigned long offset, unsigned long data);
|
||||
void asmRead(unsigned short msrReg, unsigned long msrAddr, unsigned long *ptrHigh, unsigned long *ptrLow);
|
||||
void asmWrite(unsigned short msrReg, unsigned long msrAddr, unsigned long *ptrHigh, unsigned long *ptrLow);
|
||||
|
||||
55
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/main.asm
vendored
Executable file
55
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/main.asm
vendored
Executable file
@@ -0,0 +1,55 @@
|
||||
;/*
|
||||
;* Copyright (c) 2007-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
;*
|
||||
;* This library is free software; you can redistribute it and/or modify
|
||||
;* it under the terms of the GNU Lesser General Public License as
|
||||
;* published by the Free Software Foundation; either version 2.1 of the
|
||||
;* License, or (at your option) any later version.
|
||||
;*
|
||||
;* This code is distributed in the hope that it will be useful,
|
||||
;* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
;* Lesser General Public License for more details.
|
||||
;
|
||||
;* You should have received a copy of the GNU Lesser General
|
||||
;* Public License along with this library; if not, write to the
|
||||
;* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
;* Boston, MA 02111-1307 USA
|
||||
;*/
|
||||
|
||||
;* This file contains the VSM header for the LXVG VSM
|
||||
|
||||
|
||||
.model tiny,c
|
||||
.486
|
||||
.CODE
|
||||
|
||||
include VSA2.INC
|
||||
|
||||
externdef edata:proc
|
||||
externdef _end:proc
|
||||
externdef vsa2_message_loop:proc
|
||||
|
||||
public VSM_Hdr
|
||||
|
||||
|
||||
VSM_Hdr:
|
||||
|
||||
dd VSM_SIGNATURE ; VSM signature
|
||||
db VSM_VGA ; VSM type
|
||||
db 0FFh ; Any CPU
|
||||
dw 0FFFFh ; Any Chipset
|
||||
dw 0101h ; VSM version 01.01
|
||||
dd OFFSET edata ; Size of VSM module
|
||||
dw OFFSET vsa2_message_loop; EntryPoint
|
||||
dd OFFSET _end ; DS Limit
|
||||
dw 0000h ; Requirements
|
||||
dw VSA_VERSION ; VSA version
|
||||
db sizeof(VSM_Header) - ($-VSM_Hdr) dup (0)
|
||||
|
||||
|
||||
END VSM_Hdr
|
||||
|
||||
|
||||
|
||||
|
||||
158
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/makefile
vendored
Executable file
158
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/makefile
vendored
Executable file
@@ -0,0 +1,158 @@
|
||||
# Copyright (c) 2007-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation; either version 2.1 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU Lesser General
|
||||
# Public License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
# Boston, MA 02111-1307 USA
|
||||
|
||||
######################################################################
|
||||
#
|
||||
# Init variables
|
||||
#
|
||||
######################################################################
|
||||
!ifndef VSA2ROOT
|
||||
VSA2ROOT = ..
|
||||
!endif
|
||||
|
||||
BUILD_DIR = $(VSA2ROOT)\build
|
||||
OBJECT = obj
|
||||
!include $(BUILD_DIR)\setvars.mak
|
||||
|
||||
.SUFFIXES: .asm .c .h .inc .map .obj .mac
|
||||
|
||||
INCLUDE = $(OBJECT)
|
||||
|
||||
|
||||
######################################################################
|
||||
#
|
||||
# Build Macros
|
||||
#
|
||||
######################################################################
|
||||
|
||||
VGA_C_OBJS = \
|
||||
$(OBJECT)\vsa2.obj \
|
||||
$(OBJECT)\init.obj \
|
||||
$(OBJECT)\msr.obj \
|
||||
$(OBJECT)\decode.obj \
|
||||
$(OBJECT)\vgdata.obj \
|
||||
$(OBJECT)\lxhwctl.obj \
|
||||
|
||||
VGA_ASM_OBJS = \
|
||||
$(OBJECT)\main.obj \
|
||||
$(OBJECT)\utils.obj \
|
||||
|
||||
|
||||
VGA_OBJS = $(VGA_ASM_OBJS) $(VGA_C_OBJS)
|
||||
|
||||
VGA_VSM = $(OBJECT)\lxvg.vsm
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# Targets
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
|
||||
all: setenv
|
||||
$(MAKE) lxvga.vsm "CPU=lx"
|
||||
|
||||
lxvga.vsm: $(OBJECT) $(VGA_OBJS)
|
||||
$(LN) $(LOPTS_VSM) @<<
|
||||
$(VGA_OBJS: =+^
|
||||
)
|
||||
$(VGA_VSM)
|
||||
lxvg.map
|
||||
$(BUILD_DIR)\obj\$(TOOL_LIB) ;
|
||||
<<NOKEEP
|
||||
$(COPY) $(VGA_VSM) $(BUILDOBJ)
|
||||
|
||||
#This and only this clean target must exist as it is called by cleanall
|
||||
#cleanall and cleanlocal are defined in rules.mak
|
||||
|
||||
clean: cleanlocal cleanlib
|
||||
|
||||
$(OBJECT):
|
||||
-@md $(OBJECT)
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# Dependencies
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
$(VGA_ASM_OBJS): $(MAKEDIR)\makefile \
|
||||
$(OBJECT)\vsa2.inc \
|
||||
|
||||
$(VGA_C_OBJS): $(MAKEDIR)\makefile \
|
||||
$(BUILD_DIR)\obj\$(TOOL_LIB) \
|
||||
$(OBJECT)\vsa2.h \
|
||||
$(OBJECT)\isa.h \
|
||||
$(OBJECT)\chipset.h \
|
||||
$(OBJECT)\vr.h \
|
||||
$(OBJECT)\pci.h \
|
||||
$(OBJECT)\lxvg.h \
|
||||
$(OBJECT)\vgdata.h \
|
||||
|
||||
######################################################################
|
||||
#
|
||||
# Common Targets
|
||||
#
|
||||
######################################################################
|
||||
# include common targets and inference rules
|
||||
!include $(BUILD_DIR)\rules.mak
|
||||
|
||||
######################################################################
|
||||
#
|
||||
# Inference Rules
|
||||
#
|
||||
######################################################################
|
||||
# Override common inference rules here
|
||||
|
||||
{$(INC_DIR)}.h{$(OBJECT)}.inc:
|
||||
$(H2) /Fa$(OBJECT)\$(@F) /nologo /Zni /C $<
|
||||
|
||||
{$(INC_DIR)\$(CPU)}.h{$(OBJECT)}.inc:
|
||||
$(H2) /Fa$(OBJECT)\$(@F) /nologo /Zni /C $<
|
||||
|
||||
{$(SYSMGR_SRC)}.h{$(OBJECT)}.inc:
|
||||
$(H2) /Fa$(OBJECT)\$(@F) /nologo /Zns /C $<
|
||||
|
||||
{$(SYSMGR_SRC)\$(CPU)}.h{$(OBJECT)}.inc:
|
||||
$(H2) /Fa$(OBJECT)\$(@F) /nologo /Zns /C $<
|
||||
|
||||
{$(MAKEDIR)}.c{$(OBJECT)}.obj:
|
||||
$(CC) /AT /W3 /G3s /Gx /Oi /c /I$(OBJECT) $(CDEFS) /Fo$@ $<
|
||||
|
||||
{$(MAKEDIR)\$(CPU)}.c{$(OBJECT)}.obj:
|
||||
$(CC) /AT /W3 /G3s /Gx /Oi /c /I$(OBJECT) $(CDEFS) /Fo$@ $<
|
||||
|
||||
{$(MAKEDIR)}.asm{$(OBJECT)}.obj:
|
||||
$(AS) /nologo $(AS_OPTS) $(CDEFS) /Fo$@ $<
|
||||
|
||||
{$(MAKEDIR)\$(CPU)}.asm{$(OBJECT)}.obj:
|
||||
$(AS) /nologo $(AS_OPTS) $(CDEFS) /Fo$@ $<
|
||||
|
||||
{$(MAKEDIR)}.h{$(OBJECT)}.h:
|
||||
copy $< $@
|
||||
|
||||
{$(USER)\lxvg}.h{$(OBJECT)}.h:
|
||||
copy $< $@
|
||||
|
||||
{$(USER)\lxvg}.h{$(OBJECT)}.inc:
|
||||
$(H2) /Fa$(OBJECT)\$(@F) /nologo /Zns /C $<
|
||||
|
||||
{$(USER)\lxvg}.asm{$(OBJECT)}.obj:
|
||||
$(AS) /nologo $(AS_OPTS) $(CDEFS) /Fo$@ $<
|
||||
|
||||
{$(USER)\lxvg}.c{$(OBJECT)}.obj:
|
||||
$(CC) /AT /W3 /G3s /Gx /Oi /c /I$(OBJECT) $(CDEFS) /Fo$@ $<
|
||||
305
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/msr.c
vendored
Executable file
305
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/msr.c
vendored
Executable file
@@ -0,0 +1,305 @@
|
||||
/*
|
||||
* Copyright (c) 2007-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include "lxvg.h"
|
||||
#include "vsa2.h"
|
||||
|
||||
#define FOUND 0
|
||||
#define UNKNOWN 1
|
||||
#define REQ_NOT_FOUND 2
|
||||
|
||||
struct tagMSR msrDev[] = {
|
||||
{ UNKNOWN, ID_MCP, FAKE_ADDRESS },
|
||||
{ UNKNOWN, ID_MC, FAKE_ADDRESS },
|
||||
{ UNKNOWN, ID_GP, FAKE_ADDRESS },
|
||||
{ UNKNOWN, ID_VG, FAKE_ADDRESS },
|
||||
{ UNKNOWN, ID_DF, FAKE_ADDRESS },
|
||||
{ UNKNOWN, ID_VIP, FAKE_ADDRESS } };
|
||||
// DEBUG
|
||||
// { UNKNOWN, ID_MBIU, FAKE_ADDRESS } };
|
||||
// DEBUG
|
||||
|
||||
#define NUM_DEVS sizeof(msrDev) / sizeof(struct tagMSR)
|
||||
|
||||
|
||||
//=================================================================
|
||||
// BOOL msrInit(void)
|
||||
//
|
||||
// Handles the details of finding each possible device on the MBUS.
|
||||
// If a given device is not found, its structure is left inited at default.
|
||||
// If a given device is found, its structure is updated.
|
||||
//
|
||||
// This init routine only checks for devices already in the structure.
|
||||
//
|
||||
// Returns:
|
||||
// TRUE - If, for every device, its address was found.
|
||||
// FALSE - If, for any device, an error was encountered.
|
||||
//
|
||||
|
||||
unsigned char msrInit(void)
|
||||
{
|
||||
unsigned short issues=0, i;
|
||||
|
||||
//
|
||||
// For each item in the list, try to find its address
|
||||
//
|
||||
for (i=0; i < NUM_DEVS; i++)
|
||||
{
|
||||
msrDev[i].Present = msrFindDevice(&msrDev[i]);
|
||||
if (msrDev[i].Present != FOUND) issues++;
|
||||
}
|
||||
|
||||
if (issues) return(FALSE);
|
||||
|
||||
/*
|
||||
//
|
||||
// For each item in the list, get its real device ID
|
||||
//
|
||||
for (i=0; i < NUM_DEVS; i++)
|
||||
msrDev[i].Id = msrIdDevice(msrDev[i].Address);
|
||||
*/
|
||||
return(TRUE);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//=================================================================
|
||||
// unsigned short msrFindDevice(struct msr *pDev)
|
||||
//
|
||||
// Returns:
|
||||
// FOUND - if no errors were detected. msrAddress has been updated.
|
||||
// REQ_NOT_FOUND - Address for 'devId' is unknown. Caller should
|
||||
// call msrInit() first. ptr->Address is not updated.
|
||||
//
|
||||
// NOTE: The structure default for the 'Present' field is "UNKNOWN".
|
||||
// Therefore, if a given id is passed to msrFindDevice, the 'Present'
|
||||
// field will be updated with either 'FOUND' or 'REQ_NOT_FOUND'. If
|
||||
// a given ID is not passed to msrFindDevice, the 'Present' field will
|
||||
// be left as 'UNKNOWN'.
|
||||
//
|
||||
|
||||
unsigned short msrFindDevice(struct tagMSR *pDev)
|
||||
{
|
||||
unsigned long msrAdr;
|
||||
msrAdr = SYS_LOOKUP_DEVICE(pDev->Id,1);
|
||||
if (0 != msrAdr)
|
||||
{
|
||||
pDev->Routing = msrAdr;
|
||||
return(FOUND);
|
||||
}
|
||||
|
||||
// All done...
|
||||
return(REQ_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
||||
//=================================================================
|
||||
// unsigned short msrIdDevice(unsigned long address)
|
||||
//
|
||||
// Reads the capabilities MSR register (typically 0x2000)
|
||||
// and returns the 'id' field (bits 23:8)
|
||||
//
|
||||
// Returns:
|
||||
// Bits 23:8 of MSR low DWORD
|
||||
//
|
||||
|
||||
unsigned short msrIdDevice(unsigned long address)
|
||||
{
|
||||
struct mValue msrValue;
|
||||
|
||||
asmRead(MBD_MSR_CAP, address, &msrValue.high, &msrValue.low);
|
||||
|
||||
return((unsigned short)((msrValue.low & DEVID_MASK) >> 8));
|
||||
|
||||
}
|
||||
|
||||
|
||||
//=================================================================
|
||||
// unsigned short msrRead(unsigned short msrIdx, unsigned short msrReg, struct mValue msrValue)
|
||||
//
|
||||
// Performs a 64-bit read from 'msrReg' in device 'devID'.
|
||||
//
|
||||
// Returns:
|
||||
// FOUND - if no errors were detected and msrValue has been updated.
|
||||
// UNKNOWN - an error was detected. msrValue is not updated.
|
||||
// REQ_NOT_FOUND - 'msrAddress' for 'devID' is unknown. Caller
|
||||
// should call msrInit() first. msrValue is not updated.
|
||||
//
|
||||
|
||||
unsigned short msrRead(unsigned short msrIdx, unsigned short msrReg, struct mValue *msrValue)
|
||||
{
|
||||
|
||||
if (msrDev[msrIdx].Present == FOUND) {
|
||||
asmRead(msrReg, msrDev[msrIdx].Routing, &msrValue->high, &msrValue->low);
|
||||
}
|
||||
|
||||
return (msrDev[msrIdx].Present);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//=================================================================
|
||||
// unsigned short msrWrite(unsigned short msrIdx, unsigned short msrReg, unsigned long outHi, unsigned long outLo)
|
||||
//
|
||||
// Performs a 64-bit write to 'msrReg' in device 'devID'.
|
||||
//
|
||||
// Returns:
|
||||
// FOUND - if no errors were detected and msrValue has been updated.
|
||||
// UNKNOWN - an error was detected. msrValue is not updated.
|
||||
// REQ_NOT_FOUND - 'msrAddress' for 'devID' is unknown. Caller
|
||||
// should call msrInit() first. msrValue is not updated.
|
||||
//
|
||||
|
||||
unsigned short msrWrite(unsigned short msrIdx, unsigned short msrReg, unsigned long outHi, unsigned long outLo)
|
||||
{
|
||||
struct mValue mVal;
|
||||
|
||||
if (msrDev[msrIdx].Present == FOUND) {
|
||||
// Incorporate the OR values
|
||||
mVal.high = outHi;
|
||||
mVal.low = outLo;
|
||||
|
||||
asmWrite(msrReg, msrDev[msrIdx].Routing, &mVal.high, &mVal.low);
|
||||
}
|
||||
|
||||
return (msrDev[msrIdx].Present);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//=================================================================
|
||||
// void msrModify(unsigned short msrIdx, unsigned short msrReg, unsigned long maskHi, unsigned long maskLo,
|
||||
// unsigned long orHi, unsigned long orLo)
|
||||
//
|
||||
// Performs a 64-bit read-modify-write of 'msrReg' in device 'msrIdx'.
|
||||
// The mask values indicate the bits that are to be changed, so the
|
||||
// register values are ANDed with the NOT of the mask values to clear
|
||||
// out the affected bits.
|
||||
//
|
||||
// Returns:
|
||||
// NONE
|
||||
//
|
||||
|
||||
void msrModify(unsigned short msrIdx, unsigned short msrReg, unsigned long maskHi, unsigned long maskLo, unsigned long orHi, unsigned long orLo)
|
||||
{
|
||||
struct mValue mVal;
|
||||
|
||||
if (msrDev[msrIdx].Present == FOUND) {
|
||||
asmRead(msrReg, msrDev[msrIdx].Routing, &mVal.high, &mVal.low);
|
||||
|
||||
// Incorporate the AND values
|
||||
mVal.high &= ~maskHi;
|
||||
mVal.low &= ~maskLo;
|
||||
|
||||
// Incorporate the OR values
|
||||
mVal.high |= orHi;
|
||||
mVal.low |= orLo;
|
||||
|
||||
asmWrite(msrReg, msrDev[msrIdx].Routing, &mVal.high, &mVal.low);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//=================================================================
|
||||
// void msrSave(unsigned short msrIdx, unsigned short *msrList[], struct mValue *msrValue[])
|
||||
//
|
||||
// Saves a list of MSRs limited by an index value of 0xFFFF.
|
||||
//
|
||||
//
|
||||
|
||||
void msrSave(unsigned short msrIdx, unsigned short *msrList, struct mValue *msrValue)
|
||||
{
|
||||
unsigned char finished = FALSE;
|
||||
unsigned char i = 0;
|
||||
|
||||
if (msrDev[msrIdx].Present == FOUND)
|
||||
{
|
||||
while (FALSE == finished)
|
||||
{
|
||||
if (0xFFFF == msrList[i])
|
||||
finished = TRUE;
|
||||
else
|
||||
{
|
||||
asmRead(msrList[i], msrDev[msrIdx].Routing, &msrValue[i].high, &msrValue[i].low);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//=================================================================
|
||||
// void msrRestore(unsigned short msrIdx, unsigned short *msrList[], struct mValue *msrValue[])
|
||||
//
|
||||
// Restores a previously saved list of MSRs limited by an index value of 0xFFFF.
|
||||
//
|
||||
//
|
||||
|
||||
void msrRestore(unsigned short msrIdx, unsigned short *msrList, struct mValue *msrValue)
|
||||
{
|
||||
unsigned char finished = FALSE;
|
||||
unsigned char i = 0;
|
||||
|
||||
if (msrDev[msrIdx].Present == FOUND)
|
||||
{
|
||||
while (FALSE == finished)
|
||||
{
|
||||
if (0xFFFF == msrList[i])
|
||||
finished = TRUE;
|
||||
else
|
||||
{
|
||||
asmWrite(msrList[i], msrDev[msrIdx].Routing, &msrValue[i].high, &msrValue[i].low);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//=================================================================
|
||||
// void msrDump(unsigned short msrIdx, unsigned short msrReg)
|
||||
//
|
||||
// Performs a 64-bit read of 'msrReg' in device 'msrIdx' for debug.
|
||||
//
|
||||
// Returns:
|
||||
// NONE
|
||||
//
|
||||
|
||||
void msrDump(unsigned short msrIdx, unsigned short msrReg)
|
||||
{
|
||||
struct mValue mVal;
|
||||
|
||||
asmRead(msrReg, msrDev[msrIdx].Routing, &mVal.high, &mVal.low);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
271
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/utils.asm
vendored
Executable file
271
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/utils.asm
vendored
Executable file
@@ -0,0 +1,271 @@
|
||||
;/*
|
||||
;* Copyright (c) 2007-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
;*
|
||||
;* This library is free software; you can redistribute it and/or modify
|
||||
;* it under the terms of the GNU Lesser General Public License as
|
||||
;* published by the Free Software Foundation; either version 2.1 of the
|
||||
;* License, or (at your option) any later version.
|
||||
;*
|
||||
;* This code is distributed in the hope that it will be useful,
|
||||
;* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
;* Lesser General Public License for more details.
|
||||
;
|
||||
;* You should have received a copy of the GNU Lesser General
|
||||
;* Public License along with this library; if not, write to the
|
||||
;* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
;* Boston, MA 02111-1307 USA
|
||||
;*/
|
||||
|
||||
|
||||
.MODEL TINY,c
|
||||
.CODE
|
||||
.586p
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; BASE ADDRESSES
|
||||
; These global variables are used to access the memory mapped regions.
|
||||
; VSA II maintains a flat 4 Gig selector in FS.
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
extrn framebuffer_base:dword
|
||||
extrn GPregister_base:dword
|
||||
extrn VGregister_base:dword
|
||||
extrn DFregister_base:dword
|
||||
extrn VIPregister_base:dword
|
||||
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; READ_FB_32: Returns a 32-bit value from the frame buffer.
|
||||
;
|
||||
; Parameter specifies 32-bit offset.
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
read_fb_32 proc c address: dword
|
||||
|
||||
mov ebx, [address]
|
||||
add ebx, [framebuffer_base]
|
||||
mov eax, fs:[ebx]
|
||||
mov edx, eax
|
||||
shr edx, 16
|
||||
ret
|
||||
|
||||
read_fb_32 endp
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; WRITE_FB_32: Writes a 32-bit value to the frame buffer.
|
||||
;
|
||||
; Parameters specify 32-bit offset and 32-bit data value.
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
write_fb_32 proc c address: dword, data: dword
|
||||
|
||||
mov ebx, [address]
|
||||
add ebx, [framebuffer_base]
|
||||
mov eax, [data]
|
||||
mov fs:[ebx], eax
|
||||
ret
|
||||
|
||||
write_fb_32 endp
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; READ_GP_32: Returns 32-bit value from the graphics processor register space.
|
||||
;
|
||||
; Parameter specifies 32-bit offset.
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
read_gp_32 proc c address: dword
|
||||
|
||||
mov ebx, [address]
|
||||
add ebx, [GPregister_base]
|
||||
mov eax, fs:[ebx]
|
||||
mov edx, eax
|
||||
shr edx, 16
|
||||
ret
|
||||
|
||||
read_gp_32 endp
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; WRITE_GP_32: Writes 32-bit value to graphics processor register space.
|
||||
;
|
||||
; Parameters specify 32-bit offset and 32-bit data value.
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
write_gp_32 proc c address: dword, data: dword
|
||||
|
||||
mov ebx, [address]
|
||||
add ebx, [GPregister_base]
|
||||
mov eax, [data]
|
||||
mov fs:[ebx], eax
|
||||
ret
|
||||
|
||||
write_gp_32 endp
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; READ_VG_8: Returns 8-bit value from the video generator register space.
|
||||
;
|
||||
; Parameter specifies 32-bit offset.
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
read_vg_8 proc c address: dword
|
||||
|
||||
mov ebx, [address]
|
||||
add ebx, [VGregister_base]
|
||||
mov al, fs:[ebx]
|
||||
ret
|
||||
|
||||
read_vg_8 endp
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; WRITE_VG_8: Writes 8-bit value to video generator register space.
|
||||
;
|
||||
; Parameters specify 32-bit offset and 8-bit data value.
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
write_vg_8 proc c address: dword, data: byte
|
||||
|
||||
mov ebx, [address]
|
||||
add ebx, [VGregister_base]
|
||||
mov al, [data]
|
||||
mov fs:[ebx], al
|
||||
ret
|
||||
|
||||
write_vg_8 endp
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; READ_VG_32: Returns 32-bit value from the video generator register space.
|
||||
;
|
||||
; Parameter specifies 32-bit offset.
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
read_vg_32 proc c address: dword
|
||||
|
||||
mov ebx, [address]
|
||||
add ebx, [VGregister_base]
|
||||
mov eax, fs:[ebx]
|
||||
mov edx, eax
|
||||
shr edx, 16
|
||||
ret
|
||||
|
||||
read_vg_32 endp
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; WRITE_VG_32: Writes 32-bit value to video generator register space.
|
||||
;
|
||||
; Parameters specify 32-bit offset and 32-bit data value.
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
write_vg_32 proc c address: dword, data: dword
|
||||
|
||||
mov ebx, [address]
|
||||
add ebx, [VGregister_base]
|
||||
mov eax, [data]
|
||||
mov fs:[ebx], eax
|
||||
ret
|
||||
|
||||
write_vg_32 endp
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; READ_DF_32: Returns 32-bit value from the display filter register space.
|
||||
;
|
||||
; Parameter specifies 32-bit offset.
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
read_df_32 proc c address: dword
|
||||
|
||||
mov ebx, [address]
|
||||
add ebx, [DFregister_base]
|
||||
mov eax, fs:[ebx]
|
||||
mov edx, eax
|
||||
shr edx, 16
|
||||
ret
|
||||
|
||||
read_df_32 endp
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; WRITE_DF_32: Writes 32-bit value to display filter register space.
|
||||
;
|
||||
; Parameters specify 32-bit offset and 32-bit data value.
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
write_df_32 proc c address: dword, data: dword
|
||||
|
||||
mov ebx, [address]
|
||||
add ebx, [DFregister_base]
|
||||
mov eax, [data]
|
||||
mov fs:[ebx], eax
|
||||
ret
|
||||
|
||||
write_df_32 endp
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; READ_VIP_32: Returns 32-bit value from the video input port register space.
|
||||
;
|
||||
; Parameter specifies 32-bit offset.
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
read_vip_32 proc c address: dword
|
||||
|
||||
mov ebx, [address]
|
||||
add ebx, [VIPregister_base]
|
||||
mov eax, fs:[ebx]
|
||||
mov edx, eax
|
||||
shr edx, 16
|
||||
ret
|
||||
|
||||
read_vip_32 endp
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; WRITE_VIP_32: Writes 32-bit value to video input port register space.
|
||||
;
|
||||
; Parameters specify 32-bit offset and 32-bit data value.
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
write_vip_32 proc c address: dword, data: dword
|
||||
|
||||
mov ebx, [address]
|
||||
add ebx, [VIPregister_base]
|
||||
mov eax, [data]
|
||||
mov fs:[ebx], eax
|
||||
ret
|
||||
|
||||
write_vip_32 endp
|
||||
|
||||
|
||||
asmRead proc public uses bx eax ecx edx, msrReg:word, msrAddr:dword, ptrHigh:word, ptrLow:word
|
||||
mov ecx, msrAddr
|
||||
mov cx, msrReg
|
||||
RDMSR
|
||||
|
||||
mov bx, ptrHigh
|
||||
mov [bx], edx
|
||||
mov bx, ptrLow
|
||||
mov [bx], eax
|
||||
|
||||
ret
|
||||
|
||||
asmRead endp
|
||||
|
||||
|
||||
asmWrite proc public uses bx eax ecx edx, msrReg:word, msrAddr:dword, ptrHigh:word, ptrLow:word
|
||||
|
||||
mov ecx, msrAddr
|
||||
mov cx, msrReg
|
||||
|
||||
mov bx, ptrHigh
|
||||
mov edx, [bx]
|
||||
mov bx, ptrLow
|
||||
mov eax, [bx]
|
||||
|
||||
WRMSR
|
||||
ret
|
||||
|
||||
asmWrite endp
|
||||
|
||||
END
|
||||
55
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/vgdata.c
vendored
Executable file
55
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/vgdata.c
vendored
Executable file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2007-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
// This file declares the data structures and arrays used by lxvg.
|
||||
|
||||
|
||||
|
||||
#include "lxvg.h"
|
||||
#include "vsa2.h"
|
||||
#include "vr.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// MAIN lxvg DATA STRUCTURE
|
||||
// This data structure maintains the current lxvg state.
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
VGDATA VGdata;
|
||||
|
||||
unsigned long vga_config_addr;
|
||||
|
||||
unsigned long GPregister_base;
|
||||
unsigned long VGregister_base;
|
||||
unsigned long DFregister_base;
|
||||
unsigned long VIPregister_base;
|
||||
unsigned long framebuffer_base;
|
||||
|
||||
unsigned long VG_SMI_Mask;
|
||||
|
||||
// General system information...
|
||||
Hardware SystemInfo;
|
||||
|
||||
// The main VG state information flag.
|
||||
unsigned long VGState = SF_DISABLED;
|
||||
unsigned long lockNest = 0; // Nested SMI recognition scheme
|
||||
unsigned long saveLock; // Locking
|
||||
|
||||
// The virtual registers
|
||||
unsigned short vReg[MAX_VG+1];
|
||||
|
||||
// END OF FILE
|
||||
36
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/vgdata.h
vendored
Executable file
36
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/vgdata.h
vendored
Executable file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2007-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
// This file defines the main data structure for LXVG.
|
||||
|
||||
|
||||
|
||||
#define SIZE_PCI_HEADER 0x50
|
||||
|
||||
typedef struct tagVGDATA
|
||||
{
|
||||
|
||||
// PCI HEADER
|
||||
|
||||
unsigned char pci_header[SIZE_PCI_HEADER]; // PCI header data
|
||||
unsigned long pci_fb_mask;
|
||||
|
||||
} VGDATA;
|
||||
|
||||
// END OF FILE
|
||||
133
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/vsa2.c
vendored
Executable file
133
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/vsa2.c
vendored
Executable file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
// Function:
|
||||
// This module contains the main code to handle the VSA II interface.
|
||||
|
||||
|
||||
#include "vsa2.h"
|
||||
#include "vr.h"
|
||||
#include "lxvg.h"
|
||||
|
||||
// This is required here because of inclusion problems in LXVG.h
|
||||
extern Hardware SystemInfo;
|
||||
|
||||
// ARRAY TO STORE VSA II MESSAGE PARAMETERS
|
||||
unsigned long VSAparam[MAX_MSG_PARAM];
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// vsa2_message_loop
|
||||
//
|
||||
// This is the main routine that handles the VSA II message interface.
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void vsa2_message_loop(void)
|
||||
{
|
||||
MSG Msg;
|
||||
|
||||
// SPIN FOREVER ON MESSAGE LOOP
|
||||
// The VSA system manager branches here after loading the VSM. Control
|
||||
// is returned to the system manager using an SMI.
|
||||
|
||||
do {
|
||||
|
||||
// GET THE NEXT MESSAGE
|
||||
// If a message is available, the macro reads the parameter data
|
||||
// from the VSM header and copies it to the VSAparam global array.
|
||||
// If a message is not available, control returns to the main VSA
|
||||
// dispatcher.
|
||||
Msg = SYS_GET_NEXT_MSG(&VSAparam);
|
||||
|
||||
// DECODE THE MESSAGE
|
||||
switch(Msg)
|
||||
{
|
||||
case MSG_INITIALIZE:
|
||||
|
||||
// CHECK IF NORMAL INITIALIZATION
|
||||
// Currently there is no "end of post" initialization.
|
||||
if (VSAparam[0] == EARLY_INIT) {
|
||||
|
||||
// Get information about the system I'm executing on.
|
||||
SYS_GET_SYSTEM_INFO(&SystemInfo);
|
||||
|
||||
// REGISTER FOR VGA VIRTUAL REGISTER EVENTS
|
||||
SYS_REGISTER_EVENT(EVENT_VIRTUAL_REGISTER, VRC_VG, 0, NORMAL_PRIORITY);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// Now we can handle DPMS and driver active
|
||||
VGState |= SF_END_POST;
|
||||
}
|
||||
break;
|
||||
|
||||
case MSG_EVENT:
|
||||
|
||||
// DECODE THE EVENT
|
||||
decode_vsa2_event();
|
||||
break;
|
||||
|
||||
case MSG_WARM_BOOT:
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
} while(1);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// decode_vsa2_event
|
||||
//
|
||||
// This routine is called when the message loop receives an event. For
|
||||
// LXVG, this is either a Virtual Rgister event or a pci event
|
||||
// (trapping PCI config cycles to our device).
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void decode_vsa2_event(void)
|
||||
{
|
||||
// PARSE EVENT
|
||||
|
||||
switch((unsigned short)VSAparam[0])
|
||||
{
|
||||
case EVENT_VIRTUAL_REGISTER:
|
||||
if (VRC_VG == (unsigned char)(VSAparam[1] >> 8))
|
||||
virtual_register_event((unsigned char)VSAparam[1], VSAparam[2], VSAparam[3]);
|
||||
|
||||
break;
|
||||
|
||||
case EVENT_PCI_TRAP:
|
||||
// If LXVG isn't enabled, just leave
|
||||
if (VGState & SF_DISABLED) break;
|
||||
|
||||
// CALL LXVG TO DECODE THE PCI TRAP EVENT
|
||||
// address = VSAparam[1]
|
||||
// size = VSAparam[2], bit 7 indicates write.
|
||||
// data = VSAparam[3]
|
||||
|
||||
pci_trap_event(VSAparam[1], VSAparam[2], VSAparam[3]);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
221
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/bugs.asm
vendored
Executable file
221
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/bugs.asm
vendored
Executable file
@@ -0,0 +1,221 @@
|
||||
;
|
||||
; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
;
|
||||
; This library is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU Lesser General Public License as
|
||||
; published by the Free Software Foundation; either version 2.1 of the
|
||||
; License, or (at your option) any later version.
|
||||
;
|
||||
; This code is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
; Lesser General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU Lesser General
|
||||
; Public License along with this library; if not, write to the
|
||||
; Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
; Boston, MA 02111-1307 USA
|
||||
;
|
||||
;* Function: *
|
||||
;* This file contains hardware bug fixes.
|
||||
|
||||
include VSA2.INC
|
||||
include ISA.INC
|
||||
include GX2.INC
|
||||
include CHIPSET.INC
|
||||
|
||||
.model tiny,c
|
||||
.586p
|
||||
.CODE
|
||||
|
||||
externdef Nested_SMI: proc
|
||||
externdef SysMgr_Entry: proc
|
||||
externdef Restore_IDT: proc
|
||||
externdef Install_IDT: proc
|
||||
externdef Sample_SMI_Pin: proc
|
||||
externdef Clear_SMI_Pin: proc
|
||||
externdef Header_Addr: dword
|
||||
externdef HC_Status: dword
|
||||
externdef SMI_Sources: dword
|
||||
externdef HardwareInfo: Hardware
|
||||
|
||||
|
||||
;*******************************************************************************
|
||||
; Remove the RTC fix if an RTC VSM is installed.
|
||||
;*******************************************************************************
|
||||
Remove_RTC_Fix proc
|
||||
|
||||
mov word ptr [Fix_RTC], 0C3F8h ; CLC RET
|
||||
ret
|
||||
|
||||
Remove_RTC_Fix endp
|
||||
|
||||
|
||||
; *******************************************************************************
|
||||
; This routine is called upon entry to a non-nested SMI.
|
||||
; *******************************************************************************
|
||||
VSA_Entry proc
|
||||
|
||||
; Patch a "jmp Nested_SMI" at Start
|
||||
mov word ptr ds:[1], OFFSET Nested_SMI-3
|
||||
|
||||
; Install exception handlers
|
||||
call Install_IDT
|
||||
ret
|
||||
|
||||
VSA_Entry endp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; *******************************************************************************
|
||||
; This routine is called upon exit from a non-nested SMI.
|
||||
; It performs:
|
||||
; 1) RTC fix
|
||||
; 2) USB fix
|
||||
; 3) IDT restore
|
||||
; 4) Re-enable Suspend Modulation
|
||||
;
|
||||
; If CF=1 is returned, then loop back to SMI handlers.
|
||||
; *******************************************************************************
|
||||
VSA_Exit proc
|
||||
|
||||
mov eax, [Header_Addr] ; Restore the original SMM header
|
||||
mov ecx, MSR_SMM_HDR
|
||||
wrmsr
|
||||
|
||||
call Fix_RTC
|
||||
jc short Exit ; Don't exit from VSA
|
||||
|
||||
; Restore "JMP SysMgr_Entry" at Start
|
||||
mov word ptr ds:[1], OFFSET SysMgr_Entry-3
|
||||
|
||||
|
||||
call Restore_IDT ; Restore IDT
|
||||
|
||||
clc
|
||||
|
||||
Exit: ret
|
||||
|
||||
VSA_Exit endp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; *******************************************************************************
|
||||
; Handle the case where the RTC UIP bit was clear, application code was about to
|
||||
; read the RTC, but an SMI occurs. When VSA returns, the RTC is updating, so the
|
||||
; application reads a bad value.
|
||||
;
|
||||
; The Solution:
|
||||
;
|
||||
; The Time Stamp Counter is read upon entry to VSA. On exit, if UIP is low or
|
||||
; it is determined that the SMI has taken < 250 us, then just exit. This leaves
|
||||
; 44 us for the application to finish reading the RTC safely. If the SMI has
|
||||
; taken > 250 us, then spin for 500 us minus the time spent servicing the SMI.
|
||||
; This guarantees the RTC has finished updating. Then set the SET bit, wait for
|
||||
; UIP to go low, then clear the SET bit.
|
||||
;
|
||||
; *******************************************************************************
|
||||
RTC_TIME equ 250
|
||||
|
||||
Fix_RTC proc
|
||||
|
||||
in al, CMOS_INDEX ; Get RTC index
|
||||
cmp al, 9 ; Only RTC indices 0-9 are UIP sensitive
|
||||
ja Exit
|
||||
|
||||
mov bl, al ; Save RTC index
|
||||
push si
|
||||
mov al, CMOS_STATUS_A ; Read RTC Status A
|
||||
out CMOS_INDEX, al
|
||||
in al, CMOS_DATA
|
||||
test al, UIP
|
||||
jz Restore_RTC_Index
|
||||
|
||||
|
||||
mov al, CMOS_STATUS_B ; Exit if StatusB[SET] = 1
|
||||
out CMOS_INDEX, al
|
||||
in al, CMOS_DATA
|
||||
test al, SET
|
||||
jz Restore_RTC_Index
|
||||
|
||||
|
||||
|
||||
ASSUME SI: PTR System ; Compute time servicing SMI in us
|
||||
mov si, OFFSET VSM_Header.SysStuff
|
||||
rdtsc
|
||||
sub eax, [si+0].StartTime
|
||||
sbb edx, [si+4].StartTime
|
||||
movzx ecx, [HardwareInfo].CPU_MHz
|
||||
cmp edx, ecx ; If sitting in Dowser or Standby too long,
|
||||
jae Restore_RTC_Index ; the divide could overflow.
|
||||
div ecx
|
||||
|
||||
cmp eax, RTC_TIME ; If < RTC_TIME us, exit
|
||||
jb Restore_RTC_Index
|
||||
|
||||
|
||||
call Clear_SMI_Pin
|
||||
WaitForUpdate:
|
||||
call Sample_SMI_Pin
|
||||
stc
|
||||
jnz short SMI_Abort ; Yes, go process it
|
||||
|
||||
|
||||
rdtsc ; Wait for additional 300 us
|
||||
sub eax, [si+0].StartTime
|
||||
sbb edx, [si+4].StartTime
|
||||
div ecx
|
||||
cmp eax, RTC_TIME + 300
|
||||
jb WaitForUpdate
|
||||
|
||||
ASSUME SI: NOTHING
|
||||
|
||||
|
||||
; StatusB[SET] = 1;
|
||||
mov al, CMOS_STATUS_B ; Read RTC StatusB
|
||||
out CMOS_INDEX, al
|
||||
in al, CMOS_DATA
|
||||
test al, SET ; If (SET == 1)
|
||||
jnz short Restore_RTC_Index ; bail
|
||||
or al, SET ; else
|
||||
out CMOS_DATA, al ; SET = 1
|
||||
|
||||
; Wait for StatusA[UIP] to go inactive
|
||||
mov cx, 0FFFFh ; RTC timeout
|
||||
SpinUIP:
|
||||
mov al, CMOS_STATUS_A ; Yes, spin until UIP is clear
|
||||
out CMOS_INDEX, al
|
||||
in al, CMOS_DATA
|
||||
test al, UIP
|
||||
loopnz SpinUIP
|
||||
|
||||
mov al, CMOS_STATUS_B ; SET = 0
|
||||
out CMOS_INDEX, al
|
||||
in al, CMOS_DATA
|
||||
and al, NOT SET
|
||||
out CMOS_DATA, al
|
||||
|
||||
Restore_RTC_Index:
|
||||
clc
|
||||
SMI_Abort:
|
||||
pop si
|
||||
mov al, bl ; Restore CMOS index
|
||||
out CMOS_INDEX, al
|
||||
Exit: ret
|
||||
|
||||
|
||||
Fix_RTC endp
|
||||
|
||||
|
||||
|
||||
END
|
||||
|
||||
262
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/chip.asm
vendored
Executable file
262
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/chip.asm
vendored
Executable file
@@ -0,0 +1,262 @@
|
||||
;
|
||||
; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
;
|
||||
; This library is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU Lesser General Public License as
|
||||
; published by the Free Software Foundation; either version 2.1 of the
|
||||
; License, or (at your option) any later version.
|
||||
;
|
||||
; This code is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
; Lesser General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU Lesser General
|
||||
; Public License along with this library; if not, write to the
|
||||
; Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
; Boston, MA 02111-1307 USA
|
||||
;
|
||||
;********************************************************************************
|
||||
;* This file contains the Southbridge specific code.
|
||||
;********************************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
include smimac.mac
|
||||
include chipset.inc
|
||||
include pci.inc
|
||||
include sysmgr.inc
|
||||
include init.inc
|
||||
include cs5536.inc
|
||||
|
||||
|
||||
.model small,c
|
||||
.586
|
||||
.CODE
|
||||
|
||||
|
||||
externdef Errors: word
|
||||
externdef Device_ID: word
|
||||
externdef Chipset_Base: dword
|
||||
|
||||
;***********************************************************************
|
||||
; Clear all SMI source registers
|
||||
;***********************************************************************
|
||||
Clear_SMIs proc
|
||||
|
||||
mov ax, [Device_ID] ; Get Southbridge Device ID
|
||||
cmp ax, DEVICE_ID_5536 ; If CS5536, exit
|
||||
clc
|
||||
je Exit
|
||||
|
||||
or [Errors], ERR_NO_CHIPSET
|
||||
stc
|
||||
jmp Exit
|
||||
|
||||
Exit: ret
|
||||
|
||||
Clear_SMIs endp
|
||||
|
||||
|
||||
|
||||
|
||||
;****************************************************************
|
||||
; Returns information about the Southbridge
|
||||
;
|
||||
; On Exit, if CF clear:
|
||||
; EBX = PCI address of Southbridge
|
||||
; CL = Chipset Revision
|
||||
; DX = Device ID
|
||||
;****************************************************************
|
||||
Get_Sbridge_Info proc
|
||||
|
||||
mov ebx, 80000000h+(15 SHL 11) ; Start at Bus 0; DevNum 15
|
||||
SouthbridgeLoop:
|
||||
call Read_PCI32
|
||||
cmp ax, VENDOR_ID_CYRIX ; Is it a Cyrix chipset ?
|
||||
je short CorrectVendorID
|
||||
cmp ax, VENDOR_ID_NATIONAL ; Is it a National Semiconductor chipset ?
|
||||
je short CorrectVendorID
|
||||
cmp ax, VENDOR_ID_AMD ; Is it an AMD chipset ?
|
||||
jne short NextDevice
|
||||
CorrectVendorID:
|
||||
shr eax, 16
|
||||
push ax ; Save device ID
|
||||
|
||||
mov bl, 8 ; Read Class Code & Rev ID
|
||||
call Read_PCI32
|
||||
mov cl, al ; Save revision in CL
|
||||
shr eax, 16
|
||||
cmp ax, 0601h ; Is it an ISA bridge ?
|
||||
pop dx
|
||||
mov bl, 0 ; Vendor & Device ID
|
||||
je Exit ; CF is cleared
|
||||
|
||||
|
||||
; Check the DeviceID
|
||||
cmp dx, DEVICE_ID_5536-1 ; Hardware CS5536 Device ID
|
||||
jne NextDevice
|
||||
FoundSB:
|
||||
; On CS5536, the virtualized Device ID is h/w Device ID + 1
|
||||
inc dx
|
||||
push cx
|
||||
push dx
|
||||
mov ecx, 5100002Fh ; Write-post I/O to port 84h for debug
|
||||
mov edx, 00084001h
|
||||
mov eax, edx
|
||||
or al, 8
|
||||
wrmsr
|
||||
pop dx
|
||||
pop cx
|
||||
jmp Exit
|
||||
|
||||
NextDevice:
|
||||
add bh, 8 ; Next device
|
||||
cmp bh, (19 SHL 3) ; Last possible DevNum ?
|
||||
jbe SouthbridgeLoop
|
||||
|
||||
; Can't find supported Southbridge chipset
|
||||
or [Errors], ERR_NO_CHIPSET
|
||||
stc
|
||||
|
||||
Exit: ret
|
||||
|
||||
Get_Sbridge_Info endp
|
||||
|
||||
|
||||
;****************************************************************
|
||||
; Generates a s/w SMI
|
||||
;****************************************************************
|
||||
Software_SMI proc
|
||||
|
||||
smint
|
||||
ret
|
||||
|
||||
Software_SMI endp
|
||||
|
||||
|
||||
;*********************************************************************************
|
||||
; Reads 32-bit PCI config register specified by EBX
|
||||
;*********************************************************************************
|
||||
Read_PCI32 proc
|
||||
|
||||
mov dx, PCI_CONFIG_ADDRESS
|
||||
mov eax, ebx
|
||||
out dx, eax
|
||||
mov dx, PCI_CONFIG_DATA
|
||||
in eax, dx
|
||||
ret
|
||||
|
||||
Read_PCI32 endp
|
||||
|
||||
|
||||
|
||||
|
||||
;*********************************************************************************
|
||||
; Writes a 32 bit Southbridge register
|
||||
; Input:
|
||||
; DL - register offset
|
||||
; EAX - value to write
|
||||
;*********************************************************************************
|
||||
SetReg_32 proc uses bx
|
||||
|
||||
push eax
|
||||
mov bl, dl
|
||||
call Address8
|
||||
pop eax
|
||||
out dx, eax
|
||||
ret
|
||||
|
||||
SetReg_32 endp
|
||||
|
||||
|
||||
;*********************************************************************************
|
||||
; Writes an 8 bit register
|
||||
; Input:
|
||||
; BL = register #
|
||||
; BH = Data
|
||||
;*********************************************************************************
|
||||
SetReg_8 proc
|
||||
|
||||
call Address8
|
||||
mov al, bh
|
||||
out dx, al
|
||||
ret
|
||||
|
||||
SetReg_8 endp
|
||||
|
||||
|
||||
|
||||
;*********************************************************************************
|
||||
; Reads an 8 bit register
|
||||
; Input:
|
||||
; BL = register #
|
||||
; Output:
|
||||
; AL = Data
|
||||
;*********************************************************************************
|
||||
GetReg_8 proc
|
||||
|
||||
call Address8
|
||||
in al, dx
|
||||
ret
|
||||
|
||||
GetReg_8 endp
|
||||
|
||||
;*********************************************************************************
|
||||
; Helper routine for SetReg_32, SetReg_8 & GetReg_8
|
||||
;*********************************************************************************
|
||||
Address8 proc
|
||||
|
||||
mov dx, PCI_CONFIG_ADDRESS
|
||||
mov eax, [Chipset_Base]
|
||||
mov al, bl
|
||||
and al, NOT 3
|
||||
out dx, eax
|
||||
mov dx, PCI_CONFIG_DATA
|
||||
and bl, 3
|
||||
add dl, bl
|
||||
ret
|
||||
|
||||
Address8 endp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;*********************************************************************************
|
||||
; Determines the base address of the top-level SMI status register
|
||||
; On Exit:
|
||||
; EAX = address
|
||||
;*********************************************************************************
|
||||
Get_SMI_Base proc
|
||||
|
||||
mov ebx, [Chipset_Base] ; Patch SMI_Base
|
||||
add bx, PM_FUNCTION + BAR0
|
||||
call Read_PCI32
|
||||
mov al, SMI_STATUS
|
||||
ret
|
||||
|
||||
Get_SMI_Base endp
|
||||
|
||||
|
||||
|
||||
;*********************************************************************************
|
||||
; Determines the base address of the internal IRQ register
|
||||
; On Exit:
|
||||
; EAX = address
|
||||
;*********************************************************************************
|
||||
Get_IRQ_Base proc
|
||||
|
||||
mov ebx, [Chipset_Base] ; Patch SMI_Base
|
||||
add bx, AUDIO_FUNCTION + BAR0 ; Patch IRQ_Base
|
||||
call Read_PCI32
|
||||
mov al, 1Ah
|
||||
ret
|
||||
|
||||
Get_IRQ_Base endp
|
||||
|
||||
|
||||
|
||||
END
|
||||
|
||||
239
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/chipset.c
vendored
Executable file
239
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/chipset.c
vendored
Executable file
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* The routines in this file translate requests for hardware
|
||||
* support to Southbridge-specific function calls.
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#include "VSA2.H"
|
||||
#include "CHIPSET.H"
|
||||
#include "CS5536.H"
|
||||
#include "ISA.H"
|
||||
#include "SYSMGR.H"
|
||||
#include "PROTOS.H"
|
||||
#include "GX2.H"
|
||||
|
||||
|
||||
// External function prototypes
|
||||
extern void MillisecondTimer(UCHAR, EVENT_ENTRY *);
|
||||
extern void InitTimers(void);
|
||||
extern void Init_CS5536(void);
|
||||
extern void pascal Enable_USB_5536(UCHAR, USHORT);
|
||||
extern void pascal Address_Decode_5536(UCHAR, USHORT);
|
||||
extern void pascal MBus_IO_Trap(ULONG, ULONG, UCHAR);
|
||||
extern void pascal MBus_IO_Timeout(ULONG, ULONG, UCHAR);
|
||||
extern void pascal A20_Init(UCHAR);
|
||||
extern void pascal InactivityTimer(UCHAR, USHORT, UCHAR);
|
||||
extern void pascal Program_PWM(UCHAR, UCHAR, USHORT, UCHAR);
|
||||
|
||||
// External variables
|
||||
extern EVENT_ENTRY Events[];
|
||||
extern Hardware HardwareInfo;
|
||||
extern ULONG MPCI_NB;
|
||||
extern ULONG ATA_Error;
|
||||
|
||||
// Local variables:
|
||||
typedef void (pascal * CHIPSET_DEPENDENT)(unsigned char, unsigned short);
|
||||
CHIPSET_DEPENDENT Address_Decode;
|
||||
CHIPSET_DEPENDENT Enable_USB;
|
||||
GPIO_FUNCTION GPIO_Control;
|
||||
ULONG ClocksPerMs;
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Initializes the Southbridge
|
||||
//*****************************************************************************
|
||||
void InitChipset(void)
|
||||
{
|
||||
|
||||
ClocksPerMs = HardwareInfo.CPU_MHz * 1000L;
|
||||
|
||||
InitTimers();
|
||||
|
||||
switch (HardwareInfo.Chipset_ID) {
|
||||
|
||||
case DEVICE_ID_5536:
|
||||
|
||||
Address_Decode = Address_Decode_5536;
|
||||
Enable_USB = Enable_USB_5536;
|
||||
|
||||
// Initialize the CS5536
|
||||
Init_CS5536();
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Enables trapping of a PCI function
|
||||
// Return value:
|
||||
// 0 = not supported
|
||||
// 1 = already enabled
|
||||
// 2 = previously disabled
|
||||
//*****************************************************************************
|
||||
UCHAR pascal Enable_PCI_Trapping(USHORT PCI_Address, UCHAR EnableFlag)
|
||||
{ UCHAR ReturnValue = 0;
|
||||
|
||||
|
||||
// Call the appropriate chipset routine
|
||||
switch (HardwareInfo.Chipset_ID) {
|
||||
|
||||
default:
|
||||
// Use PBUS MSR to trap this address
|
||||
Trap_PCI_IDSEL(PCI_Address, EnableFlag);
|
||||
ReturnValue = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return ReturnValue;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Diables an event
|
||||
//*****************************************************************************
|
||||
void pascal Disable_Event(EVENT Event, USHORT Index)
|
||||
{
|
||||
Enable_Event(Event, Index, 0);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// Enables an event
|
||||
//
|
||||
// EnableFlag:
|
||||
// 0 = Disable event
|
||||
// 1 = Enable event
|
||||
// 2 = Reset event logic (e.g. timer, GPIO)
|
||||
//*****************************************************************************
|
||||
void pascal Enable_Event(EVENT Event, USHORT Index, UCHAR EnableFlag)
|
||||
{ USHORT Device_ID;
|
||||
UCHAR Error = 0;
|
||||
ULONG Param1, Param2;
|
||||
EVENT_ENTRY * EventPtr;
|
||||
|
||||
Device_ID = HardwareInfo.Chipset_ID;
|
||||
|
||||
EventPtr = &Events[Index];
|
||||
Param1 = EventPtr->Param1;
|
||||
Param2 = EventPtr->Param2;
|
||||
|
||||
|
||||
switch (Event) {
|
||||
|
||||
case EVENT_USB:
|
||||
Enable_USB(EnableFlag, (USHORT)Param1);
|
||||
case EVENT_KEL:
|
||||
break;
|
||||
|
||||
case EVENT_TIMER:
|
||||
// Initialize RemainingInterval field to Interval
|
||||
if (EnableFlag == 1) {
|
||||
EventPtr->RemainingInterval = EventPtr->Param1;
|
||||
}
|
||||
MillisecondTimer(EnableFlag, EventPtr);
|
||||
break;
|
||||
|
||||
case EVENT_IO_TRAP:
|
||||
MBus_IO_Trap(Param1, Param2, EnableFlag);
|
||||
break;
|
||||
|
||||
case EVENT_DEVICE_TIMEOUT:
|
||||
// If programmer forgot to specify Instance, assume 1st instance
|
||||
if ((USHORT)Param2 == 0x0000) {
|
||||
(USHORT)Param2 = 1;
|
||||
}
|
||||
Param2 |= GLIU_ID;
|
||||
case EVENT_IO_TIMEOUT:
|
||||
MBus_IO_Timeout(Param1, Param2, EnableFlag);
|
||||
break;
|
||||
|
||||
case EVENT_PME:
|
||||
(USHORT)Param2 |= PME;
|
||||
case EVENT_GPIO:
|
||||
GPIO_Control(Param1, Param2, EnableFlag);
|
||||
break;
|
||||
|
||||
case EVENT_PCI_TRAP:
|
||||
if (Enable_PCI_Trapping((USHORT)Param1, EnableFlag) == 0) {
|
||||
// Companion I/O can't trap requested PCI function.
|
||||
Error = ERR_PCI_TRAP;
|
||||
}
|
||||
break;
|
||||
|
||||
case EVENT_ACPI:
|
||||
switch (Device_ID) {
|
||||
case DEVICE_ID_5536:
|
||||
Enable_ACPI_5536(EnableFlag);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case EVENT_PWM:
|
||||
// GPIO pin Duty cycle (%) Rate (ms)
|
||||
Program_PWM((UCHAR)Param1, (UCHAR)(Param2 >> 16), (USHORT)(Param1 >> 16), EnableFlag);
|
||||
|
||||
// 8 LSBs are GPIO pin number
|
||||
Param1 &= 0x000000FF;
|
||||
// Mask all except valid flags
|
||||
Param2 &= OPEN_DRAIN | PULLDOWN | PULLUP | INVERT;
|
||||
// Insert flags appropriate to PWM
|
||||
Param2 |= OUTPUT | NO_ASMI;
|
||||
if (EnableFlag) {
|
||||
Param2 |= AUX1;
|
||||
}
|
||||
GPIO_Control(Param1, Param2, EnableFlag);
|
||||
break;
|
||||
|
||||
} // end switch (Event)
|
||||
|
||||
if (Error) {
|
||||
Report_VSM_Error(Error, Event, Param1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void pascal Set_Address_Decode(USHORT Address, UCHAR Decode)
|
||||
{
|
||||
Address_Decode(Decode, Address);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void pascal Allocate_Resource(USHORT Resource, ULONG Param)
|
||||
{
|
||||
|
||||
switch ((UCHAR)Resource) {
|
||||
|
||||
case RESOURCE_IRQ:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
59
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/cpu.asm
vendored
Executable file
59
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/cpu.asm
vendored
Executable file
@@ -0,0 +1,59 @@
|
||||
;
|
||||
; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
;
|
||||
; This library is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU Lesser General Public License as
|
||||
; published by the Free Software Foundation; either version 2.1 of the
|
||||
; License, or (at your option) any later version.
|
||||
;
|
||||
; This code is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
; Lesser General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU Lesser General
|
||||
; Public License along with this library; if not, write to the
|
||||
; Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
; Boston, MA 02111-1307 USA
|
||||
;
|
||||
;* Function: *
|
||||
;* Implementation of routines specific to the Vail core.
|
||||
|
||||
|
||||
.model tiny,c
|
||||
.586p
|
||||
.ALPHA
|
||||
DGROUP GROUP _CODE, _TEXT
|
||||
_CODE SEGMENT PUBLIC use16 'CODE'
|
||||
ASSUME DS:_CODE
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;************************************************************************
|
||||
;************************************************************************
|
||||
Sample_SMI_Pin proc
|
||||
ret
|
||||
Sample_SMI_Pin endp
|
||||
|
||||
|
||||
|
||||
;************************************************************************
|
||||
;************************************************************************
|
||||
Clear_SMI_Pin proc
|
||||
|
||||
ret
|
||||
Clear_SMI_Pin endp
|
||||
|
||||
|
||||
|
||||
|
||||
_CODE ENDS
|
||||
|
||||
|
||||
END
|
||||
339
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/cpu_init.asm
vendored
Executable file
339
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/cpu_init.asm
vendored
Executable file
@@ -0,0 +1,339 @@
|
||||
;
|
||||
; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
;
|
||||
; This library is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU Lesser General Public License as
|
||||
; published by the Free Software Foundation; either version 2.1 of the
|
||||
; License, or (at your option) any later version.
|
||||
;
|
||||
; This code is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
; Lesser General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU Lesser General
|
||||
; Public License along with this library; if not, write to the
|
||||
; Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
; Boston, MA 02111-1307 USA
|
||||
;
|
||||
;* Function: *
|
||||
;* This file contains code specific to the processor core.
|
||||
|
||||
include vsa2.inc
|
||||
include gx2.inc
|
||||
include sysmgr.inc
|
||||
include init.inc
|
||||
include chipset.inc
|
||||
|
||||
.model small,c
|
||||
.586
|
||||
|
||||
.CODE
|
||||
|
||||
|
||||
externdef BIOS_ECX: dword
|
||||
externdef BIOS_EDX: dword
|
||||
externdef VSA_Image:byte
|
||||
|
||||
SMM_Size dd 0
|
||||
FooGlue dd 54000000h
|
||||
|
||||
;***********************************************************************
|
||||
; Sets CPU dependent fields in the SMM header
|
||||
; On entry:
|
||||
; SI = pointer to VSM header
|
||||
;***********************************************************************
|
||||
Set_CPU_Fields proc
|
||||
|
||||
SMM_CONTROL equ EXTL_SMI_EN + INTL_SMI_EN + SMM_INST_EN + NEST_SMI_EN
|
||||
|
||||
mov (VSM_Header PTR [si]).SysStuff.State.SMM_CTL_MSR, SMM_CONTROL
|
||||
ret
|
||||
|
||||
Set_CPU_Fields endp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; - Sets the SMM entry point to the location in EBX
|
||||
; - Sets the SMM header location
|
||||
; - Write protects the SMM regions
|
||||
;***********************************************************************
|
||||
Init_SMM_Region proc
|
||||
|
||||
; Set the SMM entry point
|
||||
mov ecx, MSR_SMM_LOC
|
||||
mov eax, ebx
|
||||
mov edx, [SMM_Size] ; SMM Code Limit
|
||||
wrmsr
|
||||
|
||||
; Set the SMM header location
|
||||
lea eax, (VSM_Header PTR [eax]).SysStuff.State + sizeof(SmiHeader)
|
||||
mov ecx, MSR_SMM_HDR
|
||||
xor edx, edx
|
||||
wrmsr
|
||||
|
||||
|
||||
; Write protect the SMM memory
|
||||
mov ecx, MSR_RCONF_SMM
|
||||
rdmsr
|
||||
or al, REGION_WP
|
||||
wrmsr
|
||||
|
||||
ret
|
||||
|
||||
Init_SMM_Region endp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Returns information about the LX CPU
|
||||
; On exit:
|
||||
; AX = CPU Revision
|
||||
; SI = CPU ID
|
||||
; BX = PCI MHz
|
||||
; CX = CPU MHz
|
||||
; DX = DRAM MHz
|
||||
;***********************************************************************
|
||||
Get_CPU_Info proc
|
||||
|
||||
mov ecx, 4C000014h ; GLCP_SYS_RSTPLL
|
||||
rdmsr
|
||||
|
||||
; PCI Speed
|
||||
mov bx, 33
|
||||
test al, 1 SHL 7 ; RSTPPL_LOWER_PCISPEED_SHIFT
|
||||
jz not66
|
||||
mov bx, 66
|
||||
not66:
|
||||
push bx ; save PCI speed
|
||||
|
||||
; CPU Speed
|
||||
mov ax, 333 ; 33.3MHZ * 10
|
||||
|
||||
ror dx, 1 ; RSTPLL_UPPER_CPUMULT_SHIFT
|
||||
mov bx, dx
|
||||
rol dx, 1 ; RSTPLL_UPPER_CPUMULT_SHIFT
|
||||
push dx ; save RSTPLL
|
||||
and bx, 1Fh
|
||||
inc bx ; 0 = multiply by 1....
|
||||
mul bx ; ax=PCI * bl=Mul
|
||||
|
||||
; Rounding divide
|
||||
mov bx, 10
|
||||
xor dx, dx
|
||||
div bx ; ax= quotent and dx=remainder
|
||||
cmp dx, 5
|
||||
jb NoRound ; can round because of /10
|
||||
inc ax ; round up
|
||||
NoRound:
|
||||
pop dx ; restore RSTPLL
|
||||
pop bx ; restore PCI * 10
|
||||
push ax ; save CPU speed
|
||||
|
||||
|
||||
; DRAM speed
|
||||
mov ax, 333 ; 33.3MHZ * 10
|
||||
|
||||
ror dx, 7 ; RSTPLL_UPPER_GLMULT_SHIFT
|
||||
mov bx, dx
|
||||
rol dx, 7 ; RSTPLL_UPPER_GLMULT_SHIFT
|
||||
push dx ; save RSTPLL
|
||||
and bx, 1Fh
|
||||
inc bx ; 0 = multiply by 1....
|
||||
mul bx ; ax=PCI * bl=Mul
|
||||
|
||||
; Rounding divide
|
||||
mov bx, 10
|
||||
xor dx, dx
|
||||
div bx ; ax= quotent and dx=remainder
|
||||
cmp dx, 5
|
||||
jb NoRoundmem ; can round because of /10
|
||||
inc ax ; round up
|
||||
NoRoundmem:
|
||||
|
||||
; DDR is 1/2 GeodeLink speed.
|
||||
xor dx, dx
|
||||
mov bx, 2
|
||||
div bx
|
||||
push ax ; save mem speed
|
||||
|
||||
; Get CPU Revision
|
||||
mov cx, 0017h
|
||||
rdmsr
|
||||
push ax
|
||||
|
||||
mov ecx, 10002000h ; Read MBIU0 Capabilities MSR
|
||||
rdmsr
|
||||
and ah, 0Fh ; Extract 4 LSBs of DEVID
|
||||
cmp ah, 04h ; Is it LX ?
|
||||
mov si, DEVICE_ID_GX2
|
||||
jne RestoreInfo
|
||||
mov si, DEVICE_ID_LX ; Yes
|
||||
mov [FooGlue], 4C000020h ; FooGlue is at Northbridge MCP + 20h
|
||||
RestoreInfo:
|
||||
pop ax ; Restore CPU Revision
|
||||
pop dx ; Restore DRAM MHz
|
||||
pop cx ; Restore CPU MHz
|
||||
pop bx ; Restore PCI MHz
|
||||
ret
|
||||
|
||||
Get_CPU_Info endp
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Returns the SMM information
|
||||
; On Exit:
|
||||
; EAX = SMM entry point
|
||||
; BX = Size of SMM memory in KB
|
||||
;***********************************************************************
|
||||
Get_SMM_Region proc
|
||||
Local Attributes: byte
|
||||
|
||||
mov ecx, MSR_RCONF_DEFAULT
|
||||
rdmsr
|
||||
mov [Attributes], al
|
||||
|
||||
|
||||
mov ecx, [BIOS_ECX] ; Descriptor for SMM memory
|
||||
rdmsr
|
||||
cmp cl, 27h ; P2D_BMO or P2D_RO ?
|
||||
jbe BaseMaskOffset
|
||||
mov ebx, eax ; P2D_RO
|
||||
shl eax, 12 ; EAX = SMM base
|
||||
shrd ebx, edx, 8 ; EBX = end of SMM range
|
||||
and bx, 0F000h
|
||||
sub ebx, eax ; Compute length of range
|
||||
add ebx, 1000h ; Adjust for 4KB granularity
|
||||
shr ebx, 10 ; Convert to KB
|
||||
jmp short Save_SMM_Base
|
||||
|
||||
BaseMaskOffset:
|
||||
mov ebx, eax ; BX = length of SMM memory in KB
|
||||
shrd eax, edx, 8 ; EAX = Base
|
||||
and ax, 0F000h
|
||||
|
||||
or ebx, 0FFF00000h
|
||||
neg ebx
|
||||
shl ebx, 2 ; Adjust for 4KB granularity
|
||||
|
||||
Save_SMM_Base:
|
||||
push eax ; Save SMM base
|
||||
push bx ; Save SMM size in KB
|
||||
|
||||
shl ebx, 10 ; Convert KB to bytes
|
||||
dec ebx
|
||||
mov [SMM_Size], ebx ; Save size for MSR_SMM_LOC
|
||||
|
||||
; Set SMM RCONF
|
||||
and bx, 0F000h
|
||||
mov edx, ebx ; SMM_TOP = SMM_BASE + sizeof(SMM region)
|
||||
add edx, eax
|
||||
mov dl, [Attributes] ; SMM active properties mirror RCONF_DEFAULT
|
||||
or ah, 1 ; Set Enable
|
||||
mov al, dl ; SMM inactive properties (R/W for now)
|
||||
and al, NOT REGION_WP
|
||||
mov ecx, MSR_RCONF_SMM
|
||||
wrmsr
|
||||
|
||||
pop bx ; BX = size of SMM region in KB
|
||||
pop eax ; EAX = base of SMM region
|
||||
|
||||
ret
|
||||
|
||||
Get_SMM_Region endp
|
||||
|
||||
|
||||
;****************************************************************
|
||||
; Enables SMIs
|
||||
;****************************************************************
|
||||
Enable_SMIs proc
|
||||
|
||||
; Enable internal and external SMIs
|
||||
mov ecx, MSR_SMM_CTRL
|
||||
rdmsr
|
||||
or eax, INTL_SMI_EN + EXTL_SMI_EN
|
||||
wrmsr
|
||||
|
||||
ret
|
||||
|
||||
Enable_SMIs endp
|
||||
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Enables the SMM instructions
|
||||
;***********************************************************************
|
||||
Enable_SMM_Instr proc
|
||||
|
||||
mov ecx, MSR_SMM_CTRL
|
||||
rdmsr
|
||||
or eax, SMM_INST_EN
|
||||
wrmsr
|
||||
ret
|
||||
|
||||
Enable_SMM_Instr endp
|
||||
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Disables the A20 masking at the processor.
|
||||
;***********************************************************************
|
||||
Disable_A20 proc
|
||||
|
||||
mov ecx, [FooGlue]
|
||||
add cx, FG_A20M
|
||||
rdmsr
|
||||
and al, NOT A20M ; A20M = 0
|
||||
wrmsr
|
||||
ret
|
||||
|
||||
Disable_A20 endp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Gets the size of physical memory
|
||||
; On Exit:
|
||||
; EAX = physical memory size in bytes
|
||||
;***********************************************************************
|
||||
Get_Memory_Size proc
|
||||
|
||||
mov ecx, [BIOS_EDX] ; P2D_R descriptor of physical memory
|
||||
jecxz Exit
|
||||
rdmsr
|
||||
; EDX = 2000001F
|
||||
; EAX = FDF00100
|
||||
; 1MB thru <512MB-192K)
|
||||
|
||||
shrd eax, edx, 20 ; Extract PMAX field
|
||||
shl eax, 12 ; Convert units from 4KB to bytes
|
||||
Exit: ret
|
||||
|
||||
Get_Memory_Size endp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; The linker won't allow code to be put in a PARA aligned segment.
|
||||
; The following will align the next module to a paragraph boundary.
|
||||
TEXT SEGMENT PARA 'CODE'
|
||||
|
||||
db 16 dup (0)
|
||||
|
||||
TEXT ENDS
|
||||
|
||||
END
|
||||
|
||||
328
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/cs5536.c
vendored
Executable file
328
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/cs5536.c
vendored
Executable file
@@ -0,0 +1,328 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//*****************************************************************************
|
||||
//* Routines related to the CS5536
|
||||
//*****************************************************************************
|
||||
|
||||
#include "VSA2.H"
|
||||
#include "SYSMGR.H"
|
||||
#include "PROTOS.H"
|
||||
#include "GX2.H"
|
||||
#include "VPCI.H"
|
||||
#include "DESCR.H"
|
||||
#include "PCI.H"
|
||||
#include "CHIPSET.H"
|
||||
#include "CS5536.H"
|
||||
#include "MDD.H"
|
||||
|
||||
ULONG Mbiu2 = MPCI_SOUTH + 0x00020000; // 2.4.2.0.1
|
||||
ULONG MPCI_SB = MPCI_SOUTH; // 2.4.2.0.0
|
||||
ULONG MCP_SB = MPCI_SOUTH + 0x00700000; // 2.4.2.7.0
|
||||
ULONG OHCI1_Smi=0, OHCI2_Smi=0;
|
||||
CAPABILITIES Southbridge_MBIU;
|
||||
ULONG ATA_Error;
|
||||
|
||||
// External Functions:
|
||||
extern void CS5536_GPIO_Init(void);
|
||||
extern void Init_MDD(void);
|
||||
extern ULONG Write_EPCI(UCHAR, ULONG);
|
||||
extern void ACPI_PMS_SWAPSiF(void);
|
||||
extern PCI_HEADER_ENTRY * Get_Structure(USHORT);
|
||||
extern void pascal Handle_EHCI_Wr(PCI_HEADER_ENTRY *);
|
||||
extern PCI_HEADER_ENTRY * pascal Find_Register(PCI_HEADER_ENTRY *, UCHAR);
|
||||
|
||||
// External Variables:
|
||||
extern ULONG MPCI_NB, MDD_Base;
|
||||
extern Hardware HardwareInfo;
|
||||
extern PCI_HEADER_ENTRY ISA_Hdr[];
|
||||
extern PCI_HEADER_ENTRY Audio_Hdr[];
|
||||
extern VIRTUAL_DEVICE * SouthBridge;
|
||||
extern PCI_HEADER_ENTRY * Virtual_5536[];
|
||||
|
||||
//***********************************************************************
|
||||
// Enables USB SMIs on CS5536
|
||||
//***********************************************************************
|
||||
void pascal Enable_USB_5536(UCHAR EnableFlag, USHORT Instance)
|
||||
{ ULONG MsrData;
|
||||
UCHAR Mask;
|
||||
|
||||
// OHCI is the only valid setting for now
|
||||
if (Instance == 1) {
|
||||
|
||||
MsrData = Read_MSR_LO(OHCI1_Smi);
|
||||
Mask = 0x10 << (Instance-1);
|
||||
if (EnableFlag) {
|
||||
(UCHAR)MsrData &= ~Mask;
|
||||
} else {
|
||||
(UCHAR)MsrData |= Mask;
|
||||
}
|
||||
Write_MSR_LO(OHCI1_Smi, MsrData);
|
||||
|
||||
} else {
|
||||
static UCHAR * Msg_Enable = "enable";
|
||||
static UCHAR * Msg_Disable = "disable";
|
||||
UCHAR * OnOff;
|
||||
|
||||
if (EnableFlag) {
|
||||
OnOff = Msg_Enable;
|
||||
} else {
|
||||
OnOff = Msg_Disable;
|
||||
}
|
||||
Log_Error("Attempt to %s invalid USB instance: 0x%04X", OnOff, Instance);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Enables/disables writes to PM1_CNT register
|
||||
//***********************************************************************
|
||||
void Enable_ACPI_5536(UCHAR EnableFlag)
|
||||
{ ULONG MsrAddr, MsrData;
|
||||
|
||||
// Get address to MDDs SMI MSR
|
||||
MsrAddr = MDD_Base;
|
||||
(USHORT)MsrAddr = MBD_MSR_SMI;
|
||||
|
||||
// Get current value
|
||||
MsrData = Read_MSR_LO(MsrAddr);
|
||||
|
||||
// Set/clear enable for trapping of writes to PM1_CNT
|
||||
if (EnableFlag) {
|
||||
MsrData |= PM1_CNT_SSMI_EN;
|
||||
|
||||
} else {
|
||||
MsrData &= ~PM1_CNT_SSMI_EN;
|
||||
}
|
||||
|
||||
// Update the MSR
|
||||
Write_MSR_LO(MsrAddr, MsrData);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Sets positive/subtractive decode
|
||||
//***********************************************************************
|
||||
void pascal Address_Decode_5536(UCHAR Decode, USHORT Address)
|
||||
{
|
||||
// Not yet implemented
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
// Initializes BARs in the Southbridge virtual headers
|
||||
//***********************************************************************
|
||||
void Init_SB_Headers(void)
|
||||
{ ULONG MsrAddr, BAR_Value;
|
||||
USHORT PCI_Addr, Bar;
|
||||
|
||||
|
||||
//*********************************************
|
||||
// Allocate BARs for CS5536's F0 header
|
||||
//*********************************************
|
||||
MsrAddr = MDD_Base;
|
||||
for (Bar = BAR0; Bar <= BAR5; Bar += 4) {
|
||||
ULONG BAR_Length;
|
||||
|
||||
(UCHAR)MsrAddr = ISA_Hdr[Bar/4].LBar;
|
||||
|
||||
// Get current LBAR value
|
||||
BAR_Value = Read_MSR_LO(MsrAddr);
|
||||
|
||||
// Determine the length of the I/O range
|
||||
BAR_Length = ISA_Hdr[Bar/4].Mask;
|
||||
|
||||
// Allocate a PCI BAR corresponding to the LBAR
|
||||
PCI_Addr = Allocate_BAR(RESOURCE_IO, Bar, BAR_Length, ID_MDD, ISA_Hdr[0].Device_ID);
|
||||
|
||||
// Synchronize with any LBARs that have already been initialized by the BIOS
|
||||
Virtual_PCI_Write_Handler(PCI_Addr, DWORD_IO, BAR_Value);
|
||||
|
||||
}
|
||||
|
||||
// Initialize Southbridge's COMMAND register
|
||||
(UCHAR)PCI_Addr = COMMAND;
|
||||
Virtual_PCI_Write_Handler(PCI_Addr, BYTE_IO, SPECIAL_CYCLES | IO_SPACE);
|
||||
|
||||
|
||||
//*********************************************
|
||||
// Allocate Audio BAR
|
||||
//*********************************************
|
||||
Allocate_BAR(RESOURCE_IO, BAR0, 128, ID_AC97, Audio_Hdr[0].Device_ID);
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Initializes the CS5536 chipset
|
||||
//***********************************************************************
|
||||
void Init_CS5536(void)
|
||||
{ register PCI_HEADER_ENTRY * Header;
|
||||
ULONG MsrAddr, USB20_Msr, MsrData[2];
|
||||
UCHAR i, CS5536_DevNum;
|
||||
|
||||
|
||||
|
||||
//*********************************************
|
||||
// Get routing address of CS5536's MPCI
|
||||
//*********************************************
|
||||
MPCI_SB = MPCI_NB;
|
||||
CS5536_DevNum = (UCHAR)((USHORT)HardwareInfo.Chipset_Base >> 11);
|
||||
MsrData[0] = Read_MSR_LO(MPCI_NB + MPCI_ExtMSR);
|
||||
while (MsrData[0]) {
|
||||
MPCI_SB += 1L << 23;
|
||||
if ((UCHAR)MsrData[0] == CS5536_DevNum) {
|
||||
break;
|
||||
}
|
||||
MsrData[0] >>= 8;
|
||||
}
|
||||
|
||||
//*********************************************
|
||||
// Get routing address to Southbridge's GLIU
|
||||
//*********************************************
|
||||
Mbiu2 = MPCI_SB + 0x00020000;
|
||||
|
||||
|
||||
// Read Southbridge's GLIU capabilities
|
||||
Read_MSR(Mbiu2 + MBIU_CAP, &MsrData[0]);
|
||||
|
||||
|
||||
//*********************************************
|
||||
// Initialize GLIU2
|
||||
//*********************************************
|
||||
Parse_Capabilities(MsrData, &Southbridge_MBIU);
|
||||
// The NP2D_SCO field is actually the NP2D_BMK field
|
||||
Southbridge_MBIU.NP2D_BMK = Southbridge_MBIU.NP2D_SCO;
|
||||
Southbridge_MBIU.NP2D_SCO = 0;
|
||||
|
||||
// SWAPSiF for erroneous P2D_BM/BMK numbering
|
||||
if (HardwareInfo.Chipset_ID == DEVICE_ID_5536) {
|
||||
Southbridge_MBIU.NP2D_BM = 3;
|
||||
}
|
||||
|
||||
// Find address of MCP in Southbridge
|
||||
MCP_SB = Find_MBus_ID(ID_MCP, 2) & 0xFFFF0000;
|
||||
|
||||
// Default range for IDE P2D_BM descriptor is 16 bytes.
|
||||
// Change range to 8 bytes.
|
||||
MsrAddr = Mbiu2 + MSR_IO_DESCR;
|
||||
Write_MSR_LO(MsrAddr, Read_MSR_LO(MsrAddr) | 0x00000008);
|
||||
|
||||
// Initialize the descriptor structure for Southbridge's GLIU
|
||||
Init_MBIU((UCHAR *)&Southbridge_MBIU, Mbiu2);
|
||||
|
||||
// Get Southbridge's Revision ID from MCP
|
||||
ISA_Hdr[REVISION_ID/4].Revision_ID = (UCHAR)Read_MSR_LO(MCP_SB + 0x0017);
|
||||
|
||||
|
||||
//*********************************************
|
||||
// Initialize the MDD
|
||||
//*********************************************
|
||||
Init_MDD();
|
||||
|
||||
//*********************************************
|
||||
// Add MPCI R0-R15 to available descriptor list
|
||||
//*********************************************
|
||||
MsrAddr = MPCI_SB;
|
||||
// REGION_R15 is reserved for port 84h
|
||||
for ((USHORT)MsrAddr = REGION_R0; (UCHAR)MsrAddr <= REGION_R15-1; MsrAddr++) {
|
||||
if (Init_Descr(MPCI_RCONF, MsrAddr)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Enable SSMI Received event
|
||||
(USHORT)MsrAddr = MBD_MSR_SMI;
|
||||
Write_MSR_LO(MsrAddr, Read_MSR_LO(MsrAddr) | SSMM);
|
||||
|
||||
// Add ATA LBAR to available descriptor list
|
||||
// NOTE: Not really part of MDD (just leveraging MDD logic)
|
||||
MsrAddr = Find_MBus_ID(ID_ATA, 1);
|
||||
ATA_Error = MsrAddr;
|
||||
(USHORT)ATA_Error = MBD_MSR_ERROR;
|
||||
|
||||
#if 1
|
||||
// Enable SSMI Received event
|
||||
(USHORT)MsrAddr = MBD_MSR_SMI;
|
||||
Write_MSR_LO(MsrAddr, Read_MSR_LO(MsrAddr) | SSMM);
|
||||
#endif
|
||||
|
||||
(USHORT)MsrAddr = MSR_LBAR_ATA;
|
||||
Init_Descr(MDD_LBAR, MsrAddr);
|
||||
|
||||
|
||||
//*********************************************
|
||||
// Initialize the virtual Southbridge headers
|
||||
//*********************************************
|
||||
Init_SB_Headers();
|
||||
|
||||
//*********************************************
|
||||
// Initialize the GPIO logic
|
||||
//*********************************************
|
||||
CS5536_GPIO_Init();
|
||||
|
||||
//*********************************************
|
||||
// Install workaround for ACPI & PMS bugs
|
||||
//*********************************************
|
||||
ACPI_PMS_SWAPSiF();
|
||||
|
||||
|
||||
// Find address of USB 2.0
|
||||
OHCI1_Smi = USB20_Msr = Find_MBus_ID(ID_USB_20, 1);
|
||||
|
||||
if (OHCI1_Smi == 0) {
|
||||
return;
|
||||
}
|
||||
(USHORT)OHCI1_Smi = MBD_MSR_SMI;
|
||||
|
||||
// Set PMEEN for each USB 2.0 controller
|
||||
for (i=USBMSROHCB; i<=USBMSRUOCB; i++) {
|
||||
(UCHAR)USB20_Msr = i;
|
||||
Read_MSR(USB20_Msr, MsrData);
|
||||
MsrData[1] |= PMEEN;
|
||||
Write_MSR(USB20_Msr, MsrData);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Initialize the USB 2.0 devices
|
||||
for (i=0; i <= 7; i++) {
|
||||
|
||||
// If the header exists...
|
||||
if (Header = Virtual_5536[i]) {
|
||||
// Read Class Code to see it is USB class
|
||||
if ((Header+REVISION_ID/4)->Class == 0x0C03) {
|
||||
// Initialize USB LBAR
|
||||
(UCHAR)USB20_Msr = (Header+BAR0/4)->LBar;
|
||||
Init_Descr(USB_LBAR, USB20_Msr);
|
||||
|
||||
// Allocate the PCI BAR
|
||||
Allocate_BAR(RESOURCE_MMIO, BAR0, (Header+BAR0/4)->Mask, ID_USB_20, Header->Device_ID);
|
||||
|
||||
// If EHCI, initialize FLADJ
|
||||
if (Header->Device_ID == DEVICE_ID_AMD_EHCI) {
|
||||
Header = Find_Register(Header, SRBN_REG);
|
||||
if ((USHORT)Header != UNIMPLEMENTED_REGISTER) {
|
||||
Header->FLADJ = 0x20;
|
||||
Handle_EHCI_Wr(Header);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
220
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/debug.asm
vendored
Executable file
220
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/debug.asm
vendored
Executable file
@@ -0,0 +1,220 @@
|
||||
;
|
||||
; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
;
|
||||
; This library is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU Lesser General Public License as
|
||||
; published by the Free Software Foundation; either version 2.1 of the
|
||||
; License, or (at your option) any later version.
|
||||
;
|
||||
; This code is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
; Lesser General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU Lesser General
|
||||
; Public License along with this library; if not, write to the
|
||||
; Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
; Boston, MA 02111-1307 USA
|
||||
;
|
||||
;* Function: *
|
||||
;* Debug routines for GX2-based systems
|
||||
|
||||
|
||||
include vsa2.inc
|
||||
include vr.inc
|
||||
include sysmgr.inc
|
||||
|
||||
.model tiny,c
|
||||
.586p
|
||||
.CODE
|
||||
|
||||
|
||||
CR equ 0Dh
|
||||
LF equ 0Ah
|
||||
|
||||
externdef SMM_Header: SmiHeader
|
||||
|
||||
;***********************************************************************
|
||||
; Hex dump routines
|
||||
;***********************************************************************
|
||||
Hex_32 proc pascal Num:dword
|
||||
|
||||
pushad
|
||||
mov ebx, Num
|
||||
mov cx, 8
|
||||
@@: rol ebx, 4
|
||||
call Hex_4
|
||||
loop @b
|
||||
call Space
|
||||
popad
|
||||
ret
|
||||
|
||||
Hex_32 endp
|
||||
|
||||
|
||||
|
||||
Hex_16 proc pascal Num:word
|
||||
|
||||
pusha
|
||||
mov cx, 4
|
||||
mov bx, Num
|
||||
@@: rol bx, 4
|
||||
call Hex_4
|
||||
loop @b
|
||||
call Space
|
||||
popa
|
||||
ret
|
||||
|
||||
Hex_16 endp
|
||||
|
||||
|
||||
Hex_8 proc pascal Num:byte
|
||||
|
||||
pusha
|
||||
mov cx, 2
|
||||
mov bl, Num
|
||||
@@: rol bl, 4
|
||||
call Hex_4
|
||||
loop @b
|
||||
call Space
|
||||
popa
|
||||
ret
|
||||
|
||||
Hex_8 endp
|
||||
|
||||
|
||||
Hex_4: mov al, bl
|
||||
and al, 0Fh
|
||||
add al, '0' ; Convert to ASCII
|
||||
cmp al, '9'
|
||||
jbe @f
|
||||
add al, 7 ; 'A'-'F'
|
||||
@@: mov dx, DBG_PORT
|
||||
jmp Char
|
||||
|
||||
Space: mov al, ' '
|
||||
Char: out dx, al
|
||||
in al, 80h
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Displays SMI source(s)
|
||||
;
|
||||
; On Entry:
|
||||
; ECX = SMI source(s)
|
||||
;***********************************************************************
|
||||
Show_SMI_Source proc
|
||||
|
||||
pushad
|
||||
cld
|
||||
|
||||
mov dx, DBG_PORT
|
||||
lea bx, SMI_Source_Strings-2
|
||||
MsgLoop:jecxz Exit
|
||||
add bx, 2
|
||||
shr ecx, 1
|
||||
jnc MsgLoop
|
||||
|
||||
mov si, [bx] ; Get message ptr
|
||||
cmp si, OFFSET Msg_DescrHit
|
||||
jne short CharLoop
|
||||
mov ax, [SMM_Header].IO_addr
|
||||
cmp ax, VRC_INDEX
|
||||
je IsVirtualReg
|
||||
cmp ax, VRC_DATA
|
||||
jne CharLoop
|
||||
IsVirtualReg:
|
||||
lea si, [Msg_VirtReg]
|
||||
CharLoop:
|
||||
lodsb
|
||||
or al, al ; End of string ?
|
||||
jz Blank
|
||||
out dx, al ; No, display next character
|
||||
jmp CharLoop
|
||||
|
||||
Blank: mov al, ' ' ; Yes, display trailing blank
|
||||
out dx, al
|
||||
jmp MsgLoop
|
||||
|
||||
Exit: popad
|
||||
ret
|
||||
|
||||
|
||||
Show_SMI_Source endp
|
||||
|
||||
|
||||
SMI_Source_Strings:
|
||||
dw OFFSET Msg_PM
|
||||
dw OFFSET Msg_Audio
|
||||
dw OFFSET Msg_ACPI
|
||||
dw OFFSET Msg_VG
|
||||
dw OFFSET Msg_Reserved
|
||||
dw OFFSET Msg_Retrace
|
||||
dw OFFSET Msg_VGA_Timer
|
||||
dw OFFSET Msg_A20
|
||||
dw OFFSET Msg_SW_SMI
|
||||
dw OFFSET Msg_GTT
|
||||
dw OFFSET Msg_Reserved
|
||||
dw OFFSET Msg_MFGPT
|
||||
dw OFFSET Msg_NMI
|
||||
dw OFFSET Msg_Reset
|
||||
dw OFFSET Msg_USB
|
||||
dw OFFSET Msg_Graphics
|
||||
|
||||
dw OFFSET Msg_GT1
|
||||
dw OFFSET Msg_GT2
|
||||
dw OFFSET Msg_USR_DEF_1
|
||||
dw OFFSET Msg_VirtReg
|
||||
dw OFFSET Msg_USR_DEF_3
|
||||
dw OFFSET Msg_PCI_Trap
|
||||
dw OFFSET Msg_Reserved
|
||||
dw OFFSET Msg_Reserved
|
||||
dw OFFSET Msg_MPCI
|
||||
dw OFFSET Msg_DescrHit
|
||||
dw OFFSET Msg_Stat_Hit
|
||||
dw OFFSET Msg_PIC
|
||||
dw OFFSET Msg_KEL
|
||||
dw OFFSET Msg_PME
|
||||
dw OFFSET Msg_BlockIO
|
||||
dw OFFSET Msg_Reserved
|
||||
|
||||
|
||||
Msg_Reserved db '???',0
|
||||
Msg_VG db 'VG',0
|
||||
Msg_PM db 'PM',0
|
||||
Msg_Audio db 'Audio',0
|
||||
Msg_ACPI db 'ACPI',0
|
||||
Msg_Retrace db 'Vsync',0
|
||||
Msg_VGA_Timer db 'Vga',0
|
||||
Msg_SW_SMI db 'S/W',0
|
||||
Msg_A20 db 'A20',0
|
||||
Msg_GTT db 'GTT',0
|
||||
Msg_MFGPT db 'MFGPT',0
|
||||
Msg_NMI db 'NMI',0
|
||||
Msg_GT1 db 'GT1',0
|
||||
Msg_GT2 db 'Timer',0
|
||||
Msg_USB db 'USB',0
|
||||
Msg_Reset db 'Reset',0
|
||||
Msg_Graphics db 'VGA',0
|
||||
Msg_USR_DEF_1 db 'PIC',0
|
||||
Msg_VirtReg db 'VR',0
|
||||
Msg_USR_DEF_3 db 'UDef3',0
|
||||
Msg_PCI_Trap db 'PCI',0
|
||||
Msg_MPCI db 'MPCI',0
|
||||
Msg_DescrHit db 'I/O',0
|
||||
Msg_Stat_Hit db 'StatHit',0
|
||||
Msg_PIC db 'PIC',0
|
||||
Msg_KEL db 'KEL',0
|
||||
Msg_PME db 'PME',0
|
||||
Msg_BlockIO db 'BlockIO',0
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
521
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/descr.c
vendored
Executable file
521
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/descr.c
vendored
Executable file
@@ -0,0 +1,521 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//******************************************************************************
|
||||
//* Utility routines for managing descriptors
|
||||
//******************************************************************************
|
||||
|
||||
|
||||
|
||||
#include "VSA2.H"
|
||||
#include "PROTOS.H"
|
||||
#include "GX2.H"
|
||||
#include "VPCI.H"
|
||||
#include "DESCR.H"
|
||||
#include "SYSMGR.H"
|
||||
|
||||
|
||||
|
||||
// External variables:
|
||||
extern UCHAR NumMbius;
|
||||
extern UCHAR MBIU1_SelfReference;
|
||||
|
||||
// Local variables:
|
||||
UCHAR NumDescriptors = 1;
|
||||
DESCRIPTOR MSRs[MAX_DESCR]={0};
|
||||
UCHAR DynamicVSALoad=0;
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Computes the 32 LSBs of an IOD_SC descriptor from Address/Range
|
||||
//***********************************************************************
|
||||
ULONG pascal Compute_IOD_SC(ULONG * AddressPtr, USHORT * RangePtr, UCHAR Flag)
|
||||
{ ULONG IO_Mask, Address;
|
||||
USHORT Range;
|
||||
UCHAR Addr_LSBs, Bit_Mask, Max_Bits;
|
||||
|
||||
Address = * AddressPtr;
|
||||
Range = * RangePtr;
|
||||
|
||||
// Set IOD_SC Base field
|
||||
IO_Mask = Address & 0x0000FFF8;
|
||||
|
||||
// Compute the R/W attributes
|
||||
if (!(Address & WRITES_ONLY)) {
|
||||
IO_Mask |= REN;
|
||||
}
|
||||
if (!(Address & READS_ONLY)) {
|
||||
IO_Mask |= WEN;
|
||||
}
|
||||
|
||||
// Initialize bit mask
|
||||
Addr_LSBs = (UCHAR)Address & 0x7;
|
||||
Max_Bits = 8 - Addr_LSBs;
|
||||
if (Range > Max_Bits) {
|
||||
Range = Max_Bits;
|
||||
}
|
||||
Bit_Mask = (UCHAR)(0x01 << Range) - 1;
|
||||
Bit_Mask <<= Addr_LSBs;
|
||||
|
||||
// Insert byte enables
|
||||
IO_Mask |= (ULONG)Bit_Mask << 24;
|
||||
|
||||
|
||||
// Adjust Address & Range parameters by # bytes handled by this descriptor
|
||||
if (Flag) {
|
||||
* AddressPtr += (ULONG)Range;
|
||||
* RangePtr -= (USHORT)Range;
|
||||
}
|
||||
return IO_Mask;
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Returns the default value for the given descriptor Type
|
||||
//***********************************************************************
|
||||
void pascal Get_Descriptor_Default(UCHAR Type, ULONG * Msr)
|
||||
{
|
||||
|
||||
*Msr = *(Msr+1) = 0x00000000;
|
||||
|
||||
switch (Type) {
|
||||
|
||||
case IOD_BM:
|
||||
case P2D_BM:
|
||||
case P2D_BMO:
|
||||
case P2D_BMK:
|
||||
*Msr = 0xFFF00000;
|
||||
*(Msr+1) = 0x000000FF;
|
||||
break;
|
||||
|
||||
case P2D_R:
|
||||
case P2D_RO:
|
||||
*(Msr) = 0x000FFFFF;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Initializes a MSRs[] entry
|
||||
//***********************************************************************
|
||||
UCHAR pascal Init_Descr(UCHAR Type, ULONG MsrAddr)
|
||||
{ register DESCRIPTOR * Descr;
|
||||
|
||||
// Keep count of total # descriptors
|
||||
if (NumDescriptors >= MAX_DESCR) {
|
||||
// Log an error: Not enough descriptor entries.
|
||||
Report_VSM_Error(ERR_NO_MORE_DESCRIPTORS, MAX_DESCR, 0x77 );
|
||||
return 0x01;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Descr = &MSRs[NumDescriptors++];
|
||||
|
||||
// Initialize the descriptor entry
|
||||
Descr->Mbiu = NumMbius;
|
||||
Descr->Split = 0x00;
|
||||
Descr->Flag = AVAILABLE;
|
||||
Descr->Type = Type;
|
||||
Descr->Link = 0x00;
|
||||
Descr->Owner = 0x0000;
|
||||
Descr->MsrAddr = MsrAddr;
|
||||
Descr->Physical = 0x00000000;
|
||||
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Returns a descriptor to the available pool
|
||||
//***********************************************************************
|
||||
void Deallocate_Descriptor(DESCRIPTOR * Descr)
|
||||
{
|
||||
// Mark MSR available
|
||||
Descr->Flag = AVAILABLE;
|
||||
Descr->Link = 0x00;
|
||||
Descr->Owner = 0x0000;
|
||||
// Set MSR to default value
|
||||
Get_Descriptor_Default(Descr->Type, Descr->MsrData);
|
||||
Write_MSR(Descr->MsrAddr, Descr->MsrData);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Restores all descriptors owned by VSA to their default values.
|
||||
// Used when VSA is installed from DOS.
|
||||
//***********************************************************************
|
||||
void ReInit_Descriptors(void)
|
||||
{ register USHORT Index;
|
||||
register DESCRIPTOR * Descr;
|
||||
ULONG MDD_Msr;
|
||||
|
||||
DynamicVSALoad = 1;
|
||||
|
||||
Descr = &MSRs[1];
|
||||
|
||||
MDD_Msr = Find_MBus_ID(ID_MDD, 1) & ROUTING;
|
||||
|
||||
// Restore VSA-owned MSRs to their default values
|
||||
for (Index = 1; Index < NumDescriptors; Index++) {
|
||||
// Don't zero MDD LBARs
|
||||
if ((Descr->MsrAddr & ROUTING) == MDD_Msr) {
|
||||
Descr->Flag = AVAILABLE;
|
||||
} else {
|
||||
if (Descr->MsrAddr == 0x5100002F) {
|
||||
continue;
|
||||
}
|
||||
Deallocate_Descriptor(Descr);
|
||||
}
|
||||
Descr++;
|
||||
}
|
||||
|
||||
NumDescriptors = 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Searches for an unused descriptor of the specified type(s) on the
|
||||
// specified MBIU.
|
||||
// NOTE: This implementation makes multiple passes through the table, but
|
||||
// this removes the requirement that they be in a particular order.
|
||||
//***********************************************************************
|
||||
UCHAR pascal Allocate_Descriptor(UCHAR Type, UCHAR EndType, ULONG Msr)
|
||||
{ register DESCRIPTOR * Descr;
|
||||
register UCHAR Index;
|
||||
ULONG Mask;
|
||||
UCHAR Incr = 1;
|
||||
|
||||
if (EndType < Type) {
|
||||
Incr = 0xFF;
|
||||
}
|
||||
EndType += Incr;
|
||||
|
||||
do {
|
||||
|
||||
// Find an available descriptor of the right type
|
||||
Index = 1;
|
||||
do {
|
||||
|
||||
Descr = &MSRs[Index];
|
||||
|
||||
if ((Descr->Flag & AVAILABLE) && (Type == Descr->Type)) {
|
||||
|
||||
switch (Type) {
|
||||
|
||||
case MPCI_RCONF:
|
||||
case GX2_RCONF:
|
||||
// Any register will do
|
||||
Mask = 0x00000000;
|
||||
break;
|
||||
|
||||
case USB_LBAR:
|
||||
case MDD_LBAR:
|
||||
// Entire MSR must match
|
||||
Mask = 0xFFFFFFFF;
|
||||
break;
|
||||
|
||||
case EPCI:
|
||||
// Entire routing field must match
|
||||
Mask = ROUTING;
|
||||
break;
|
||||
|
||||
default:
|
||||
// MSR must match in 1st 3 routing fields
|
||||
Mask = 0xFF800000;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if ((Descr->MsrAddr & Mask) == (Msr & Mask)) {
|
||||
// Mark descriptor in-use
|
||||
Descr->Flag &= ~AVAILABLE;
|
||||
return Index;
|
||||
}
|
||||
}
|
||||
|
||||
Index++;
|
||||
} while (Index != NumDescriptors);
|
||||
Type += Incr;
|
||||
} while (Type != EndType);
|
||||
|
||||
return DESCRIPTOR_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Searches existing descriptors for the specified address range.
|
||||
// If possible, a descriptor is updated to add/remove the new range.
|
||||
// Parameter Enable:
|
||||
// = 0, the range is removed
|
||||
// = 1, the range is added for I/O timeout
|
||||
// = 2, the range is added for I/O trap
|
||||
// = 3, the range is being searched (SYS_IO_DESCRIPTOR)
|
||||
//***********************************************************************
|
||||
UCHAR pascal Find_Matching_IO_Descriptor(ULONG * AddressPtr, USHORT * RangePtr, UCHAR Enable)
|
||||
{ UCHAR Index, HitFlag, DescrFlag;
|
||||
ULONG Attributes, Mask;
|
||||
USHORT Address, StartRange, EndRange, Length, Range;
|
||||
register DESCRIPTOR * Descr;
|
||||
static ULONG GLIU_Masks[3] = {NOT_GLIU0, NOT_GLIU1, NOT_GLIU2};
|
||||
|
||||
Range = * RangePtr;
|
||||
Address = (USHORT) * AddressPtr;
|
||||
Attributes = * AddressPtr;
|
||||
|
||||
|
||||
// Scan descriptors for those used for I/O trap or timeout
|
||||
// NOTE: We must be careful about mixing I/O traps with I/O address that
|
||||
// are directed to Northbridge devices. This may cause multiple
|
||||
// MBUI descriptors set to the same address.
|
||||
for (Index = 1; Index < NumDescriptors; Index++) {
|
||||
|
||||
Descr = &MSRs[Index];
|
||||
DescrFlag = Descr->Flag;
|
||||
|
||||
// Only examine allocated descriptors
|
||||
if (DescrFlag & AVAILABLE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore descriptors that route transactions Northbound
|
||||
if (Descr->MsrData[1] >> 29 == MBIU1_SelfReference) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If an MBIU is to be excluded, don't allow a match on that MBIU
|
||||
if (Attributes & GLIU_Masks[Descr->Mbiu]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Check if this descriptor matches the requested address range.
|
||||
// Cases:
|
||||
// - Descriptor needs to be split, since I/O ranges are not compatible.
|
||||
// - Subtractive port: timeout is set for this I/O range
|
||||
// - It is currently routed to an MBus device: change Port to 0
|
||||
// - Address ranges need to be merged
|
||||
switch (Descr->Type) {
|
||||
|
||||
case IOD_SC:
|
||||
HitFlag = 1;
|
||||
// Does the I/O range overlap an existing Swiss-cheese descriptor ?
|
||||
if ((USHORT)Descr->MsrData[0] == (Address & 0xFFF8)) {
|
||||
UCHAR CurrentByteEnables, NewByteEnables, CommonByteEnables;
|
||||
|
||||
// Yes, compute the byte enables
|
||||
Mask = Compute_IOD_SC(AddressPtr, RangePtr, 1);
|
||||
CurrentByteEnables = (UCHAR)(Descr->MsrData[0] >> 24);
|
||||
NewByteEnables = (UCHAR)(Mask >> 24);
|
||||
|
||||
// Compute # bytes of overlap
|
||||
CommonByteEnables = CurrentByteEnables & NewByteEnables;
|
||||
Length = 0;
|
||||
while (CommonByteEnables) {
|
||||
if (CommonByteEnables & 1) {
|
||||
Length++;
|
||||
}
|
||||
CommonByteEnables >>= 1;
|
||||
}
|
||||
|
||||
switch (Enable) {
|
||||
|
||||
case 0:
|
||||
if (CurrentByteEnables == NewByteEnables) {
|
||||
if (Descr->MsrData[0] == Mask) {
|
||||
// Entire range is being disabled
|
||||
Deallocate_Descriptor(Descr);
|
||||
} else {
|
||||
// Only change REN/WEN, not byte enables
|
||||
Mask &= 0x00FFFFFF;
|
||||
}
|
||||
} else {
|
||||
// Only subset of range is being disabled
|
||||
// Don't change REN/WEN
|
||||
Mask &= ~(WEN | REN);
|
||||
}
|
||||
if (Length) {
|
||||
// Don't change base address
|
||||
(USHORT)Mask = 0x0000;
|
||||
Descr->MsrData[0] &= ~Mask;
|
||||
} else {
|
||||
HitFlag = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if ((Descr->MsrData[0] & (WEN | REN)) != (Mask & (WEN | REN))) {
|
||||
// R/W attributes mismatch; descriptor is not compatible
|
||||
HitFlag = 0;
|
||||
} else {
|
||||
// Descriptors are compatible: set additional byte enables
|
||||
Descr->MsrData[0] |= Mask;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if ((Descr->MsrData[0] & (WEN | REN)) != (Mask & (WEN | REN))) {
|
||||
// R/W attributes mismatch.
|
||||
// Descriptor is not compatible unless byte enables are the same.
|
||||
if (CurrentByteEnables != NewByteEnables) {
|
||||
HitFlag = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Descriptors are compatible: set additional byte enables
|
||||
Descr->MsrData[0] |= Mask;
|
||||
|
||||
// If the descriptors overlap but not exactly (disjoint enables)
|
||||
// then Address & Range need to be handled according to special cases
|
||||
if (CurrentByteEnables != NewByteEnables) {
|
||||
// Restore Address & Range (modified above by Compute_IOD_SC)
|
||||
* (USHORT *)AddressPtr = Address;
|
||||
* RangePtr = Range;
|
||||
|
||||
if (NewByteEnables > CurrentByteEnables) {
|
||||
// For example: 01110000 - NewByteEnables
|
||||
// 00011100 - CurrentByteEnables
|
||||
// Increment Address by overlapped range
|
||||
* (USHORT *)AddressPtr += Length;
|
||||
}
|
||||
|
||||
// Decrement Range by overlapped range
|
||||
* RangePtr -= Length;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (CurrentByteEnables & NewByteEnables) {
|
||||
return Index;
|
||||
}
|
||||
continue;
|
||||
|
||||
} // end switch(Enable)
|
||||
|
||||
Write_MSR(Descr->MsrAddr, Descr->MsrData);
|
||||
|
||||
if (HitFlag == 0) {
|
||||
// Restore Address/Range.
|
||||
* (USHORT *)AddressPtr = Address;
|
||||
* RangePtr = Range;
|
||||
continue;
|
||||
} else {
|
||||
return Index;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IOD_BM:
|
||||
HitFlag = 0;
|
||||
Mask = ~((USHORT)Descr->MsrData[0])+1;
|
||||
Length = 1 << BitScanForward(Mask);
|
||||
StartRange = Descr->Address;
|
||||
EndRange = StartRange + Length;
|
||||
|
||||
// Check if the requested range is covered by the existing descriptor
|
||||
if ((Address >= StartRange) && (Address < EndRange)) {
|
||||
if (Enable == 3) {
|
||||
return Index;
|
||||
}
|
||||
HitFlag = 1;
|
||||
Range -= Address - StartRange;
|
||||
}
|
||||
|
||||
|
||||
Mask = Address ^ StartRange;
|
||||
|
||||
if (Enable) {
|
||||
if (HitFlag) {
|
||||
Length = Range;
|
||||
break; //??????????????????????????
|
||||
}
|
||||
} else {
|
||||
|
||||
// Range is being disabled
|
||||
if (HitFlag) {
|
||||
if (Length <= Range) {
|
||||
Deallocate_Descriptor(Descr);
|
||||
} else {
|
||||
// Descriptor must be trimmed
|
||||
if (Address == StartRange) {
|
||||
// I/O Base needs to be adjusted up
|
||||
Descr->MsrData[0] += (ULONG)Range << 20;
|
||||
Mask = (1L << Range) - 1;
|
||||
Length = Range;
|
||||
} else {
|
||||
// Adjust IO_MASK to trim range down
|
||||
(USHORT)Descr->MsrData[0] &= ~(Range-1);
|
||||
}
|
||||
|
||||
// Adjust IO_MASK
|
||||
(USHORT)Descr->MsrData[0] |= Mask;
|
||||
HitFlag = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Recompute start address of descriptor
|
||||
if (HitFlag == 2) {
|
||||
Descr->Address = (USHORT)(Descr->MsrData[0] >> 20);
|
||||
Descr->Address |= (USHORT)(Descr->MsrData[1] << 12);
|
||||
}
|
||||
|
||||
if (HitFlag) {
|
||||
if (Length > Range) {
|
||||
Length = Range;
|
||||
}
|
||||
* AddressPtr += Length;
|
||||
* RangePtr -= Length;
|
||||
|
||||
// Write descriptor if matching descriptor was modified
|
||||
if (HitFlag == 2) {
|
||||
Write_MSR(Descr->MsrAddr, Descr->MsrData);
|
||||
}
|
||||
return Index;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
} // end switch(Descr->Type)
|
||||
}
|
||||
|
||||
// If a descriptor gets deallocated, need to clean up any possible links to a BAR
|
||||
return DESCRIPTOR_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
47
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/descr.h
vendored
Executable file
47
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/descr.h
vendored
Executable file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
// Descriptor types: (don't use 0)
|
||||
|
||||
|
||||
#define P2D_BM 1
|
||||
#define P2D_BMO 2
|
||||
#define P2D_R 3
|
||||
#define P2D_RO 4
|
||||
#define P2D_SC 5
|
||||
#define P2D_SCO 6
|
||||
#define P2D_BMK 7
|
||||
#define IOD_BM 8
|
||||
#define IOD_SC 9
|
||||
#define MDD_LBAR 10
|
||||
#define GX2_RCONF 11
|
||||
#define MPCI_RCONF 12
|
||||
#define EPCI 13
|
||||
#define USB_LBAR 14
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned long Mbiu;
|
||||
unsigned long SubtrPid;
|
||||
unsigned long ClockGating;
|
||||
unsigned char NumCounters; // Number of statistic counters on this MBIU
|
||||
unsigned char ActiveCounters; // Count of # active statistic counters in use
|
||||
} MBIU_INFO;
|
||||
|
||||
#define MAX_MBIU 3
|
||||
371
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/errors.c
vendored
Executable file
371
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/errors.c
vendored
Executable file
@@ -0,0 +1,371 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//*****************************************************************************
|
||||
//* Implements the error reporting code.
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
#include "VSA2.H"
|
||||
#include "SYSMGR.H"
|
||||
#include "PROTOS.H"
|
||||
|
||||
extern void pascal write_flat_size(ULONG, ULONG, UCHAR);
|
||||
extern ULONG pascal Get_SysCall_Address(ULONG, UCHAR);
|
||||
extern ULONG VSMs_EAX;
|
||||
extern ULONG Saved_EAX, Saved_EBX, Saved_ECX, Saved_EDX, Saved_ESI, Saved_EDI;
|
||||
extern ULONG Current_VSM;
|
||||
|
||||
|
||||
#define MAX_ERROR_BUFFER 500
|
||||
UCHAR ErrorStrings[MAX_ERROR_BUFFER];
|
||||
UCHAR * ErrorBuffer = ErrorStrings;
|
||||
UCHAR * CurrentError;
|
||||
UCHAR * PreviousError = ErrorStrings;
|
||||
UCHAR DuplicateFlag;
|
||||
|
||||
int letbase;
|
||||
|
||||
|
||||
//***************************************************************************
|
||||
// Input:
|
||||
// BH - 1 to clear error log
|
||||
// CL - Error number (0 for 1st)
|
||||
// Exit:
|
||||
// AL - 0 if last error
|
||||
//***************************************************************************
|
||||
void Get_Errors()
|
||||
{ USHORT ErrorNumber, Flag;
|
||||
ULONG Destination;
|
||||
|
||||
// Get parameters passed in from INFO
|
||||
Flag = (UCHAR)(Saved_EBX >> 8);
|
||||
ErrorNumber = (UCHAR)Saved_ECX;
|
||||
Destination = Saved_EDI;
|
||||
|
||||
(UCHAR)Saved_EAX = 0x00;
|
||||
|
||||
// If no errors, return AL = 0;
|
||||
if (ErrorBuffer == ErrorStrings) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If request for 1st error, initialize buffer ptr
|
||||
if (ErrorNumber == 0) {
|
||||
CurrentError = ErrorStrings;
|
||||
}
|
||||
|
||||
|
||||
// Copy next message to EDI
|
||||
while (CurrentError < ErrorBuffer) {
|
||||
// Copy 1 byte of error message
|
||||
write_flat_size(Destination++, (ULONG)*CurrentError, BYTE_IO);
|
||||
// If end of this message, return
|
||||
if (*CurrentError++ == 0) {
|
||||
|
||||
write_flat_size(Destination-1, '$', BYTE_IO);
|
||||
|
||||
(UCHAR)Saved_EAX = 1;
|
||||
|
||||
// Is this the last message ?
|
||||
if (*CurrentError == 0) {
|
||||
// Clear error log ? (/E flag)
|
||||
if (Flag == 1) {
|
||||
PreviousError = ErrorBuffer = ErrorStrings;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//*****************************************************************************
|
||||
static void printchar(char **str, int c)
|
||||
{
|
||||
out_8(DBG_PORT, (UCHAR)c);
|
||||
in_8(0x80);
|
||||
if (ErrorBuffer < &ErrorStrings[MAX_ERROR_BUFFER-2]) {
|
||||
*ErrorBuffer = c;
|
||||
if (*ErrorBuffer++ != *PreviousError++) {
|
||||
DuplicateFlag = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define PAD_RIGHT 1
|
||||
#define PAD_ZERO 2
|
||||
|
||||
//*****************************************************************************
|
||||
//*****************************************************************************
|
||||
static int prints(char **out, const char *string, int width, int pad)
|
||||
{ register int pc = 0, padchar = ' ';
|
||||
|
||||
if (width > 0) {
|
||||
register int len = 0;
|
||||
register const char *ptr;
|
||||
|
||||
for (ptr = string; *ptr; ++ptr) {
|
||||
++len;
|
||||
}
|
||||
|
||||
if (len >= width) {
|
||||
width = 0;
|
||||
} else {
|
||||
width -= len;
|
||||
}
|
||||
|
||||
if (pad & PAD_ZERO) {
|
||||
padchar = '0';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!(pad & PAD_RIGHT)) {
|
||||
for ( ; width > 0; --width) {
|
||||
printchar(out, padchar);
|
||||
++pc;
|
||||
}
|
||||
}
|
||||
|
||||
for ( ; *string ; ++string) {
|
||||
printchar(out, *string);
|
||||
++pc;
|
||||
}
|
||||
|
||||
for ( ; width > 0; --width) {
|
||||
printchar(out, padchar);
|
||||
++pc;
|
||||
}
|
||||
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* the following should be enough for 32 bit int */
|
||||
#define PRINT_BUF_LEN 12
|
||||
|
||||
//*****************************************************************************
|
||||
// Prints an integer with the specified formatting
|
||||
//*****************************************************************************
|
||||
static int printi(char **out, unsigned long u, int base, int sg, int width, int pad)
|
||||
{ char print_buf[PRINT_BUF_LEN];
|
||||
register char *s;
|
||||
register int t, neg = 0, pc = 0;
|
||||
|
||||
if (u == 0) {
|
||||
print_buf[0] = '0';
|
||||
print_buf[1] = '\0';
|
||||
return prints (out, print_buf, width, pad);
|
||||
}
|
||||
if (sg && (base == 10) && (u & 0x8000)) {
|
||||
neg = 1;
|
||||
u = ~u;
|
||||
u++;
|
||||
}
|
||||
|
||||
s = print_buf + PRINT_BUF_LEN-1;
|
||||
*s = '\0';
|
||||
|
||||
while (u) {
|
||||
t = (int)(u % base);
|
||||
if (t >= 10 ) {
|
||||
t += letbase - '0' - 10;
|
||||
}
|
||||
*--s = t + '0';
|
||||
u /= base;
|
||||
}
|
||||
|
||||
if (neg) {
|
||||
if (width && (pad & PAD_ZERO) ) {
|
||||
printchar(out, '-');
|
||||
++pc;
|
||||
--width;
|
||||
} else {
|
||||
*--s = '-';
|
||||
}
|
||||
}
|
||||
|
||||
return pc + prints(out, s, width, pad);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//*****************************************************************************
|
||||
static int print(char **out, int *varg)
|
||||
{ register int width, pad;
|
||||
register int pc = 0;
|
||||
register char *format = (char *)(*varg++);
|
||||
char scr[2];
|
||||
unsigned long number;
|
||||
char *s;
|
||||
|
||||
|
||||
for (; *format != 0; ++format) {
|
||||
if (*format == '%') {
|
||||
++format;
|
||||
pad = 0;
|
||||
if (*format == '\0') {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (*format) {
|
||||
case '%':
|
||||
printchar(out, *format);
|
||||
++pc;
|
||||
continue;
|
||||
|
||||
case '-':
|
||||
++format;
|
||||
pad = PAD_RIGHT;
|
||||
break;
|
||||
}
|
||||
|
||||
while (*format == '0') {
|
||||
++format;
|
||||
pad |= PAD_ZERO;
|
||||
}
|
||||
|
||||
for (width = 0; *format >= '0' && *format <= '9'; ++format) {
|
||||
width *= 10;
|
||||
width += *format - '0';
|
||||
}
|
||||
|
||||
letbase = 'a';
|
||||
switch (*format) {
|
||||
|
||||
case 's':
|
||||
s = *((char **)varg++);
|
||||
pc += prints (out, s ? s :"(null)", width, pad);
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
number = *varg++;
|
||||
pc += printi (out, number, 10, 0, width, pad);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
number = *varg++;
|
||||
pc += printi (out, number, 10, 1, width, pad);
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
// pc += printi (out, number, 16, 0, width, pad);
|
||||
// break;
|
||||
|
||||
case 'X':
|
||||
letbase = 'A';
|
||||
number = (USHORT)*varg++;
|
||||
if (width > 4) {
|
||||
number |= (ULONG)(*varg++) << 16;
|
||||
}
|
||||
pc += printi (out, number, 16, 0, width, pad);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
// char are converted to int then pushed on the stack
|
||||
scr[0] = *varg++;
|
||||
scr[1] = '\0';
|
||||
pc += prints (out, scr, width, pad);
|
||||
break;
|
||||
|
||||
} // end switch
|
||||
|
||||
} else {
|
||||
printchar(out, *format);
|
||||
++pc;
|
||||
}
|
||||
} // end for
|
||||
|
||||
if (out) {
|
||||
**out = '\0';
|
||||
}
|
||||
return pc;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//*****************************************************************************
|
||||
void Log_Error(const char *format, ...)
|
||||
{ register int *varg = (int *)(&format);
|
||||
UCHAR * SavedErrorBuffer;
|
||||
UCHAR * SavedPrevious;
|
||||
|
||||
SavedErrorBuffer = ErrorBuffer;
|
||||
SavedPrevious = PreviousError;
|
||||
if (PreviousError == ErrorStrings) {
|
||||
DuplicateFlag = 0;
|
||||
} else {
|
||||
DuplicateFlag = 1;
|
||||
}
|
||||
|
||||
// Store a formatted error message
|
||||
print(0, varg);
|
||||
|
||||
// Terminate the error buffer
|
||||
if (ErrorBuffer < &ErrorStrings[MAX_ERROR_BUFFER]) {
|
||||
*(ErrorBuffer++) = 0;
|
||||
}
|
||||
|
||||
// Same error as previous?
|
||||
if (DuplicateFlag) {
|
||||
// Yes, then restore ptrs
|
||||
PreviousError = SavedPrevious;
|
||||
ErrorBuffer = SavedErrorBuffer;
|
||||
*(ErrorBuffer) = 0;
|
||||
} else {
|
||||
// No, then advance previous error buffer ptr
|
||||
PreviousError = SavedErrorBuffer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Inserts an error entry into the error log.
|
||||
//*****************************************************************************
|
||||
void pascal Error_Report(UCHAR ErrorCode, ULONG Info1, ULONG Info2, ULONG Vsm, UCHAR Depth)
|
||||
{ ULONG CallingAddress;
|
||||
static UCHAR ErrorString[50];
|
||||
|
||||
CallingAddress = Get_SysCall_Address(Vsm, Depth);
|
||||
|
||||
Log_Error("Error code 0x%02X reported at %08X. Parameters: 0x%08X and 0x%08X.", \
|
||||
ErrorCode, CallingAddress, Info1, Info2);
|
||||
}
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Reports an error from a VSM.
|
||||
//*****************************************************************************
|
||||
void pascal Report_VSM_Error(UCHAR ErrorCode, ULONG Info1, ULONG Info2)
|
||||
{
|
||||
if (Current_VSM == 0) {
|
||||
Error_Report(ErrorCode, Info1, Info2, SysMgr_VSM, 0);
|
||||
} else {
|
||||
Error_Report(ErrorCode, Info1, Info2, Current_VSM, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
616
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/events.c
vendored
Executable file
616
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/events.c
vendored
Executable file
@@ -0,0 +1,616 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//******************************************************************************
|
||||
//* This file contains code for:
|
||||
//* 1) Initialization of the Events[] array
|
||||
//* 2) Registering events
|
||||
//* 3) Sending event messages
|
||||
//******************************************************************************
|
||||
|
||||
|
||||
|
||||
#include "VSA2.H"
|
||||
#include "SYSMGR.H"
|
||||
#include "PROTOS.H"
|
||||
|
||||
|
||||
#define MAX_HIT 10 // Max. # of hits on any single event
|
||||
|
||||
// External function prototypes:
|
||||
extern USHORT FilterTimer(EVENT_ENTRY *, EVENT);
|
||||
extern UCHAR VSM_Is_Yielded(VSM);
|
||||
|
||||
// External variables:
|
||||
extern ULONG VSM_Ptrs[];
|
||||
|
||||
// Local variables:
|
||||
//*****************************************************************************
|
||||
// The first MAX_EVENT entries are indexed by the EVENT code.
|
||||
// The Link field contains the index of the next VSM registered for that event.
|
||||
// A link of 00h terminates the list.
|
||||
//*****************************************************************************
|
||||
EVENT_ENTRY Events[MAX_REGISTRATIONS];
|
||||
UCHAR FreeEvent; // Head of available Events[] entries
|
||||
ULONG MsgPacket[MAX_MSG_PARAM+1];
|
||||
ULONG MsgParams[MAX_HIT][4];
|
||||
|
||||
UCHAR * VsmNames[] = {
|
||||
"SYS_MGR",
|
||||
"AUDIO",
|
||||
"VGA",
|
||||
"LEGACY",
|
||||
"PM",
|
||||
"OHCI",
|
||||
"i8042",
|
||||
"DEBUGGER",
|
||||
"ACPI",
|
||||
"APM",
|
||||
"OEM_ACPI",
|
||||
"SMB",
|
||||
"BATTERY",
|
||||
"RTC",
|
||||
"S2D",
|
||||
"EXT_AMP",
|
||||
"PCMCIA",
|
||||
"SPY",
|
||||
"NETWORK",
|
||||
"GPIO",
|
||||
"KEYBOARD",
|
||||
"MOUSE",
|
||||
"USB",
|
||||
"FLASH",
|
||||
"INFRARED",
|
||||
"THERMAL",
|
||||
"NULL",
|
||||
"MPEG",
|
||||
"VIP",
|
||||
"LPC",
|
||||
"VUART",
|
||||
"MICRO",
|
||||
"USER1",
|
||||
"USER2",
|
||||
"USER3",
|
||||
"SYSINFO",
|
||||
"SUPERIO",
|
||||
"EHCI",
|
||||
};
|
||||
|
||||
UCHAR * EventNames[] = {
|
||||
"????",
|
||||
"GRAPHICS",
|
||||
"AUDIO",
|
||||
"USB",
|
||||
"ACPI",
|
||||
"ACPI_TIMER",
|
||||
"IO_TRAP",
|
||||
"IO_TIMEOUT",
|
||||
"PME",
|
||||
"KEL",
|
||||
"VIDEO_INACTIVITY",
|
||||
"GPIO",
|
||||
"SOFTWARE_SMI",
|
||||
"PCI_TRAP",
|
||||
"VIRTUAL_REGISTER",
|
||||
"NMI",
|
||||
"TIMER",
|
||||
"DEVICE_TIMEOUT",
|
||||
"SEMAPHORE",
|
||||
"VBLANK",
|
||||
"A20",
|
||||
"SMB",
|
||||
"RTC",
|
||||
"THERMAL",
|
||||
"LPC",
|
||||
"UART",
|
||||
"BLOCKIO",
|
||||
};
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Copies an Events[] entry
|
||||
//*****************************************************************************
|
||||
void pascal Copy_Event(USHORT From, USHORT To)
|
||||
{
|
||||
Events[To].Vsm = Events[From].Vsm;
|
||||
Events[To].Param1 = Events[From].Param1;
|
||||
Events[To].Param2 = Events[From].Param2;
|
||||
Events[To].Param3 = Events[From].Param3;
|
||||
Events[To].Link = Events[From].Link;
|
||||
Events[To].Priority = Events[From].Priority;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Initializes the Events[] array
|
||||
//*****************************************************************************
|
||||
void Initialize_Events(void)
|
||||
{ int i;
|
||||
|
||||
Events[0].RemainingInterval = 0xFFFFFFFF;
|
||||
|
||||
for (i = 0; i < MAX_REGISTRATIONS ; i++) {
|
||||
Events[i].Priority = 0xffff;
|
||||
Events[i].Index = i;
|
||||
}
|
||||
|
||||
// Initialize the list of free event entries
|
||||
for (i = MAX_REGISTRATIONS-2; i > MAX_EVENT ; i--) {
|
||||
Events[i].Link = i+1;
|
||||
}
|
||||
FreeEvent = MAX_EVENT+1;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// Checks Events[EventIndex] for parameters matching those in MsgPacket[].
|
||||
// Return value is EventIndex if the parameters match else 0x00.
|
||||
//*****************************************************************************
|
||||
USHORT pascal FilterEvent(EVENT Event, EVENT EventIndex)
|
||||
{ USHORT IO_Hit, IO_Base, IO_Range, ClassIndex, RdWrAttribute;
|
||||
UCHAR Size;
|
||||
ULONG Vsm;
|
||||
register EVENT_ENTRY * EventPtr;
|
||||
USHORT PCI_Hit;
|
||||
static ULONG PCI_Data;
|
||||
static USHORT PCI_Addr;
|
||||
static UCHAR PCI_Size;
|
||||
|
||||
EventPtr = &Events[EventIndex];
|
||||
Vsm = EventPtr->Vsm;
|
||||
|
||||
switch (Event) {
|
||||
|
||||
case EVENT_USB:
|
||||
if ((UCHAR)MsgPacket[2] == (UCHAR)EventPtr->Param1) {
|
||||
return EventIndex;
|
||||
}
|
||||
break;
|
||||
|
||||
case EVENT_TIMER:
|
||||
// Check if the registered interval has expired
|
||||
return FilterTimer(EventPtr, EventIndex);
|
||||
|
||||
case EVENT_GPIO:
|
||||
// Verify the pin & edge match the event registration
|
||||
if (MsgPacket[1] == EventPtr->Pin && (MsgPacket[2] & EventPtr->Attributes)) {
|
||||
// If GPIO is Sleep button being used to wake system, don't send event
|
||||
return EventIndex;
|
||||
}
|
||||
break;
|
||||
|
||||
case EVENT_PME:
|
||||
// MsgPacket[1] = ACPI GPE0_STS
|
||||
// MsgPacket[2] = ACPI PM1_STS
|
||||
if (EventPtr->Attributes & GPE) {
|
||||
if ((1L << EventPtr->Pme) & MsgPacket[1]) {
|
||||
return EventIndex;
|
||||
}
|
||||
}
|
||||
if (EventPtr->Attributes & PM1) {
|
||||
if ((1L << EventPtr->Pm1) & MsgPacket[2]) {
|
||||
return EventIndex;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EVENT_IO_TRAP:
|
||||
case EVENT_IO_TIMEOUT:
|
||||
IO_Base = EventPtr->IO_Base;
|
||||
IO_Range = EventPtr->IO_Range;
|
||||
IO_Hit = (USHORT)MsgPacket[2];
|
||||
// Check address range
|
||||
if ((IO_Hit >= IO_Base) && (IO_Hit <= (IO_Base+IO_Range-1))) {
|
||||
|
||||
if (Event == EVENT_IO_TIMEOUT) {
|
||||
return EventIndex;
|
||||
}
|
||||
|
||||
// Filter reads/writes
|
||||
if (MsgPacket[1] & 2) {
|
||||
RdWrAttribute = READS_ONLY >> 16;
|
||||
} else {
|
||||
RdWrAttribute = WRITES_ONLY >> 16;
|
||||
}
|
||||
if (!(EventPtr->Flags & RdWrAttribute)) {
|
||||
return EventIndex;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EVENT_VIRTUAL_REGISTER:
|
||||
// Check for correct Class::Index
|
||||
ClassIndex = (USHORT)MsgPacket[1];
|
||||
if ((ClassIndex >= EventPtr->ClassLow) && (ClassIndex <= EventPtr->ClassHigh)) {
|
||||
return EventIndex;
|
||||
}
|
||||
break;
|
||||
|
||||
case EVENT_PCI_TRAP:
|
||||
if (EventIndex == EVENT_PCI_TRAP) {
|
||||
// Save original parameters
|
||||
PCI_Addr = (USHORT)MsgPacket[1];
|
||||
PCI_Size = (UCHAR)MsgPacket[2];
|
||||
PCI_Data = MsgPacket[3];
|
||||
} else {
|
||||
// Restore original parameters
|
||||
(USHORT)MsgPacket[1] = PCI_Addr;
|
||||
(UCHAR)MsgPacket[2] = PCI_Size;
|
||||
MsgPacket[3] = PCI_Data;
|
||||
}
|
||||
|
||||
// Ignore SysMgr's virtualization
|
||||
if (Vsm == SysMgr_VSM) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (MsgPacket[2] & 0x20000) {
|
||||
RdWrAttribute = READS_ONLY >> 16;
|
||||
} else {
|
||||
RdWrAttribute = WRITES_ONLY >> 16;
|
||||
}
|
||||
|
||||
|
||||
PCI_Hit = PCI_Addr;
|
||||
Size = PCI_Size & DWORD_IO;
|
||||
|
||||
while (Size) {
|
||||
|
||||
// Check for PCI address match after applying mask
|
||||
if (EventPtr->PCI_Addr == (PCI_Hit & ~(EventPtr->PCI_Mask))) {
|
||||
|
||||
// Filter reads/writes
|
||||
if (!(EventPtr->Flags & RdWrAttribute)) {
|
||||
// Limit Size to correct boundaries
|
||||
Size = PCI_Size & DWORD_IO;
|
||||
switch (PCI_Hit & 0x3) {
|
||||
case 2:
|
||||
if (Size == DWORD_IO) {
|
||||
Size = WORD_IO;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
Size = BYTE_IO;
|
||||
break;
|
||||
}
|
||||
MsgPacket[2] &= ~DWORD_IO;
|
||||
MsgPacket[2] |= Size;
|
||||
(USHORT)MsgPacket[1] = PCI_Hit;
|
||||
return EventIndex;
|
||||
}
|
||||
}
|
||||
|
||||
// Don't cross DWORD boundaries
|
||||
if ((++PCI_Hit & 0x3) == 0) {
|
||||
break;
|
||||
}
|
||||
MsgPacket[3] >>= 8;
|
||||
if (!(PCI_Size & IO_WRITE)) {
|
||||
MsgPacket[3] |= 0xFF000000;
|
||||
}
|
||||
Size >>= 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case EVENT_SOFTWARE_SMI:
|
||||
// Check for code match after applying mask
|
||||
if (EventPtr->Param1 == (MsgPacket[1] & ~EventPtr->Param2)) {
|
||||
return EventIndex;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return EventIndex;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Sends a MSG_EVENT to all VSMs registered for the specified event.
|
||||
//
|
||||
//*****************************************************************************
|
||||
EVENT pascal Send_Event(EVENT Event, VSM From_VSM)
|
||||
{ ULONG To_VSM, ErrorParam = Event;
|
||||
UCHAR HitCount = 0;
|
||||
EVENT Hits[MAX_HIT], EventIndex;
|
||||
USHORT i;
|
||||
register EVENT_ENTRY * EventPtr;
|
||||
|
||||
// Perform sanity checks
|
||||
if (Event == 0 || Event > MAX_EVENT) {
|
||||
Log_Error("Invalid event 0x%04X", Event);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (Events[Event].Vsm == 0) {
|
||||
// No VSM has registered this event.
|
||||
Log_Error("EVENT_%s[0x%08X;0x%08X] is not registered to a VSM", EventNames[Event], MsgPacket[1], MsgPacket[2]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EventIndex = Event;
|
||||
|
||||
#if HISTORY
|
||||
Keep_History(Event, EventIndex);
|
||||
#endif
|
||||
|
||||
// Store Event code as message parameter[0]
|
||||
MsgPacket[0] = Event;
|
||||
|
||||
// Walk the entire event chain looking for parameter matches
|
||||
while (EventIndex) {
|
||||
|
||||
EventPtr = &Events[EventIndex];
|
||||
|
||||
// Check if the parameters for the current event match this event registration
|
||||
if (FilterEvent(Event, EventIndex)) {
|
||||
if (HitCount < MAX_HIT-1) {
|
||||
// Record the hit
|
||||
Hits[++HitCount] = EventIndex;
|
||||
MsgParams[HitCount][1] = MsgPacket[1];
|
||||
MsgParams[HitCount][2] = MsgPacket[2];
|
||||
MsgParams[HitCount][3] = MsgPacket[3];
|
||||
} else {
|
||||
// ERROR: MAX_HIT is too small
|
||||
Log_Error("Hits[] array is too small");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Point to the next registered VSM
|
||||
EventIndex = EventPtr->Link;
|
||||
}
|
||||
|
||||
// Send messages in priority order
|
||||
for (i = HitCount; i > 0; i--) {
|
||||
EventPtr = &Events[Hits[i]];
|
||||
To_VSM = EventPtr->Vsm;
|
||||
|
||||
// Is the VSM being awakened prematurely from SYS_YIELD_CONTROL?
|
||||
if (VSM_Is_Yielded(To_VSM)) {
|
||||
EVENT_ENTRY * TimerPtr;
|
||||
|
||||
// Find the wakeup timer being used
|
||||
EventIndex = EVENT_TIMER;
|
||||
while (EventIndex) {
|
||||
TimerPtr = &Events[EventIndex];
|
||||
|
||||
if ((TimerPtr->Vsm == To_VSM) && (TimerPtr->Param2 & SYS_YIELD)) {
|
||||
Unregister_Event(EVENT_TIMER, To_VSM, TimerPtr->Param1, TimerPtr->Param2);
|
||||
break;
|
||||
}
|
||||
EventIndex = TimerPtr->Link;
|
||||
}
|
||||
}
|
||||
|
||||
// Send a message to the VSM
|
||||
if (!(EventPtr->Param2 & SYS_YIELD)) {
|
||||
MsgPacket[1] = MsgParams[i][1];
|
||||
MsgPacket[2] = MsgParams[i][2];
|
||||
MsgPacket[3] = MsgParams[i][3];
|
||||
Send_Message(From_VSM, To_VSM, MSG_EVENT);
|
||||
}
|
||||
|
||||
// Unregister one-shot events
|
||||
if (EventPtr->Param2 & ONE_SHOT) {
|
||||
Unregister_Event(Event, To_VSM, EventPtr->Param1, EventPtr->Param2);
|
||||
}
|
||||
}
|
||||
|
||||
// Send message to Spy VSM, if present
|
||||
if (HitCount && VSM_Ptrs[VSM_SPY]) {
|
||||
Send_Message(From_VSM, VSM_Ptrs[VSM_SPY], MSG_EVENT);
|
||||
}
|
||||
|
||||
|
||||
return HitCount;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Associates a VSM with an Event and associated Parameters.
|
||||
// The System Manager maintains a table indexed by the Event. Each entry
|
||||
// contains a Link (array index) to the next VSM registered as a handler for
|
||||
// that Event. Entries are ordered by Priority (high to low). Unused array
|
||||
// elements are denoted by the Vsm field == 0000.
|
||||
//*****************************************************************************
|
||||
void pascal Register_Event(EVENT Event, PRIORITY Priority, VSM Vsm, ULONG Param1, ULONG Param2)
|
||||
{ UCHAR index, previous, next, Match=0;
|
||||
register EVENT_ENTRY * EventPtr;
|
||||
|
||||
if (Event > MAX_EVENT) {
|
||||
// Illegal Event
|
||||
Log_Error("Attempt to register invalid event 0x%04X by the %s VSM", Event, VsmNames[Get_VSM_Type(Vsm)]);
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle special cases
|
||||
switch (Event) {
|
||||
|
||||
case EVENT_VIRTUAL_REGISTER:
|
||||
// Param2[15:8] = low index Param2[7:0] = high index
|
||||
// If index == 0x00, then any index is valid
|
||||
Param1 <<= 8; // Shift class to bits 15:8
|
||||
index = 0xFF; // Default upper index
|
||||
if (Param2) {
|
||||
index = (UCHAR)Param2; // Get upper index
|
||||
(UCHAR)Param1 = (UCHAR)(Param2 >> 8); // Get lower index
|
||||
}
|
||||
Param2 = Param1;
|
||||
(UCHAR)Param2 = index;
|
||||
break;
|
||||
|
||||
case EVENT_IO_TRAP:
|
||||
// 16 MSBs of Param1 are reserved
|
||||
Param1 &= 0x0000FFFF;
|
||||
// Don't allow PCI config cycles to be trapped
|
||||
if (Param1 >= 0xCF8 && Param1 <= 0xCFF) {
|
||||
Log_Error("Attempt to trap I/O 0xCF8-0xCFF by the %s VSM", VsmNames[Get_VSM_Type(Vsm)]);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case EVENT_TIMER:
|
||||
// Mask all except Handle and valid flags
|
||||
Param2 &= FOR_STANDBY | ONE_SHOT | SYS_YIELD | 0xFFFF;
|
||||
if (Param1 == 0) {
|
||||
Priority = UNREGISTER_PRIORITY;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// If unregistering event(s)...
|
||||
if (Priority >= UNREGISTER_PRIORITY) {
|
||||
Unregister_Event(Event, Vsm, Param1, Param2);
|
||||
return;
|
||||
}
|
||||
|
||||
index = (UCHAR)Event;
|
||||
next = 0;
|
||||
|
||||
if (Events[Event].Vsm) {
|
||||
|
||||
// Ensure a VSM doesn't register for the same event twice
|
||||
do {
|
||||
EventPtr = &Events[index];
|
||||
|
||||
// If it is the same VSM...
|
||||
if (EventPtr->Vsm == Vsm) {
|
||||
|
||||
switch (Event) {
|
||||
|
||||
// If existing timer handle, assign new interval and/or priority
|
||||
case EVENT_TIMER:
|
||||
if (EventPtr->Handle == (USHORT)Param2) {
|
||||
Match = 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case EVENT_PWM:
|
||||
// If existing pin, change rate and/or duty cycle
|
||||
if (EventPtr->Pin == (USHORT)Param1) {
|
||||
Match = 3;
|
||||
}
|
||||
break;
|
||||
|
||||
// If existing pin, accumulate attributes
|
||||
case EVENT_GPIO:
|
||||
if (EventPtr->Pin == Param1 && EventPtr->Priority == Priority) {
|
||||
EventPtr->Attributes |= Param2;
|
||||
Match = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
// If params match, then just update the event priority
|
||||
if (EventPtr->Param1 == Param1 && EventPtr->Param2 == Param2) {
|
||||
#if SUPPORT_PRIORITY
|
||||
// Sort list again according to priority
|
||||
#endif
|
||||
Match = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Early out
|
||||
if (Match) {
|
||||
break;
|
||||
}
|
||||
// Get link to next event
|
||||
index = EventPtr->Link;
|
||||
|
||||
} while (index);
|
||||
|
||||
|
||||
|
||||
if (Match == 0) {
|
||||
|
||||
// Report error if no more Events[] entries
|
||||
if (FreeEvent == 0) {
|
||||
Log_Error("Failed attempt to register EVENT_%s[0x%08X;0x%08X] by the %s VSM", EventNames[Event], Param1, Param2, VsmNames[Get_VSM_Type(Vsm)]);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get an unused Events[] entry
|
||||
index = FreeEvent;
|
||||
FreeEvent = Events[index].Link;
|
||||
|
||||
//
|
||||
// Find the insertion point. There are two cases:
|
||||
// 1) The new entry is higher priority than the current 1st entry
|
||||
// 2) The new entry belongs somewhere down the chain.
|
||||
//
|
||||
previous = next = (UCHAR)Event;
|
||||
while (next = Events[next].Link) {
|
||||
|
||||
if (Priority > Events[next].Priority) {
|
||||
break;
|
||||
}
|
||||
previous = next;
|
||||
}
|
||||
|
||||
if (Priority > Events[Event].Priority) {
|
||||
// case 1: Need to copy 1st entry to Events[index]
|
||||
Copy_Event(Event, index);
|
||||
next = index;
|
||||
index = (UCHAR)Event;
|
||||
|
||||
} else {
|
||||
// case 2:
|
||||
// Insert new event into linked list
|
||||
Events[previous].Link = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create new Events[] entry
|
||||
EventPtr = &Events[index];
|
||||
|
||||
|
||||
switch (Match) {
|
||||
|
||||
// New registration
|
||||
case 0:
|
||||
EventPtr->Link = next;
|
||||
EventPtr->Vsm = Vsm;
|
||||
case 3:
|
||||
EventPtr->Param2 = Param2;
|
||||
|
||||
// Update of Priority
|
||||
case 1:
|
||||
EventPtr->Priority = Priority;
|
||||
|
||||
// Update of Parameter (e.g. timer interval)
|
||||
case 2:
|
||||
EventPtr->Param1 = Param1;
|
||||
|
||||
}
|
||||
|
||||
// Enable the appropriate hardware
|
||||
Enable_Event(Event, index, 1);
|
||||
|
||||
}
|
||||
62
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/gpio.c
vendored
Executable file
62
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/gpio.c
vendored
Executable file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//* Function: *
|
||||
//* This file contains non-chipset specific GPIO code.
|
||||
|
||||
|
||||
#include "VSA2.H"
|
||||
#include "SYSMGR.H"
|
||||
#include "PROTOS.H"
|
||||
|
||||
|
||||
extern ULONG MsgPacket[];
|
||||
extern Hardware HardwareInfo;
|
||||
|
||||
|
||||
|
||||
//************************************************************************************
|
||||
// Reports invalid GPIO pin
|
||||
//************************************************************************************
|
||||
void Report_GPIO_Error(USHORT Pin)
|
||||
{
|
||||
Report_VSM_Error(ERR_HW_MISMATCH, EVENT_GPIO, Pin);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//************************************************************************************
|
||||
// Sends the EVENT_GPIO message
|
||||
//************************************************************************************
|
||||
void Send_GPIO_Event(USHORT Pin, USHORT Edge)
|
||||
{
|
||||
|
||||
MsgPacket[1] = Pin;
|
||||
MsgPacket[2] = Edge;
|
||||
Send_Event(EVENT_GPIO, 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
488
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/gpio5536.c
vendored
Executable file
488
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/gpio5536.c
vendored
Executable file
@@ -0,0 +1,488 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//******************************************************************************
|
||||
//* This file contains code specific to CS5536 GPIOs
|
||||
//******************************************************************************
|
||||
|
||||
|
||||
|
||||
#include "VSA2.H"
|
||||
#include "SYSMGR.H"
|
||||
#include "PROTOS.H"
|
||||
#include "VPCI.H"
|
||||
#include "PCI.H"
|
||||
#include "MDD.H"
|
||||
#include "MAPPER.H"
|
||||
|
||||
|
||||
#define POWER_BUTTON_PIN 28
|
||||
|
||||
// External Functions:
|
||||
extern void Send_GPIO_Event(USHORT Pin, USHORT Edge);
|
||||
extern void Enable_PME_Event(UCHAR, UCHAR, UCHAR, USHORT);
|
||||
extern UCHAR pascal BitScanReverse(ULONG);
|
||||
|
||||
// External Variables:
|
||||
extern PCI_HEADER_ENTRY ISA_Hdr[];
|
||||
extern GPIO_FUNCTION GPIO_Control;
|
||||
|
||||
// Local Variables:
|
||||
ULONG Enable_Mask;
|
||||
USHORT Lock_Port, Lock_Data;
|
||||
USHORT GPIO_Port;
|
||||
UCHAR Bank=0;
|
||||
UCHAR ShiftCount;
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
UCHAR SelectOffset; // Offset to filter select register
|
||||
UCHAR FilterOffset; // Offset to filter amount register
|
||||
UCHAR Pin; // Pin this filter is associated to
|
||||
UCHAR FilterRestore;
|
||||
} FILTERS;
|
||||
|
||||
FILTERS FilterInfo[8] = {
|
||||
{GPIO_FILTER_SELECT0, GPIO_FILTER_AMOUNT+0*8, 0xFF, 0},
|
||||
{GPIO_FILTER_SELECT1, GPIO_FILTER_AMOUNT+1*8, 0xFF, 0},
|
||||
{GPIO_FILTER_SELECT2, GPIO_FILTER_AMOUNT+2*8, 0xFF, 0},
|
||||
{GPIO_FILTER_SELECT3, GPIO_FILTER_AMOUNT+3*8, 0xFF, 0},
|
||||
{GPIO_FILTER_SELECT4, GPIO_FILTER_AMOUNT+4*8, 0xFF, 0},
|
||||
{GPIO_FILTER_SELECT5, GPIO_FILTER_AMOUNT+5*8, 0xFF, 0},
|
||||
{GPIO_FILTER_SELECT6, GPIO6_FILTER_AMOUNT, 28, 1}, // power button pre-defined
|
||||
{GPIO_FILTER_SELECT7, GPIO7_FILTER_AMOUNT, 0xFF, 0},
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Sends EVENT_GPIO messages for pins that have the specified edge status pending
|
||||
//*****************************************************************************
|
||||
void GPIO_Helper(UCHAR Edge, UCHAR PinBase)
|
||||
{ ULONG PinMask;
|
||||
UCHAR Pin;
|
||||
|
||||
if (Edge == RISING_EDGE) {
|
||||
(UCHAR)GPIO_Port = GPIO_POSEDGE_STATUS;
|
||||
} else {
|
||||
(UCHAR)GPIO_Port = GPIO_NEGEDGE_STATUS;
|
||||
}
|
||||
if (PinBase) {
|
||||
(UCHAR)GPIO_Port |= GPIO_HIGH_BANK_SELECT;
|
||||
}
|
||||
|
||||
// Get edge status
|
||||
PinMask = in_32(GPIO_Port);
|
||||
|
||||
// Clear the edge status
|
||||
out_32(GPIO_Port, PinMask);
|
||||
|
||||
// Ignore transitions that are not enabled
|
||||
GPIO_Port -= GPIO_POSEDGE_STATUS;
|
||||
GPIO_Port += GPIO_POSEDGE_ENABLE;
|
||||
PinMask &= in_32(GPIO_Port) & 0x0000FFFFL;
|
||||
|
||||
// Loop through all pending GPIO edges
|
||||
while (PinMask) {
|
||||
|
||||
// Determine next pending GPIO pin
|
||||
Pin = BitScanReverse(PinMask);
|
||||
PinMask &= ~(1L << Pin);
|
||||
|
||||
// Send the event to the VSM(s)
|
||||
Send_GPIO_Event(PinBase+Pin, Edge);
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// Handles GPIO SMIs
|
||||
//*****************************************************************************
|
||||
void CS5536_GPIO_Handler(ULONG Active_GPIOs)
|
||||
{
|
||||
// Get the current GPIO address
|
||||
GPIO_Port = ISA_Hdr[BAR1/4].Value_LO;
|
||||
Bank = GPIO_LOW_BANK_SELECT;
|
||||
GPIO_Helper( RISING_EDGE, 0); // Handle GPIO[15:00] rising edges
|
||||
GPIO_Helper(FALLING_EDGE, 0); // Handle GPIO[15:00] falling edges
|
||||
Bank = GPIO_HIGH_BANK_SELECT;
|
||||
GPIO_Helper( RISING_EDGE, 16); // Handle GPIO[31:16] rising edges
|
||||
GPIO_Helper(FALLING_EDGE, 16); // Handle GPIO[31:16] falling edges
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Unlocks specified GPIO register(s).
|
||||
// After GPIO registers are accessed, Relock_GPIO_Regs() should be invoked.
|
||||
//*****************************************************************************
|
||||
void Unlock_GPIO_Regs(USHORT UnlockMask)
|
||||
{
|
||||
// Get current Lock register
|
||||
Lock_Port = ISA_Hdr[BAR1/4].Value_LO;
|
||||
(UCHAR)Lock_Port = Bank + GPIO_LOCK_ENABLE;
|
||||
Lock_Data = in_16(Lock_Port);
|
||||
|
||||
// Unlock required registers
|
||||
out_16(Lock_Port, Lock_Data & ~UnlockMask);
|
||||
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// Restores GPIO register lock
|
||||
//*****************************************************************************
|
||||
void Relock_GPIO_Regs(void)
|
||||
{
|
||||
out_16(Lock_Port, Lock_Data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Writes a 32-bit value to a GPIO register
|
||||
//*****************************************************************************
|
||||
void Write_GPIO_Register(UCHAR Register, ULONG Data)
|
||||
{
|
||||
// Write register
|
||||
(UCHAR)GPIO_Port = Bank + Register;
|
||||
out_32(GPIO_Port, Data);
|
||||
|
||||
// Handle registers that are slow due to being in the Standby power domain
|
||||
if (Bank == GPIO_HIGH_BANK_SELECT) {
|
||||
in_32(GPIO_Port);
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// Writes Enable_Mask to a GPIO register
|
||||
//*****************************************************************************
|
||||
void Configure_GPIO(UCHAR Reg)
|
||||
{
|
||||
Write_GPIO_Register(Reg, Enable_Mask);
|
||||
}
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Maps the specified GPIO pin to the specified GPIO Interrupt
|
||||
//*****************************************************************************
|
||||
void GPIO_Mapper(UCHAR Pin, UCHAR Irq)
|
||||
{ ULONG Data;
|
||||
|
||||
// Unlock GPIO register(s)
|
||||
Unlock_GPIO_Regs(LKIE | LKOE | LKPU | LKPD);
|
||||
|
||||
// Configure pin as Input
|
||||
if (Pin != POWER_BUTTON_PIN) { // Keeps sleep pin from generating SMI
|
||||
Configure_GPIO(GPIO_INPUT_ENABLE);
|
||||
}
|
||||
|
||||
// Disable Output, Pullup & Pulldown
|
||||
Data = Enable_Mask << 16;
|
||||
Write_GPIO_Register(GPIO_OUTPUT_ENABLE, Data);
|
||||
Write_GPIO_Register(GPIO_PULLDOWN_ENABLE, Data);
|
||||
Write_GPIO_Register(GPIO_PULLUP_ENABLE, Data);
|
||||
|
||||
// Restore Lock register
|
||||
Relock_GPIO_Regs();
|
||||
|
||||
|
||||
// Program GPIO Mapper
|
||||
(UCHAR)GPIO_Port = (UCHAR)(GPIO_MAPPER_X + ((Pin >> 1) & 0x0C));
|
||||
ShiftCount = (Pin % 8) * 4;
|
||||
Data = in_32(GPIO_Port);
|
||||
|
||||
Data &= ~(0x0000000FL << ShiftCount);
|
||||
Data |= (ULONG)Irq << ShiftCount;
|
||||
out_32(GPIO_Port, Data);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Clears the positive & negative edge status registers for the specified GPIOs
|
||||
//*****************************************************************************
|
||||
void ClearEdgeStatus(ULONG Mask)
|
||||
{
|
||||
Write_GPIO_Register(GPIO_POSEDGE_STATUS, Mask);
|
||||
Write_GPIO_Register(GPIO_NEGEDGE_STATUS, Mask);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Enables/Disables generation of SMI on GPIO edge(s) for the CS5536 chipset
|
||||
//*****************************************************************************
|
||||
void CS5536_GPIO_Control(ULONG Param1, ULONG Param2, UCHAR EnableFlag)
|
||||
{ ULONG Attributes;
|
||||
UCHAR Pin, Pme, Pm1, i, PinToMatch, FilterAmount, filter_to_use;
|
||||
ULONG Clear_Mask;
|
||||
|
||||
|
||||
// Unpack parameters
|
||||
Pin = (UCHAR)Param1;
|
||||
Pme = (UCHAR)(Param1 >> 16);
|
||||
Pm1 = (UCHAR)(Param2 >> 16);
|
||||
Attributes = Param2 & 0xff00ffff;
|
||||
|
||||
GPIO_Port = ISA_Hdr[BAR1/4].Value_LO;
|
||||
|
||||
// Log_Error("GPIO %d (%d) %d %d 0x%08X 0x%08X 0x%08X\r\n",Pin,EnableFlag,Pme,Pm1,Attributes,Param1,Param2);
|
||||
// Validate parameters
|
||||
if (Pin >= 32) {
|
||||
Log_Error("Invalid GPIO pin # = 0x%02X\r\n", Pin);
|
||||
return;
|
||||
}
|
||||
if ((Pme > 7) && (Attributes & PME)) {
|
||||
Log_Error("Invalid PME # = 0x%02X\r\n", Pme);
|
||||
return;
|
||||
}
|
||||
if ((Pm1 > 10) && (Attributes & PM1)) {
|
||||
Log_Error("Invalid PM1 # = 0x%02X\r\n", Pm1);
|
||||
return;
|
||||
}
|
||||
|
||||
// Select Low/High bank
|
||||
ShiftCount = Pin;
|
||||
Bank = GPIO_LOW_BANK_SELECT;
|
||||
if (Pin >= 16) {
|
||||
ShiftCount -= 16;
|
||||
Bank = GPIO_HIGH_BANK_SELECT;
|
||||
}
|
||||
// Generate masks
|
||||
Clear_Mask = Enable_Mask = 1L << ShiftCount;
|
||||
|
||||
// Clear possible false edge events
|
||||
ClearEdgeStatus(Clear_Mask);
|
||||
|
||||
// If disable, set 16 MSBs of Enable_Mask
|
||||
if (!EnableFlag) {
|
||||
Enable_Mask <<= 16;
|
||||
}
|
||||
|
||||
// Set GPIO Interrupt/PME Mapper to generate an ASMI or PME
|
||||
if (Attributes & PME) {
|
||||
// Map the GPIO as a PME
|
||||
GPIO_Mapper(Pin, (UCHAR)(Pme | 0x08));
|
||||
} else {
|
||||
// Route to ASMI unless PCI interrupt is specified
|
||||
if (Pme) {
|
||||
// Map the GPIO to a GPIO Interrupt
|
||||
GPIO_Mapper(Pin, (UCHAR)(Pme & 0x07));
|
||||
} else {
|
||||
if (!(Attributes & NO_ASMI)) {
|
||||
// Map the GPIO to an ASMI
|
||||
GPIO_Mapper(Pin, (Z_IRQ_SMI & 0x07));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// This will set the MDD MSR_SMI bit for SMI on any PM event
|
||||
// and program the appropriate ACPI PM1_EN or GPE0_EN bit.
|
||||
// Additionally, it will clear the corresponding ACPI PM1_STS or GPE0_STS bit.
|
||||
Enable_PME_Event(EnableFlag, Pm1, Pme, (USHORT)Attributes);
|
||||
|
||||
// If power button, don't touch any GPIO regs!
|
||||
if (Pin == POWER_BUTTON_PIN) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Unlock GPIO registers
|
||||
Unlock_GPIO_Regs(LKPE | LKNE | LKFE | LKEE);
|
||||
|
||||
// Configure as Output ?
|
||||
if (Attributes & OUTPUT) {
|
||||
|
||||
Configure_GPIO(GPIO_OUTPUT_ENABLE);
|
||||
|
||||
// Configure output pin inversion
|
||||
if (Attributes & INVERT) {
|
||||
Configure_GPIO(GPIO_OUTPUT_INVERT);
|
||||
}
|
||||
|
||||
// Configure open drain
|
||||
if (Attributes & OPEN_DRAIN) {
|
||||
Configure_GPIO(GPIO_OUTPUT_OPENDRAIN);
|
||||
}
|
||||
|
||||
// Configure AUX output selects
|
||||
if (Attributes & AUX1) {
|
||||
Configure_GPIO(GPIO_OUT_AUX1_SELECT);
|
||||
} else {
|
||||
if (Attributes & AUX2) {
|
||||
Configure_GPIO(GPIO_OUT_AUX2_SELECT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Configure as Input ?
|
||||
if ((Attributes & INPUT) || !(Attributes & OUTPUT)) {
|
||||
// Configure input pin inversion
|
||||
if (Attributes & INVERT) {
|
||||
Configure_GPIO(GPIO_INPUT_INVERT);
|
||||
}
|
||||
|
||||
if (Attributes & AUX1) {
|
||||
Configure_GPIO(GPIO_IN_AUX1_SELECT);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Configure input for correct edge(s)
|
||||
switch (Attributes & BOTH_EDGES) {
|
||||
|
||||
case BOTH_EDGES:
|
||||
case RISING_EDGE:
|
||||
// Enable/Disable the RISING edge
|
||||
Configure_GPIO(GPIO_POSEDGE_ENABLE);
|
||||
if ((Attributes & BOTH_EDGES) == RISING_EDGE) {
|
||||
break;
|
||||
}
|
||||
// fall through intended
|
||||
|
||||
case FALLING_EDGE:
|
||||
// Enable/Disable the FALLING edge
|
||||
Configure_GPIO(GPIO_NEGEDGE_ENABLE);
|
||||
break;
|
||||
|
||||
default:
|
||||
// If neither edge is enabled, an event is 'active' as long
|
||||
// as the input is high (or low if inverted).
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// NOTE: If pullup is enabled, pulldown is automatically disabled
|
||||
// Configure pullup
|
||||
if (Attributes & PULLUP) {
|
||||
Configure_GPIO(GPIO_PULLUP_ENABLE);
|
||||
} else {
|
||||
// Configure pulldown
|
||||
if (Attributes & PULLDOWN) {
|
||||
Configure_GPIO(GPIO_PULLDOWN_ENABLE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Configure debounce filter
|
||||
if (Attributes & DEBOUNCE) {
|
||||
PinToMatch = (UCHAR)Pin;
|
||||
|
||||
if (EnableFlag) {
|
||||
FilterAmount = 1; // Units = ~30 usec
|
||||
} else {
|
||||
FilterAmount = 0;
|
||||
}
|
||||
|
||||
// Find a filter
|
||||
i=0;
|
||||
if (Attributes & FOR_STANDBY ) {
|
||||
i=6; // if pme 6/7 set for filter 6/7 (in standby domain)
|
||||
}
|
||||
filter_to_use=0xff;
|
||||
|
||||
for (; i < 8; i++) {
|
||||
if (FilterInfo[i].Pin == PinToMatch) {
|
||||
filter_to_use=i;
|
||||
break;
|
||||
}
|
||||
// see if we have found an open filter - use only for enable
|
||||
if ((filter_to_use == 0xff) && (FilterInfo[i].Pin == 0xff) && (EnableFlag)) {
|
||||
filter_to_use=i;
|
||||
}
|
||||
}
|
||||
// Log_Error("GPIO %d using filter %d\r\n",Pin,filter_to_use);
|
||||
// found an matching pin for filter or an open one
|
||||
if (filter_to_use != 0xff) { // found one
|
||||
i=filter_to_use; // use this filter
|
||||
if (EnableFlag) {
|
||||
// Mark filter in-use
|
||||
FilterInfo[i].Pin = (UCHAR)Pin;
|
||||
|
||||
// Save the filter select register
|
||||
(UCHAR)GPIO_Port = FilterInfo[i].SelectOffset;
|
||||
FilterInfo[i].FilterRestore = in_8(GPIO_Port);
|
||||
|
||||
// Select the filter
|
||||
out_8(GPIO_Port, (UCHAR)Pin);
|
||||
}
|
||||
|
||||
// Program filter Amount & Count
|
||||
(UCHAR)GPIO_Port = FilterInfo[i].FilterOffset;
|
||||
out_32(GPIO_Port, (ULONG)FilterAmount);
|
||||
|
||||
if (!EnableFlag) {
|
||||
// Mark filter as available
|
||||
FilterInfo[i].Pin = 0xFF;
|
||||
|
||||
// Restore the filter select register
|
||||
(UCHAR)GPIO_Port = FilterInfo[i].SelectOffset;
|
||||
out_8(GPIO_Port, FilterInfo[i].FilterRestore);
|
||||
}
|
||||
// Enable/Disable filter
|
||||
Configure_GPIO(GPIO_IN_FILTER_ENABLE);
|
||||
}
|
||||
else {
|
||||
// no filter found
|
||||
Log_Error("No filter found for GPIO %d\r\n",Pin);
|
||||
}
|
||||
}
|
||||
|
||||
// Enable/Disable GPIO as an event unless it is EVENT_PWM
|
||||
if ((Attributes & (OUTPUT | NO_ASMI)) != (OUTPUT | NO_ASMI)) {
|
||||
Configure_GPIO(GPIO_EVENTS_ENABLE);
|
||||
}
|
||||
|
||||
|
||||
// Clear possible false edge events
|
||||
ClearEdgeStatus(Clear_Mask);
|
||||
|
||||
|
||||
// Restore Lock register
|
||||
Relock_GPIO_Regs();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Initialized CS5536 GPIO logic
|
||||
//*****************************************************************************
|
||||
void CS5536_GPIO_Init(void)
|
||||
{
|
||||
|
||||
// Point GPIO_Control to correct GPIO routine for CS5536
|
||||
GPIO_Control = CS5536_GPIO_Control;
|
||||
|
||||
// Clear pending GPIOs
|
||||
CS5536_GPIO_Handler(0);
|
||||
|
||||
// Map the GPIO SMI source
|
||||
IRQZ_Mapper(Z_IRQ_SMI, 2);
|
||||
|
||||
}
|
||||
645
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/handlers.c
vendored
Executable file
645
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/handlers.c
vendored
Executable file
@@ -0,0 +1,645 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//*****************************************************************************
|
||||
//* Implements the handlers for top-level SMI source
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
#include "VSA2.H"
|
||||
#include "CHIPSET.H"
|
||||
#include "PROTOS.H"
|
||||
#include "SYSMGR.H"
|
||||
#include "VPCI.H"
|
||||
#include "PCI.H"
|
||||
|
||||
// External variables
|
||||
extern SmiHeader SMM_Header;
|
||||
extern SmiHeader Nested_Header;
|
||||
extern ULONG Saved_EAX, Saved_EBX, Saved_ECX;
|
||||
extern ULONG MsgPacket[];
|
||||
extern ULONG VSM_ListHead;
|
||||
extern ULONG Virtualized_PCI_Devices;
|
||||
extern ULONG Stats_Sources;
|
||||
extern ULONG IRQ_Mask;
|
||||
extern ULONG MPCI_NB;
|
||||
extern ULONG VSM_Buffer;
|
||||
extern ULONG Nested_Flag;
|
||||
extern ULONG Video_Sources;
|
||||
extern USHORT Audio_Sources;
|
||||
extern Hardware HardwareInfo;
|
||||
extern EVENT_ENTRY Events[];
|
||||
extern PCI_HEADER_ENTRY ISA_Hdr[];
|
||||
extern PCI_HEADER_ENTRY HostBridge_Hdr[];
|
||||
|
||||
|
||||
// External function prototypes
|
||||
extern void pascal Timer_Handler(USHORT);
|
||||
extern void CS5536_GPIO_Handler(ULONG);
|
||||
extern void INT_Return(void);
|
||||
extern void Send_OHCI_Event(UCHAR);
|
||||
extern void VR_Handler(SmiHeader *);
|
||||
extern void ACPI_Workaround(SmiHeader *, USHORT);
|
||||
extern void Remove_RTC_Fix(void);
|
||||
extern void set_reset_state(void);
|
||||
extern void pascal Unblock_VSM(ULONG);
|
||||
extern void pascal Return_Virtual_Value(SmiHeader *, ULONG);
|
||||
extern SmiHeader * pascal Get_Header_Params(ULONG);
|
||||
extern ULONG Get_ACPI_Status(ULONG *);
|
||||
extern USHORT Get_Timeout(ULONG, UCHAR *);
|
||||
extern USHORT CS5536_MFGPT_Handler(void);
|
||||
extern void ReInit_Descriptors(void);
|
||||
extern void Init_SysMgr();
|
||||
extern void A20_Sync(void);
|
||||
extern void Update_VSMs_CR0(void);
|
||||
|
||||
|
||||
ULONG INT_Vectors[MAX_INT] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xF000F859};
|
||||
ULONG VSM_Ptrs[VSM_MAX_TYPE+1];
|
||||
ULONG Audio_IRQ = 0;
|
||||
ULONG NativeAudioStatus = 0x4F0; // Defaults to 0040:00F0
|
||||
UCHAR End_of_POST = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void Broadcast_SysMgr_Msg (MSG Message, UCHAR Param1)
|
||||
{
|
||||
MsgPacket[0] = (ULONG)Param1;
|
||||
MsgPacket[1] = MsgPacket[2] = 0;
|
||||
Broadcast_Message(Message, VSM_ANY, 0x00000000);
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Sends a message for an asynchronous event
|
||||
//***********************************************************************
|
||||
void pascal Send_Asynchronous_Event(EVENT Event)
|
||||
{
|
||||
MsgPacket[1] = MsgPacket[3] = MsgPacket[4] = 00000000;
|
||||
if (Event != EVENT_IO_TIMEOUT) {
|
||||
MsgPacket[2] = 00000000;
|
||||
}
|
||||
Send_Event(Event, 0x00000000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Sends a message for a synchronous event
|
||||
// Returns TRUE if the event was registered.
|
||||
//***********************************************************************
|
||||
USHORT pascal Send_Synchronous_Event(EVENT Event, SmiHeader * SmiHdr)
|
||||
{ ULONG Vsm;
|
||||
USHORT EventRegistered;
|
||||
|
||||
if ((USHORT)SmiHdr == 0x0000 || (USHORT)SmiHdr == (USHORT)&SMM_Header) {
|
||||
Vsm = SysMgr_VSM;
|
||||
} else {
|
||||
Vsm = Current_VSM;
|
||||
}
|
||||
EventRegistered = Send_Event(Event, Vsm);
|
||||
if (!EventRegistered) {
|
||||
|
||||
// No VSM is registered for this event
|
||||
// If nested event, change the VSM's state from 'Blocked' to 'Ready'
|
||||
if (Nested_Flag) {
|
||||
Unblock_VSM(Vsm);
|
||||
}
|
||||
}
|
||||
|
||||
return EventRegistered;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// This routine walks the VSM linked list, recording ptrs to VSMs that
|
||||
// have special requirements.
|
||||
//***********************************************************************
|
||||
void Record_VSM_Locations(void)
|
||||
{ ULONG VSM_Ptr;
|
||||
UCHAR VSM_Type;
|
||||
|
||||
for (VSM_Type=0; VSM_Type<=VSM_MAX_TYPE; VSM_Type++) {
|
||||
VSM_Ptrs[VSM_Type] = 0x00000000;
|
||||
}
|
||||
VSM_Ptr = VSM_ListHead;
|
||||
|
||||
while (VSM_Ptr) {
|
||||
|
||||
VSM_Type = Get_VSM_Type(VSM_Ptr);
|
||||
|
||||
if (VSM_Type < sizeof(VSM_Ptrs)/4) {
|
||||
VSM_Ptrs[VSM_Type] = VSM_Ptr;
|
||||
}
|
||||
if (VSM_Type == VSM_RTC) {
|
||||
Remove_RTC_Fix();
|
||||
}
|
||||
VSM_Ptr = GetFlink(VSM_Ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// This routine handles software SMI events.
|
||||
//***********************************************************************
|
||||
void pascal SMINT_Handler(USHORT Code)
|
||||
{ int i;
|
||||
|
||||
// Handle return from INT callback
|
||||
if (VSM_Buffer) {
|
||||
INT_Return();
|
||||
return;
|
||||
}
|
||||
|
||||
switch (Code) {
|
||||
|
||||
case SYS_BIOS_INIT:
|
||||
|
||||
// If installing VSA from DOS, restore descriptors to default state
|
||||
if (Saved_EBX != 0) {
|
||||
ReInit_Descriptors();
|
||||
}
|
||||
|
||||
// VSA Initialization
|
||||
Init_SysMgr();
|
||||
if (Saved_EBX == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_END_OF_POST:
|
||||
Current_VSM = 0;
|
||||
|
||||
End_of_POST = 1;
|
||||
//
|
||||
// Take a snapshot of the interrupt vectors
|
||||
//
|
||||
for (i = 0; i < MAX_INT; i++) {
|
||||
if (INT_Vectors[i] == 0) {
|
||||
INT_Vectors[i] = read_flat((ULONG) i << 2 );
|
||||
}
|
||||
}
|
||||
|
||||
// Entry point to video ROM
|
||||
INT_Vectors[1] = 0xC0000003;
|
||||
|
||||
//
|
||||
// The BIOS may have enabled the changed the cache setting
|
||||
// since early init, so update each VSM's CR0 field
|
||||
//
|
||||
Update_VSMs_CR0();
|
||||
|
||||
// Send a phase 1 initialization message to each VSM
|
||||
Broadcast_SysMgr_Msg(MSG_INITIALIZE, END_OF_POST_INIT);
|
||||
break;
|
||||
|
||||
|
||||
case SYS_REMOVE:
|
||||
Unregister_VSM_Events(Saved_ECX);
|
||||
break;
|
||||
|
||||
case SYS_VSM_INSTALL:
|
||||
|
||||
// EBX points to the new VSM
|
||||
// ECX points to the old VSM
|
||||
Unregister_VSM_Events(Saved_ECX);
|
||||
|
||||
Record_VSM_Locations();
|
||||
|
||||
|
||||
//
|
||||
// Send both phase 0 & 1 initialization messages to the new VSM
|
||||
//
|
||||
MsgPacket[0] = EARLY_INIT;
|
||||
MsgPacket[1] = 1;
|
||||
Send_Message(SysMgr_VSM, Saved_EBX, MSG_INITIALIZE);
|
||||
|
||||
MsgPacket[0] = END_OF_POST_INIT;
|
||||
MsgPacket[1] = 1;
|
||||
Send_Message(SysMgr_VSM, Saved_EBX, MSG_INITIALIZE);
|
||||
break;
|
||||
|
||||
default:
|
||||
//
|
||||
// Send event to appropriate VSM
|
||||
//
|
||||
MsgPacket[1] = (ULONG)Code;
|
||||
MsgPacket[2] = Saved_EBX;
|
||||
MsgPacket[3] = Saved_ECX;
|
||||
Send_Synchronous_Event(EVENT_SOFTWARE_SMI, 0);
|
||||
break;
|
||||
|
||||
} // end switch
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// This routine handles graphics events.
|
||||
//***********************************************************************
|
||||
void VG_Handler(void)
|
||||
{ register SmiHeader * SmiHdr;
|
||||
|
||||
SmiHdr = Get_Header_Params(0);
|
||||
|
||||
// Set bit 24 of MsgPacket[2] if I/O write
|
||||
if (SmiHdr->SMI_Flags.IO_Write) {
|
||||
MsgPacket[2] |= 0x01000000L;
|
||||
}
|
||||
MsgPacket[1] = Video_Sources;
|
||||
Send_Synchronous_Event(EVENT_GRAPHICS, SmiHdr);
|
||||
|
||||
// Reset video event flags
|
||||
Video_Sources = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// This routine handles A20
|
||||
//***********************************************************************
|
||||
void A20_Handler(void)
|
||||
{
|
||||
|
||||
A20_Sync();
|
||||
|
||||
// Send event so it will be recorded in the history buffer
|
||||
// Send_Synchronous_Event(EVENT_A20, SMM_Header);
|
||||
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
// This routine handles reset
|
||||
//***********************************************************************
|
||||
void Reset_Handler(void)
|
||||
{
|
||||
|
||||
|
||||
// Schedule reset routine after VSMs have processes MSG_SHUTDOWN
|
||||
Schedule_VSM((ULONG)((USHORT)set_reset_state));
|
||||
|
||||
// Tell each VSM to get ready for cold boot
|
||||
// No VSMs use this message at this time, so don't broadcast message
|
||||
// (to keep overhead down)
|
||||
// Broadcast_SysMgr_Msg(MSG_SHUTDOWN, 0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
// This routine handles NMI
|
||||
//***********************************************************************
|
||||
void NMI_Handler(void)
|
||||
{
|
||||
Send_Asynchronous_Event(EVENT_NMI);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// This routine handles trapped PCI events.
|
||||
// The event may come from an SSMI (CPU) or an external SMI (chipset)
|
||||
//***********************************************************************
|
||||
void PCI_Handler(void)
|
||||
{ ULONG ID_Select, Data;
|
||||
USHORT Address;
|
||||
UCHAR Size;
|
||||
register SmiHeader * SmiHdr;
|
||||
|
||||
|
||||
SmiHdr = Get_Header_Params(SMI_SRC_PCI_TRAP);
|
||||
Address = (USHORT)MsgPacket[2];
|
||||
|
||||
Size = (UCHAR)SmiHdr->data_size;
|
||||
ID_Select = 1L << ((Address >> 11) & 0x1F);
|
||||
|
||||
|
||||
if (SmiHdr->SMI_Flags.IO_Write) {
|
||||
|
||||
//
|
||||
// Trapped PCI header WRITE
|
||||
//
|
||||
Data = MsgPacket[3];
|
||||
|
||||
// Is it is a totally virtual PCI header ?
|
||||
if (ID_Select & Virtualized_PCI_Devices) {
|
||||
MsgPacket[3] = Virtual_PCI_Write_Handler(Address, Size, Data);
|
||||
Address &= 0xFFFC;
|
||||
Size = DWORD_IO;
|
||||
}
|
||||
|
||||
// Set the write flag
|
||||
Size |= IO_WRITE;
|
||||
|
||||
} else {
|
||||
|
||||
//
|
||||
// Trapped PCI header READ
|
||||
//
|
||||
|
||||
// Is it is a totally virtual PCI header ?
|
||||
if (ID_Select & Virtualized_PCI_Devices) {
|
||||
|
||||
Data = Virtual_PCI_Read_Handler(Address);
|
||||
|
||||
} else {
|
||||
Trap_PCI_IDSEL(Address, 0);
|
||||
out_32(PCI_CONFIG_ADDRESS, 0x80000000 | Address);
|
||||
Data = in_32(PCI_CONFIG_DATA);
|
||||
Trap_PCI_IDSEL(Address, 1);
|
||||
}
|
||||
// Return virtualized PCI device value to the right environment
|
||||
Return_Virtual_Value(SmiHdr, Data);
|
||||
MsgPacket[3] = Data;
|
||||
}
|
||||
|
||||
// Repackage the parameters
|
||||
MsgPacket[2] = MsgPacket[1] << 16;
|
||||
MsgPacket[1] = 0x80000000 + (USHORT)Address;
|
||||
(USHORT)MsgPacket[2] = Size;
|
||||
|
||||
// Send EVENT_PCI_TRAP message
|
||||
if (!Send_Synchronous_Event(EVENT_PCI_TRAP, SmiHdr)) {
|
||||
// This PCI register was not trapped.
|
||||
// Re-issue configuration writes to real PCI hardware devices.
|
||||
if (Size & IO_WRITE) {
|
||||
if (!(ID_Select & Virtualized_PCI_Devices)) {
|
||||
USHORT PCI_Data_Reg;
|
||||
// Disable trapping for this device
|
||||
Trap_PCI_IDSEL(Address, 0);
|
||||
|
||||
// Re-issue the configuration write to the h/w device
|
||||
out_32(PCI_CONFIG_ADDRESS, 0x80000000 | Address);
|
||||
PCI_Data_Reg = PCI_CONFIG_DATA + (Address & 3);
|
||||
switch (Size & ~IO_WRITE) {
|
||||
|
||||
case BYTE_IO:
|
||||
out_8(PCI_Data_Reg, (UCHAR)Data);
|
||||
break;
|
||||
|
||||
case WORD_IO:
|
||||
out_16(PCI_Data_Reg, (USHORT)Data);
|
||||
break;
|
||||
|
||||
case DWORD_IO:
|
||||
out_32(PCI_Data_Reg, Data);
|
||||
break;
|
||||
}
|
||||
|
||||
// Re-enable trapping for this device
|
||||
Trap_PCI_IDSEL(Address, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// This routine handles USB1 events.
|
||||
//***********************************************************************
|
||||
void USB1_Handler(void)
|
||||
{
|
||||
Send_OHCI_Event(1);
|
||||
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
// This routine handles USB2 events.
|
||||
//***********************************************************************
|
||||
void USB2_Handler(void)
|
||||
{
|
||||
Send_OHCI_Event(2);
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// This routine handles the CS5536's KEL events
|
||||
//***********************************************************************
|
||||
void KEL_Handler(void)
|
||||
{
|
||||
Send_OHCI_Event(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// This routine handles a BLOCKIO event (PIO to ATA during UDMA).
|
||||
//***********************************************************************
|
||||
void BLOCKIO_Handler(void)
|
||||
{ SmiHeader * SmiHdr;
|
||||
|
||||
SmiHdr = Get_Header_Params(SMI_SRC_BLOCKIO);
|
||||
Send_Synchronous_Event(EVENT_BLOCKIO, SmiHdr);
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
// This routine handles hits on MBus descriptors.
|
||||
//***********************************************************************
|
||||
void Descr_Hit_Handler(void)
|
||||
{ USHORT Address;
|
||||
SmiHeader * SmiHdr;
|
||||
|
||||
SmiHdr = Get_Header_Params(SMI_SRC_DESCR_HIT);
|
||||
|
||||
// Ignore if one of the other sources of SSMI_FLAGS
|
||||
if (!SmiHdr->SMI_Flags.Ext_IO_Trap && !SmiHdr->SMI_Flags.IO_Trap) {
|
||||
return;
|
||||
}
|
||||
|
||||
Address = (USHORT)SmiHdr->IO_addr;
|
||||
|
||||
// Handle virtual registers
|
||||
if ((Address & 0xFFFC) == (HostBridge_Hdr[BAR0/4].Value_LO)) {
|
||||
if (SmiHdr == &SMM_Header) {
|
||||
// Handle virtual register
|
||||
VR_Handler(SmiHdr);
|
||||
} else {
|
||||
Report_VSM_Error(ERR_NESTED_ACCESS, 0, 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle workaround for PM Support registers
|
||||
if ((Address & (USHORT)ISA_Hdr[BAR4/4].Mask) == (ISA_Hdr[BAR4/4].Value_LO)) {
|
||||
ACPI_Workaround(SmiHdr, 0);
|
||||
}
|
||||
|
||||
// Handle workaround for ACPI registers
|
||||
if ((Address & 0xFFE0) == (ISA_Hdr[BAR5/4].Value_LO)) {
|
||||
ACPI_Workaround(SmiHdr, 1);
|
||||
}
|
||||
// Send the event
|
||||
Send_Synchronous_Event(EVENT_IO_TRAP, SmiHdr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// This routine handles statistic counter ASMIs
|
||||
//***********************************************************************
|
||||
void StatCntr_Handler(void)
|
||||
{ UCHAR StartIndex = 0;
|
||||
USHORT Address;
|
||||
ULONG SFlag;
|
||||
|
||||
|
||||
while (Stats_Sources) {
|
||||
SFlag = 1L << BitScanForward(Stats_Sources);
|
||||
|
||||
Address = Get_Timeout(SFlag, &StartIndex);
|
||||
if (Address) {
|
||||
(USHORT)MsgPacket[2] = Address;
|
||||
Send_Asynchronous_Event(EVENT_IO_TIMEOUT);
|
||||
} else {
|
||||
// Clear status bit
|
||||
Stats_Sources &= ~SFlag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// This routine handles the Southbridge's PIC events
|
||||
//***********************************************************************
|
||||
void PIC_Handler(void)
|
||||
{ USHORT ExpiredTimerMask, Timer;
|
||||
|
||||
// Need to read PIC registers to determine if one of:
|
||||
// USB1, USB2, S/W Generated, RTC Alarm, Audio, PM, NAND Flash,
|
||||
// SMB, KEL, UART1, UART2, MFGPT comparator, or GPIO.
|
||||
CS5536_GPIO_Handler(0);
|
||||
|
||||
|
||||
// Check if any MFGPT events occurred
|
||||
ExpiredTimerMask = CS5536_MFGPT_Handler();
|
||||
Timer = 0;
|
||||
while (ExpiredTimerMask) {
|
||||
if (ExpiredTimerMask & 1) {
|
||||
Timer_Handler(Timer);
|
||||
}
|
||||
Timer++;
|
||||
ExpiredTimerMask >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// This routine handles the CS5536's ACPI events
|
||||
//***********************************************************************
|
||||
void ACPI_Handler(void)
|
||||
{ SmiHeader * SmiHdr;
|
||||
|
||||
SmiHdr = Get_Header_Params(0);
|
||||
|
||||
// Handle mis-aligned access to the PM1_CNT register
|
||||
while ((UCHAR)SmiHdr->IO_addr != 0x08) {
|
||||
(UCHAR)SmiHdr->IO_addr++;
|
||||
(UCHAR)SmiHdr->data_size >>= 1;
|
||||
SmiHdr->write_data >>= 8;
|
||||
}
|
||||
if ((UCHAR)SmiHdr->data_size == 0x07) {
|
||||
(UCHAR)SmiHdr->data_size = WORD_IO;
|
||||
}
|
||||
|
||||
|
||||
Send_Synchronous_Event(EVENT_ACPI, SmiHdr);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// This routine handles the CS5536's Power Management Events
|
||||
//***********************************************************************
|
||||
void PME_Handler(void)
|
||||
{
|
||||
|
||||
// Handle GPIOs that are routed to PM logic
|
||||
CS5536_GPIO_Handler(0);
|
||||
|
||||
// Filter any false event caused by enabling PME
|
||||
if (Get_ACPI_Status(MsgPacket)) {
|
||||
Send_Synchronous_Event(EVENT_PME, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// This routine handles events for which no other handler applies.
|
||||
//***********************************************************************
|
||||
void Leftover_Handler(void)
|
||||
{
|
||||
|
||||
// Report that the event was not handled.
|
||||
Log_Error("Unhandled event");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// The SMI_Sources table is used for determining the proper handler for
|
||||
// a top-level SMI source. Note that a single handler may process multiple
|
||||
// SMI sources. The order of entries in this table governs the order that
|
||||
// the handlers will be invoked. This is NOT the order that the VSMs will
|
||||
// be given control. Therefore, the order of entries is unimportant with
|
||||
// respect to controlling priority. However, in terms of finding a match
|
||||
// more quickly, the more frequent SMI events should be placed earlier in
|
||||
// the table.
|
||||
//
|
||||
//*************************************************************************
|
||||
|
||||
SMI_ENTRY Handler_Table[] = {
|
||||
PCI_Handler, SMI_SRC_PCI_TRAP,
|
||||
VG_Handler, SMI_SRC_VG,
|
||||
USB1_Handler, SMI_SRC_USB1,
|
||||
USB2_Handler, SMI_SRC_USB2,
|
||||
A20_Handler, SMI_SRC_A20,
|
||||
Reset_Handler, SMI_SRC_RESET,
|
||||
NMI_Handler, SMI_SRC_NMI,
|
||||
|
||||
|
||||
Descr_Hit_Handler, SMI_SRC_DESCR_HIT,
|
||||
PIC_Handler, SMI_SRC_PIC,
|
||||
StatCntr_Handler, SMI_SRC_STAT,
|
||||
KEL_Handler, SMI_SRC_KEL,
|
||||
ACPI_Handler, SMI_SRC_ACPI,
|
||||
PME_Handler, SMI_SRC_PME,
|
||||
BLOCKIO_Handler, SMI_SRC_BLOCKIO,
|
||||
|
||||
Leftover_Handler, 0xFFFFFFFF,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
193
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/history.c
vendored
Executable file
193
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/history.c
vendored
Executable file
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//* Function: *
|
||||
//* This file contains the code for recording event history.
|
||||
|
||||
|
||||
#include "VSA2.H"
|
||||
#include "SYSMGR.H"
|
||||
#include "PROTOS.H"
|
||||
|
||||
|
||||
extern EVENT_ENTRY Events[];
|
||||
extern ULONG MsgPacket[];
|
||||
|
||||
extern UCHAR VSM_Filter;
|
||||
|
||||
#if HISTORY
|
||||
EVENT NonReportableEvents[] = {
|
||||
EVENT_A20,
|
||||
EVENT_GRAPHICS,
|
||||
EVENT_ACPI_TIMER
|
||||
};
|
||||
#define UNREPORT_COUNT (sizeof(NonReportableEvents)/sizeof(EVENT))
|
||||
|
||||
//
|
||||
// Event history
|
||||
//
|
||||
EVENT_HISTORY History[HISTORY];
|
||||
int HistoryWrap = 0;
|
||||
int HistoryStart = 0;
|
||||
int HistoryEnd = 0;
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Record the event history
|
||||
//
|
||||
//*****************************************************************************
|
||||
void Keep_History(EVENT Event, EVENT EventIndex)
|
||||
{ int i;
|
||||
ULONG ParamMask, Param2;
|
||||
UCHAR VSM_Type;
|
||||
register EVENT_ENTRY * EventPtr;
|
||||
|
||||
EventPtr = &Events[EventIndex];
|
||||
|
||||
VSM_Type = Get_VSM_Type(EventPtr->Vsm);
|
||||
|
||||
|
||||
// Filter out VSM(s)
|
||||
if (VSM_Filter != VSM_ANY && VSM_Type != VSM_Filter)
|
||||
return;
|
||||
|
||||
//
|
||||
// Filter events from reporting
|
||||
//
|
||||
|
||||
for (i=0; i < UNREPORT_COUNT; i++) {
|
||||
if (Event == NonReportableEvents[i])
|
||||
return;
|
||||
}
|
||||
|
||||
// Generate mask for Param1
|
||||
ParamMask = 0xFFFFFFFF;
|
||||
Param2 = EventPtr->Param2;
|
||||
switch (Event) {
|
||||
|
||||
case EVENT_PCI_TRAP:
|
||||
// Report all PCI events together by PCI function
|
||||
ParamMask = ~Param2;
|
||||
break;
|
||||
|
||||
case EVENT_GPIO:
|
||||
// Get current edge
|
||||
Param2 = EventPtr->CurrentEdge;
|
||||
break;
|
||||
|
||||
case EVENT_SOFTWARE_SMI:
|
||||
// Don't report APM calls CPU_Busy or CPU_Idle
|
||||
if ((EventPtr->Param1 & 0xFF00) == 0x5300) {
|
||||
switch (EventPtr->Param1 & 0x00FF) {
|
||||
case 0x05:
|
||||
case 0x06:
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case EVENT_VIRTUAL_REGISTER:
|
||||
// Report all VR events together by classes
|
||||
ParamMask = 0x0000FF00;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
// If it's the same event for the same VSM...
|
||||
if ((History[HistoryEnd].Event == Event) &&
|
||||
(History[HistoryEnd].Vsm == EventPtr->Vsm) ) {
|
||||
|
||||
switch (Event) {
|
||||
|
||||
case EVENT_IO_TRAP:
|
||||
if (History[HistoryEnd].Param1 != (MsgPacket[2] & 0x0000FFFFL)) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// Events to be recorded together if (Param1 & ParamMask) matches
|
||||
case EVENT_PCI_TRAP:
|
||||
case EVENT_SOFTWARE_SMI:
|
||||
case EVENT_VIRTUAL_REGISTER:
|
||||
if (History[HistoryEnd].Param1 != (MsgPacket[1] & ParamMask)) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
// Record together if 1st two parameters match
|
||||
if (History[HistoryEnd].Param1 == EventPtr->Param1 &&
|
||||
History[HistoryEnd].Param2 == EventPtr->Param2 ) {
|
||||
History[HistoryEnd].Count++;
|
||||
Store_Timestamp(&History[HistoryEnd].TimeStamp);
|
||||
return;
|
||||
}
|
||||
|
||||
} // end switch
|
||||
}
|
||||
|
||||
//
|
||||
// Report event in a new history entry.
|
||||
//
|
||||
// Increment HistoryEnd unless it's the 1st event
|
||||
if (History[HistoryEnd].Vsm) {
|
||||
HistoryEnd++;
|
||||
if (HistoryEnd >= HISTORY) {
|
||||
HistoryEnd = 0;
|
||||
HistoryWrap = 1;
|
||||
}
|
||||
|
||||
// Increment HistoryStart index too if HistoryEnd has wrapped
|
||||
if (HistoryWrap) {
|
||||
HistoryStart++;
|
||||
if (HistoryStart >= HISTORY)
|
||||
HistoryStart = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
History[HistoryEnd].Vsm = EventPtr->Vsm;
|
||||
History[HistoryEnd].Event = Event;
|
||||
History[HistoryEnd].Param1 = MsgPacket[1] & ParamMask;
|
||||
History[HistoryEnd].Param2 = Param2;
|
||||
History[HistoryEnd].Count = 1;
|
||||
Store_Timestamp(&History[HistoryEnd].TimeStamp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Initialize_History(void)
|
||||
{
|
||||
|
||||
// Initialize timestamp field of history buffer entry "previous" to 1st entry
|
||||
Store_Timestamp(&History[HISTORY-1].TimeStamp);
|
||||
HistoryWrap = 0;
|
||||
HistoryStart = 0;
|
||||
HistoryEnd = 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void Initialize_History(void) { }
|
||||
|
||||
|
||||
#endif
|
||||
697
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/idt.asm
vendored
Executable file
697
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/idt.asm
vendored
Executable file
@@ -0,0 +1,697 @@
|
||||
;
|
||||
; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
;
|
||||
; This library is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU Lesser General Public License as
|
||||
; published by the Free Software Foundation; either version 2.1 of the
|
||||
; License, or (at your option) any later version.
|
||||
;
|
||||
; This code is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
; Lesser General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU Lesser General
|
||||
; Public License along with this library; if not, write to the
|
||||
; Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
; Boston, MA 02111-1307 USA
|
||||
;
|
||||
;********************************************************************************
|
||||
; Routines to:
|
||||
; -set up an SMM-based IDT
|
||||
; -save/restore of FPU state only as needed
|
||||
;********************************************************************************
|
||||
|
||||
|
||||
|
||||
include sysmgr.inc
|
||||
include vsa2.inc
|
||||
include gx2.inc
|
||||
|
||||
.model tiny,c
|
||||
.586p
|
||||
.CODE
|
||||
|
||||
|
||||
CR equ 0Dh
|
||||
LF equ 0Ah
|
||||
|
||||
|
||||
public Saved_INTs
|
||||
public Trap_Common
|
||||
externdef Trap_Code: dword
|
||||
externdef SysMgr_VSM: dword
|
||||
externdef Current_VSM: dword
|
||||
externdef IDT_Base: dword
|
||||
externdef IDT_Limit: dword
|
||||
externdef IDT_Selector:dword
|
||||
externdef pascal Parse_Capabilities: proc
|
||||
externdef pascal Read_MSR_HI: proc
|
||||
|
||||
FPU_Owner dd 0
|
||||
FPU_State db 108 dup (0)
|
||||
CR0_PE equ 1
|
||||
CR0_EM equ 4
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Saves the non-SMM IDT and installs VSA's exception vectors
|
||||
;***********************************************************************
|
||||
Install_IDT proc
|
||||
|
||||
; Save IDT of interrupted thread
|
||||
mov ecx, 1329h
|
||||
rdmsr
|
||||
mov [IDT_Selector], eax
|
||||
mov eax, IDT_SIZE-1
|
||||
wrmsr
|
||||
|
||||
mov cl, 39h
|
||||
rdmsr
|
||||
mov [IDT_Base], eax
|
||||
mov [IDT_Limit], edx
|
||||
mov eax, [SysMgr_VSM]
|
||||
add eax, OFFSET Saved_INTs
|
||||
mov dx, IDT_SIZE
|
||||
wrmsr
|
||||
|
||||
|
||||
nop
|
||||
mov byte ptr [$-1], 0C3h ; Patch a RET at the NOP above
|
||||
|
||||
mov eax, [SysMgr_VSM] ; Initialize FPU owner
|
||||
mov [FPU_Owner], eax
|
||||
|
||||
; The following code is only necessary if SysMgr starts on a non-MB boundary.
|
||||
; HandlerBase = {SMM_base[31:20], CS_selector[15:0], 4'b0}
|
||||
; lea di, [Saved_INTs+2] ; Patch SysMgr's CS into vector table
|
||||
; mov cx, IDT_SIZE/4
|
||||
; shr eax, 4 ; Compute SysMgr's CS
|
||||
;InsertCS:
|
||||
; mov [di], ax ; Store SysMgr's CS into vector table
|
||||
; add di, 4
|
||||
; loop InsertCS
|
||||
|
||||
ret
|
||||
|
||||
|
||||
Install_IDT endp
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Restores the IDT ptr and FPU state (if modified)
|
||||
;***********************************************************************
|
||||
Restore_IDT proc
|
||||
|
||||
; Restore the IDT of interrupted thread
|
||||
mov ecx, 1329h
|
||||
mov eax, [IDT_Selector]
|
||||
wrmsr
|
||||
mov cl, 39h
|
||||
mov eax, [IDT_Base]
|
||||
mov edx, [IDT_Limit]
|
||||
wrmsr
|
||||
|
||||
|
||||
; The RET will be patched with a NOP if FPU usage occurs
|
||||
RestoreRET::
|
||||
ret
|
||||
|
||||
; Restore the RET at RestoreRET
|
||||
mov byte ptr [RestoreRET], 0C3h
|
||||
|
||||
; Get last VSM to use FPU
|
||||
mov esi, [SysMgr_VSM]
|
||||
xchg [FPU_Owner], esi
|
||||
|
||||
; Set VSM's CR0.EM
|
||||
or fs:(VSM_Header PTR [esi]).SysStuff.State.r_CR0, CR0_EM
|
||||
|
||||
; Save VSM's FPU state
|
||||
; NOTE: This can be done in real-mode
|
||||
fnsave fs:(VSM_Header PTR [esi]).SysStuff.FPU_State
|
||||
|
||||
; Restore non-SMM FPU state
|
||||
; NOTE: This must be done in 32-bit protected mode
|
||||
mov eax, CR0 ; Enter protected mode for FPU save
|
||||
or al, CR0_PE
|
||||
mov CR0, eax
|
||||
jmp $+2
|
||||
|
||||
db 66h
|
||||
frstor byte ptr cs:[FPU_State]
|
||||
|
||||
and al, NOT CR0_PE ; Return to real mode
|
||||
mov CR0, eax
|
||||
|
||||
ret
|
||||
|
||||
Restore_IDT endp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Handler for Trap 7 (Device Not Available)
|
||||
;***********************************************************************
|
||||
Trap7 proc
|
||||
|
||||
push eax
|
||||
|
||||
; Clear interrupted VSM's CR0.EM (so it will own the FPU)
|
||||
mov eax, CR0
|
||||
and al, NOT CR0_EM
|
||||
mov CR0, eax
|
||||
|
||||
|
||||
; Get current owner of FPU
|
||||
mov eax, cs:[FPU_Owner]
|
||||
|
||||
; Is it non-SMM thread ?
|
||||
cmp eax, cs:[SysMgr_VSM]
|
||||
jne Set_EM
|
||||
|
||||
|
||||
; Yes, enable FPU restore code in Restore_IDT
|
||||
mov byte ptr cs:[RestoreRET], 90h
|
||||
|
||||
; Save non-SMM FPU state
|
||||
; NOTE: This must be done in 32-bit protected mode
|
||||
mov eax, CR0 ; Enter protected mode for FPU save
|
||||
or al, CR0_PE
|
||||
mov CR0, eax
|
||||
jmp $+2
|
||||
|
||||
db 66h
|
||||
fnsave byte ptr cs:[FPU_State]
|
||||
|
||||
and al, NOT CR0_PE ; Return to real mode
|
||||
mov CR0, eax
|
||||
|
||||
jmp short Record_FPU_Owner
|
||||
|
||||
|
||||
|
||||
|
||||
Set_EM:
|
||||
; Set previous owner's CR0.EM
|
||||
or fs:(VSM_Header PTR [eax]).SysStuff.State.r_CR0, CR0_EM
|
||||
|
||||
; Save the FPU state of the previous owner
|
||||
; NOTE: This can be done in 16-bit real-mode
|
||||
fnsave byte ptr fs:(VSM_Header PTR [eax]).SysStuff.FPU_State
|
||||
|
||||
; Set FPU flag
|
||||
mov fs:(VSM_Header PTR [eax]).SysStuff.FPU_Flag, 1
|
||||
|
||||
|
||||
Record_FPU_Owner:
|
||||
; Record the new owner of the FPU
|
||||
mov eax, cs:[Current_VSM]
|
||||
mov cs:[FPU_Owner], eax
|
||||
|
||||
; Has this VSM used the FPU previously ?
|
||||
cmp fs:(VSM_Header PTR [eax]).SysStuff.FPU_Flag, 0
|
||||
je short Exit
|
||||
|
||||
; Yes, restore its FPU state
|
||||
; NOTE: This can be done in 16-bit real-mode
|
||||
lea eax, (VSM_Header PTR [eax]).SysStuff.FPU_State
|
||||
frstor byte ptr fs:[eax]
|
||||
|
||||
Exit: pop eax
|
||||
iret ; Return to the interrupted VSM
|
||||
|
||||
Trap7 endp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Exception vectors (segments will be patched)
|
||||
;***********************************************************************
|
||||
Saved_INTs:
|
||||
dd OFFSET Trap_Code + 8*0
|
||||
dd OFFSET Trap_Code + 8*1
|
||||
dd OFFSET Trap_Code + 8*2
|
||||
dd OFFSET Trap_Code + 8*3
|
||||
dd OFFSET Trap_Code + 8*4
|
||||
dd OFFSET Trap_Code + 8*5
|
||||
dd OFFSET Trap_Code + 8*6
|
||||
dd OFFSET Trap_Code + 8*7
|
||||
dd OFFSET Trap_Code + 8*8
|
||||
dd OFFSET Trap_Code + 8*9
|
||||
dd OFFSET Trap_Code + 8*0Ah
|
||||
dd OFFSET Trap_Code + 8*0Bh
|
||||
dd OFFSET Trap_Code + 8*0Ch
|
||||
dd OFFSET Trap_Code + 8*0Dh
|
||||
dd OFFSET Trap_Code + 8*0Eh
|
||||
dd OFFSET Trap_Code + 8*0Fh
|
||||
IDT_SIZE equ ($-Saved_INTs)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Macros for performing stackless CALLs & RETs
|
||||
;***********************************************************************
|
||||
ROM_CALL macro Subr
|
||||
local RetAddr
|
||||
mov dx, RetAddr ; Put return addr in BP
|
||||
jmp Subr
|
||||
RetAddr:
|
||||
endm
|
||||
|
||||
|
||||
|
||||
ROM_RET macro
|
||||
jmp dx ; Return to caller
|
||||
endm
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; BX = Exception #
|
||||
;***********************************************************************
|
||||
Trap_Common:
|
||||
mov cs:[TrapNum], bx
|
||||
mov cs:[Reg_ECX], ecx
|
||||
|
||||
|
||||
; Disable SMIs
|
||||
mov ecx, MSR_SMM_CTRL
|
||||
xor eax, eax
|
||||
wrmsr
|
||||
|
||||
ROM_CALL NewLine
|
||||
|
||||
cmp bl, LastTrap
|
||||
jbe @f
|
||||
mov bl, LastTrap
|
||||
@@:
|
||||
add bx, bx
|
||||
mov bx, cs:[bx+TrapMsgTbl]
|
||||
ROM_CALL String
|
||||
|
||||
lea bx, [Msg_in]
|
||||
ROM_CALL String
|
||||
|
||||
;
|
||||
; Display the VSM which generated the exception
|
||||
;
|
||||
pop ecx ; Get SEG:OFFSET of faulting code
|
||||
mov cs:[SegOff], ecx
|
||||
mov esi, cs:[Current_VSM]
|
||||
mov ah, fs:(VSM_Header PTR [esi]).VSM_Type
|
||||
lea si, [VSM_Table]
|
||||
ASSUME SI: PTR TableItem
|
||||
test ecx, 0FFFF0000h ; Is it System Manager ?
|
||||
jnz ScanVSM
|
||||
mov eax, cs:[SysMgr_VSM]
|
||||
mov cs:[Current_VSM], eax
|
||||
jmp ShowVSM
|
||||
ScanVSM:
|
||||
mov al, cs:[si].Vsm ; Get VSM Type from table
|
||||
cmp ah, al
|
||||
je ShowVSM
|
||||
cmp al, VSM_ANY ; End of table ?
|
||||
je ShowVSM
|
||||
add si, sizeof(TableItem) ; Advance to next table entry
|
||||
jmp ScanVSM
|
||||
|
||||
ShowVSM:
|
||||
mov bx, cs:[si].MsgStr
|
||||
ROM_CALL String
|
||||
|
||||
lea bx, Msg_VSM ; VSM
|
||||
ROM_CALL String
|
||||
|
||||
ROM_CALL NewLine
|
||||
lea bx, Msg_IP ; IP = xxxx
|
||||
ROM_CALL String
|
||||
|
||||
cmp cs:[TrapNum], 000Dh ; Is it Trap 0Dh ?
|
||||
jne ShowIP
|
||||
mov ebx, cs:[Current_VSM] ; Yes, check for bad MSR address
|
||||
test ecx, 0FFFF0000h ; Did SysMgr cause it ?
|
||||
jnz ComputeAddr
|
||||
mov ebx, cs:[SysMgr_VSM] ; Yes
|
||||
ComputeAddr:
|
||||
movzx esi, cx
|
||||
add esi, ebx
|
||||
mov eax, dword ptr fs:[esi]
|
||||
cmp al, 0Fh
|
||||
jne short ShowIP
|
||||
cmp ah, 30h ; WRMSR ?
|
||||
je short BadMSR
|
||||
cmp ah, 32h ; RDMSR ?
|
||||
jne ShowIP
|
||||
BadMSR:
|
||||
mov cs:[MSR_Access], ah
|
||||
mov si, sp ; Show caller
|
||||
mov cx, ss:[si+4]
|
||||
sub cx, 3
|
||||
|
||||
; If one of the MSR routines, show caller
|
||||
cmp si, OFFSET Read_MSR_HI
|
||||
jb short ShowIP
|
||||
cmp si, OFFSET Parse_Capabilities
|
||||
jae short ShowIP
|
||||
mov cx, ss:[si+2]
|
||||
ShowIP:
|
||||
|
||||
|
||||
mov ax, cx
|
||||
ROM_CALL Hex16
|
||||
|
||||
mov al, '/'
|
||||
out dx, al
|
||||
movzx eax, cx
|
||||
add eax, cs:[Current_VSM]
|
||||
ROM_CALL Hex32
|
||||
|
||||
|
||||
lea bx, Msg_SP ; SP = xxxx
|
||||
ROM_CALL String
|
||||
mov ax, sp
|
||||
ROM_CALL Hex16
|
||||
|
||||
lea bx, Msg_BP ; BP = xxxx
|
||||
ROM_CALL String
|
||||
mov ax, bp
|
||||
ROM_CALL Hex16
|
||||
|
||||
cmp cs:[MSR_Access], 0 ; Was it an MSR access ?
|
||||
je Beep
|
||||
ROM_CALL NewLine ; Yes
|
||||
lea bx, [Msg_MSR]
|
||||
ROM_CALL String
|
||||
lea bx, [Msg_MSR_Wr]
|
||||
cmp cs:[MSR_Access], 30h
|
||||
je short ShowMSR
|
||||
lea bx, [Msg_MSR_Rd]
|
||||
ShowMSR:
|
||||
ROM_CALL String
|
||||
mov eax, cs:[Reg_ECX] ; Display invalid MSR address
|
||||
ROM_CALL Hex32
|
||||
|
||||
|
||||
HI_TONE equ 1193180/3000 ; 3 KHz
|
||||
LO_TONE equ 1193180/750 ; 750 Hz
|
||||
INTERVAL equ 100000/15 ; .10 second
|
||||
BEEP_LOOPS equ 10
|
||||
|
||||
Beep:
|
||||
mov bx, BEEP_LOOPS
|
||||
in al, 61h
|
||||
or al, 3 ; connect speaker to timer 2
|
||||
out 61h, al
|
||||
BeepLoop:
|
||||
mov dx, HI_TONE ; Start frequency
|
||||
TwoTone:
|
||||
mov al, 0B6h ; timer 2 mode set
|
||||
out 43h, al ; set mode
|
||||
mov ax, dx
|
||||
out 42h, al ; set LSB of counter
|
||||
mov al, ah
|
||||
out 42h, al ; set MSB of counter
|
||||
|
||||
mov cx, INTERVAL ; # 15 usec intervals
|
||||
Interval:
|
||||
in al, 61h ; Wait for 15 usec
|
||||
xor al, ah
|
||||
test al, 10h
|
||||
jz Interval
|
||||
xor ah, 10h
|
||||
loop Interval
|
||||
|
||||
shl dx, 1 ; Divide frequency by 2
|
||||
cmp dx, LO_TONE ; End frequency
|
||||
jb TwoTone
|
||||
dec bx ; Decrement loop counter
|
||||
jnz BeepLoop ; Start tones over
|
||||
|
||||
in al, 61h ; Turn off speaker
|
||||
and al, NOT 3
|
||||
out 61h, al
|
||||
|
||||
Halt: hlt
|
||||
jmp Halt
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; VSM strings for display of VSM causing the exception
|
||||
;***********************************************************************
|
||||
TableItem struc
|
||||
Vsm db ?
|
||||
MsgStr dw ?
|
||||
TableItem ends
|
||||
|
||||
|
||||
VSM_Table:
|
||||
TableItem {VSM_SYS_MGR, Sys_Mgr_VSM}
|
||||
TableItem {VSM_AUDIO, XpressAudio}
|
||||
TableItem {VSM_VGA, SoftVGA}
|
||||
TableItem {VSM_LEGACY, Legacy_VSM}
|
||||
TableItem {VSM_PM, PM_VSM}
|
||||
TableItem {VSM_OHCI, OHCI_VSM}
|
||||
TableItem {VSM_i8042, i8042_VSM}
|
||||
TableItem {VSM_ACPI, ACPI_VSM}
|
||||
TableItem {VSM_APM, APM_VSM}
|
||||
TableItem {VSM_SMB, SMB_VSM}
|
||||
TableItem {VSM_BATTERY, Battery_VSM}
|
||||
TableItem {VSM_RTC, RTC_VSM}
|
||||
TableItem {VSM_S2D, S2D_VSM}
|
||||
TableItem {VSM_SPY, Spy_VSM}
|
||||
TableItem {VSM_NETWORK, Network_VSM}
|
||||
TableItem {VSM_GPIO, GPIO_VSM}
|
||||
TableItem {VSM_USB, USB_VSM}
|
||||
TableItem {VSM_FLASH, Flash_VSM}
|
||||
TableItem {VSM_INFRARED,Infrared_VSM}
|
||||
TableItem {VSM_THERMAL, Thermal_VSM}
|
||||
TableItem {VSM_NULL, Null_VSM}
|
||||
TableItem {VSM_VIP, VIP_VSM}
|
||||
TableItem {VSM_LPC, LPC_VSM}
|
||||
TableItem {VSM_VUART, VUART_VSM}
|
||||
TableItem {VSM_MICRO, Micro_VSM}
|
||||
TableItem {VSM_USER1, User1_VSM}
|
||||
TableItem {VSM_USER2, User2_VSM}
|
||||
TableItem {VSM_USER3, User3_VSM}
|
||||
TableItem {VSM_SUPERIO, SuperIO_VSM}
|
||||
TableItem {VSM_ANY, Unknown_VSM} ; Catch-all
|
||||
|
||||
|
||||
Msg macro TrapString
|
||||
db TrapString
|
||||
db 0
|
||||
endm
|
||||
|
||||
XpressAudio: Msg "Audio"
|
||||
SoftVGA: Msg "SoftVG"
|
||||
Legacy_VSM: Msg "Legacy"
|
||||
USB_VSM: Msg "USB"
|
||||
GPIO_VSM: Msg "GPIO"
|
||||
ACPI_VSM: Msg "ACPI"
|
||||
Sample_VSM: Msg "Sample"
|
||||
APM_VSM: Msg "APM"
|
||||
Battery_VSM: Msg "Battery"
|
||||
PM_VSM: Msg "PM"
|
||||
S2D_VSM: Msg "SaveToRAM"
|
||||
Sys_Mgr_VSM: Msg "SysMgr"
|
||||
i8042_VSM: Msg "i8042"
|
||||
OHCI_VSM: Msg "OHCI"
|
||||
SuperIO_VSM: Msg "SuperIO"
|
||||
Null_VSM: Msg "Null"
|
||||
Spy_VSM: Msg "Spy"
|
||||
RTC_VSM: Msg "RTC"
|
||||
SPY_VSM: Msg "Spy"
|
||||
Network_VSM: Msg "Network"
|
||||
Infrared_VSM: Msg "Infrared"
|
||||
Thermal_VSM: Msg "Thermal"
|
||||
VIP_VSM: Msg "VIP"
|
||||
LPC_VSM: Msg "LPC"
|
||||
User1_VSM: Msg "User1"
|
||||
User2_VSM: Msg "User2"
|
||||
User3_VSM: Msg "User3"
|
||||
SMB_VSM: Msg "SMB"
|
||||
Flash_VSM: Msg "Flash"
|
||||
VUART_VSM: Msg "VUART"
|
||||
Micro_VSM: Msg "Micro"
|
||||
Unknown_VSM: Msg "VSM???"
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Strings describing the type of exception
|
||||
;***********************************************************************
|
||||
TrapMsgTbl:
|
||||
dw OFFSET Trap00
|
||||
dw OFFSET Trap01
|
||||
dw OFFSET Trap02
|
||||
dw OFFSET Trap03
|
||||
dw OFFSET Trap04
|
||||
dw OFFSET Trap05
|
||||
dw OFFSET Trap06
|
||||
dw OFFSET Trap07
|
||||
dw OFFSET Trap08
|
||||
dw OFFSET Trap09
|
||||
dw OFFSET Trap0A
|
||||
dw OFFSET Trap0B
|
||||
dw OFFSET Trap0C
|
||||
dw OFFSET Trap0D
|
||||
dw OFFSET Trap0E
|
||||
dw OFFSET Trap0F
|
||||
dw OFFSET Trap10
|
||||
dw OFFSET Trap11
|
||||
dw OFFSET Trapnn
|
||||
LastTrap equ ($-TrapMsgTbl)/2
|
||||
|
||||
|
||||
|
||||
Trap00: Msg "Divide by Zero"
|
||||
Trap01: Msg "Debug"
|
||||
Trap02: Msg "NMI/INT 02h"
|
||||
Trap03: Msg "Breakpoint"
|
||||
Trap04: Msg "Overflow"
|
||||
Trap05: Msg "Bounds Check"
|
||||
Trap06: Msg "Invalid Opcode"
|
||||
Trap07: Msg "Device Not Available"
|
||||
Trap08: Msg "Double Fault"
|
||||
Trap09: Msg "Invalid TSS"
|
||||
Trap0A: Msg "INT 0Ah"
|
||||
Trap0B: Msg "Segment Not Present"
|
||||
Trap0C: Msg "Stack Fault"
|
||||
Trap0D: Msg "General Protection"
|
||||
Trap0E: Msg "Page Fault"
|
||||
Trap0F: Msg "INT 0Fh"
|
||||
Trap10: Msg "INT 10h"
|
||||
Trap11: Msg "Aligment Check"
|
||||
Trapnn: Msg "Trap ??"
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Miscellaneous strings
|
||||
;***********************************************************************
|
||||
Msg_in: Msg " in "
|
||||
Msg_VSM: Msg " VSM"
|
||||
Msg_SP: Msg " SP="
|
||||
Msg_BP: Msg " BP="
|
||||
Msg_IP: Msg "IP="
|
||||
Msg_MSR: Msg "Invalid MSR "
|
||||
Msg_MSR_Rd: Msg "read: "
|
||||
Msg_MSR_Wr: Msg "write: "
|
||||
|
||||
;***********************************************************************
|
||||
; Stackless display routines
|
||||
;***********************************************************************
|
||||
NewLine:
|
||||
mov al, CR
|
||||
out DBG_PORT, al
|
||||
ROM_RET
|
||||
|
||||
String:
|
||||
mov al, cs:[bx]
|
||||
or al, al
|
||||
jz StringExit
|
||||
out DBG_PORT, al
|
||||
in al, 80h
|
||||
inc bx ; Advance ptr
|
||||
jmp String
|
||||
StringExit:
|
||||
ROM_RET
|
||||
|
||||
|
||||
Seg_Addr:
|
||||
mov si, bp
|
||||
rol eax, 16
|
||||
xchg ah, al
|
||||
ROM_CALL Hex8
|
||||
xchg ah, al
|
||||
ROM_CALL Hex8
|
||||
mov al, ':'
|
||||
out DBG_PORT, al
|
||||
|
||||
rol eax, 16
|
||||
xchg ah, al
|
||||
ROM_CALL Hex8
|
||||
xchg ah, al
|
||||
ROM_CALL Hex8
|
||||
|
||||
mov bp, si ; Restore ret addr
|
||||
ROM_RET
|
||||
|
||||
|
||||
Hex32: rol edx, 16 ; Save return address in upper EDX
|
||||
|
||||
rol eax, 8
|
||||
ROM_CALL Hex8
|
||||
rol eax, 8
|
||||
ROM_CALL Hex8
|
||||
rol eax, 8
|
||||
ROM_CALL Hex8
|
||||
rol eax, 8
|
||||
ROM_CALL Hex8
|
||||
mov al, ' '
|
||||
out DBG_PORT, al
|
||||
rol edx, 16 ; Restore return address
|
||||
ROM_RET
|
||||
|
||||
|
||||
|
||||
Hex16: rol edx, 16 ; Save return address in upper EDX
|
||||
xchg ah, al
|
||||
ROM_CALL Hex8
|
||||
xchg ah, al
|
||||
ROM_CALL Hex8
|
||||
rol edx, 16 ; Restore return address
|
||||
mov al, ' '
|
||||
out DBG_PORT, al
|
||||
ROM_RET
|
||||
|
||||
|
||||
Hex8:
|
||||
; Display 4 MSBs
|
||||
mov di, ax
|
||||
rol al, 4
|
||||
and al, 0Fh
|
||||
add al, '0' ; Convert to ASCII
|
||||
cmp al, '9'
|
||||
jbe @f
|
||||
add al, 7 ; 'A'-'F'
|
||||
@@: out DBG_PORT, al
|
||||
in al, 80h
|
||||
mov ax, di
|
||||
|
||||
|
||||
; Display 4 LSBs
|
||||
and al, 0Fh
|
||||
add al, '0' ; Convert to ASCII
|
||||
cmp al, '9'
|
||||
jbe Char
|
||||
add al, 7 ; 'A'-'F'
|
||||
Char: out DBG_PORT, al
|
||||
in al, 80h
|
||||
ROM_RET
|
||||
|
||||
SegOff dd 0
|
||||
Reg_ECX dd 0
|
||||
TrapNum dw 0
|
||||
MSR_Access db 0
|
||||
|
||||
|
||||
end
|
||||
|
||||
37
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/image.asm
vendored
Executable file
37
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/image.asm
vendored
Executable file
@@ -0,0 +1,37 @@
|
||||
;
|
||||
; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
;
|
||||
; This library is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU Lesser General Public License as
|
||||
; published by the Free Software Foundation; either version 2.1 of the
|
||||
; License, or (at your option) any later version.
|
||||
;
|
||||
; This code is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
; Lesser General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU Lesser General
|
||||
; Public License along with this library; if not, write to the
|
||||
; Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
; Boston, MA 02111-1307 USA
|
||||
;
|
||||
;* Function: *
|
||||
;* This file contains the label for the beginning of the VSA image *
|
||||
;* It MUST be the last .OBJ file in the link
|
||||
|
||||
|
||||
.model small,c
|
||||
.586
|
||||
.CODE
|
||||
|
||||
public VSA_Image
|
||||
|
||||
TEXT SEGMENT PARA 'CODE'
|
||||
|
||||
VSA_Image:
|
||||
|
||||
TEXT ENDS
|
||||
|
||||
END
|
||||
|
||||
1017
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/init.asm
vendored
Executable file
1017
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/init.asm
vendored
Executable file
File diff suppressed because it is too large
Load Diff
39
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/init.h
vendored
Executable file
39
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/init.h
vendored
Executable file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#define CR 0x0D
|
||||
#define LF 0x0A
|
||||
|
||||
#define ERR_NO_FIT (1 << 0)
|
||||
#define ERR_NO_SYS_MGR (1 << 1)
|
||||
#define ERR_BAD_TYPE (1 << 2)
|
||||
#define ERR_SMI_STATUS (1 << 3)
|
||||
#define ERR_BAD_CPU (1 << 4)
|
||||
#define ERR_NO_CHIPSET (1 << 5)
|
||||
#define ERR_NOT_CPL0 (1 << 6)
|
||||
#define ERR_VERIFY (1 << 7)
|
||||
#define ERR_VERSION (1 << 8)
|
||||
#define ERR_INTERNAL (1 << 9)
|
||||
#define ERR_INVALID_VSM (1 << 10)
|
||||
|
||||
|
||||
|
||||
#define DOS_LOAD (1 << 0)
|
||||
#define VSM_LOAD (1 << 1)
|
||||
|
||||
196
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/io.c
vendored
Executable file
196
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/io.c
vendored
Executable file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//* Function: *
|
||||
//* Handles trapped and virtualized I/O
|
||||
|
||||
|
||||
|
||||
|
||||
#include "VSA2.H"
|
||||
#include "PROTOS.H"
|
||||
#include "SYSMGR.H"
|
||||
|
||||
|
||||
// External variables
|
||||
extern ULONG Saved_EAX, Saved_EDI;
|
||||
extern ULONG Nested_EAX, Nested_EDI;
|
||||
extern Descriptor Saved_ES, Flat_Descriptor;
|
||||
extern SmiHeader SMM_Header;
|
||||
|
||||
// External routines
|
||||
extern void pascal write_flat_size(ULONG, ULONG, UCHAR);
|
||||
extern ULONG pascal Convert_To_Physical_Addr(ULONG);
|
||||
|
||||
#define PAGING_ENABLED 0x80000001
|
||||
|
||||
#define ADDR32 1
|
||||
#define DATA32 2
|
||||
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
ULONG Ulong;
|
||||
struct {
|
||||
USHORT LowAddr;
|
||||
UCHAR MidAddr;
|
||||
UCHAR HiAddr;
|
||||
};
|
||||
};
|
||||
} DESCR;
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Returns the physical address of the location to return the value
|
||||
//***********************************************************************
|
||||
ULONG pascal Get_Logical_Address(SmiHeader * SmiHdr, ULONG * CR0_Ptr)
|
||||
{ UCHAR Override = 0, Size, Instruction;
|
||||
static UCHAR SizeToIncr[16] = {0,1,0,2,0,0,0,0,0,0,0,0,0,0,0,4};
|
||||
ULONG EDI, Logical_Addr, Incr, Phys_Addr, Reg_Ptr;
|
||||
register Descriptor * Callers_ES;
|
||||
DESCR Mem_Ptr;
|
||||
|
||||
|
||||
Size = (UCHAR)SmiHdr->data_size;
|
||||
|
||||
if (SmiHdr == &SMM_Header) {
|
||||
Reg_Ptr = SysMgr_VSM + (ULONG)((USHORT)&Saved_EAX);
|
||||
// Get ES:EDI in case it's INSW
|
||||
Callers_ES = &Saved_ES;
|
||||
EDI = Saved_EDI;
|
||||
} else {
|
||||
// Nested_EAX is a flat ptr to EAX on the VSM's stack
|
||||
Reg_Ptr = Nested_EAX;
|
||||
// Get ES:EDI in case it's INSW
|
||||
Callers_ES = &Flat_Descriptor;
|
||||
EDI = Nested_EDI;
|
||||
}
|
||||
|
||||
|
||||
// Determine default operand and address size
|
||||
if (Callers_ES->attr & D_BIT) {
|
||||
Override = DATA32 | ADDR32;
|
||||
}
|
||||
|
||||
|
||||
// Get address of trapped code
|
||||
Logical_Addr = SmiHdr->Current_EIP + SmiHdr->_CS.base;
|
||||
|
||||
do {
|
||||
|
||||
// If paging is enabled...
|
||||
if ((SmiHdr->r_CR0 & PAGING_ENABLED) == PAGING_ENABLED){
|
||||
// translate logical to physical address via the page tables
|
||||
Phys_Addr = Convert_To_Physical_Addr(Logical_Addr);
|
||||
} else {
|
||||
Phys_Addr = Logical_Addr;
|
||||
}
|
||||
|
||||
|
||||
// Get opcode
|
||||
Instruction = (UCHAR)read_flat(Phys_Addr);
|
||||
|
||||
switch (Instruction) {
|
||||
|
||||
case 0xE4: // IN AL, <nn>
|
||||
case 0xE5: // IN AX, <nn>
|
||||
case 0xEC: // IN AL, DX
|
||||
case 0xED: // IN AX, DX
|
||||
*CR0_Ptr = 0x00000000;
|
||||
return Reg_Ptr;
|
||||
|
||||
case 0x67: // Address Size
|
||||
Override ^= ADDR32;
|
||||
break;
|
||||
|
||||
case 0x66: // Data Size
|
||||
// Override ^= DATA32;
|
||||
case 0xF2: // REPNE
|
||||
case 0xF3: // REPE
|
||||
break;
|
||||
|
||||
case 0x6C: // INSB
|
||||
case 0x6D: // INSW/INSD
|
||||
Mem_Ptr.LowAddr = Callers_ES->base_15_0;
|
||||
Mem_Ptr.MidAddr = Callers_ES->base_23_16;
|
||||
Mem_Ptr.HiAddr = Callers_ES->base_31_24;
|
||||
|
||||
// (E)DI has already been inc'd/dec'd
|
||||
Incr = SizeToIncr[Size];
|
||||
if (SmiHdr->EFLAGS & EFLAGS_DF) {
|
||||
EDI += Incr;
|
||||
} else {
|
||||
EDI -= Incr;
|
||||
}
|
||||
|
||||
// If 16-bit mode, mask 16 MSBs of ptr
|
||||
if (!(Override & ADDR32)) {
|
||||
EDI &= 0x0000FFFF;
|
||||
}
|
||||
Mem_Ptr.Ulong += EDI;
|
||||
*CR0_Ptr = SmiHdr->r_CR0;
|
||||
return Mem_Ptr.Ulong;
|
||||
|
||||
default:
|
||||
// Unexpected opcode
|
||||
Log_Error("Unexpected opcode at 0x%08X = 0x%08X", Phys_Addr, read_flat(Phys_Addr));
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
// Increment code ptr
|
||||
Logical_Addr++;
|
||||
|
||||
} while (1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Returns an I/O value to AL/AX/EAX or ES:(E)DI
|
||||
//***********************************************************************
|
||||
void pascal Return_Virtual_Value(SmiHeader * SmiHdr, ULONG Data)
|
||||
{ ULONG PhysicalAddr, LogicalAddr, CR0;
|
||||
UCHAR Size;
|
||||
|
||||
LogicalAddr = Get_Logical_Address(SmiHdr, &CR0);
|
||||
|
||||
if (LogicalAddr == 0xFFFFFFFF)
|
||||
return;
|
||||
|
||||
Size = (UCHAR)SmiHdr->data_size;
|
||||
|
||||
|
||||
if ((CR0 & PAGING_ENABLED) == PAGING_ENABLED){
|
||||
// If paging is enabled, translate logical to physical address and
|
||||
// write one byte at a time since buffer could cross page boundary.
|
||||
do {
|
||||
PhysicalAddr = Convert_To_Physical_Addr(LogicalAddr++);
|
||||
write_flat_size(PhysicalAddr, Data, BYTE_IO);
|
||||
Data >>= 8;
|
||||
Size >>= 1;
|
||||
} while (Size);
|
||||
|
||||
} else {
|
||||
// Write the data to memory
|
||||
write_flat_size(LogicalAddr, Data, Size);
|
||||
}
|
||||
}
|
||||
218
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/io_trap.c
vendored
Executable file
218
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/io_trap.c
vendored
Executable file
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//******************************************************************************
|
||||
//* Routines for setting I/O traps
|
||||
//******************************************************************************
|
||||
|
||||
|
||||
|
||||
#include "VSA2.H"
|
||||
#include "PROTOS.H"
|
||||
#include "GX2.H"
|
||||
#include "VPCI.H"
|
||||
#include "DESCR.H"
|
||||
#include "CHIPSET.H"
|
||||
|
||||
ULONG pascal Compute_IOD_SC(ULONG *, USHORT *, UCHAR);
|
||||
|
||||
// External variables:
|
||||
extern DESCRIPTOR MSRs[];
|
||||
extern UCHAR NumMbius;
|
||||
extern MBIU_INFO MbiuInfo[MAX_MBIU];
|
||||
extern Hardware HardwareInfo;
|
||||
extern UCHAR * VsmNames[];
|
||||
extern ULONG Current_VSM;
|
||||
|
||||
|
||||
// Local variables:
|
||||
UCHAR MbiuSearchOrder[MAX_MBIU] = {2,1,0};
|
||||
ULONG MbiuSkipFlags[] = {NOT_GLIU0, NOT_GLIU1, NOT_GLIU2};
|
||||
|
||||
//***********************************************************************
|
||||
// Creates an I/O descriptor for the specified Address/Range.
|
||||
// UsePID:
|
||||
// 0 = set PID to zero (generate SMI)
|
||||
// 1 = set PID to MBIU's subtractive port
|
||||
//***********************************************************************
|
||||
UCHAR pascal Setup_IO_Descriptor(ULONG * AddressPtr, USHORT * RangePtr, UCHAR UsePID)
|
||||
{ UCHAR i, j, Index, FirstChoice, SecondChoice;
|
||||
USHORT Range, MaxRange;
|
||||
ULONG Address, Flags;
|
||||
MBIU_INFO * MbiuPtr;
|
||||
register DESCRIPTOR * Descr;
|
||||
|
||||
|
||||
Range = * RangePtr;
|
||||
Flags = Address = * AddressPtr;
|
||||
|
||||
// Determine type(s) of I/O descriptor to use
|
||||
FirstChoice = IOD_BM;
|
||||
SecondChoice = IOD_SC;
|
||||
if (Flags & (READS_ONLY | WRITES_ONLY)) {
|
||||
FirstChoice = IOD_SC;
|
||||
} else {
|
||||
// Check if we should try to use a swiss-cheese descriptor
|
||||
if (Address & 7 || Range < 8) {
|
||||
FirstChoice = IOD_SC;
|
||||
SecondChoice = IOD_BM;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Find an appropriate descriptor
|
||||
for (i = 0; i < NumMbius; i++) {
|
||||
j = MbiuSearchOrder[i];
|
||||
|
||||
// Skip this MBIU ?
|
||||
if (Flags & MbiuSkipFlags[j]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
MbiuPtr = &MbiuInfo[j];
|
||||
Index = Allocate_Descriptor(FirstChoice, SecondChoice, MbiuPtr->Mbiu);
|
||||
if (Index != DESCRIPTOR_NOT_FOUND) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (Index == DESCRIPTOR_NOT_FOUND) {
|
||||
return Index;
|
||||
}
|
||||
|
||||
Descr = &MSRs[Index];
|
||||
Descr->Address = (USHORT)Address;
|
||||
|
||||
// Set appropriate port
|
||||
if (UsePID) {
|
||||
Descr->MsrData[1] = MbiuPtr->SubtrPid;
|
||||
}
|
||||
|
||||
switch (Descr->Type) {
|
||||
|
||||
case IOD_BM:
|
||||
// Mask must not include any valid address bits
|
||||
MaxRange = 1 << BitScanForward(Address);
|
||||
if (Range > MaxRange) {
|
||||
Range = MaxRange;
|
||||
} else {
|
||||
while (!IsPowerOfTwo(Range)) {
|
||||
Range--;
|
||||
}
|
||||
}
|
||||
(USHORT)Descr->MsrData[1] = (USHORT)Address >> 12;
|
||||
Descr->MsrData[0] = ~(Range-1) | 0x000F0000;
|
||||
Descr->MsrData[0] |= Address << 20;
|
||||
Descr->Range = Range;
|
||||
* AddressPtr += Range;
|
||||
* RangePtr -= Range;
|
||||
break;
|
||||
|
||||
case IOD_SC:
|
||||
Descr->MsrData[0] = Compute_IOD_SC(AddressPtr, RangePtr, 1);
|
||||
Descr->Range = Range - * RangePtr;
|
||||
break;
|
||||
|
||||
default:
|
||||
return DESCRIPTOR_NOT_FOUND;
|
||||
|
||||
}
|
||||
|
||||
Write_MSR(Descr->MsrAddr, Descr->MsrData);
|
||||
return Index;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Clears an I/O trap on the specified I/O Range
|
||||
//***********************************************************************
|
||||
void pascal Clr_MBus_IO_Trap(ULONG Address, USHORT Range)
|
||||
{ UCHAR Index;
|
||||
|
||||
while (Range) {
|
||||
|
||||
// Find an existing descriptor that matches Address
|
||||
Index = Find_Matching_IO_Descriptor(&Address, &Range, 0);
|
||||
|
||||
if (Index == DESCRIPTOR_NOT_FOUND) {
|
||||
// Report error
|
||||
Log_Error("Unregistration of I/O 0x%04X by the %s VSM", Address, VsmNames[Get_VSM_Type(Current_VSM)]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Sets an I/O trap on the specified I/O Range
|
||||
//***********************************************************************
|
||||
void pascal Set_MBus_IO_Trap(ULONG Address, USHORT Range)
|
||||
{ UCHAR Index;
|
||||
|
||||
|
||||
// If the range is > 8 bytes and/or is not a power of 2,
|
||||
// multiple descriptors may be required.
|
||||
while (Range) {
|
||||
// Find an existing descriptor that matches Address
|
||||
Index = Find_Matching_IO_Descriptor(&Address, &Range, 2);
|
||||
|
||||
if (Index == DESCRIPTOR_NOT_FOUND) {
|
||||
// An existing descriptor does not match the range.
|
||||
// Allocate a new descriptor
|
||||
Index = Setup_IO_Descriptor(&Address, &Range, 0);
|
||||
if (Index == DESCRIPTOR_NOT_FOUND) {
|
||||
// Report resource error
|
||||
Log_Error("No descriptors for I/O trap of 0x%04X by the %s VSM", Address, VsmNames[Get_VSM_Type(Current_VSM)]);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// An existing descriptor was modified for the new Addr/Range
|
||||
}
|
||||
MSRs[Index].Flag |= IO_TRAP;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Enable/Disable I/O trap
|
||||
//***********************************************************************
|
||||
void pascal MBus_IO_Trap(ULONG Param1, ULONG Param2, UCHAR EnableFlag)
|
||||
{ ULONG Address;
|
||||
USHORT Range;
|
||||
|
||||
// Repackage parameters
|
||||
Address = Param2;
|
||||
(USHORT)Address = (USHORT)Param1;
|
||||
Range = (USHORT)Param2;
|
||||
|
||||
|
||||
// Check for illegal combination of flags
|
||||
if ((Address & ALL_GLIUS) == ALL_GLIUS) {
|
||||
// Report error
|
||||
Log_Error("Illegal combination of flags for I/O 0x%04X by the %s VSM", Address, VsmNames[Get_VSM_Type(Current_VSM)]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (EnableFlag) {
|
||||
Set_MBus_IO_Trap(Address, Range);
|
||||
} else {
|
||||
Clr_MBus_IO_Trap(Address, Range);
|
||||
}
|
||||
}
|
||||
222
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/makefile
vendored
Executable file
222
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/makefile
vendored
Executable file
@@ -0,0 +1,222 @@
|
||||
|
||||
#
|
||||
# Copyright (c) 2006 Advanced Micro Devices,Inc. ("AMD").
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation; either version 2.1 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General
|
||||
# Public License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
# Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
######################################################################
|
||||
#
|
||||
# Init variables
|
||||
#
|
||||
######################################################################
|
||||
|
||||
!ifndef VSA2ROOT
|
||||
VSA2ROOT = ..
|
||||
!endif
|
||||
|
||||
BUILD_DIR = $(VSA2ROOT)\build
|
||||
OBJECT = obj
|
||||
!include $(BUILD_DIR)\setvars.mak
|
||||
.SUFFIXES: .asm .c .h .inc .map .obj .mac
|
||||
|
||||
INCLUDE = $(OBJECT);$(INCLUDE)
|
||||
|
||||
VSMNAME = sysmgr
|
||||
|
||||
|
||||
######################################################################
|
||||
#
|
||||
# Build Macros
|
||||
#
|
||||
######################################################################
|
||||
|
||||
INIT_ASM_OBJS = \
|
||||
$(OBJECT)\init.obj \
|
||||
$(OBJECT)\cpu_init.obj \
|
||||
$(OBJECT)\chip.obj \
|
||||
$(OBJECT)\image.obj \
|
||||
|
||||
SYSMGR_ASM_OBJS = \
|
||||
$(OBJECT)\sysmgr.obj \
|
||||
$(OBJECT)\bugs.obj \
|
||||
$(OBJECT)\utils.obj \
|
||||
$(OBJECT)\syscalls.obj \
|
||||
$(OBJECT)\smis.obj \
|
||||
$(OBJECT)\port92.obj \
|
||||
$(OBJECT)\sw_int.obj \
|
||||
$(OBJECT)\debug.obj \
|
||||
$(OBJECT)\vr_misc.obj \
|
||||
$(OBJECT)\cpu.obj \
|
||||
$(OBJECT)\idt.obj \
|
||||
$(OBJECT)\message.obj \
|
||||
$(OBJECT)\msr.obj \
|
||||
|
||||
SYSMGR_C_OBJS = \
|
||||
$(OBJECT)\events.obj \
|
||||
$(OBJECT)\handlers.obj \
|
||||
$(OBJECT)\chipset.obj \
|
||||
$(OBJECT)\gpio.obj \
|
||||
$(OBJECT)\errors.obj \
|
||||
$(OBJECT)\history.obj \
|
||||
$(OBJECT)\io.obj \
|
||||
$(OBJECT)\virt_pci.obj \
|
||||
$(OBJECT)\mbus.obj \
|
||||
$(OBJECT)\vsa_init.obj \
|
||||
$(OBJECT)\descr.obj \
|
||||
$(OBJECT)\vr.obj \
|
||||
$(OBJECT)\topology.obj \
|
||||
$(OBJECT)\pci_rd.obj \
|
||||
$(OBJECT)\pci_wr.obj \
|
||||
$(OBJECT)\cs5536.obj \
|
||||
$(OBJECT)\swapsif.obj \
|
||||
$(OBJECT)\unregstr.obj \
|
||||
$(OBJECT)\mdd.obj \
|
||||
$(OBJECT)\pci_pm.obj \
|
||||
$(OBJECT)\gpio5536.obj \
|
||||
$(OBJECT)\mfgpt.obj \
|
||||
$(OBJECT)\mapper.obj \
|
||||
$(OBJECT)\timeout.obj \
|
||||
$(OBJECT)\io_trap.obj \
|
||||
$(OBJECT)\mbiu.obj \
|
||||
$(OBJECT)\timer.obj \
|
||||
$(OBJECT)\ohci.obj \
|
||||
|
||||
SYSMGR_C_CODS = $(SYSMGR_C_SRCS:.obj=.cod)
|
||||
|
||||
SYSMGR_OBJS = $(SYSMGR_ASM_OBJS) $(SYSMGR_C_OBJS)
|
||||
|
||||
SYSMGR_VSM = $(OBJECT)\sysmgr.vsm
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# Targets
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
|
||||
all: $(OBJECT) setenv sysmgr.vsm vsainit.bin
|
||||
!ifdef BUILDOBJ
|
||||
$(COPY) $(OBJECT)\sysmgr.vsm $(BUILDOBJ)
|
||||
$(COPY) $(OBJECT)\vsainit.bin $(BUILDOBJ)
|
||||
!endif
|
||||
|
||||
sysmgr.vsm: $(SYSMGR_OBJS)
|
||||
$(LN) /MAP $(LOPTS_VSM) @<<sysmgr.lnk
|
||||
$(SYSMGR_OBJS: =+^
|
||||
)
|
||||
$(SYSMGR_VSM)
|
||||
|
||||
;
|
||||
<<NOKEEP
|
||||
|
||||
vsainit.bin init.exe: $(INIT_ASM_OBJS)
|
||||
$(LN) $(LD_OPTS) /MAP $**,$(OBJECT)\init.exe,$(OBJECT)\init.map;
|
||||
$(X2ROM) $(OBJECT)\init.exe $(OBJECT)\vsainit.bin
|
||||
# $(COPY) $(OBJECT)\init.rom $(OBJECT)\vsainit.bin
|
||||
|
||||
#This and only this clean target must exist as it is called by cleanall
|
||||
#cleanall and cleanlocal are defined in rules.mak
|
||||
|
||||
clean: cleanlocal
|
||||
|
||||
$(OBJECT):
|
||||
-@md $(OBJECT)
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# Dependencies
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
$(SYSMGR_ASM_OBJS): $(MAKEDIR)\makefile \
|
||||
$(OBJECT)\sysmgr.inc \
|
||||
$(OBJECT)\smimac.mac \
|
||||
$(OBJECT)\vsa2.inc \
|
||||
$(OBJECT)\isa.inc \
|
||||
$(OBJECT)\chipset.inc \
|
||||
$(OBJECT)\vr.inc \
|
||||
$(OBJECT)\pci.inc \
|
||||
$(OBJECT)\hce.inc \
|
||||
$(OBJECT)\gx2.inc \
|
||||
$(OBJECT)\protos.inc \
|
||||
$(OBJECT)\descr.inc \
|
||||
$(OBJECT)\mdd.inc \
|
||||
$(OBJECT)\cs5536.inc \
|
||||
|
||||
$(SYSMGR_C_OBJS): $(MAKEDIR)\makefile \
|
||||
$(OBJECT)\sysmgr.h \
|
||||
$(OBJECT)\vsa2.h \
|
||||
$(OBJECT)\isa.h \
|
||||
$(OBJECT)\chipset.h \
|
||||
$(OBJECT)\vr.h \
|
||||
$(OBJECT)\pci.h \
|
||||
$(OBJECT)\vpci.h \
|
||||
$(OBJECT)\protos.h \
|
||||
$(OBJECT)\mdd.h \
|
||||
$(OBJECT)\timer.h \
|
||||
$(OBJECT)\mapper.h \
|
||||
$(OBJECT)\gx2.h \
|
||||
$(OBJECT)\hce.h \
|
||||
$(OBJECT)\acpi.h \
|
||||
$(OBJECT)\cs5536.h \
|
||||
|
||||
$(INIT_ASM_OBJS): $(MAKEDIR)\makefile \
|
||||
$(OBJECT)\sysmgr.inc \
|
||||
$(OBJECT)\smimac.mac \
|
||||
$(OBJECT)\vsa2.inc \
|
||||
$(OBJECT)\isa.inc \
|
||||
$(OBJECT)\chipset.inc \
|
||||
$(OBJECT)\vr.inc \
|
||||
$(OBJECT)\pci.inc \
|
||||
$(OBJECT)\init.inc \
|
||||
$(OBJECT)\mdd.inc \
|
||||
$(OBJECT)\gx2.inc \
|
||||
$(OBJECT)\cs5536.inc \
|
||||
|
||||
######################################################################
|
||||
#
|
||||
# Common Targets
|
||||
#
|
||||
######################################################################
|
||||
# include common targets and inference rules
|
||||
!include $(BUILD_DIR)\rules.mak
|
||||
|
||||
######################################################################
|
||||
#
|
||||
# Inference Rules
|
||||
#
|
||||
######################################################################
|
||||
# Override common inference rules here
|
||||
|
||||
{$(INC_DIR)}.h{$(OBJECT)}.inc:
|
||||
$(H2) /Fa$(OBJECT)\$(@F) /nologo /Zni /C $<
|
||||
|
||||
{$(INC_DIR)\$(CPU)}.h{$(OBJECT)}.inc:
|
||||
$(H2) /Fa$(OBJECT)\$(@F) /nologo /Zni /C $<
|
||||
|
||||
{$(SYSMGR_SRC)}.h{$(OBJECT)}.inc:
|
||||
$(H2) /Fa$(OBJECT)\$(@F) /nologo /Zns /C $<
|
||||
|
||||
{$(SYSMGR_SRC)\$(CPU)}.h{$(OBJECT)}.inc:
|
||||
$(H2) /Fa$(OBJECT)\$(@F) /nologo /Zns /C $<
|
||||
|
||||
$(OBJECT)\hce.inc:
|
||||
$(H2) /Fa$(OBJECT)\hce.inc /Znh /C $(INC_DIR)\hce.h
|
||||
|
||||
$(OBJECT)\protos.inc:
|
||||
$(H2) /Fa$(OBJECT)\protos.inc /Zn"q" /C $(SYSMGR_SRC)\protos.h
|
||||
|
||||
118
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/mapper.c
vendored
Executable file
118
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/mapper.c
vendored
Executable file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//******************************************************************************
|
||||
//* This file contains code specific to the IRQ Mapper
|
||||
//******************************************************************************
|
||||
|
||||
#include "VSA2.H"
|
||||
#include "SYSMGR.H"
|
||||
#include "PROTOS.H"
|
||||
#include "VPCI.H"
|
||||
#include "PCI.H"
|
||||
#include "MDD.H"
|
||||
#include "MAPPER.H"
|
||||
#include "ISA.H"
|
||||
|
||||
// Local Variables:
|
||||
UCHAR PCI_INTs[4] = {0,0,0,0}; // Current PCI INT mappings
|
||||
UCHAR Max_PCI_Interrupt=4;
|
||||
|
||||
// External Variables:
|
||||
extern ULONG MDD_Base;
|
||||
extern USHORT Saved_AX;
|
||||
|
||||
|
||||
|
||||
|
||||
// External Functions:
|
||||
void PCI_Interrupts(void);
|
||||
|
||||
|
||||
|
||||
//************************************************************************************
|
||||
// Maps an Unrestricted Source to a PIC IRQ via the IRQ Mapper logic
|
||||
//************************************************************************************
|
||||
void pascal IRQ_Mapper(UCHAR Reg, UCHAR Source, UCHAR Irq)
|
||||
{ ULONG MsrAddr, MsrData;
|
||||
UCHAR ShiftCount;
|
||||
|
||||
// 8 sources per MSR
|
||||
Reg += Source/8;
|
||||
|
||||
MsrAddr = MDD_Base + Reg;
|
||||
|
||||
// 4 bits per field
|
||||
ShiftCount = (Source % 8) * 4;
|
||||
|
||||
// Map Unrestricted Source[Source] to Irq via IRQ Mapper
|
||||
MsrData = Read_MSR_LO(MsrAddr);
|
||||
MsrData &= ~(0x0000000FL << ShiftCount);
|
||||
MsrData |= (ULONG)Irq << ShiftCount;
|
||||
Write_MSR_LO(MsrAddr, MsrData);
|
||||
}
|
||||
|
||||
//************************************************************************************
|
||||
// Maps an Unrestricted Source Y to a PIC IRQ
|
||||
//************************************************************************************
|
||||
void pascal IRQY_Mapper(UCHAR Y_Source, UCHAR Irq)
|
||||
{
|
||||
IRQ_Mapper(MSR_IRQM_YLOW, Y_Source, Irq);
|
||||
}
|
||||
|
||||
|
||||
//************************************************************************************
|
||||
// Maps an Unrestricted Source Z to a PIC IRQ
|
||||
//************************************************************************************
|
||||
void pascal IRQZ_Mapper(UCHAR Z_Source, UCHAR Irq)
|
||||
{
|
||||
IRQ_Mapper(MSR_IRQM_ZLOW, Z_Source, Irq);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//************************************************************************************
|
||||
// Implements the SYS_GENERATE_IRQ macro for CS5536
|
||||
//************************************************************************************
|
||||
void pascal Generate_IRQ_5536(USHORT IRQ_Mask)
|
||||
{ UCHAR Irq=0;
|
||||
USHORT Level;
|
||||
|
||||
Level = in_16(PIC1_EDGE);
|
||||
|
||||
// Don't attempt to generate a level-sensitive interrupt
|
||||
if (IRQ_Mask & Level) {
|
||||
Log_Error("Attempt to generate a level-sensitive IRQ. Mask= 0x%04X", IRQ_Mask);
|
||||
return;
|
||||
}
|
||||
|
||||
while (IRQ_Mask) {
|
||||
if (IRQ_Mask & 1) {
|
||||
// Map the software IRQ to the requested IRQ
|
||||
IRQY_Mapper(Y_IRQ_SW, Irq);
|
||||
|
||||
// Generate an edge to the PIC
|
||||
Write_MSR_LO(MDD_Base + MSR_SOFT_IRQ, 0L);
|
||||
Write_MSR_LO(MDD_Base + MSR_SOFT_IRQ, 1L);
|
||||
}
|
||||
IRQ_Mask >>= 1;
|
||||
Irq++;
|
||||
}
|
||||
}
|
||||
|
||||
48
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/mapper.h
vendored
Executable file
48
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/mapper.h
vendored
Executable file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
// Unrestricted Y usage:
|
||||
#define Y_IRQ_SW 0
|
||||
#define Y_IRQ_USB1 1
|
||||
#define Y_IRQ_USB2 2
|
||||
#define Y_IRQ_RTC 3
|
||||
#define Y_IRQ_AUDIO 4
|
||||
#define Y_IRQ_PME 5
|
||||
#define Y_IRQ_FLASH 6
|
||||
#define Y_IRQ_SMB 12
|
||||
#define Y_IRQ_KEL 13
|
||||
#define Y_IRQ_UART1 14
|
||||
#define Y_IRQ_UART2 15
|
||||
|
||||
|
||||
|
||||
// Unrestricted Z usage:
|
||||
#define Z_IRQ_MFGPT_04 0
|
||||
#define Z_IRQ_MFGPT_15 1
|
||||
#define Z_IRQ_MFGPT_26 2
|
||||
#define Z_IRQ_MFGPT_37 3
|
||||
|
||||
#define Z_IRQ_SMI 8
|
||||
#define Z_IRQ_INTA 9
|
||||
#define Z_IRQ_INTB 10
|
||||
#define Z_IRQ_INTC 11
|
||||
#define Z_IRQ_INTD 12
|
||||
|
||||
|
||||
135
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/mbiu.c
vendored
Executable file
135
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/mbiu.c
vendored
Executable file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//* Function: *
|
||||
//* Utility routines for managing MBIUs
|
||||
|
||||
|
||||
#include "VSA2.H"
|
||||
#include "PROTOS.H"
|
||||
#include "GX2.H"
|
||||
#include "VPCI.H"
|
||||
#include "DESCR.H"
|
||||
#include "SYSMGR.H"
|
||||
|
||||
|
||||
extern void InitStatCounters(ULONG, UCHAR);
|
||||
|
||||
|
||||
// External variables:
|
||||
extern ULONG Mbiu0;
|
||||
|
||||
// Local variables:
|
||||
ULONG ExtendedMemoryDescr0, ExtendedMemoryDescr1 = 0;
|
||||
MBIU_INFO MbiuInfo[MAX_MBIU];
|
||||
UCHAR NumMbius=0;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Called once for each MBIU:
|
||||
// - Initializes statistic counters
|
||||
// - Records all available descriptors
|
||||
//***********************************************************************
|
||||
void pascal Init_MBIU(UCHAR * CountPtr, ULONG Msr)
|
||||
{ UCHAR Type, i;
|
||||
ULONG Default[2], MsrData[2];
|
||||
|
||||
|
||||
// Record info about MBIU
|
||||
MbiuInfo[NumMbius].Mbiu = Msr;
|
||||
MbiuInfo[NumMbius].SubtrPid = Read_MSR_LO(Msr + MBD_MSR_CONFIG) << 29;
|
||||
MbiuInfo[NumMbius].NumCounters = ((CAPABILITIES *)CountPtr)->NSTATS;
|
||||
MbiuInfo[NumMbius].ActiveCounters = 0x00;
|
||||
MbiuInfo[NumMbius].ClockGating = Read_MSR_LO(Msr + MBD_MSR_PM);
|
||||
|
||||
// Clear SMIs on this MBIU & disable all events except HW Emulation
|
||||
MsrData[0] = 0x0000000E;
|
||||
MsrData[1] = 0x0000000F;
|
||||
(USHORT)Msr = MBD_MSR_SMI;
|
||||
Write_MSR(Msr, MsrData);
|
||||
|
||||
//*********************************************
|
||||
// Initialize Statistics MSRs
|
||||
//*********************************************
|
||||
InitStatCounters(Msr, ((CAPABILITIES *)CountPtr)->NSTATS);
|
||||
|
||||
//*********************************************
|
||||
// Begin with P2D_BM descriptors
|
||||
//*********************************************
|
||||
Type = P2D_BM;
|
||||
(USHORT)Msr = MSR_MEM_DESCR;
|
||||
|
||||
do {
|
||||
|
||||
// Get number of next type of descriptor
|
||||
if (i = *(CountPtr++)) {
|
||||
|
||||
// Get the default value for this descriptor type
|
||||
Get_Descriptor_Default(Type, Default);
|
||||
|
||||
// Loop through all descriptors of a given type
|
||||
do {
|
||||
|
||||
// If descriptor is already in use by the BIOS, skip it
|
||||
Read_MSR(Msr, MsrData);
|
||||
if ((MsrData[0] == Default[0]) && (MsrData[1] == Default[1])) {
|
||||
|
||||
// Initialize Descriptor[] entry
|
||||
if (Init_Descr(Type, Msr)) {
|
||||
// Not enough table entries...abort
|
||||
Type = 0x99;
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
// Descriptor is in use.
|
||||
// If it's an extended memory descriptor, record the routing address.
|
||||
if (Type == P2D_R) {
|
||||
if ((Msr & ROUTING) == Mbiu0) {
|
||||
ExtendedMemoryDescr0 = Msr;
|
||||
} else {
|
||||
ExtendedMemoryDescr1 = Msr;
|
||||
}
|
||||
}
|
||||
}
|
||||
Msr++;
|
||||
} while (--i);
|
||||
}
|
||||
|
||||
// Check next descriptor type.
|
||||
// If transitioning from P2D to IOD descriptors...
|
||||
if (++Type == IOD_BM) {
|
||||
// change MSR offset to 0xE0
|
||||
(USHORT)Msr = MSR_IO_DESCR;
|
||||
}
|
||||
} while (Type <= IOD_SC);
|
||||
|
||||
// Increment number of MBIUs
|
||||
NumMbius++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
758
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/mbus.c
vendored
Executable file
758
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/mbus.c
vendored
Executable file
@@ -0,0 +1,758 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//******************************************************************************
|
||||
//* Routines related to the MBus
|
||||
//******************************************************************************
|
||||
|
||||
|
||||
#include "VSA2.H"
|
||||
#include "PROTOS.H"
|
||||
#include "PCI.H"
|
||||
#include "GX2.H"
|
||||
#include "VPCI.H"
|
||||
#include "CHIPSET.H"
|
||||
#include "DESCR.H"
|
||||
#include "MDD.H"
|
||||
#include "SYSMGR.H"
|
||||
|
||||
// Externals:
|
||||
extern void InitLogicalCounters(void);
|
||||
extern UCHAR GetPortID(ULONG);
|
||||
extern void pascal ClearMbiu(ULONG);
|
||||
extern UCHAR pascal Get_MBus_Status(ULONG, USHORT);
|
||||
extern UCHAR pascal Is_LBAR_Enabled(PCI_HEADER_ENTRY * Pci);
|
||||
extern ULONG pascal Compute_IOD_SC(ULONG *, USHORT *, UCHAR);
|
||||
extern PCI_HEADER_ENTRY * pascal Get_Structure(USHORT);
|
||||
|
||||
extern USHORT Class;
|
||||
extern CAPABILITIES Southbridge_MBIU;
|
||||
extern ULONG Mbiu2, MPCI_SB;
|
||||
extern ULONG ACPI_Timer_MSR;
|
||||
extern Hardware HardwareInfo;
|
||||
extern MBIU_INFO MbiuInfo[];
|
||||
extern DESCRIPTOR MSRs[];
|
||||
|
||||
// Local Variables:
|
||||
static ULONG PCI_Value;
|
||||
ULONG Mbiu0 = PORT_MBIU0;
|
||||
ULONG Mbiu1;
|
||||
ULONG LookupMbiu;
|
||||
ULONG MPCI_NB=0;
|
||||
ULONG MCP_NB =0;
|
||||
ULONG FooGlue=0;
|
||||
UCHAR MBIU1_SelfReference;
|
||||
UCHAR VG_Port;
|
||||
UCHAR MC_Port;
|
||||
CAPABILITIES Northbridge_MBIU0, Northbridge_MBIU1;
|
||||
|
||||
typedef struct {
|
||||
ULONG Routing;
|
||||
USHORT MBus_ID;
|
||||
UCHAR Instance;
|
||||
} SCAN_RESULTS;
|
||||
|
||||
#define MAX_HITS (3*8) // Num-GLIUs * Max-Ports-per-GLIU
|
||||
SCAN_RESULTS PriorScans[MAX_HITS];
|
||||
int j;
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Scans an MBIU for the specified MBus_ID.
|
||||
// Returns MBIU routing address (LSB = MBIU port)
|
||||
//***********************************************************************
|
||||
ULONG pascal Scan_MBIU(ULONG Mbiu, USHORT Port_ID, UCHAR * Instance, UCHAR Shift)
|
||||
{ USHORT Port;
|
||||
ULONG RoutingMask;
|
||||
|
||||
RoutingMask = 1L << Shift;
|
||||
|
||||
LookupMbiu = Mbiu;
|
||||
|
||||
// Adjustment for Southbridge MPCI
|
||||
if (Port_ID == ID_MPCI && Mbiu == Mbiu2) {
|
||||
Mbiu &= ~(RoutingMask - 1);
|
||||
}
|
||||
|
||||
// Scan MBIU's ports for specified ID
|
||||
for (Port = 0; Port <= 7; Port++) {
|
||||
|
||||
// If correct ID...
|
||||
if (GetPortID(Mbiu) == Port_ID) {
|
||||
|
||||
// and correct instance...
|
||||
if (--(* Instance) == 0) {
|
||||
|
||||
// return the routing address and port # (in 3 LSBs)
|
||||
return (Mbiu | Port);
|
||||
}
|
||||
}
|
||||
|
||||
// Get MSR address to next device
|
||||
Mbiu &= ~(RoutingMask - 1);
|
||||
Mbiu += RoutingMask;
|
||||
|
||||
}
|
||||
|
||||
return 0x00000000;
|
||||
}
|
||||
|
||||
// Port = 1
|
||||
// Mbiu = Southbridge = 0x51000000
|
||||
// Port_ID = 0x47
|
||||
// RoutingMask = 1 << 20 = 0x00100000
|
||||
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Finds an MBUS ID and returns the routing address.
|
||||
// The port number is also returned in the 3 LSBs.
|
||||
//***********************************************************************
|
||||
ULONG pascal Find_MBus_ID(USHORT MBus_ID, UCHAR Instance)
|
||||
{ ULONG DeviceAddr;
|
||||
int i, SavedInstance=Instance;
|
||||
|
||||
// Check results of previous scans for a match
|
||||
for (i=0; i<j; i++) {
|
||||
if (PriorScans[i].MBus_ID == MBus_ID && PriorScans[i].Instance == Instance) {
|
||||
return PriorScans[i].Routing;
|
||||
}
|
||||
}
|
||||
|
||||
// Filter out MBIU1 self-reference
|
||||
if (MBus_ID == ID_MBIU) {
|
||||
if (Instance > 2) {
|
||||
Instance++;
|
||||
}
|
||||
}
|
||||
|
||||
// MBus_ID = 0x47
|
||||
// Instance = 1
|
||||
if (!(DeviceAddr = Scan_MBIU(Mbiu0, MBus_ID, &Instance, 29))) {
|
||||
if (!(DeviceAddr = Scan_MBIU(Mbiu1, MBus_ID, &Instance, 26))) {
|
||||
if (!(DeviceAddr = Scan_MBIU(Mbiu2, MBus_ID, &Instance, 20)) && MBus_ID == ID_ATA) {
|
||||
DeviceAddr = Scan_MBIU(Mbiu2, ID_ATA100, &Instance, 20);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clear h/w emulation events generated by scanning empty ports
|
||||
ClearMbiu(Mbiu0);
|
||||
ClearMbiu(Mbiu1);
|
||||
|
||||
// SDG: if Mbiu2 is 0x51020000, then the folliwng call
|
||||
// sets bit 32 (EDX[0]) in 0x51022002. Does this actually talk
|
||||
// MSR 0x51000002? If so... BUG!
|
||||
|
||||
ClearMbiu(Mbiu2);
|
||||
|
||||
// Record this scan for future reference
|
||||
if (DeviceAddr && j < MAX_HITS-1) {
|
||||
PriorScans[j].Instance = SavedInstance;
|
||||
PriorScans[j].MBus_ID = MBus_ID;
|
||||
PriorScans[j].Routing = DeviceAddr;
|
||||
j++;
|
||||
}
|
||||
|
||||
return DeviceAddr;
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Returns the MSR address of the MPCI associated with the current device
|
||||
//***********************************************************************
|
||||
ULONG pascal GetMSR(void)
|
||||
{
|
||||
switch (Class) {
|
||||
|
||||
case 0x0600: // Bridge: Host
|
||||
return MPCI_NB;
|
||||
|
||||
case 0x0601: // Bridge: ISA
|
||||
return MPCI_SB;
|
||||
|
||||
default:
|
||||
return 0x00000000;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Gets the PCI Latency Timer
|
||||
//***********************************************************************
|
||||
UCHAR pascal Get_Latency(PCI_HEADER_ENTRY * Pci)
|
||||
{ ULONG MsrAddr, MPCI_Ctrl[2];
|
||||
UCHAR LatencyTimer=Pci->LatencyTimer;
|
||||
|
||||
// If bridge device, get MSR address of its MPCI
|
||||
if (MsrAddr = GetMSR()) {
|
||||
// Read Latency timer from MPCI_CTRL.LAT
|
||||
Read_MSR(MsrAddr + MPCI_CTRL, MPCI_Ctrl);
|
||||
LatencyTimer = (UCHAR)MPCI_Ctrl[1];
|
||||
}
|
||||
return LatencyTimer;
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
// Sets the PCI Latency timer
|
||||
//***********************************************************************
|
||||
void pascal Set_Latency(UCHAR Latency)
|
||||
{ ULONG MsrAddr=0, MPCI_Ctrl[2];
|
||||
|
||||
// If bridge device, get MSR address of its MPCI
|
||||
if (MsrAddr = GetMSR()) {
|
||||
|
||||
// Set the PCI Latency timer
|
||||
Read_MSR(MsrAddr + MPCI_CTRL, MPCI_Ctrl);
|
||||
(UCHAR)MPCI_Ctrl[1] = Latency;
|
||||
|
||||
// LDE is only defined in Northbridge MPCI
|
||||
if (MsrAddr == MPCI_NB) {
|
||||
if (Latency) {
|
||||
// Issues 118.176 & 118.197 require LDE to be set unless Latency Timer == 0
|
||||
(USHORT)MPCI_Ctrl[0] |= LDE;
|
||||
} else {
|
||||
// Clear MPCI_CTRL[LDE] if Latency Timer = 0x00
|
||||
(USHORT)MPCI_Ctrl[0] &= ~LDE;
|
||||
}
|
||||
}
|
||||
Write_MSR(MsrAddr + MPCI_CTRL, MPCI_Ctrl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Enables/Disables a trap on a PCI Address
|
||||
//***********************************************************************
|
||||
void pascal Trap_PCI_IDSEL(USHORT PCI_Address, UCHAR EnableFlag)
|
||||
{ ULONG Pbus, IDSEL_Mask;
|
||||
|
||||
IDSEL_Mask = 1L << (UCHAR)(PCI_Address >> 11);
|
||||
Pbus = Read_MSR_LO(MPCI_NB + MPCI_PBUS);
|
||||
|
||||
if (EnableFlag) {
|
||||
Pbus |= IDSEL_Mask;
|
||||
} else {
|
||||
Pbus &= ~IDSEL_Mask;
|
||||
}
|
||||
|
||||
Write_MSR_LO(MPCI_NB + MPCI_PBUS, Pbus);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Initializes MBus related structures and MSRs
|
||||
// Input:
|
||||
// IDSEL_Mask = Mask of IDSELs to be virtualized
|
||||
//***********************************************************************
|
||||
void Init_MBus(void)
|
||||
{ ULONG MsrAddr, MsrData[2];
|
||||
|
||||
|
||||
//*********************************************
|
||||
// Add RCONF0-RCONF7 to available descriptor list
|
||||
//*********************************************
|
||||
for (MsrAddr = MSR_RCONF0; MsrAddr <= MSR_RCONF7; MsrAddr++) {
|
||||
if (Init_Descr(GX2_RCONF, MsrAddr)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//*********************************************
|
||||
// Initialize MBIU0
|
||||
//*********************************************
|
||||
Read_MSR(Mbiu0 + MBIU_CAP, &MsrData[0]);
|
||||
Parse_Capabilities(&MsrData[0], &Northbridge_MBIU0);
|
||||
Init_MBIU((UCHAR *)&Northbridge_MBIU0, Mbiu0);
|
||||
|
||||
|
||||
|
||||
|
||||
//*********************************************
|
||||
// Initialize MBIU1
|
||||
//*********************************************
|
||||
// MBIU1 is MBIU0's subtractive port
|
||||
Mbiu1 = MbiuInfo[0].SubtrPid;
|
||||
// Determine MBIU1 self-reference
|
||||
MBIU1_SelfReference = (UCHAR)Read_MSR_LO(Mbiu1 + MBIU_WHOAMI);
|
||||
|
||||
Read_MSR(Mbiu1 + MBIU_CAP, &MsrData[0]);
|
||||
Parse_Capabilities(&MsrData[0], &Northbridge_MBIU1);
|
||||
Init_MBIU((UCHAR *)&Northbridge_MBIU1, Mbiu1);
|
||||
|
||||
// Find address of MPCI_NB
|
||||
MPCI_NB = Find_MBus_ID(ID_MPCI, 1) & 0xFFFF0000;
|
||||
|
||||
// Find address of MCP
|
||||
MCP_NB = Find_MBus_ID(ID_MCP, 1) & 0xFFFF0000;
|
||||
|
||||
// Enable SMIs from the companion I/O
|
||||
MsrAddr = MCP_NB | MBD_MSR_SMI;
|
||||
Write_MSR_LO(MsrAddr, Read_MSR_LO(MsrAddr) & ~0x00000010L);
|
||||
|
||||
PriorScans[j].Routing = 0x00000000;
|
||||
PriorScans[j].MBus_ID = ID_VAIL;
|
||||
PriorScans[j].Instance = 1;
|
||||
j++;
|
||||
|
||||
// On LX, FooGlue MSRs == MCP_NB+0x20
|
||||
if (HardwareInfo.CPU_ID == DEVICE_ID_LX) {
|
||||
PriorScans[j].Routing = MCP_NB+0x20;
|
||||
PriorScans[j].MBus_ID = ID_FG;
|
||||
PriorScans[j].Instance = 1;
|
||||
j++;
|
||||
}
|
||||
|
||||
// Find address of FooGlue
|
||||
FooGlue = Find_MBus_ID(ID_FG, 1) & 0xFFFFFFF0;
|
||||
|
||||
// Find port of Video Generator
|
||||
VG_Port = (UCHAR)Find_MBus_ID(ID_VG, 1);
|
||||
|
||||
|
||||
// Find port of Memory Controller
|
||||
MC_Port = (UCHAR)Find_MBus_ID(ID_MC, 1);
|
||||
|
||||
|
||||
// Enable MPCI error masks
|
||||
MsrAddr = MPCI_NB | MBD_MSR_ERROR;
|
||||
Write_MSR_LO(MsrAddr, Read_MSR_LO(MsrAddr) & ~(MARM | TARM | BMM | SYSM | PARM));
|
||||
|
||||
|
||||
|
||||
// Initialize logical timeout counters
|
||||
InitLogicalCounters();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Computes the MSR data corresponding to an enabled PCI BAR
|
||||
//***********************************************************************
|
||||
void Compute_Msr_Value(register DESCRIPTOR * Descr, register PCI_HEADER_ENTRY * Pci)
|
||||
{ ULONG PBase, PMask, POffset=0;
|
||||
|
||||
|
||||
Descr->MsrData[0] = Pci->Value;
|
||||
|
||||
if (Pci->Flag & IO_BAR) {
|
||||
if (Descr->MsrAddr == ACPI_Timer_MSR) {
|
||||
PCI_Value += 4; // Skip over ACPI timer
|
||||
}
|
||||
Descr->Address = (USHORT)PCI_Value;
|
||||
}
|
||||
|
||||
switch (Descr->Type) {
|
||||
|
||||
case USB_LBAR:
|
||||
Descr->MsrData[1] |= MEM_SPACE;
|
||||
return;
|
||||
|
||||
case MDD_LBAR:
|
||||
Descr->MsrData[1] |= Pci->Mask | LBAR_EN;
|
||||
|
||||
// If Memory LBAR, set MEM_IO
|
||||
if (!(Pci->Flag & IO_BAR)) {
|
||||
Descr->MsrData[1] |= MEM_IO;
|
||||
} else {
|
||||
Descr->MsrData[1] &= 0x0000FFFF;
|
||||
Descr->MsrData[0] &= 0x0000FFFF;
|
||||
}
|
||||
return;
|
||||
|
||||
case MPCI_RCONF:
|
||||
Descr->MsrData[1] = Pci->Value;
|
||||
|
||||
// If I/O BAR, set SPACE bit & shift BASE & TOP
|
||||
if (Pci->Flag & IO_BAR) {
|
||||
Descr->MsrData[0] <<= 12; // Move BASE to MSR[31:14]
|
||||
Descr->MsrData[1] += ~(Pci->Mask | 3);
|
||||
Descr->MsrData[1] <<= 12; // Move TOP to MSR[63:46]
|
||||
Descr->MsrData[1] |= 1; // Set SPACE bit
|
||||
} else {
|
||||
Descr->MsrData[1] += ~Pci->Mask & 0xFFFFF000;
|
||||
}
|
||||
Descr->MsrData[0] |= 1; // Enable region
|
||||
return;
|
||||
|
||||
case EPCI:
|
||||
return;
|
||||
|
||||
case GX2_RCONF:
|
||||
// Mark region non-cacheable and write-combined
|
||||
Descr->MsrData[0] |= REGION_CD | REGION_EN;
|
||||
Descr->MsrData[1] = Pci->Value + ~Pci->Mask & 0xFFFFF000;
|
||||
|
||||
if (Pci->Flag & MMIO_BAR) {
|
||||
// Memory-mapped I/O must be write-serialized to avoid deadlocks
|
||||
// They are also marked write-burstable
|
||||
// Descr->MsrData[0] |= REGION_WS | REGION_WT;
|
||||
}
|
||||
if (Pci->Flag & MEM_BAR) {
|
||||
// Mark frame buffers write-combined
|
||||
Descr->MsrData[0] |= REGION_WC;
|
||||
}
|
||||
return;
|
||||
|
||||
case IOD_SC:
|
||||
PMask = Descr->Range;
|
||||
Descr->MsrData[0] = Compute_IOD_SC(&PCI_Value, &(USHORT)PMask, 1);
|
||||
break;
|
||||
|
||||
case IOD_BM:
|
||||
PMask = ~(Descr->Range-1) | 0xF0000;
|
||||
PBase = PCI_Value & PMask;
|
||||
PCI_Value += Descr->Range;
|
||||
break;
|
||||
|
||||
case P2D_BMK:
|
||||
case P2D_BMO:
|
||||
case P2D_BM:
|
||||
PMask = Pci->Mask >> 12;
|
||||
PBase = Pci->Value >> 12;
|
||||
break;
|
||||
|
||||
case P2D_RO:
|
||||
// Fixup for VG alias bug
|
||||
if (Descr->Physical) {
|
||||
POffset = (~Pci->Value + 1) >> 12;
|
||||
}
|
||||
case P2D_R:
|
||||
PMask = Pci->Value >> 12;
|
||||
PBase = PMask + ((Descr->Range-1) >> 12);
|
||||
break;
|
||||
|
||||
// These descriptor types are not used for PCI BARs
|
||||
case P2D_SCO:
|
||||
case P2D_SC:
|
||||
default:
|
||||
Log_Error("Compute_Msr_Value() was called with an invalid descriptor type: 0x%0x", Descr->Type);
|
||||
return;
|
||||
|
||||
} // end switch()
|
||||
|
||||
if (Descr->Type != IOD_SC) {
|
||||
if (Pci->Flag & MEM_BAR) {
|
||||
POffset = (Descr->Physical - Pci->Value) >> 12;
|
||||
}
|
||||
// Assemble fields into MSR value
|
||||
MergeFields(Descr->MsrData, PMask, PBase, POffset);
|
||||
}
|
||||
|
||||
// Set PID field
|
||||
Descr->MsrData[1] |= (ULONG)Descr->Port << 29;
|
||||
|
||||
// Set Bizarro bit, if necessary
|
||||
if (Pci->Flag & USE_BMK) {
|
||||
Descr->MsrData[1] |= BIZARRO;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Updates all descriptors/LBARs/RCONF associated with a PCI BAR
|
||||
//***********************************************************************
|
||||
void pascal Update_BAR(register PCI_HEADER_ENTRY * Pci, UCHAR Enable)
|
||||
{ register DESCRIPTOR * Descr;
|
||||
UCHAR Link;
|
||||
|
||||
PCI_Value = Pci->Value;
|
||||
Link = Pci->Link;
|
||||
|
||||
|
||||
// For each linked item, update the associated MSR
|
||||
while (Link) {
|
||||
|
||||
Descr = &MSRs[Link];
|
||||
|
||||
// Get link to next MSR
|
||||
Link = Descr->Link;
|
||||
|
||||
// Section 3.2.2 of PCI Spec 2.1: A BAR of zero is not a valid address.
|
||||
// If the BAR value is zero, the corresponding MSR will be disabled.
|
||||
if (Enable && Pci->Value != 0) {
|
||||
|
||||
// Don't update MSRs if querying resource requirements
|
||||
if (Pci->Value == Pci->Mask) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// BAR is being enabled
|
||||
Compute_Msr_Value(Descr, Pci);
|
||||
|
||||
} else {
|
||||
|
||||
// Graphics device ignores disabling Command[1] (Issue 118.181)
|
||||
if (Class == 0x0300) {
|
||||
if (!(Pci->Flag & IO_BAR)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// BAR is being disabled
|
||||
Read_MSR(Descr->MsrAddr, Descr->MsrData);
|
||||
|
||||
switch (Descr->Type) {
|
||||
|
||||
case USB_LBAR:
|
||||
Descr->MsrData[1] &= ~2;
|
||||
break;
|
||||
|
||||
case MDD_LBAR:
|
||||
Descr->MsrData[1] &= ~LBAR_EN;
|
||||
break;
|
||||
|
||||
case EPCI:
|
||||
break;
|
||||
|
||||
case GX2_RCONF:
|
||||
Descr->MsrData[0] &= ~REGION_EN;
|
||||
break;
|
||||
|
||||
case MPCI_RCONF:
|
||||
Descr->MsrData[0] &= ~1;
|
||||
break;
|
||||
|
||||
case IOD_SC:
|
||||
Descr->MsrData[0] &= ~(WEN | REN);
|
||||
break;
|
||||
|
||||
default:
|
||||
Get_Descriptor_Default(Descr->Type, Descr->MsrData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Write the MSR
|
||||
Write_MSR(Descr->MsrAddr, Descr->MsrData);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Parses a MBD_MSR_ERROR & returns the Status register equivalent.
|
||||
// NOTE:
|
||||
// PERR# is not implemented, so MASTER_PARITY_ERROR always reads 0.
|
||||
//***********************************************************************
|
||||
ULONG pascal Get_Device_Status(PCI_HEADER_ENTRY * Pci)
|
||||
{ ULONG MsrAddr, MsrData, Status=0;
|
||||
|
||||
// Read MBD_MSR_ERROR
|
||||
if (MsrAddr = GetMSR()) {
|
||||
(USHORT)MsrAddr = MBD_MSR_ERROR;
|
||||
|
||||
MsrData = Read_MSR_LO(MsrAddr);
|
||||
|
||||
if (MsrData & (BME | TASE))
|
||||
Status |= SIGNALED_TARGET_ABORT; // Status[11]
|
||||
|
||||
if (MsrData & TARE)
|
||||
Status |= RECEIVED_TARGET_ABORT; // Status[12]
|
||||
|
||||
if (MsrData & MARE)
|
||||
Status |= RECEIVED_MASTER_ABORT; // Status[13]
|
||||
|
||||
if (MsrData & SYSE)
|
||||
Status |= SIGNALED_SYSTEM_ERROR; // Status[14]
|
||||
|
||||
if (MsrData & PARE)
|
||||
Status |= DETECTED_PARITY_ERROR; // Status[15]
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Clears error(s) pending on a device according to the Status mask
|
||||
//***********************************************************************
|
||||
void pascal Clear_MBus_Error(PCI_HEADER_ENTRY * Pci, ULONG Status)
|
||||
{ ULONG MsrAddr, MsrData;
|
||||
|
||||
// Read MBD_MSR_ERROR
|
||||
if (MsrAddr = GetMSR()) {
|
||||
|
||||
(USHORT)MsrAddr = MBD_MSR_ERROR;
|
||||
|
||||
MsrData = Read_MSR_LO(MsrAddr);
|
||||
|
||||
|
||||
// Status[15:11] write-1-to-clear.
|
||||
// Only clear the MSR bits corresponding to Status[15:11]
|
||||
MsrData &= ~(TASE | BME | TARE | MARE | SYSE | PARE);
|
||||
|
||||
if (Status & SIGNALED_TARGET_ABORT) // Status[11]
|
||||
MsrData |= TASE | BME;
|
||||
|
||||
if (Status & RECEIVED_TARGET_ABORT) // Status[12]
|
||||
MsrData |= TARE;
|
||||
|
||||
if (Status & RECEIVED_MASTER_ABORT) // Status[13]
|
||||
MsrData |= MARE;
|
||||
|
||||
if (Status & SIGNALED_SYSTEM_ERROR) // Status[14]
|
||||
MsrData |= SYSE;
|
||||
|
||||
if (Status & DETECTED_PARITY_ERROR) // Status[15]
|
||||
MsrData |= PARE;
|
||||
|
||||
Write_MSR_LO(MsrAddr, MsrData);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Enables/disables bus mastering on a GLIU device
|
||||
// Returns non-zero if no more bus-master MSRs for this device
|
||||
//***********************************************************************
|
||||
UCHAR pascal Update_BusMaster(PCI_HEADER_ENTRY * Pci, UCHAR EnableFlag)
|
||||
{ register DESCRIPTOR * Descr;
|
||||
ULONG MsrAddr, MsrData[2];
|
||||
USHORT Mask;
|
||||
UCHAR Link, Shift;
|
||||
|
||||
switch (Class) {
|
||||
|
||||
// Filter out devices that don't affect PAE when Command[2] is changed
|
||||
case 0x0600: // Bridge: Host
|
||||
case 0x0601: // Bridge: ISA
|
||||
case 0x0300: // Graphics
|
||||
case 0x1010: // AES
|
||||
return 1;
|
||||
|
||||
default:
|
||||
|
||||
Link = Pci->Link;
|
||||
|
||||
// For each linked item, update the associated MSR
|
||||
while (Link) {
|
||||
|
||||
Descr = &MSRs[Link];
|
||||
|
||||
// Get link to next MSR
|
||||
Link = Descr->Link;
|
||||
|
||||
|
||||
MsrAddr = Descr->MsrAddr;
|
||||
// Each USB 2.0 device on port 2 has its own bus-master control
|
||||
if (Descr->Type == USB_LBAR) {
|
||||
// Modify bus-master control
|
||||
Read_MSR(MsrAddr, MsrData);
|
||||
(UCHAR)MsrData[1] &= ~BUS_MASTER;
|
||||
if (EnableFlag) {
|
||||
(UCHAR)MsrData[1] |= BUS_MASTER;
|
||||
}
|
||||
Write_MSR(MsrAddr, MsrData);
|
||||
Descr->MsrData[1] = MsrData[1];
|
||||
return 1;
|
||||
}
|
||||
// Only change PAE in MBIU0 & MBIU2
|
||||
MsrAddr &= ROUTING;
|
||||
if (MsrAddr == Mbiu0 || MsrAddr == Mbiu2) {
|
||||
(USHORT)MsrAddr = MBIU_PAE;
|
||||
|
||||
// Generate shift count from port #
|
||||
Shift = 14; // Port 0 is in 8th position (bits 15:14)
|
||||
if (Descr->Port) {
|
||||
Shift = (Descr->Port-1) * 2;
|
||||
}
|
||||
|
||||
// Generate mask for PAE MSR. 2 bits/field.
|
||||
Mask = 3 << Shift;
|
||||
|
||||
// Modify bus-master control
|
||||
Read_MSR(MsrAddr, MsrData);
|
||||
(USHORT)MsrData[0] &= ~Mask;
|
||||
if (EnableFlag) {
|
||||
(USHORT)MsrData[0] |= Mask;
|
||||
}
|
||||
Write_MSR(MsrAddr, MsrData);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Supports macro SYS_MBUS_DESCRIPTOR.
|
||||
// Returns the MSR address associated with a virtualized PCI resource.
|
||||
//***********************************************************************
|
||||
ULONG pascal Lookup_PCI(USHORT Address)
|
||||
{ register PCI_HEADER_ENTRY * Pci;
|
||||
register DESCRIPTOR * Descr;
|
||||
UCHAR LO_Address, Index=0;
|
||||
|
||||
LO_Address = (UCHAR)Address;
|
||||
|
||||
// Limit search to PCI BARs and OEM registers
|
||||
if (((LO_Address >= BAR0) && (LO_Address <= BAR5)) || (LO_Address >= 0x40)) {
|
||||
|
||||
Pci = Get_Structure(Address);
|
||||
|
||||
if ((USHORT)Pci > UNIMPLEMENTED_REGISTER) {
|
||||
if (Index = Pci->Link) {
|
||||
// For OHCI devices, return embedded PCI address
|
||||
if (Pci->Flag & EPCI_RW ) {
|
||||
do {
|
||||
Descr = &MSRs[Index];
|
||||
if (Descr->Type == EPCI) {
|
||||
break;
|
||||
}
|
||||
} while (Index = Descr->Link);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Descr = &MSRs[Index];
|
||||
return Descr->MsrAddr;
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
// Supports macro SYS_IO_DESCRIPTOR.
|
||||
// Returns the MSR address associated with an I/O address.
|
||||
//***********************************************************************
|
||||
ULONG pascal Lookup_IO(USHORT Address)
|
||||
{ USHORT Range;
|
||||
ULONG Addr;
|
||||
UCHAR Index=0;
|
||||
|
||||
Range = 1;
|
||||
Addr = (ULONG)Address;
|
||||
Index = Find_Matching_IO_Descriptor(&Addr, &Range, 3);
|
||||
return MSRs[Index].MsrAddr;
|
||||
}
|
||||
367
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/mdd.c
vendored
Executable file
367
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/mdd.c
vendored
Executable file
@@ -0,0 +1,367 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//******************************************************************************
|
||||
//* Routines related to the MBus Diverse Device
|
||||
//******************************************************************************
|
||||
|
||||
|
||||
#include "VSA2.H"
|
||||
#include "SYSMGR.H"
|
||||
#include "GX2.H"
|
||||
#include "MDD.H"
|
||||
#include "PROTOS.H"
|
||||
#include "DESCR.H"
|
||||
#include "ACPI.H"
|
||||
#include "VPCI.H"
|
||||
#include "PCI.H"
|
||||
#include "ACPI.H"
|
||||
#include "CHIPSET.H"
|
||||
|
||||
#define A20_EN (A20_P_EN | A20_K_EN)
|
||||
#define INIT_EN (INIT_K_EN | INIT_P_EN)
|
||||
|
||||
|
||||
// External function prototypes:
|
||||
void Init_MFGPT(void);
|
||||
UCHAR pascal ACPI_Trapping(USHORT);
|
||||
|
||||
// Local function prototypes:
|
||||
void pascal Control_MDD_SMI(USHORT, ULONG);
|
||||
|
||||
|
||||
// Local variables:
|
||||
ULONG MDD_Base;
|
||||
|
||||
// External variables:
|
||||
extern PCI_HEADER_ENTRY ISA_Hdr[];
|
||||
extern Hardware HardwareInfo;
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Enables/disables KEL SMIs
|
||||
//***********************************************************************
|
||||
void pascal Control_KEL_SMI(USHORT EnableFlag)
|
||||
{
|
||||
Control_MDD_SMI(EnableFlag, KEL_ASMI_EN);
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
// Enable/disable keyboard command snooping by KEL
|
||||
//***********************************************************************
|
||||
void pascal Control_KEL_Snoop(USHORT EnableFlag)
|
||||
{ ULONG MsrAddr, MsrData;
|
||||
|
||||
MsrAddr = MDD_Base;
|
||||
(USHORT)MsrAddr = MSR_KEL_CNTRL;
|
||||
MsrData = Read_MSR_LO(MsrAddr);
|
||||
|
||||
if (EnableFlag) {
|
||||
MsrData |= KEL_SNOOP;
|
||||
} else {
|
||||
MsrData &= ~KEL_SNOOP;
|
||||
}
|
||||
Write_MSR_LO(MsrAddr, MsrData);
|
||||
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
// Initializes the MBus Diverse Device
|
||||
//***********************************************************************
|
||||
void Init_MDD(void)
|
||||
{ ULONG MsrAddr;
|
||||
USHORT ACPI_Bar;
|
||||
UCHAR i;
|
||||
|
||||
|
||||
// Find address of MBus Diverse Device
|
||||
MsrAddr = MDD_Base = Find_MBus_ID(ID_MDD, 1) & 0xFFFF0000;
|
||||
|
||||
//*********************************************
|
||||
// Record MDD's LBARs in MSRs[]
|
||||
//*********************************************
|
||||
for (i = MSR_LBAR_IRQ; i <= MSR_LBAR_FLSH3; i++) {
|
||||
|
||||
(UCHAR)MsrAddr = i;
|
||||
|
||||
if (Init_Descr(MDD_LBAR, MsrAddr)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Clear PM1_STS
|
||||
(UCHAR)MsrAddr = ISA_Hdr[BAR5/4].LBar;
|
||||
ACPI_Bar = (USHORT)Read_MSR_LO(MsrAddr);
|
||||
out_16(ACPI_Bar, in_16(ACPI_Bar));
|
||||
|
||||
|
||||
// Initialize KEL
|
||||
|
||||
// Enable keyboard snooping by KEL
|
||||
Control_KEL_Snoop(1);
|
||||
|
||||
// Enable SMIs from:
|
||||
// - A20 & Init (keyboard and port 92h)
|
||||
// - KEL
|
||||
// - Extended PIC Mapper
|
||||
Control_MDD_SMI(1, A20_EN | INIT_EN | PIC_ASMI_EN | KEL_ASMI_EN);
|
||||
|
||||
|
||||
// Initialize the MFGPT
|
||||
Init_MFGPT();
|
||||
|
||||
// Clear any pending PIC events
|
||||
(USHORT)MsrAddr = MBD_MSR_SMI;
|
||||
Write_MSR_HI(MsrAddr, PIC_ASMI_EN);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Implements CS5536's F0 Special Cycles.
|
||||
// Linked to MDD's MSR_LEG_IO[31].
|
||||
//
|
||||
// When set, a Shutdown special cycle causes a reset. When the Special
|
||||
// Cycles bit is cleared, a Shutdown special cycle is ignored. Before
|
||||
// updating MSR_LEG_IO, VSA will check MSR_ERR[15] and MSR_SMI[1]. If
|
||||
// either of these MSR bits are set, then no action is taken. It will
|
||||
// be assumed that a debugger is in use and VSA will not interfere.
|
||||
//***********************************************************************
|
||||
void pascal Update_Special_Cycles(USHORT EnableFlag)
|
||||
{ ULONG MSR_Addr, MSR_Data;
|
||||
|
||||
|
||||
// If either MSR_ERR[15] and MSR_SMI[1] is set, then bail.
|
||||
if (Read_MSR_LO(MDD_Base + MBD_MSR_SMI) & 2) {
|
||||
return;
|
||||
}
|
||||
if (Read_MSR_LO(MDD_Base + MBD_MSR_ERROR) & 0x8000) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Link MSR_LEG_IO[RESET_SHUT_EN] to COMMAND[3]
|
||||
MSR_Addr = MDD_Base + MSR_LEG_IO;
|
||||
MSR_Data = Read_MSR_LO(MSR_Addr);
|
||||
|
||||
if (EnableFlag) {
|
||||
MSR_Data |= RESET_SHUT_EN;
|
||||
} else {
|
||||
MSR_Data &= ~RESET_SHUT_EN;
|
||||
}
|
||||
|
||||
Write_MSR_LO(MSR_Addr, MSR_Data);
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Enable/disable of MDD ASMI(s)
|
||||
//***********************************************************************
|
||||
void pascal Control_MDD_SMI(USHORT EnableFlag, ULONG EnableMask)
|
||||
{ ULONG MsrAddr, MsrData;
|
||||
|
||||
MsrAddr = MDD_Base;
|
||||
(USHORT)MsrAddr = MBD_MSR_SMI;
|
||||
|
||||
MsrData = Read_MSR_LO(MsrAddr);
|
||||
if (EnableFlag) {
|
||||
MsrData |= EnableMask;
|
||||
} else {
|
||||
MsrData &= ~EnableMask;
|
||||
}
|
||||
Write_MSR_LO(MsrAddr, MsrData);
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Clears the ACPI Status register
|
||||
// This routine fills in MsgPacket[0] = ACPI GPE0_STS
|
||||
// and MsgPacket[1] bits[15:0] = ACPI PM1_STS
|
||||
//***********************************************************************
|
||||
USHORT Get_ACPI_Status(ULONG *msgp)
|
||||
{ USHORT ACPI_Bar, PM1_Status;
|
||||
ULONG GPE_Status;
|
||||
UCHAR Flag;
|
||||
|
||||
// Disable ACPI trapping
|
||||
Flag = ACPI_Trapping(0);
|
||||
|
||||
// Get ACPI Status
|
||||
ACPI_Bar = ISA_Hdr[BAR5/4].Value_LO;
|
||||
|
||||
(UCHAR)ACPI_Bar = GPE0_STS_OFS;
|
||||
GPE_Status = in_32(ACPI_Bar);
|
||||
|
||||
// Don't clear PIC status
|
||||
GPE_Status &= ~1;
|
||||
|
||||
|
||||
msgp[1] = GPE_Status;
|
||||
|
||||
|
||||
(UCHAR)ACPI_Bar = PM1_STS_OFS;
|
||||
PM1_Status = in_16(ACPI_Bar);
|
||||
|
||||
|
||||
// Enable ACPI trapping
|
||||
if (Flag) {
|
||||
ACPI_Trapping(1);
|
||||
}
|
||||
|
||||
msgp[2] = (ULONG)PM1_Status;
|
||||
|
||||
return (PM1_Status || GPE_Status);
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
// Enable PM logic
|
||||
//***********************************************************************
|
||||
void Enable_PME_Event(UCHAR EnableFlag, UCHAR Pm1Bit, UCHAR PmeBit, USHORT Attributes)
|
||||
{ ULONG Gpe, Pm1, bmGPE0;
|
||||
USHORT ACPI_Bar, bmPM1;
|
||||
UCHAR Flag;
|
||||
static UCHAR pme_instance = 0;
|
||||
static UCHAR PM1_Instance[11] = {0,0,0,0,0,0,0,0,0,0,0};
|
||||
static UCHAR PME_Instance[8] = {0,0,0,0,0,0,0,0};
|
||||
static ULONG GPE0_Masks[] = { // Maps PME # to GPE0 bits
|
||||
0x00010000,
|
||||
0x00020000,
|
||||
0x00040000,
|
||||
0x00080000,
|
||||
0x00100000,
|
||||
0x00200000,
|
||||
0x40000000,
|
||||
0x80000000,
|
||||
};
|
||||
|
||||
bmPM1 = 0;
|
||||
bmGPE0 = 0L;
|
||||
if (Attributes & PM1) {
|
||||
bmPM1 = 1 << Pm1Bit;
|
||||
|
||||
if (EnableFlag) {
|
||||
PM1_Instance[Pm1Bit]++;
|
||||
} else {
|
||||
if (PM1_Instance[Pm1Bit]) {
|
||||
// If there are still registrations for this PM1 bit...
|
||||
if (--PM1_Instance[Pm1Bit]) {
|
||||
// then don't turn disable it
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Error:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Attributes & GPE) {
|
||||
bmGPE0 = GPE0_Masks[PmeBit];
|
||||
if (EnableFlag) {
|
||||
PME_Instance[PmeBit]++;
|
||||
} else {
|
||||
if (PME_Instance[PmeBit]) {
|
||||
// If there are still registrations for this GEP0 bit...
|
||||
if (--PME_Instance[PmeBit]) {
|
||||
// then don't turn disable it
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Error:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!(Attributes & NO_ASMI)) {
|
||||
// Keep a count of PME events.
|
||||
// Once all have been de-registered, turn off PM_ASMI bit.
|
||||
if (EnableFlag) {
|
||||
if (Attributes & PME) {
|
||||
pme_instance++;
|
||||
}
|
||||
// Enable ASMIs from Power Management logic
|
||||
Control_MDD_SMI(EnableFlag, PM_ASMI_EN);
|
||||
} else {
|
||||
if (Attributes & PME) {
|
||||
if (pme_instance != 0) {
|
||||
if (--pme_instance == 0) {
|
||||
// Disable ASMIs from Power Management logic
|
||||
Control_MDD_SMI(0, PM_ASMI_EN);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// See if we want to enable the approriate bits in PM1_EN and GPE0_EN
|
||||
// if set to NO_ENALE we don't enable (Used by ACPI as the OS controls)
|
||||
if (!(Attributes & NO_ENABLE)) {
|
||||
// Disable ACPI trapping
|
||||
Flag = ACPI_Trapping(0);
|
||||
|
||||
// Get ACPI base address
|
||||
ACPI_Bar = ISA_Hdr[BAR5/4].Value_LO;
|
||||
|
||||
if (bmPM1) {
|
||||
// Must do 32-bit I/O to avoid shadow register bug (IAeng00003062)
|
||||
(UCHAR)ACPI_Bar = 0x00;
|
||||
Pm1 = in_32(ACPI_Bar);
|
||||
if (EnableFlag) {
|
||||
Pm1 |= (ULONG)bmPM1 << 16;
|
||||
} else {
|
||||
Pm1 &= ~((ULONG)bmPM1 << 16);
|
||||
}
|
||||
out_32(ACPI_Bar, Pm1);
|
||||
|
||||
// Serialize the previous I/O write
|
||||
in_16(ACPI_Bar);
|
||||
|
||||
// Clear spurious status
|
||||
(UCHAR)ACPI_Bar = PM1_STS_OFS;
|
||||
out_32(ACPI_Bar, (ULONG)Pm1);
|
||||
}
|
||||
|
||||
if (bmGPE0) {
|
||||
(UCHAR)ACPI_Bar = GPE0_EN_OFS;
|
||||
Gpe = in_32(ACPI_Bar);
|
||||
if (EnableFlag) {
|
||||
Gpe |= bmGPE0;
|
||||
} else {
|
||||
Gpe &= ~bmGPE0;
|
||||
}
|
||||
out_32(ACPI_Bar, Gpe);
|
||||
// Serialize the previous I/O write
|
||||
in_32(ACPI_Bar);
|
||||
|
||||
// Clear spurious status
|
||||
(UCHAR)ACPI_Bar = GPE0_STS_OFS;
|
||||
out_32(ACPI_Bar, Gpe);
|
||||
}
|
||||
|
||||
// Serialize the previous I/O write
|
||||
in_32(ACPI_Bar);
|
||||
|
||||
// Re-enable ACPI trapping
|
||||
if (Flag) {
|
||||
ACPI_Trapping(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
226
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/mdd.h
vendored
Executable file
226
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/mdd.h
vendored
Executable file
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
// ATA
|
||||
#define MSR_LBAR_ATA 0x0008
|
||||
|
||||
|
||||
// Diverse Integration Logic
|
||||
|
||||
#define MSR_MAST_CONF 0x0001
|
||||
#define NON_COH_RD (1L << 12)
|
||||
#define NON_COH_WR (1L << 13)
|
||||
|
||||
#define LBAR_EN (1 << 0)
|
||||
#define NOR_NAND (1 << 1)
|
||||
#define MEM_IO (1 << 2)
|
||||
#define LBAR_IO_MASK 0x0001FFF0
|
||||
#define LBAR_MEM_MASK 0xFFFFF000
|
||||
|
||||
|
||||
#define MSR_LBAR_IRQ 0x0008
|
||||
#define MSR_LBAR_KEL1 0x0009
|
||||
#define MSR_LBAR_KEL2 0x000A
|
||||
#define MSR_LBAR_SMB 0x000B
|
||||
|
||||
#define MSR_LBAR_GPIO 0x000C
|
||||
#define GPIO_LOW_BANK_SELECT 0x00
|
||||
#define GPIO_HIGH_BANK_SELECT 0x80
|
||||
#define GPIO_OUTPUT_VALUE 0x00
|
||||
#define GPIO_OUTPUT_ENABLE 0x04
|
||||
#define GPIO_OUTPUT_OPENDRAIN 0x08
|
||||
#define GPIO_OUTPUT_INVERT 0x0C
|
||||
#define GPIO_OUT_AUX1_SELECT 0x10
|
||||
#define GPIO_OUT_AUX2_SELECT 0x14
|
||||
#define GPIO_PULLUP_ENABLE 0x18
|
||||
#define GPIO_PULLDOWN_ENABLE 0x1C
|
||||
#define GPIO_INPUT_ENABLE 0x20
|
||||
#define GPIO_INPUT_INVERT 0x24
|
||||
#define GPIO_IN_FILTER_ENABLE 0x28
|
||||
#define GPIO_IN_EVENTCOUNT 0x2C
|
||||
#define GPIO_READ_BACK 0x30
|
||||
#define GPIO_IN_AUX1_SELECT 0x34
|
||||
#define GPIO_EVENTS_ENABLE 0x38
|
||||
#define GPIO_LOCK_ENABLE 0x3C
|
||||
#define LKOV (1 < 0)
|
||||
#define LKOE (1 < 1)
|
||||
#define LKOD (1 < 2)
|
||||
#define LKOI (1 < 3)
|
||||
#define LKA1 (1 < 4)
|
||||
#define LKA2 (1 < 5)
|
||||
#define LKPU (1 < 6)
|
||||
#define LKPD (1 < 7)
|
||||
#define LKIE (1 < 8)
|
||||
#define LKII (1 < 9)
|
||||
#define LKFE (1 < 10)
|
||||
#define LKEE (1 < 11)
|
||||
#define LKIA (1 < 12)
|
||||
#define LKIP (1 < 13)
|
||||
#define LKPE (1 < 14)
|
||||
#define LKNE (1 < 15)
|
||||
#define GPIO_POSEDGE_ENABLE 0x40
|
||||
#define GPIO_NEGEDGE_ENABLE 0x44
|
||||
#define GPIO_POSEDGE_STATUS 0x48
|
||||
#define GPIO_NEGEDGE_STATUS 0x4C
|
||||
|
||||
// GPIO IRQ Mapper
|
||||
#define GPIO_MAPPER_X 0xE0
|
||||
#define GPIO_MAPPER_Y 0xE4
|
||||
#define GPIO_MAPPER_Z 0xE8
|
||||
#define GPIO_MAPPER_W 0xEC
|
||||
|
||||
// Digital Filter
|
||||
#define GPIO_FILTER_AMOUNT 0x50
|
||||
#define GPIO_FILTER_COUNT 0x52
|
||||
#define GPIO_EVENT_COUNT 0x54
|
||||
#define GPIO_EVENT_COMPARE 0x56
|
||||
|
||||
#define GPIO6_FILTER_AMOUNT 0xD0
|
||||
#define GPIO7_FILTER_AMOUNT 0xD8
|
||||
|
||||
#define GPIO_FILTER_SELECT0 0xF0
|
||||
#define GPIO_FILTER_SELECT1 0xF1
|
||||
#define GPIO_FILTER_SELECT2 0xF2
|
||||
#define GPIO_FILTER_SELECT3 0xF3
|
||||
#define GPIO_FILTER_SELECT4 0xF4
|
||||
#define GPIO_FILTER_SELECT5 0xF5
|
||||
#define GPIO_FILTER_SELECT6 0xF6
|
||||
#define GPIO_FILTER_SELECT7 0xF7
|
||||
|
||||
|
||||
|
||||
|
||||
#define MSR_LBAR_MFGPT 0x000D
|
||||
// I/O offsets relative to MFGPT LBAR
|
||||
#define MFGPT_CMP1 0x00
|
||||
#define MFGPT_CMP2 0x02
|
||||
#define MFGPT_COUNTER 0x04
|
||||
#define MFGPT_SETUP 0x06
|
||||
|
||||
#define MFGPT_OFFSET 8
|
||||
|
||||
#define MSR_LBAR_ACPI 0x000E
|
||||
#define MSR_LBAR_PMS 0x000F
|
||||
#define MSR_LBAR_FLSH0 0x0010
|
||||
#define MSR_LBAR_FLSH1 0x0011
|
||||
#define MSR_LBAR_FLSH2 0x0012
|
||||
#define MSR_LBAR_FLSH3 0x0013
|
||||
#define MSR_LEG_IO 0x0014
|
||||
#define RESET_SHUT_EN (0x80000000L)
|
||||
#define UART1_SHIFT (16)
|
||||
#define UART2_SHIFT (20)
|
||||
#define UART_MASK (0x07)
|
||||
#define UART_IO_MASK (0x03)
|
||||
#define UART_EN (0x04)
|
||||
#define MSR_PIN_OPTS 0x0015
|
||||
#define PIN_OPT_IDE (1 << 0)
|
||||
#define MSR_SOFT_IRQ 0x0016
|
||||
#define MSR_SOFT_RESET 0x0017
|
||||
#define MSR_AC_DMA 0x0019
|
||||
|
||||
#define MSR_KEL_CNTRL 0x001F
|
||||
#define KEL_SNOOP (1 << 0)
|
||||
#define KEL_EER (1 << 1)
|
||||
#define KEL_PRTA_EN (1 << 4)
|
||||
|
||||
|
||||
// IRQ Mask & Mapper (from MDD Specification)
|
||||
#define MSR_IRQM_YLOW 0x0020
|
||||
#define MSR_IRQM_YHIGH 0x0021
|
||||
#define MSR_IRQM_ZLOW 0x0022
|
||||
#define MSR_IRQM_ZHIGH 0x0023
|
||||
#define MSR_IRQM_PRIM 0x0024
|
||||
#define MSR_IRQM_LPC 0x0025
|
||||
#define MSR_IRQM_LXIRR 0x0026
|
||||
#define MSR_IRQM_HXIRR 0x0027
|
||||
#define MSR_MFGPT_IRQ 0x0028
|
||||
#define MSR_MFGPT_NR 0x0029
|
||||
#define MSR_MFGPT_CLR_SETUP 0x002B
|
||||
|
||||
#define MSR_FLOP_S3F2 0x0030
|
||||
#define MSR_FLOP_S3F7 0x0031
|
||||
#define MSR_FLOP_S372 0x0032
|
||||
#define MSR_FLOP_S377 0x0033
|
||||
#define MSR_PIC_SHADOW 0x0034
|
||||
#define MSR_PIT_SHADOW 0x0036
|
||||
|
||||
// UART's
|
||||
#define MSR_UART1_MOD 0x0038
|
||||
#define MSR_UART1_DONG 0x0039
|
||||
#define MSR_UART1_CONF 0x003A
|
||||
#define UART_SOFT_RESET (0x01L)
|
||||
#define UART_DEVEN (0x02L)
|
||||
#define UART_FREEZE (0x04L)
|
||||
#define UART_TEST (0x08L)
|
||||
#define UART_EXT_BANKS (0x10L)
|
||||
#define MSR_UART2_MOD 0x003C
|
||||
#define MSR_UART2_DONG 0x003D
|
||||
#define MSR_UART2_CONF 0x003E
|
||||
|
||||
#define MSR_DMA_MAP 0x0040
|
||||
#define MSR_DMA_SHAD0 0x0041
|
||||
#define MSR_DMA_SHAD1 0x0042
|
||||
#define MSR_DMA_SHAD2 0x0043
|
||||
#define MSR_DMA_SHAD3 0x0044
|
||||
#define MSR_DMA_SHAD4 0x0045
|
||||
#define MSR_DMA_SHAD5 0x0046
|
||||
#define MSR_DMA_SHAD6 0x0047
|
||||
#define MSR_DMA_SHAD7 0x0048
|
||||
#define MSR_DMA_MSK_SHAD 0x0049
|
||||
|
||||
// LPC
|
||||
#define MSR_LPC_SIRQ 0x004E
|
||||
|
||||
|
||||
|
||||
// MSR_SMI
|
||||
#define HLT_ASMI_EN (1L << 0)
|
||||
#define SHUTDOWN_ASMI_EN (1L << 1)
|
||||
#define KEL_ASMI_EN (1L << 2)
|
||||
#define PIC_ASMI_EN (1L << 3)
|
||||
#define PM_ASMI_EN (1L << 4)
|
||||
#define INIT_K_EN (1L << 5)
|
||||
#define A20_P_EN (1L << 6)
|
||||
#define INIT_P_EN (1L << 7)
|
||||
#define UART1_SSMI_EN (1L << 8)
|
||||
#define UART2_SSMI_EN (1L << 9)
|
||||
#define RESERVED_EN (1L << 10)
|
||||
#define LPC_SSMI_EN (1L << 11)
|
||||
#define DMA_SSMI_EN (1L << 12)
|
||||
#define A20_K_EN (1L << 13)
|
||||
#define PM2_CNT_SSMI_EN (1L << 14)
|
||||
#define PM1_CNT_SSMI_EN (1L << 15)
|
||||
|
||||
#define HLT_ASMI_STAT (1L << 32)
|
||||
#define SHUTDOWN_ASMI_STAT (1L << 33)
|
||||
#define KEL_ASMI_STAT (1L << 34)
|
||||
#define PIC_ASMI_STAT (1L << 35)
|
||||
#define PM_ASMI_STAT (1L << 36)
|
||||
#define INIT_K_STAT (1L << 37)
|
||||
#define A20_P_STAT (1L << 38)
|
||||
#define INIT_P_STAT (1L << 39)
|
||||
#define UART1_SSMI_STAT (1L << 40)
|
||||
#define UART2_SSMI_STAT (1L << 41)
|
||||
#define RESERVED_STAT (1L << 42)
|
||||
#define LPC_SSMI_STAT (1L << 43)
|
||||
#define DMA_SSMI_STAT (1L << 44)
|
||||
#define A20_K_STAT (1L << 45)
|
||||
#define PM2_CNT_SSMI_STAT (1L << 46)
|
||||
#define PM1_CNT_SSMI_STAT (1L << 47)
|
||||
|
||||
393
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/message.asm
vendored
Executable file
393
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/message.asm
vendored
Executable file
@@ -0,0 +1,393 @@
|
||||
;
|
||||
; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
;
|
||||
; This library is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU Lesser General Public License as
|
||||
; published by the Free Software Foundation; either version 2.1 of the
|
||||
; License, or (at your option) any later version.
|
||||
;
|
||||
; This code is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
; Lesser General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU Lesser General
|
||||
; Public License along with this library; if not, write to the
|
||||
; Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
; Boston, MA 02111-1307 USA
|
||||
;
|
||||
;* Function: *
|
||||
;* Implements message handling routines
|
||||
|
||||
include SYSMGR.INC
|
||||
include VSA2.INC
|
||||
|
||||
|
||||
|
||||
.model tiny,c
|
||||
.586p
|
||||
.CODE
|
||||
|
||||
externdef SysMgr_VSM: dword
|
||||
externdef MsgPacket: dword
|
||||
externdef VSM_ListHead: dword
|
||||
externdef Current_VSM: dword
|
||||
|
||||
externdef Events: EVENT_ENTRY
|
||||
externdef Sys_Exit: proc
|
||||
externdef pascal Schedule_VSM: proc
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; This routine is called from the System Manager to enter a message
|
||||
; packet into a VSM's message queue.
|
||||
;
|
||||
; Input:
|
||||
; To_VSM = Flat ptr to VSM to which message is to be sent
|
||||
; MsgCode = Priority::Message
|
||||
; From_VSM = value to be put in Async_VSM field
|
||||
; MsgPacket contains the message parameters
|
||||
;***********************************************************************
|
||||
Send_Message proc pascal uses di si \
|
||||
From_VSM: dword, \
|
||||
To_VSM: dword, \
|
||||
MsgCode: dword
|
||||
|
||||
mov edi, [To_VSM]
|
||||
cmp edi, [SysMgr_VSM] ; Don't send messages to SysMgr
|
||||
je short Exit
|
||||
|
||||
mov eax, [MsgCode]
|
||||
lea si, [MsgPacket]
|
||||
mov ebx, [From_VSM]
|
||||
call Insert_Msg
|
||||
Exit: ret
|
||||
|
||||
Send_Message endp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; This routine enters a message packet into a VSM's message queue.
|
||||
;
|
||||
; Input:
|
||||
; EAX = Priority::Message
|
||||
; EBX = From_VSM
|
||||
; EDI = To_VSM
|
||||
; SI = Ptr to message packet
|
||||
;***********************************************************************
|
||||
Insert_Msg proc
|
||||
|
||||
cld
|
||||
|
||||
push ebx ; Save From_VSM
|
||||
|
||||
; Get ptr to the head of the message queue
|
||||
movzx ebx, fs:(VSM_Header PTR [edi]).SysStuff.Qhead
|
||||
|
||||
; Compute ptr to the next available message queue entry
|
||||
lea dx, [bx+sizeof(Message)]
|
||||
cmp dx, fs:(VSM_Header PTR [edi]).SysStuff.EndMsgQ
|
||||
jb short Check_Q_Overflow
|
||||
mov dx, OFFSET VSM_Header.SysStuff.MsgQueue
|
||||
Check_Q_Overflow:
|
||||
|
||||
; Is Qhead == Qtail ?
|
||||
cmp dx, fs:(VSM_Header PTR [edi]).SysStuff.Qtail
|
||||
jne short UpdateQueueHead
|
||||
|
||||
; Yes, then message queue has overflowed
|
||||
mov [si+8], eax ; Store previous message into Param2
|
||||
mov ax, MSG_QUEUE_OVERFLOW ; Replace previous message
|
||||
mov dx, bx ; Qhead = old Qhead
|
||||
UpdateQueueHead:
|
||||
mov fs:(VSM_Header PTR [edi]).SysStuff.Qhead, dx
|
||||
|
||||
pop edx ; From_VSM
|
||||
push edi ; Parameter to Schedule_VSM() below
|
||||
|
||||
; Store the message into the VSM's message queue.
|
||||
; NOTE: This code is dependent on "#typedef Message"
|
||||
add edi, ebx
|
||||
stosd [edi] ; Priority::Message
|
||||
|
||||
mov eax, edx ; From_VSM
|
||||
stosd [edi]
|
||||
|
||||
REPEAT MAX_MSG_PARAM
|
||||
lodsd ; Copy parameters to message queue
|
||||
stosd [edi]
|
||||
ENDM
|
||||
|
||||
|
||||
|
||||
; Sort messages by Priority
|
||||
if SUPPORT_PRIORITY
|
||||
|
||||
pop ebx ; To_VSM
|
||||
push ebx
|
||||
|
||||
push fs:(VSM_Header PTR [ebx]).SysStuff.Qhead
|
||||
BubbleSort:
|
||||
|
||||
; Get ptr to latest queue entry
|
||||
movzx esi, fs:(VSM_Header PTR [ebx]).SysStuff.Qhead
|
||||
sub esi, sizeof(Message)
|
||||
cmp si, OFFSET VSM_Header.SysStuff.MsgQueue
|
||||
jae short @f
|
||||
mov si, fs:(VSM_Header PTR [ebx]).SysStuff.EndMsgQ
|
||||
sub si, sizeof(Message)
|
||||
@@:
|
||||
cmp si, fs:(VSM_Header PTR [ebx]).SysStuff.Qtail
|
||||
je Bail
|
||||
|
||||
; Get ptr to previous queue entry
|
||||
lea edi, [esi-sizeof(Message)]
|
||||
cmp di, OFFSET VSM_Header.SysStuff.MsgQueue
|
||||
jae short @f
|
||||
mov di, fs:(VSM_Header PTR [ebx]).SysStuff.EndMsgQ
|
||||
sub di, sizeof(Message)
|
||||
@@:
|
||||
|
||||
mov fs:(VSM_Header PTR [ebx]).SysStuff.Qhead, di
|
||||
|
||||
; Add VSM base to ptrs
|
||||
add edi, ebx
|
||||
add esi, ebx
|
||||
|
||||
; Compare their priorities
|
||||
mov ax, fs:(Message PTR [esi]).Priority
|
||||
cmp ax, fs:(Message PTR [edi]).Priority
|
||||
jbe short Bail
|
||||
|
||||
|
||||
|
||||
; Swap the entries in the message queue
|
||||
mov cx, sizeof(Message)/4 ; Assumes entry is multiple of dword
|
||||
Interchange:
|
||||
mov eax, fs:[edi]
|
||||
xchg fs:[esi], eax
|
||||
stosd [edi]
|
||||
add esi, 4
|
||||
loop Interchange
|
||||
|
||||
jmp BubbleSort
|
||||
|
||||
|
||||
Bail:
|
||||
pop fs:(VSM_Header PTR [ebx]).SysStuff.Qhead
|
||||
|
||||
endif
|
||||
|
||||
|
||||
; Schedule the VSM to execute
|
||||
pop eax
|
||||
cmp eax, [SysMgr_VSM]
|
||||
je short Exit
|
||||
push eax
|
||||
call Schedule_VSM
|
||||
Exit:
|
||||
ret
|
||||
|
||||
|
||||
Insert_Msg endp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;************************************************************************
|
||||
;
|
||||
; Sends a message to each VSM of type VSM_Type (or all if VSM_ANY).
|
||||
; Called from HANDLERS.C
|
||||
;
|
||||
;************************************************************************
|
||||
Broadcast_Message proc pascal uses si di \
|
||||
MsgCode: word, \
|
||||
VSM_Type: word, \
|
||||
From_VSM: dword
|
||||
|
||||
mov edi, [VSM_ListHead] ; Get ptr to list of VSMs
|
||||
VSM_Loop:
|
||||
or edi, edi ; End of VSM list ?
|
||||
jz Exit_Broadcast
|
||||
|
||||
mov dx, [VSM_Type]
|
||||
mov ah, fs:(VSM_Header PTR [edi]).VSM_Type
|
||||
|
||||
cmp dl, VSM_ANY ; Schedule all VSMs ?
|
||||
je Schedule_It
|
||||
|
||||
test dh, (VSM_ALL_EXCEPT SHR 8)
|
||||
jz CheckType
|
||||
|
||||
cmp dl, ah ; Skip the one that matches
|
||||
je Skip_VSM
|
||||
jmp Schedule_It
|
||||
|
||||
CheckType:
|
||||
cmp dl, ah ; Is it the correct VSM ?
|
||||
jne Skip_VSM
|
||||
|
||||
Schedule_It:
|
||||
|
||||
cmp edi, [From_VSM] ; Is it the requesting VSM ?
|
||||
je Skip_VSM ; Yes, don't send to sender
|
||||
|
||||
push edi
|
||||
|
||||
movzx eax, [MsgCode] ; Send the message
|
||||
xor ebx, ebx
|
||||
lea si, [MsgPacket]
|
||||
|
||||
; EAX = Priority::Message
|
||||
; EBX = 00000000h (a broadcast is not a synchronous event)
|
||||
; SI = Ptr to message packet
|
||||
; EDI = Ptr to VSM header where message is to be sent
|
||||
call Insert_Msg
|
||||
pop edi
|
||||
|
||||
|
||||
Skip_VSM:
|
||||
mov edi, fs:(VSM_Header PTR [edi]).SysStuff.Flink
|
||||
jmp VSM_Loop
|
||||
|
||||
Exit_Broadcast:
|
||||
ret
|
||||
|
||||
Broadcast_Message endp
|
||||
|
||||
|
||||
|
||||
;************************************************************************
|
||||
; Broadcasts a message to one or more VSMs.
|
||||
;
|
||||
; Input:
|
||||
; EBX = message code (16 MSBs)
|
||||
; BH = Flags
|
||||
; BL = VSM_Type
|
||||
; ECX = Param1
|
||||
; ESI = Param2
|
||||
; EDI = Param3
|
||||
;************************************************************************
|
||||
Sys_Broadcast proc
|
||||
|
||||
mov dx, bx ; Put VSM_Type::Flags into DX
|
||||
shr ebx, 16 ; Put message into BX
|
||||
|
||||
mov eax, esi
|
||||
lea si, [MsgPacket]
|
||||
mov [si+0], ecx
|
||||
mov [si+4], eax
|
||||
mov [si+8], edi
|
||||
|
||||
; Re-schedule the broadcasting VSM
|
||||
; RunFlag will be changed from RUN_FLAG_ACTIVE to RUN_FLAG_READY
|
||||
mov edi, [Current_VSM]
|
||||
push edi
|
||||
call Schedule_VSM
|
||||
; If RunFlag == RUN_FLAG_READY, Insert_Msg() won't schedule it again
|
||||
mov fs:(VSM_Header PTR [edi]).SysStuff.RunFlag, RUN_FLAG_BLOCKED
|
||||
|
||||
; Push parameters for call to Broadcast_Message()
|
||||
push bx ; Message code
|
||||
push dx ; VSM type
|
||||
push edi ; From_VSM
|
||||
|
||||
; Normally, the message is sent to the broadcasting VSM
|
||||
; after all VSMs have handled the broadcasted message.
|
||||
; There are two exceptions to this rule:
|
||||
; 1) VSM_NOT_SELF | <VSM type>
|
||||
; 2) VSM_ALL_EXCEPT | <self>
|
||||
test dh, (VSM_NOT_SELF SHR 8)
|
||||
jnz short Broadcast
|
||||
|
||||
test dh, (VSM_ALL_EXCEPT SHR 8)
|
||||
jz short SendToSelf
|
||||
cmp dl, fs:(VSM_Header PTR [edi]).VSM_Type
|
||||
je short Broadcast
|
||||
|
||||
SendToSelf:
|
||||
; Put callback address onto the scheduler stack
|
||||
mov eax, OFFSET BroadcastCallback
|
||||
push eax
|
||||
call Schedule_VSM
|
||||
|
||||
mov ax, BROADCAST_PRIORITY ; EAX = Priority::Message
|
||||
shl eax, 16
|
||||
mov ax, bx
|
||||
|
||||
mov edi, [SysMgr_VSM] ; EDI = To_VSM
|
||||
mov ebx, [Current_VSM] ; EBX = From_VSM
|
||||
call Insert_Msg
|
||||
|
||||
Broadcast:
|
||||
call Broadcast_Message
|
||||
|
||||
jmp Sys_Exit ; Exit w/o scheduling current VSM
|
||||
|
||||
Sys_Broadcast endp
|
||||
|
||||
|
||||
;************************************************************************
|
||||
; Control comes here when all VSMs have processed the broadcasted message.
|
||||
; Copies the broadcasted message from SysMgr's message queue to the
|
||||
; broadcasting VSM's message queue.
|
||||
;************************************************************************
|
||||
BroadcastCallback proc
|
||||
ASSUME DI: PTR VSM_Header
|
||||
ASSUME BX: PTR Message
|
||||
|
||||
; Point BX to parameters in SysMgr's message queue head
|
||||
xor di, di
|
||||
mov bx, [di].SysStuff.Qhead
|
||||
sub bx, sizeof(Message)
|
||||
cmp bx, OFFSET VSM_Header.SysStuff.MsgQueue
|
||||
jb short BadMsgStack
|
||||
mov [di].SysStuff.Qhead, bx
|
||||
|
||||
mov eax, dword ptr [bx].Msg ; Get Priority::Message
|
||||
mov edi, [bx].From_VSM ; To_VSM (the VSM it was originally from)
|
||||
|
||||
lea si, [bx].Param
|
||||
xor ebx, ebx ; From_VSM (asynchronous)
|
||||
call Insert_Msg
|
||||
BadMsgStack:
|
||||
ret
|
||||
|
||||
ASSUME BX: NOTHING
|
||||
ASSUME DI: NOTHING
|
||||
|
||||
BroadcastCallback endp
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Passes an event to the next VSM registered for this event
|
||||
; NOTE: This system call is now obsolete.
|
||||
;***********************************************************************
|
||||
Sys_PassEvent proc
|
||||
|
||||
jmp Sys_Exit ; Exit to VSM dispatcher
|
||||
|
||||
Sys_PassEvent endp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
END
|
||||
|
||||
|
||||
|
||||
500
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/mfgpt.c
vendored
Executable file
500
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/mfgpt.c
vendored
Executable file
@@ -0,0 +1,500 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//*****************************************************************************
|
||||
//* This file contains code specific to CS5536 MFGPTs
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
#include "VSA2.H"
|
||||
#include "SYSMGR.H"
|
||||
#include "PROTOS.H"
|
||||
#include "MDD.H"
|
||||
#include "MAPPER.H"
|
||||
#include "TIMER.H"
|
||||
|
||||
// External variables:
|
||||
extern ULONG MDD_Base;
|
||||
|
||||
// Local variables:
|
||||
USHORT MFGPT_Base=0;
|
||||
ULONG MFGPT_LBAR[2];
|
||||
|
||||
|
||||
|
||||
// NOTE: Timers that use the 32KHz clock interfere with LPC DMA (see PBZ 709)
|
||||
|
||||
// Clock Prescalar Period
|
||||
#define TIMER_SETUP (MFGPT_SCALE_1K | MFGPT_CMP1MODE | MFGPT_CLK_SEL) // 14 MHz 1024 71 us
|
||||
#define STDBY_SETUP (MFGPT_SCALE_32 | MFGPT_CMP1MODE) // 32 KHz 32 1 ms
|
||||
#define PWM_SETUP (MFGPT_SCALE_32 | MFGPT_CMP1GE) // 32 KHz 32 1 ms
|
||||
TIMERS TimerInfo[] = {
|
||||
// # Z Mapper Setup
|
||||
// Save for OS (Linux) use { 0, Z_IRQ_MFGPT_04, PWM_SETUP},
|
||||
{ 1, Z_IRQ_MFGPT_15, PWM_SETUP},
|
||||
{ 2, Z_IRQ_MFGPT_26, PWM_SETUP},
|
||||
{ 3, Z_IRQ_MFGPT_37, TIMER_SETUP},
|
||||
// Save for OS (Linux) use { 4, Z_IRQ_MFGPT_04, TIMER_SETUP},
|
||||
{ 5, Z_IRQ_MFGPT_15, TIMER_SETUP},
|
||||
{ 6, Z_IRQ_MFGPT_26, STDBY_SETUP},
|
||||
{ 7, Z_IRQ_MFGPT_37, PWM_SETUP},
|
||||
};
|
||||
#define NUM_MFGPTS (sizeof(TimerInfo)/sizeof(TIMERS)) // Number of MFGPTs available
|
||||
|
||||
//************************************************************************************
|
||||
// Saves the MFGPT LBAR setting and enables the LBAR
|
||||
//************************************************************************************
|
||||
void Enable_MFGPT_LBAR()
|
||||
{ ULONG Tmp;
|
||||
int i;
|
||||
|
||||
// Get MFGPT LBAR
|
||||
Read_MSR(MDD_Base + MSR_LBAR_MFGPT, MFGPT_LBAR);
|
||||
|
||||
// Has the MFGPT base address changed?
|
||||
if (MFGPT_Base != (USHORT)MFGPT_LBAR[0]) {
|
||||
// Yes, record the new base address of MFGPT
|
||||
MFGPT_Base = (USHORT)MFGPT_LBAR[0];
|
||||
|
||||
// Update the individual timer base addresses
|
||||
for (i = 0; i < NUM_MFGPTS; i++) {
|
||||
TimerInfo[i].TimerBase = MFGPT_Base + TimerInfo[i].Timer*MFGPT_OFFSET;
|
||||
}
|
||||
}
|
||||
|
||||
// Save the current LBAR enable
|
||||
Tmp = MFGPT_LBAR[1];
|
||||
|
||||
// Enable the LBAR
|
||||
MFGPT_LBAR[1] |= LBAR_EN;
|
||||
Write_MSR(MDD_Base + MSR_LBAR_MFGPT, MFGPT_LBAR);
|
||||
MFGPT_LBAR[1] = Tmp;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//************************************************************************************
|
||||
// Restores the MFGPT LBAR
|
||||
//************************************************************************************
|
||||
void Restore_MFGPT_LBAR()
|
||||
{
|
||||
// Restore MFGPT LBAR
|
||||
Write_MSR(MDD_Base + MSR_LBAR_MFGPT, MFGPT_LBAR);
|
||||
}
|
||||
|
||||
|
||||
//************************************************************************************
|
||||
// Checks for MFGPT events
|
||||
// Returns a mask of which timer(s) have expired
|
||||
//************************************************************************************
|
||||
USHORT CS5536_MFGPT_Handler(void)
|
||||
{ USHORT Setup, Status, Accum_Status=0, i;
|
||||
register TIMERS * TimerPtr;
|
||||
|
||||
Enable_MFGPT_LBAR();
|
||||
|
||||
for (i = 0; i < NUM_MFGPTS; i++) {
|
||||
|
||||
TimerPtr = &TimerInfo[i];
|
||||
|
||||
// Get timer status
|
||||
Setup = TimerPtr->TimerBase + MFGPT_SETUP;
|
||||
Status = in_16(Setup);
|
||||
if (Status & MFGPT_INITED) {
|
||||
out_16(Setup, Status);
|
||||
}
|
||||
|
||||
// Check if MFGPT is reserved for EVENT_PWM
|
||||
if(TimerPtr->Setup == PWM_SETUP) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If timer is enabled and expired...
|
||||
Status &= MFGPT_ENABLE | MFGPT_COMPARE1;
|
||||
if (Status == (MFGPT_ENABLE | MFGPT_COMPARE1)) {
|
||||
// disable the timer
|
||||
out_16(Setup, Status & (~MFGPT_ENABLE));
|
||||
// record timer event
|
||||
Accum_Status |= TimerPtr->Mask;
|
||||
}
|
||||
}
|
||||
|
||||
// Restore the MFGPT LBAR
|
||||
Restore_MFGPT_LBAR();
|
||||
|
||||
return Accum_Status;
|
||||
}
|
||||
|
||||
//************************************************************************************
|
||||
// Initializes a single MFGPT
|
||||
//************************************************************************************
|
||||
void Init_Timer(TIMERS * TimerPtr)
|
||||
{ USHORT Setup, TimerKHz;
|
||||
ULONG MicrosPerCount;
|
||||
|
||||
TimerPtr->TimerBase = MFGPT_Base + TimerPtr->Timer*MFGPT_OFFSET;
|
||||
|
||||
TimerPtr->Mask = 1 << TimerPtr->Timer;
|
||||
|
||||
Setup = TimerPtr->Setup;
|
||||
|
||||
// Compute microseconds / tick
|
||||
MicrosPerCount = 1000L << (Setup & 0xF);
|
||||
TimerKHz = 32;
|
||||
if (Setup & MFGPT_CLK_SEL) {
|
||||
TimerKHz = 14318;
|
||||
}
|
||||
TimerPtr->Period = (USHORT)(MicrosPerCount / TimerKHz);
|
||||
|
||||
// Initialize the timer
|
||||
out_16(TimerPtr->TimerBase + MFGPT_SETUP, Setup);
|
||||
|
||||
// NOTE: Counter resets to 0 when Counter == Comparator2 register
|
||||
out_32(TimerPtr->TimerBase + MFGPT_CMP1, 0xFFFFFFFF);
|
||||
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
// Marks a MFGPT as available
|
||||
//***********************************************************************
|
||||
void pascal MarkTimerAvailable(USHORT Timer)
|
||||
{ USHORT i;
|
||||
|
||||
for (i = 0; i < NUM_MFGPTS; i++) {
|
||||
if (TimerInfo[i].Timer == Timer) {
|
||||
TimerInfo[i].Interval = 0x00000000;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Log_Error("Invalid timer: %d.", Timer);
|
||||
}
|
||||
|
||||
|
||||
//************************************************************************************
|
||||
// Initializes the MFGPT timers to be used for EVENT_TIMER
|
||||
//************************************************************************************
|
||||
void Init_MFGPT(void)
|
||||
{ ULONG MsrAddr, IRQ_Enables;
|
||||
USHORT i;
|
||||
register TIMERS * TimerPtr;
|
||||
|
||||
Enable_MFGPT_LBAR();
|
||||
|
||||
// Get current MFGPT IRQ mask
|
||||
MsrAddr = MDD_Base;
|
||||
(USHORT)MsrAddr = MSR_MFGPT_IRQ;
|
||||
IRQ_Enables = Read_MSR_LO(MsrAddr);
|
||||
|
||||
for (i = 0; i < NUM_MFGPTS; i++) {
|
||||
|
||||
TimerPtr = &TimerInfo[i];
|
||||
|
||||
// Initialize a MFGPT
|
||||
Init_Timer(TimerPtr);
|
||||
|
||||
// Mark timer as available
|
||||
MarkTimerAvailable(TimerPtr->Timer);
|
||||
|
||||
// Route Compare 1 events to SMI
|
||||
IRQZ_Mapper(TimerPtr->Mapper, 2);
|
||||
|
||||
// Enable timer event
|
||||
IRQ_Enables |= TimerPtr->Mask;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Restore the MFGPT LBAR
|
||||
Restore_MFGPT_LBAR();
|
||||
|
||||
|
||||
// Enable MFGPT SMIs
|
||||
Write_MSR_LO(MsrAddr, IRQ_Enables);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Disables a millisecond timer
|
||||
//***********************************************************************
|
||||
void DisableMsTimer_5536(USHORT Timer)
|
||||
{ USHORT Setup, i;
|
||||
|
||||
Enable_MFGPT_LBAR();
|
||||
|
||||
|
||||
for (i = 0; i < NUM_MFGPTS; i++) {
|
||||
if (TimerInfo[i].Timer == Timer) {
|
||||
// Mark timer as available
|
||||
MarkTimerAvailable(Timer);
|
||||
|
||||
// Clear timer event and disable timer
|
||||
Setup = TimerInfo[i].TimerBase + MFGPT_SETUP;
|
||||
out_16(Setup, MFGPT_COMPARE1 | MFGPT_COMPARE2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Restore the MFGPT LBAR
|
||||
Restore_MFGPT_LBAR();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Allocates a h/w timer for the specified interval
|
||||
// Returns the timer # allocated else 0xFFFF
|
||||
//***********************************************************************
|
||||
USHORT AllocateTimer_5536(ULONG Interval, UCHAR Attributes)
|
||||
{ UCHAR i, Exact = 0, Unused=0, Compat=0, Mask;
|
||||
register TIMERS * TimerPtr;
|
||||
|
||||
// Find the MFGPT whose timebase is the best-match
|
||||
for (i = 0; i < NUM_MFGPTS; i++) {
|
||||
TimerPtr = &TimerInfo[i];
|
||||
|
||||
// Don't use timers reserved for EVENT_PWM
|
||||
if (TimerPtr->Setup == PWM_SETUP) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Attributes & (FOR_STANDBY >> 24)) {
|
||||
// Timers used for PM must be in the 32 KHz domain
|
||||
if (TimerPtr->Setup & MFGPT_CLK_SEL) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (TimerPtr->Timer >= 6) {
|
||||
// Timers 6 & 7 are reserved for PM
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Mask = (UCHAR)TimerPtr->Mask;
|
||||
|
||||
// Is timer unused?
|
||||
if (TimerPtr->Interval == 0x00000000) {
|
||||
Unused |= Mask;
|
||||
}
|
||||
|
||||
// Is timebase a perfect match?
|
||||
if ((Interval*1000 % TimerPtr->Period) == 0) {
|
||||
Exact |= Mask;
|
||||
}
|
||||
|
||||
// Is timebase compatible?
|
||||
if (Interval*1000 >= TimerPtr->Period) {
|
||||
Compat |= Mask;
|
||||
}
|
||||
}
|
||||
|
||||
// Is there an UNUSED timer whose timebase is an exact match?
|
||||
if (!(Mask = (Unused & Exact))) {
|
||||
// No, is there an UNUSED timer that is compatible?
|
||||
if (!(Mask = (Unused & Compat))) {
|
||||
// No, is there ANY timer whose timebase is an exact match?
|
||||
if (!(Mask = Exact)) {
|
||||
// No, is there ANY timer that is compatible?
|
||||
if (!(Mask = Compat)) {
|
||||
// No timers are available
|
||||
return 0xFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return the MFGPT index
|
||||
Mask = 1 << BitScanReverse(Mask);
|
||||
for (i = 0; i < NUM_MFGPTS; i++) {
|
||||
if (TimerInfo[i].Mask == Mask) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Enables a millisecond timer
|
||||
//***********************************************************************
|
||||
UCHAR EnableMsTimer_5536(ULONG Interval, UCHAR Attributes)
|
||||
{ USHORT i, Count, TimerBase;
|
||||
ULONG MsrAddr, IRQ_Enables, TotalCounts, Roundoff;
|
||||
register TIMERS * TimerPtr;
|
||||
|
||||
// Get current MFGPT IRQ mask
|
||||
MsrAddr = MDD_Base;
|
||||
(USHORT)MsrAddr = MSR_MFGPT_IRQ;
|
||||
IRQ_Enables = Read_MSR_LO(MsrAddr);
|
||||
|
||||
// Allocate a h/w timer
|
||||
i = AllocateTimer_5536(Interval, Attributes);
|
||||
if (i == 0xFFFF) {
|
||||
Log_Error("Attempt to enable %d ms timer interval failed", Interval);
|
||||
return 0;
|
||||
}
|
||||
|
||||
TimerPtr = &TimerInfo[i];
|
||||
|
||||
// A timer was allocated, is it already in use?
|
||||
if (TimerPtr->Interval) {
|
||||
// Yes, does it need to be reprogrammed?
|
||||
if (Interval > TimerPtr->Interval) {
|
||||
// No, but since the timer has already been running for an
|
||||
// indeterminate period, the 1st interval will be shortened.
|
||||
return (UCHAR)TimerPtr->Timer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (Interval) {
|
||||
|
||||
Enable_MFGPT_LBAR();
|
||||
|
||||
// Get I/O address of this timer
|
||||
TimerBase = TimerPtr->TimerBase;
|
||||
|
||||
// The MFGPT document specifies the following sequence in order
|
||||
// to prevent any spurious resets, interrupt, or output events:
|
||||
// - Set Counter Enable bit to 0.
|
||||
// - Clear SMI enable in MSR_MFGPT_IRQ
|
||||
// - Update Count as desired
|
||||
// - When updates are completed, clear event bits
|
||||
// - Set SMI enable in MSR_MFGPT_IRQ
|
||||
// - Set Counter Enable bit to 1
|
||||
|
||||
// Does this timer need to be initialized again (e.g. after S3) ?
|
||||
if (!(in_16(TimerBase + MFGPT_SETUP) & MFGPT_INITED)) {
|
||||
// Initialize the timer
|
||||
Init_Timer(TimerPtr);
|
||||
}
|
||||
|
||||
// Set Counter Enable to 0
|
||||
out_16(TimerBase + MFGPT_SETUP, 0);
|
||||
|
||||
// Disable SMIs
|
||||
Write_MSR_LO(MsrAddr, 0x00000000);
|
||||
|
||||
// Scale the interval appropriately
|
||||
Roundoff = 0;
|
||||
if (TimerPtr->Period < 1000) {
|
||||
Roundoff = TimerPtr->Period;
|
||||
}
|
||||
TotalCounts = (Interval*1000 + Roundoff)/TimerPtr->Period;
|
||||
Count = (USHORT)TotalCounts;
|
||||
if (TotalCounts & 0xFFFF0000) {
|
||||
Count = 0xFFFF;
|
||||
}
|
||||
|
||||
// Record the timer's interval
|
||||
TimerPtr->Interval = ((ULONG)Count * TimerPtr->Period)/1000;
|
||||
|
||||
// Zero the counter
|
||||
out_16(TimerBase + MFGPT_COUNTER, 0x0000);
|
||||
|
||||
// Set Comparator1 to Count and Comparator2 to 0xFFFF
|
||||
out_32(TimerBase + MFGPT_CMP1, 0xFFFF0000L | Count);
|
||||
|
||||
// Clear timer event(s)
|
||||
out_16(TimerBase + MFGPT_SETUP, MFGPT_COMPARE1 | MFGPT_COMPARE2);
|
||||
|
||||
// Re-enable SMIs
|
||||
Write_MSR_LO(MsrAddr, IRQ_Enables);
|
||||
|
||||
// Set Counter Enable to 1
|
||||
out_16(TimerBase + MFGPT_SETUP, MFGPT_ENABLE);
|
||||
|
||||
// Restore the MFGPT LBAR
|
||||
Restore_MFGPT_LBAR();
|
||||
}
|
||||
|
||||
return (UCHAR)TimerPtr->Timer;
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Configures a MFGPT as a PWM signal generator
|
||||
//***********************************************************************
|
||||
void pascal Program_PWM(UCHAR Gpio, UCHAR Duty, USHORT Rate, UCHAR EnableFlag)
|
||||
{ USHORT i, Timer;
|
||||
register TIMERS * TimerPtr;
|
||||
|
||||
// Determine the MFGPT associated with the specified GPIO
|
||||
switch (Gpio) {
|
||||
case 5:
|
||||
Timer = 0;
|
||||
break;
|
||||
case 6:
|
||||
Timer = 1;
|
||||
break;
|
||||
case 7:
|
||||
Timer = 2;
|
||||
break;
|
||||
case 27:
|
||||
Timer = 7;
|
||||
break;
|
||||
default:
|
||||
Log_Error("EVENT_PWM is not supported on GPIO%d", Gpio);
|
||||
return;
|
||||
}
|
||||
|
||||
// Program the MFGPT to the specified rate and duty cycle
|
||||
for (i = 0; i < NUM_MFGPTS; i++) {
|
||||
|
||||
TimerPtr = &TimerInfo[i];
|
||||
|
||||
if (TimerPtr->Timer == Timer) {
|
||||
|
||||
// Check if MFGPT is reserved for EVENT_PWM
|
||||
if(TimerPtr->Setup != PWM_SETUP) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Enable the MFGPT LBAR
|
||||
Enable_MFGPT_LBAR();
|
||||
|
||||
// Clear this timer's SETUP register in case it has been used previously as a timer
|
||||
// Write_MSR_LO(MDD_Base + MSR_MFGPT_CLR_SETUP, TimerPtr->Mask);
|
||||
// out_16(TimerPtr->TimerBase + MFGPT_SETUP, PWM_SETUP);
|
||||
|
||||
|
||||
// Clamp duty cycle to 100%
|
||||
if (Duty > 100) {
|
||||
Duty = 100;
|
||||
}
|
||||
|
||||
// Program the Count registers
|
||||
out_16(TimerPtr->TimerBase + MFGPT_COUNTER, 0x0000);
|
||||
out_16(TimerPtr->TimerBase + MFGPT_CMP1, (USHORT)(((ULONG)Rate * Duty)/100));
|
||||
out_16(TimerPtr->TimerBase + MFGPT_CMP2, Rate);
|
||||
|
||||
// Enable the counter
|
||||
out_16(TimerPtr->TimerBase + MFGPT_SETUP, EnableFlag ? MFGPT_ENABLE: 0);
|
||||
|
||||
Restore_MFGPT_LBAR();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Log_Error("EVENT_PWM on GPIO%d failed because MFGPT%d is reserved.", Gpio, Timer);
|
||||
}
|
||||
|
||||
348
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/msr.asm
vendored
Executable file
348
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/msr.asm
vendored
Executable file
@@ -0,0 +1,348 @@
|
||||
;
|
||||
; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
;
|
||||
; This library is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU Lesser General Public License as
|
||||
; published by the Free Software Foundation; either version 2.1 of the
|
||||
; License, or (at your option) any later version.
|
||||
;
|
||||
; This code is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
; Lesser General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU Lesser General
|
||||
; Public License along with this library; if not, write to the
|
||||
; Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
; Boston, MA 02111-1307 USA
|
||||
;
|
||||
;* Function: *
|
||||
;* Routines related to MSRs.
|
||||
|
||||
include VSA2.INC
|
||||
include DESCR.INC
|
||||
|
||||
|
||||
.model tiny,c
|
||||
.586p
|
||||
.CODE
|
||||
|
||||
extern SMM_Header: SmiHeader
|
||||
|
||||
;***********************************************************************
|
||||
; Returns the high DWORD of an MSR.
|
||||
; Usage: HighMsrValue = Read_MSR_HI(Msr_Address);
|
||||
;***********************************************************************
|
||||
Read_MSR_HI proc pascal \
|
||||
Msr: dword
|
||||
|
||||
mov ecx, [Msr]
|
||||
rdmsr
|
||||
mov ax, dx
|
||||
shr edx, 16
|
||||
ret
|
||||
|
||||
Read_MSR_HI endp
|
||||
|
||||
;***********************************************************************
|
||||
; Writes the high DWORD of an MSR. The low DWORD is preserved.
|
||||
; Usage: Write_MSR_HI(Msr_Address, Data);
|
||||
;***********************************************************************
|
||||
Write_MSR_HI proc pascal \
|
||||
Msr: dword, \
|
||||
Data: dword
|
||||
|
||||
mov ecx, [Msr]
|
||||
rdmsr ; Get low 32 bits
|
||||
mov edx, [Data]
|
||||
wrmsr
|
||||
ret
|
||||
|
||||
Write_MSR_HI endp
|
||||
|
||||
;***********************************************************************
|
||||
; Returns the low DWORD of an MSR.
|
||||
; Usage: LowMsrValue = Read_MSR_LO(Msr_Address);
|
||||
;***********************************************************************
|
||||
Read_MSR_LO proc pascal \
|
||||
Msr: dword
|
||||
|
||||
mov ecx, [Msr]
|
||||
rdmsr
|
||||
mov edx, eax
|
||||
shr edx, 16
|
||||
ret
|
||||
|
||||
Read_MSR_LO endp
|
||||
|
||||
;***********************************************************************
|
||||
; Writes the low DWORD of an MSR. The high DWORD is preserved.
|
||||
; Usage: Write_MSR_LO(Msr_Address, Data);
|
||||
;***********************************************************************
|
||||
Write_MSR_LO proc pascal \
|
||||
Msr: dword, \
|
||||
Data: dword
|
||||
|
||||
mov ecx, [Msr]
|
||||
rdmsr ; Get high 32 bits
|
||||
mov eax, [Data]
|
||||
wrmsr
|
||||
ret
|
||||
|
||||
Write_MSR_LO endp
|
||||
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Returns an MSR value in a buffer.
|
||||
; Usage: Read_MSR(ULONG Msr, ULONG * Buffer);
|
||||
;***********************************************************************
|
||||
Read_MSR proc pascal \
|
||||
Msr: dword, \
|
||||
Buffer: PTR
|
||||
|
||||
mov ecx, [Msr]
|
||||
rdmsr
|
||||
|
||||
mov bx, [Buffer]
|
||||
mov [bx+0], eax
|
||||
mov [bx+4], edx
|
||||
ret
|
||||
|
||||
Read_MSR endp
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Writes an MSR.
|
||||
; Usage: Write_MSR(ULONG Msr, ULONG * Buffer);
|
||||
;***********************************************************************
|
||||
Write_MSR proc pascal \
|
||||
Msr: dword, \
|
||||
Buffer: PTR
|
||||
|
||||
mov ecx, [Msr]
|
||||
mov bx, [Buffer]
|
||||
mov eax, [bx+0]
|
||||
mov edx, [bx+4]
|
||||
wrmsr
|
||||
ret
|
||||
|
||||
Write_MSR endp
|
||||
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Parses MSR_MBIU_CAP of an MBIU and returns descriptor counts in
|
||||
; a byte buffer.
|
||||
;***********************************************************************
|
||||
Parse_Capabilities proc pascal \
|
||||
Msr: PTR, \
|
||||
Buffer: PTR
|
||||
|
||||
mov bx, [Msr]
|
||||
mov eax, [bx+0] ; Get 1st dword of CAPABILITIES
|
||||
mov edx, [bx+4] ; Get 2nd dword of CAPABILITIES
|
||||
mov bx, [Buffer]
|
||||
mov cl, 6 ; Number of P2D descriptors
|
||||
NxtCount:
|
||||
mov ch, al
|
||||
and ch, 3Fh ; 6 bits per field
|
||||
mov [bx], ch
|
||||
inc bx
|
||||
|
||||
shrd eax, edx, 6 ; Shift next field into LSBs
|
||||
shr edx, 6
|
||||
dec cl
|
||||
jnz NxtCount
|
||||
|
||||
mov ch, al ; Get NIOD_BM
|
||||
and ch, 3Fh
|
||||
mov [bx+1], ch
|
||||
|
||||
shr eax, 6 ; Get NIOD_SC
|
||||
mov ch, al
|
||||
and ch, 3Fh
|
||||
mov [bx+2], ch
|
||||
|
||||
shr eax, 9 ; Skip NCOH field
|
||||
mov ch, al
|
||||
and ch, 07h ; Get NPORTS
|
||||
mov [bx+3], ch
|
||||
|
||||
shr ax, 9 ; Get NSTAT_CNT
|
||||
and al, 07h
|
||||
mov [bx+4], al
|
||||
ret
|
||||
|
||||
Parse_Capabilities endp
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Extract the 3 main fields from a P2D descriptor
|
||||
;***********************************************************************
|
||||
Parse_Descriptor proc pascal uses edi \
|
||||
P2D_Type: byte, \
|
||||
Source: ptr, \
|
||||
Dest: ptr
|
||||
|
||||
mov bx, [Source]
|
||||
|
||||
mov ecx, [bx] ; Get low MSR
|
||||
mov eax, ecx
|
||||
mov edx, [bx+4] ; Get high MSR
|
||||
|
||||
cmp bl, IOD_BM
|
||||
je Descr_IO_BM
|
||||
|
||||
shl ecx, 12 ; Extract 1st field
|
||||
shrd eax, edx, 20 ; Extract 2nd field
|
||||
shl eax, 12
|
||||
|
||||
xor dl, dl ; Extract 3rd field
|
||||
shl edx, 12-8
|
||||
mov edi, edx ; EDI = Offset
|
||||
|
||||
mov bl, [P2D_Type] ; Dispatch to correct descriptor parser
|
||||
cmp bl, P2D_BM
|
||||
je Descr_BM
|
||||
cmp bl, P2D_BMO
|
||||
je Descr_BMO
|
||||
cmp bl, P2D_BMK
|
||||
je Descr_BMK
|
||||
cmp bl, P2D_R
|
||||
je Descr_R
|
||||
cmp bl, P2D_RO
|
||||
je Descr_RO
|
||||
jmp Exit
|
||||
|
||||
|
||||
Descr_IO_BM:
|
||||
and ecx, 000FFFFFh ; ECX = IMASK
|
||||
shrd eax, edx, 20 ; EAX = IBASE
|
||||
xor edi, edi ; EDI = 00000000
|
||||
|
||||
Descr_BMO: ; Assume OFFSET == 0
|
||||
Descr_BM:
|
||||
Descr_BMK:
|
||||
; ECX = PMASK
|
||||
; EAX = PBASE
|
||||
and eax, ecx ; Start = PBASE & PMASK
|
||||
mov edx, eax ; End = Start + ~PMASK
|
||||
not ecx
|
||||
add edx, ecx
|
||||
jmp StoreResult
|
||||
|
||||
|
||||
Descr_RO: ; Assume OFFSET == 0
|
||||
Descr_R:
|
||||
; ECX = PMIN
|
||||
; EAX = PMAX
|
||||
xchg eax, ecx ; Start = PMIN
|
||||
mov edx, ecx ; End = PMAX
|
||||
or dx, 0FFFh
|
||||
|
||||
StoreResult:
|
||||
mov bx, [Dest]
|
||||
mov [bx], eax ; Start
|
||||
mov [bx+4], edx ; End
|
||||
add edi, eax ; Physical = Start + Offset
|
||||
mov [bx+8], edi
|
||||
|
||||
Exit: ret
|
||||
|
||||
|
||||
Parse_Descriptor endp
|
||||
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
;***********************************************************************
|
||||
MergeFields proc pascal \
|
||||
Dest: PTR, \
|
||||
Field1: DWORD, \
|
||||
Field2: DWORD, \
|
||||
Field3: DWORD
|
||||
|
||||
mov bx, [Dest]
|
||||
|
||||
;// Descr->MsrData[0] = (PBase << 20) | (PMask & 0xFFFFF);
|
||||
;// Descr->MsrData[1] = (PBase >> 12) | (POffset << 8);
|
||||
mov eax, [Field2]
|
||||
mov edx, eax
|
||||
shl eax, 20
|
||||
mov ecx, [Field1]
|
||||
and ecx, 0FFFFFh
|
||||
or eax, ecx
|
||||
mov [bx], eax
|
||||
|
||||
shr edx, 12
|
||||
mov eax, [Field3]
|
||||
shl eax, 8
|
||||
or eax, edx
|
||||
mov [bx+4], eax
|
||||
ret
|
||||
|
||||
MergeFields endp
|
||||
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Returns TRUE if Range is a power of 2
|
||||
;***********************************************************************
|
||||
IsPowerOfTwo proc pascal \
|
||||
Range: dword
|
||||
|
||||
mov ebx, [Range]
|
||||
bsf eax, ebx ; Scan LSB to MSB
|
||||
bsr edx, ebx ; Scan MSB to LSB
|
||||
cmp al, dl ; Same bit found ?
|
||||
mov al, 0 ; No, return FALSE
|
||||
jne Exit
|
||||
mov al, 1 ; else return TRUE
|
||||
Exit: ret
|
||||
|
||||
IsPowerOfTwo endp
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Returns index of first bit set when scanning from MSB to LSB
|
||||
;***********************************************************************
|
||||
BitScanReverse proc pascal \
|
||||
Range: dword
|
||||
|
||||
mov ebx, [Range]
|
||||
bsr eax, ebx ; Scan MSB to LSB
|
||||
ret
|
||||
|
||||
BitScanReverse endp
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Returns index of first bit set when scanning from LSB to MSB
|
||||
;***********************************************************************
|
||||
BitScanForward proc pascal \
|
||||
Range: dword
|
||||
|
||||
mov ebx, [Range]
|
||||
bsf eax, ebx ; Scan LSB to MSB
|
||||
ret
|
||||
|
||||
BitScanForward endp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
end
|
||||
164
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/ohci.c
vendored
Executable file
164
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/ohci.c
vendored
Executable file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//*****************************************************************************
|
||||
//* Handler for EVENT_USB and EVENT_KEL
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
#include "VSA2.H"
|
||||
#include "PROTOS.H"
|
||||
#include "CHIPSET.H"
|
||||
#include "VPCI.H"
|
||||
#include "PCI.H"
|
||||
#include "HCE.H"
|
||||
|
||||
extern ULONG MsgPacket[];
|
||||
extern SmiHeader SMM_Header;
|
||||
extern Hardware HardwareInfo;
|
||||
extern VIRTUAL_DEVICE * SouthBridge;
|
||||
extern void pascal write_flat_size(ULONG, ULONG, UCHAR);
|
||||
|
||||
USHORT OHCI_Address;
|
||||
ULONG OHCI_Command;
|
||||
ULONG HC_Status;
|
||||
#define HC ((ULONG)(&((HCOR *)0)
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Restores the OHCI COMMAND register to the original value
|
||||
//***********************************************************************
|
||||
void Restore_OHCI_Command()
|
||||
{
|
||||
Virtual_PCI_Write_Handler(OHCI_Address, BYTE_IO, OHCI_Command & ~MEM_SPACE);
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
// Sends EVENT_USB or EVENT_KEL
|
||||
//***********************************************************************
|
||||
void Send_OHCI_Event(UCHAR HC_Number)
|
||||
{ USHORT Hce_Status;
|
||||
HCE_CONTROL Hce_Control;
|
||||
ULONG HC_Enable, HC_Address;
|
||||
ULONG Timeout;
|
||||
PCI_HEADER_ENTRY * OHCI_Hdr;
|
||||
|
||||
// Get ptr to virtualized PCI header
|
||||
OHCI_Hdr = *(SouthBridge+3 + HC_Number);
|
||||
if (!OHCI_Hdr) {
|
||||
Log_Error("Invalid HC number 0x%02X", HC_Number);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get HC address from BAR0
|
||||
if (!(HC_Address = (OHCI_Hdr+(BAR0/4))->Value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
OHCI_Address = 0x7C00 + (((USHORT)HC_Number-1) << 8) + COMMAND;
|
||||
// Are memory-mapped registers enabled?
|
||||
if (!((OHCI_Hdr+(COMMAND/4))->Value & MEM_SPACE)) {
|
||||
|
||||
OHCI_Command = (OHCI_Hdr+(COMMAND/4))->Value;
|
||||
// No, temporarily enable access to them
|
||||
Virtual_PCI_Write_Handler(OHCI_Address, BYTE_IO, OHCI_Command | MEM_SPACE);
|
||||
|
||||
// Schedule a routine to restore the original COMMAND value
|
||||
// after the VSM has processed the EVENT_USB or EVENT_KEL.
|
||||
Schedule_VSM((USHORT)Restore_OHCI_Command);
|
||||
}
|
||||
|
||||
|
||||
// Get HC's Hce_Control register
|
||||
Hce_Control.HceUshort = (USHORT)read_flat(HC_Address + HC->HceControl)));
|
||||
|
||||
// Prepare message packet
|
||||
MsgPacket[1] = HC_Address;
|
||||
MsgPacket[2] = HC_Number;
|
||||
MsgPacket[3] = 0;
|
||||
|
||||
// Is it an emulation event ?
|
||||
if (Hce_Control.EmulationInterrupt) {
|
||||
|
||||
// SiBZ 3069/3370: HceStatus[3] is not updated properly
|
||||
if (SMM_Header.SMI_Flags.Ext_IO_Trap) {
|
||||
if (SMM_Header.SMI_Flags.IO_Write) {
|
||||
|
||||
Hce_Status = (USHORT)read_flat(HC_Address + HC->HceStatus)));
|
||||
switch ((USHORT)SMM_Header.IO_addr) {
|
||||
case 0x60:
|
||||
Hce_Status &= ~CMD_DATA;
|
||||
break;
|
||||
case 0x64:
|
||||
Hce_Status |= CMD_DATA;
|
||||
break;
|
||||
}
|
||||
write_flat_size(HC_Address + HC->HceStatus)), Hce_Status, BYTE_IO);
|
||||
}
|
||||
}
|
||||
|
||||
// SiBZ 3509/3571: KEL SMIs are level instead of edge-triggered
|
||||
MsgPacket[3] = Hce_Control.HceUshort;
|
||||
Timeout = 1000;
|
||||
while (Timeout--) {
|
||||
|
||||
Hce_Control.HceUshort = (USHORT)read_flat(HC_Address + HC->HceControl)));
|
||||
if (Hce_Control.IRQ1Active || Hce_Control.IRQ12Active) {
|
||||
// Clear the active IRQ & disable emulation
|
||||
Hce_Control.EmulationEnable = 0;
|
||||
write_flat_size(HC_Address + HC->HceControl)), Hce_Control.HceUshort , WORD_IO);
|
||||
|
||||
// Read a byte from the data port to dismiss the 8042 interrupt
|
||||
in_8(0x60);
|
||||
|
||||
// Re-enable emulation
|
||||
Hce_Control.EmulationEnable = 1;
|
||||
write_flat_size(HC_Address + HC->HceControl)), Hce_Control.HceUshort, WORD_IO);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Report if SiBZ 3571 workaround failed
|
||||
if (Timeout == 0) {
|
||||
Log_Error("IRQx_ACTIVE won't clear");
|
||||
}
|
||||
|
||||
// Send emulation event to the i8042 VSM
|
||||
Send_Event(EVENT_KEL, SysMgr_VSM);
|
||||
}
|
||||
|
||||
// Any unmasked events pending ?
|
||||
HC_Status |= read_flat(HC_Address + HC->HcInterruptStatus)));
|
||||
|
||||
|
||||
HC_Enable = read_flat(HC_Address + HC->HcInterruptEnable)));
|
||||
if (HC_Status & HC_Enable) {
|
||||
// SWAPSiF for PBZ 2300:
|
||||
MsgPacket[3] = HC_Status;
|
||||
write_flat(HC_Address + HC->HcInterruptStatus)), HC_Status);
|
||||
|
||||
// Send Host Controller event to the OHCI VSM
|
||||
Send_Event(EVENT_USB, 0x00000000);
|
||||
}
|
||||
|
||||
HC_Status = 0;
|
||||
}
|
||||
539
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/pci_pm.c
vendored
Executable file
539
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/pci_pm.c
vendored
Executable file
@@ -0,0 +1,539 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//* Routines related to PCI power management.
|
||||
|
||||
#include "VSA2.H"
|
||||
#include "SYSMGR.H"
|
||||
#include "VPCI.H"
|
||||
#include "PROTOS.H"
|
||||
#include "PCI.H"
|
||||
#include "CHIPSET.H"
|
||||
#include "GX2.H"
|
||||
#include "ACPI.H"
|
||||
#include "DESCR.H"
|
||||
|
||||
|
||||
|
||||
#if SUPPORT_CAPABILITIES
|
||||
|
||||
extern DESCRIPTOR MSRs[];
|
||||
extern PCI_HEADER_ENTRY * HdrPtr;
|
||||
extern PCI_HEADER_ENTRY * CommandPtr;
|
||||
extern UCHAR End_of_POST;
|
||||
extern ULONG OHCI1_Smi;
|
||||
extern ULONG MCP_SB;
|
||||
|
||||
#define OHC_IN_D3 1
|
||||
#define EHC_IN_D3 2
|
||||
#define UDC_IN_D3 4
|
||||
#define UOC_IN_D3 8
|
||||
#define ALL_IN_D3 (OHC_IN_D3 | EHC_IN_D3 | UDC_IN_D3 | UOC_IN_D3)
|
||||
|
||||
typedef struct { // All bits are Read-Only
|
||||
union {
|
||||
ULONG AsDword;
|
||||
struct {
|
||||
ULONG CompatibilityID: 8;
|
||||
ULONG NextItemPtr: 8;
|
||||
ULONG Version: 3;
|
||||
ULONG PME_Clock: 1;
|
||||
ULONG Reserved: 1;
|
||||
ULONG DSI: 1;
|
||||
ULONG Aux_Current: 3;
|
||||
ULONG D1_Support: 1;
|
||||
ULONG D2_Support: 1;
|
||||
ULONG PME_D0: 1;
|
||||
ULONG PME_D1: 1;
|
||||
ULONG PME_D2: 1;
|
||||
ULONG PME_D3_Hot: 1;
|
||||
ULONG PME_D3_Cold: 1;
|
||||
};
|
||||
};
|
||||
} PMC;
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
ULONG AsDword;
|
||||
struct {
|
||||
union {
|
||||
USHORT AsWord;
|
||||
struct {
|
||||
USHORT PowerState: 2; // Read-write
|
||||
USHORT Reserved: 6; // Read-only
|
||||
USHORT PME_En: 1; // Read-write
|
||||
USHORT Data_Select: 4; // Read-write
|
||||
USHORT Data_Scale: 2; // Read-only
|
||||
USHORT PME_Status: 1; // Read/Write-Clear
|
||||
};
|
||||
};
|
||||
UCHAR PMCSR_BSE; // Bridge Support Extensions
|
||||
UCHAR Data;
|
||||
};
|
||||
};
|
||||
} PMCR;
|
||||
// R/W Mask = 1001_1111_0000_0011
|
||||
#define PMCR_MASK 0x9F03
|
||||
|
||||
|
||||
|
||||
// Fields in USBMSROHCB, USBMSREHCB, USBMSRUDCB, USBMSRUOCB:
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
ULONG Reserved: 1;
|
||||
ULONG MEMEN: 1;
|
||||
ULONG BMEN: 1;
|
||||
ULONG PMEEN: 1;
|
||||
ULONG PMESTS: 1;
|
||||
};
|
||||
struct {
|
||||
UCHAR Enables;
|
||||
// NOTE: the next 3 fields are actually 6 bits, but the compiler
|
||||
// generates crappy code if defined as such
|
||||
UCHAR FLADJ;
|
||||
UCHAR LEGSMIEN;
|
||||
UCHAR LEGSMISTS;
|
||||
};
|
||||
};
|
||||
} USBMSR;
|
||||
|
||||
|
||||
// Fields in 32-MSBs of GLCP's PMCLKACTIVE, PMCLKOFF, PMCLKDISABLE, PMCLK4ACK, PMCLKDISABLE:
|
||||
typedef struct {
|
||||
union {
|
||||
ULONG AsDword;
|
||||
struct {
|
||||
ULONG GL0_0: 1;
|
||||
ULONG GL0_1: 1;
|
||||
ULONG GLPCI_GLIU: 1;
|
||||
ULONG GLPCI_PCI: 1;
|
||||
ULONG GLPCI_PCIF: 1;
|
||||
ULONG RSVD: 6;
|
||||
ULONG ATAC_GLIU: 1;
|
||||
ULONG ATAC_LB: 1;
|
||||
ULONG ACC_GLIU: 1;
|
||||
ULONG ACC_LB: 1;
|
||||
ULONG ACC_BIT: 1;
|
||||
ULONG DIVIL_GLIU: 1;
|
||||
ULONG DIVIL_LB: 1;
|
||||
ULONG DIVIL_LPC: 1;
|
||||
ULONG DIVIL_DMA: 1;
|
||||
ULONG DIVIL_SMB: 1;
|
||||
ULONG DIVIL_PIT: 1;
|
||||
ULONG DIVIL_UART1: 1;
|
||||
ULONG DIVIL_UART2: 1;
|
||||
ULONG DIVIL_PMC: 1;
|
||||
ULONG DIVIL_PMC_STD: 1;
|
||||
ULONG DIVIL_GPIO: 1;
|
||||
ULONG DIVIL_GPIO_STD: 1;
|
||||
ULONG DIVIL_MFGPT_32K: 1;
|
||||
ULONG DIVIL_MFGPT_14M: 1;
|
||||
ULONG DIVIL_32K_STD: 1;
|
||||
ULONG GLCP_GLIU: 1;
|
||||
};
|
||||
};
|
||||
union {
|
||||
ULONG AsDword_HI;
|
||||
struct {
|
||||
ULONG GLCP_DBG: 1;
|
||||
ULONG GLCP_PCI: 1;
|
||||
ULONG OHC_CLK48: 1;
|
||||
ULONG UDC_HCLK: 1;
|
||||
ULONG EHC_HCLK: 1;
|
||||
ULONG OHC_HCLK: 1;
|
||||
ULONG EHC_CLK60: 1;
|
||||
ULONG UDC_CLK60: 1;
|
||||
ULONG USBP1_CLK60: 1;
|
||||
ULONG USBP2_CLK60: 1;
|
||||
ULONG USBP3_CLK60: 1;
|
||||
ULONG USBP4_CLK60: 1;
|
||||
ULONG OTC_HCLK: 1;
|
||||
ULONG USB_GLIU: 1; // aka M2A_HCLK in USB 2.0 IDS
|
||||
ULONG USBPHYPLLEN: 1;
|
||||
};
|
||||
};
|
||||
} GLCP_CLKS;
|
||||
|
||||
// Local variables:
|
||||
ULONG MsrAddr, MsrData[2];
|
||||
USBMSR * UsbMsr = (USBMSR *)&MsrData[1];
|
||||
GLCP_CLKS Clocks;
|
||||
USHORT D3_Flag = 0;
|
||||
ULONG EHCI_BAR;
|
||||
|
||||
//***********************************************************************
|
||||
// Returns TRUE if the specified EHCI port is suspended
|
||||
// NOTE: Port is 1-based
|
||||
//***********************************************************************
|
||||
UCHAR pascal EHCI_Port_Suspended(UCHAR Port)
|
||||
{
|
||||
if ((UCHAR)READ_MEMORY(EHCI_BAR + 0x50 + Port*4) & 0x80) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
// Reads the MSR corresponding to the current USB 2.0 function
|
||||
//***********************************************************************
|
||||
void Get_USB_MSR(void)
|
||||
{
|
||||
MsrAddr = OHCI1_Smi;
|
||||
(UCHAR)MsrAddr = (HdrPtr+BAR0/4)->LBar;
|
||||
|
||||
// Get current MSR value
|
||||
Read_MSR(MsrAddr, MsrData);
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Returns value of the EHCI Power Management register USBLEGCTLSTS
|
||||
//***********************************************************************
|
||||
ULONG pascal Handle_EHCI_Rd(PCI_HEADER_ENTRY * Pci)
|
||||
{
|
||||
|
||||
// Filter out non-EHCI functions
|
||||
if (((HdrPtr+REVISION_ID/4)->Value & 0xFFFFFF00) == 0x0C032000) {
|
||||
|
||||
// Read USBMSREHCB MSR
|
||||
Get_USB_MSR();
|
||||
|
||||
Pci->EHCI_Errors = (UCHAR)UsbMsr->LEGSMISTS;
|
||||
|
||||
// Sync PCI register with MSR (optional):
|
||||
Pci->EHCI_SMI_Enables = (UCHAR)UsbMsr->LEGSMIEN;
|
||||
|
||||
}
|
||||
return Pci->Value;
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
// Handles writes to the EHCI PCI registers:
|
||||
// COMMAND
|
||||
// BAR0
|
||||
// USBLEGSUP
|
||||
// USBLEGCTLSTS
|
||||
// FLADJ
|
||||
//***********************************************************************
|
||||
void pascal Handle_EHCI_Wr(PCI_HEADER_ENTRY * Pci)
|
||||
{ ULONG SMI_Status = SMI_ON_COMMAND;
|
||||
|
||||
// Read USBMSREHCB MSR
|
||||
Get_USB_MSR();
|
||||
|
||||
switch (Pci->Reg & 0xFC) {
|
||||
case BAR0:
|
||||
EHCI_BAR = Pci->Value;
|
||||
SMI_Status = SMI_ON_BAR;
|
||||
case COMMAND:
|
||||
if (End_of_POST) {
|
||||
// Set USBLEGCTLSTS[31/30]
|
||||
(HdrPtr+9)->Value |= SMI_Status;
|
||||
}
|
||||
return;
|
||||
|
||||
case USBLEGSUP: // EECP
|
||||
// If ownership changing, set USBLEGCTLSTS[29]
|
||||
if (Pci->Value & (OS_OWNED_SEMAPHORE | BIOS_OWNED_SEMAPHORE)) {
|
||||
// Set USBLEGCTLSTS[29]
|
||||
(Pci+1)->Value |= SMI_ON_OC;
|
||||
}
|
||||
// If system software is requesting ownership...
|
||||
if (Pci->Value & OS_OWNED_SEMAPHORE) {
|
||||
// Clear BIOS Owned Semaphore
|
||||
Pci->Value &= ~BIOS_OWNED_SEMAPHORE;
|
||||
// Clear SMI enables
|
||||
UsbMsr->LEGSMIEN = 0x00;
|
||||
}
|
||||
// If BIOS is requesting ownership...
|
||||
if (Pci->Value & BIOS_OWNED_SEMAPHORE) {
|
||||
// Clear system software Owned Semaphore
|
||||
Pci->Value &= ~OS_OWNED_SEMAPHORE;
|
||||
}
|
||||
break;
|
||||
|
||||
case USBLEGCTLSTS: // EECP+4
|
||||
UsbMsr->LEGSMIEN = Pci->EHCI_SMI_Enables;
|
||||
break;
|
||||
|
||||
case SRBN_REG:
|
||||
UsbMsr->FLADJ = Pci->FLADJ;
|
||||
break;
|
||||
}
|
||||
|
||||
// Update USBMSREHCB
|
||||
Write_MSR(MsrAddr, MsrData);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Handles reads from a PCI Power Management register
|
||||
// Returns value of PCI register
|
||||
//***********************************************************************
|
||||
ULONG pascal Handle_PCI_PM_Rd(PCI_HEADER_ENTRY * Pci)
|
||||
{ PMCR * PMCR_Ptr;
|
||||
|
||||
// Get PME status from MSR
|
||||
Get_USB_MSR();
|
||||
|
||||
// Cast register ptr
|
||||
PMCR_Ptr = (PMCR *)&Pci->Value;
|
||||
PMCR_Ptr->PME_Status = UsbMsr->PMESTS ? 1: 0;
|
||||
|
||||
return Pci->Value;
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
// Handles writes to the PCI Power Management register
|
||||
//***********************************************************************
|
||||
void pascal Handle_PCI_PM_Wr(PCI_HEADER_ENTRY * Pci, USHORT PreviousData)
|
||||
{ PMCR Delta;
|
||||
PMCR * PMCR_Ptr;
|
||||
PMC * PMC_Ptr;
|
||||
USHORT Value;
|
||||
|
||||
// Cast register ptrs
|
||||
PMCR_Ptr = (PMCR *)&Pci->Value;
|
||||
PMC_Ptr = (PMC *)&(Pci-1)->Value;
|
||||
|
||||
Value = (USHORT)Pci->Value;
|
||||
|
||||
// Mask read-only bits
|
||||
Value &= PMCR_MASK;
|
||||
|
||||
|
||||
// Compute changes
|
||||
Delta.AsWord = (USHORT)PreviousData ^ PMCR_Ptr->AsWord;
|
||||
|
||||
|
||||
// Select data to be reported through the Data register
|
||||
// Return as "not implemented"
|
||||
PMCR_Ptr->Data = 0; //Power[PMCR_Ptr->Data_Select].Data;
|
||||
PMCR_Ptr->Data_Scale = 0; //Power[PMCR_Ptr->Data_Select].Scale;
|
||||
|
||||
Get_USB_MSR();
|
||||
|
||||
// PME# status write-to-clear
|
||||
if (PMCR_Ptr->PME_Status) {
|
||||
UsbMsr->PMESTS = 1;
|
||||
}
|
||||
|
||||
// PME# enable
|
||||
if (Delta.PME_En) {
|
||||
// Check if PME# is supported
|
||||
if (PMC_Ptr->PME_D3_Cold || PMC_Ptr->PME_D3_Hot ||
|
||||
PMC_Ptr->PME_D0 || PMC_Ptr->PME_D1 || PMC_Ptr->PME_D2) {
|
||||
if (PMCR_Ptr->PME_En) {
|
||||
// Enable PME# assertion
|
||||
UsbMsr->PMEEN = 1;
|
||||
} else {
|
||||
// Disable PME# assertion
|
||||
UsbMsr->PMEEN = 0;
|
||||
}
|
||||
} else {
|
||||
// PME# not supported
|
||||
PMCR_Ptr->PME_En = 0;
|
||||
}
|
||||
}
|
||||
// Update USBMSRxxCB
|
||||
Write_MSR(MsrAddr, MsrData);
|
||||
|
||||
// Power state
|
||||
if (Delta.PowerState) {
|
||||
UCHAR SupportedState=0;
|
||||
ULONG ClocksMsr;
|
||||
register USHORT USB_20_D3_Flag = D3_Flag;
|
||||
|
||||
ClocksMsr = MCP_SB + MCP_PMCLKOFF;
|
||||
Read_MSR(ClocksMsr, &Clocks.AsDword);
|
||||
|
||||
switch (PMCR_Ptr->PowerState) {
|
||||
case D0_STATE:
|
||||
// If D0 is supported...
|
||||
if (PMC_Ptr->PME_D0) {
|
||||
switch (HdrPtr->Device_ID) {
|
||||
case DEVICE_ID_AMD_OHCI:
|
||||
Clocks.OHC_HCLK = 0;
|
||||
Clocks.OHC_CLK48 = 0;
|
||||
USB_20_D3_Flag &= ~OHC_IN_D3;
|
||||
break;
|
||||
|
||||
case DEVICE_ID_AMD_EHCI:
|
||||
Clocks.EHC_HCLK = 0;
|
||||
Clocks.EHC_CLK60 = 0;
|
||||
Clocks.USBP1_CLK60 = 0;
|
||||
Clocks.USBP2_CLK60 = 0;
|
||||
Clocks.USBP3_CLK60 = 0;
|
||||
Clocks.USBP4_CLK60 = 0;
|
||||
Clocks.USBPHYPLLEN = 0;
|
||||
USB_20_D3_Flag &= ~EHC_IN_D3;
|
||||
break;
|
||||
|
||||
case DEVICE_ID_AMD_UDC:
|
||||
Clocks.UDC_HCLK = 0;
|
||||
Clocks.UDC_CLK60 = 0;
|
||||
USB_20_D3_Flag &= ~UDC_IN_D3;
|
||||
break;
|
||||
|
||||
case DEVICE_ID_AMD_OTG:
|
||||
Clocks.OTC_HCLK = 0;
|
||||
USB_20_D3_Flag &= ~UOC_IN_D3;
|
||||
break;
|
||||
}
|
||||
SupportedState = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case D1_STATE:
|
||||
case D2_STATE:
|
||||
// D1 & D2 are not supported
|
||||
switch (HdrPtr->Device_ID) {
|
||||
case DEVICE_ID_AMD_OHCI:
|
||||
USB_20_D3_Flag &= ~OHC_IN_D3;
|
||||
break;
|
||||
|
||||
case DEVICE_ID_AMD_EHCI:
|
||||
USB_20_D3_Flag &= ~EHC_IN_D3;
|
||||
break;
|
||||
|
||||
case DEVICE_ID_AMD_UDC:
|
||||
USB_20_D3_Flag &= ~UDC_IN_D3;
|
||||
break;
|
||||
|
||||
case DEVICE_ID_AMD_OTG:
|
||||
USB_20_D3_Flag &= ~UOC_IN_D3;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case D3_STATE: // D3hot
|
||||
// If D3hot is supported...
|
||||
if (PMC_Ptr->PME_D3_Hot) {
|
||||
switch (HdrPtr->Device_ID) {
|
||||
case DEVICE_ID_AMD_OHCI:
|
||||
Clocks.OHC_HCLK = 0;
|
||||
Clocks.OHC_CLK48 = 0;
|
||||
USB_20_D3_Flag |= OHC_IN_D3;
|
||||
break;
|
||||
|
||||
case DEVICE_ID_AMD_EHCI:
|
||||
Clocks.EHC_HCLK = 0;
|
||||
Clocks.EHC_CLK60 = 0;
|
||||
Clocks.USBP1_CLK60 = 0;
|
||||
Clocks.USBP2_CLK60 = 0;
|
||||
Clocks.USBP3_CLK60 = 0;
|
||||
Clocks.USBP4_CLK60 = 0;
|
||||
Clocks.USBPHYPLLEN = 1;
|
||||
|
||||
// In D3 *only* USBPHYPLLEN should be gated (Phy Clock switched off).
|
||||
// This guarantees max. power saving during S1 and proper USB Remote WakeUp functionality and Resume from S1
|
||||
// If all EHC ports are suspended USBPHYPLLEN should not be gated, because USBPHYPLL is switched off by Phy-HW
|
||||
if (EHCI_Port_Suspended(1) & EHCI_Port_Suspended(2) & EHCI_Port_Suspended(3) & EHCI_Port_Suspended(4)) {
|
||||
Clocks.USBPHYPLLEN = 0;
|
||||
}
|
||||
USB_20_D3_Flag |= EHC_IN_D3;
|
||||
break;
|
||||
|
||||
case DEVICE_ID_AMD_UDC:
|
||||
USB_20_D3_Flag |= UDC_IN_D3;
|
||||
break;
|
||||
|
||||
case DEVICE_ID_AMD_OTG:
|
||||
USB_20_D3_Flag |= UOC_IN_D3;
|
||||
break;
|
||||
}
|
||||
|
||||
SupportedState = 1;
|
||||
}
|
||||
break;
|
||||
} // end switch (PMCR_Ptr->PowerState)
|
||||
|
||||
if (SupportedState) {
|
||||
PCI_HEADER_ENTRY * Bar;
|
||||
DESCRIPTOR * Descr;
|
||||
ULONG MsrData[2];
|
||||
UCHAR Index;
|
||||
|
||||
// If going to D3, turn off P2D_BM descriptor so accesses will master-abort.
|
||||
// Otherwise, the system hangs when the device registers are accessed since
|
||||
// the clocks have been turned off. Restore the descriptor when going to D0.
|
||||
Bar = HdrPtr+BAR0/4;
|
||||
while ((Bar->Reg >= BAR0) && (Bar->Reg <= BAR5)) {
|
||||
if (Bar->Flag & (MMIO_BAR | MEM_BAR)) {
|
||||
|
||||
// For each linked item, update the associated MSR
|
||||
// Get the P2D_BM descriptor linked to this BAR
|
||||
Index = Bar->Link;
|
||||
do {
|
||||
Descr = &MSRs[Index];
|
||||
if (Descr->Type == P2D_BM || Descr->Type == P2D_BMK) {
|
||||
if (PMCR_Ptr->PowerState == D3_STATE) {
|
||||
Get_Descriptor_Default(Descr->Type, MsrData);
|
||||
} else {
|
||||
MsrData[0] = Descr->MsrData[0];
|
||||
MsrData[1] = Descr->MsrData[1];
|
||||
}
|
||||
Write_MSR(Descr->MsrAddr, MsrData);
|
||||
break;
|
||||
}
|
||||
} while (Index = Descr->Link);
|
||||
}
|
||||
if (Pci->Flag & EOL) {
|
||||
break;
|
||||
}
|
||||
Bar++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// PBZ 2292 - Can't turn off USB_GLIU else MSR read of USB 2.0 hangs
|
||||
#if 0
|
||||
// Are all USB 2.0 functions are in D3?
|
||||
if (USB_20_D3_Flag == ALL_IN_D3) {
|
||||
// Yes, then turn off USB_GLIU
|
||||
Clocks.USB_GLIU = 1;
|
||||
} else {
|
||||
Clocks.USB_GLIU = 0;
|
||||
}
|
||||
#endif
|
||||
// Update D3 state for each function
|
||||
D3_Flag = USB_20_D3_Flag;
|
||||
// Update clock settings
|
||||
Write_MSR(ClocksMsr, &Clocks.AsDword);
|
||||
|
||||
} else {
|
||||
PMCR Previous;
|
||||
|
||||
// PCI PM Specification (page 29; Table 7):
|
||||
// Writes of an unsupported state should discard the data
|
||||
Previous.AsWord = PreviousData;
|
||||
PMCR_Ptr->PowerState = Previous.PowerState;
|
||||
}
|
||||
} // end if (Delta.PowerState)
|
||||
|
||||
// Record current value
|
||||
Pci->Value = PMCR_Ptr->AsDword;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
177
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/pci_rd.c
vendored
Executable file
177
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/pci_rd.c
vendored
Executable file
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//*****************************************************************************
|
||||
//* Implements reads of virtualized PCI configuration headers
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
#include "VSA2.H"
|
||||
#include "PCI.H"
|
||||
#include "VPCI.H"
|
||||
#include "PROTOS.H"
|
||||
#include "SYSMGR.H"
|
||||
#include "CHIPSET.H"
|
||||
|
||||
|
||||
// External function declarations:
|
||||
ULONG pascal Get_Device_Status(PCI_HEADER_ENTRY *);
|
||||
ULONG pascal Handle_PCI_PM_Rd(PCI_HEADER_ENTRY *);
|
||||
ULONG pascal Handle_EHCI_Rd(PCI_HEADER_ENTRY *);
|
||||
ULONG pascal Read_MSR_LO(ULONG);
|
||||
UCHAR pascal Get_Latency(PCI_HEADER_ENTRY *);
|
||||
PCI_HEADER_ENTRY * pascal Get_Structure(USHORT);
|
||||
extern Hardware HardwareInfo;
|
||||
|
||||
|
||||
|
||||
// External variable declarations:
|
||||
extern DESCRIPTOR MSRs[];
|
||||
extern UCHAR Shift, AlignedReg, Function;
|
||||
extern PCI_HEADER_ENTRY * CommandPtr;
|
||||
extern ULONG ATA_Error;
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Reads an embedded PCI register
|
||||
//***********************************************************************
|
||||
ULONG pascal Read_EPCI(UCHAR AlignedReg)
|
||||
{ ULONG MsrAddr;
|
||||
|
||||
MsrAddr = MSRs[CommandPtr->Link].MsrAddr;
|
||||
if (MsrAddr) {
|
||||
(UCHAR)MsrAddr = AlignedReg/4;
|
||||
return Read_MSR_LO(MsrAddr);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
//
|
||||
// This routine implements reads to virtualized configuration space.
|
||||
//
|
||||
// NOTES:
|
||||
// 1) Misaligned accesses are handled. If an access crosses a DWORD
|
||||
// boundary, only the bytes within the addressed DWORD are read.
|
||||
// The remaining bytes return FFs.
|
||||
// 2) The variable Pci points to a PCI_HEADER_ENTRY entry that defines
|
||||
// the state and characteristics of the register being read.
|
||||
//***********************************************************************
|
||||
ULONG pascal Virtual_PCI_Read_Handler(USHORT PCI_Address)
|
||||
{ ULONG Data;
|
||||
register PCI_HEADER_ENTRY * Pci;
|
||||
|
||||
|
||||
// Get ptr to virtualized table entry
|
||||
Pci = Get_Structure(PCI_Address);
|
||||
|
||||
|
||||
switch ((USHORT)Pci) {
|
||||
|
||||
case UNIMPLEMENTED_FUNCTION:
|
||||
Data = 0xFFFFFFFF;
|
||||
break;
|
||||
|
||||
case UNIMPLEMENTED_REGISTER:
|
||||
Data = 0x00000000;
|
||||
break;
|
||||
|
||||
default:
|
||||
// Handle special cases
|
||||
if (Pci->Flag & EPCI_R && AlignedReg < 0x40) {
|
||||
|
||||
// Embedded PCI device: read its h/w PCI configuration space
|
||||
Data = Read_EPCI(AlignedReg);
|
||||
|
||||
if (AlignedReg == COMMAND) {
|
||||
// Mark device '66 MHz capable'
|
||||
Data |= PCI_66MHZ_CAPABLE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Data = Pci->Value;
|
||||
|
||||
switch (AlignedReg) {
|
||||
|
||||
case COMMAND:
|
||||
// Get device's Status
|
||||
Data |= Get_Device_Status(Pci);
|
||||
break;
|
||||
|
||||
case BAR0:
|
||||
case BAR1:
|
||||
case BAR2:
|
||||
case BAR3:
|
||||
case BAR4:
|
||||
case BAR5:
|
||||
// If I/O BAR, set bit 0
|
||||
if (Pci->Flag & IO_BAR) {
|
||||
Data |= 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case CACHE_LINE:
|
||||
Pci->LatencyTimer = Get_Latency(Pci);
|
||||
Data = Pci->Value;
|
||||
break;
|
||||
|
||||
#if SUPPORT_CAPABILITIES
|
||||
case (PCI_PM_REG+4): // 0x44
|
||||
if (Pci->Flag & PCI_PM) {
|
||||
Data = Handle_PCI_PM_Rd(Pci);
|
||||
break;
|
||||
}
|
||||
|
||||
case USBLEGCTLSTS:
|
||||
if (Pci->Flag & PCI_EHCI) {
|
||||
Data = Handle_EHCI_Rd(Pci);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Thor ATA vendor-specific registers:
|
||||
case IDE_CFG: // 0x40
|
||||
case IDE_DTC: // 0x48
|
||||
case IDE_CAST: // 0x4C
|
||||
case IDE_ETC: // 0x50
|
||||
if (Pci->LBar) {
|
||||
ULONG MsrAddr = ATA_Error;
|
||||
|
||||
(USHORT)MsrAddr = (USHORT)Pci->LBar;
|
||||
Data = Read_MSR_LO(MsrAddr);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Handle non-dword aligned accesses
|
||||
Data >>= Shift;
|
||||
Data |= 0xFFFFFFFFL << (32-Shift);
|
||||
|
||||
return Data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
375
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/pci_wr.c
vendored
Executable file
375
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/pci_wr.c
vendored
Executable file
@@ -0,0 +1,375 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//*****************************************************************************
|
||||
//* Implements writes of virtualized PCI configuration headers
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
#include "VSA2.H"
|
||||
#include "PCI.H"
|
||||
#include "GX2.H"
|
||||
#include "VPCI.H"
|
||||
#include "SYSMGR.H"
|
||||
#include "CHIPSET.H"
|
||||
#include "PROTOS.H"
|
||||
#include "MAPPER.H"
|
||||
|
||||
|
||||
// External function declarations:
|
||||
PCI_HEADER_ENTRY * pascal Get_Structure(USHORT);
|
||||
UCHAR pascal Update_BusMaster(PCI_HEADER_ENTRY *, UCHAR);
|
||||
void pascal Set_Latency(UCHAR);
|
||||
void pascal Clear_MBus_Error(PCI_HEADER_ENTRY *, ULONG);
|
||||
void pascal SMINT_Handler(USHORT);
|
||||
void pascal PCI_Interrupt_Steering(USHORT);
|
||||
void pascal Handle_EHCI_Wr(PCI_HEADER_ENTRY *);
|
||||
void pascal Handle_PCI_PM_Wr(PCI_HEADER_ENTRY *, USHORT);
|
||||
void pascal Update_Special_Cycles(USHORT);
|
||||
void Deallocate_Descriptor(DESCRIPTOR *);
|
||||
|
||||
// External variable declarations:
|
||||
extern DESCRIPTOR MSRs[];
|
||||
extern ULONG ATA_Error;
|
||||
extern UCHAR Shift, AlignedReg, Function;
|
||||
extern PCI_HEADER_ENTRY * CommandPtr;
|
||||
extern PCI_HEADER_ENTRY * HdrPtr;
|
||||
extern VIRTUAL_DEVICE * IDSELs;
|
||||
extern Hardware HardwareInfo;
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Writes an embedded PCI register
|
||||
//***********************************************************************
|
||||
void pascal Write_EPCI(UCHAR AlignedReg, ULONG Data)
|
||||
{ ULONG MsrAddr;
|
||||
|
||||
MsrAddr = MSRs[CommandPtr->Link].MsrAddr;
|
||||
if (MsrAddr) {
|
||||
(UCHAR)MsrAddr = AlignedReg/4;
|
||||
Write_MSR_LO(MsrAddr, Data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
//
|
||||
// Handle changes to the COMMAND register
|
||||
//
|
||||
//***********************************************************************
|
||||
void pascal Update_Command(USHORT PreviousValue, USHORT NewValue)
|
||||
{ UCHAR Changes, EnableFlag;
|
||||
register PCI_HEADER_ENTRY * Pci;
|
||||
ULONG OldValue;
|
||||
|
||||
Changes = (UCHAR)(PreviousValue ^ NewValue);
|
||||
|
||||
//
|
||||
// Handle changes to Special Cycles
|
||||
//
|
||||
if (Changes & SPECIAL_CYCLES) {
|
||||
Update_Special_Cycles((UCHAR)NewValue & SPECIAL_CYCLES);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Handle changes to bus master & address space enables
|
||||
//
|
||||
if (Changes & (IO_SPACE | MEM_SPACE | BUS_MASTER)) {
|
||||
|
||||
Pci = CommandPtr + 2;
|
||||
|
||||
// Walk through BAR entries & enable/disable corresponding descriptors/LBARs
|
||||
do {
|
||||
|
||||
// Advance ptr to next implemented register
|
||||
Pci++;
|
||||
|
||||
// Only concerned with allocated BARs
|
||||
if (Pci->Flag & (MMIO_BAR | MEM_BAR | IO_BAR)) {
|
||||
|
||||
// Only write descriptors for BARs that have had resources allocated
|
||||
// and have a non-zero value.
|
||||
if ((Pci->Link) && Pci->Value) {
|
||||
|
||||
// Check correct Command bit according to BAR type
|
||||
EnableFlag = (Pci->Flag & IO_BAR) ? IO_SPACE : MEM_SPACE;
|
||||
|
||||
// Handle changes to address space enable
|
||||
if (Changes & EnableFlag) {
|
||||
EnableFlag &= (UCHAR)NewValue;
|
||||
|
||||
// Update the descriptor(s)
|
||||
OldValue = Pci->Value;
|
||||
Update_BAR(Pci, EnableFlag);
|
||||
Pci->Value = OldValue;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Handle changes to bus master enable
|
||||
//
|
||||
if (Changes & BUS_MASTER) {
|
||||
EnableFlag = (UCHAR)NewValue & BUS_MASTER;
|
||||
if (Update_BusMaster(Pci, EnableFlag)) {
|
||||
// Early-out (e.g. bridge)
|
||||
Changes &= ~BUS_MASTER;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} while (!(Pci->Flag & EOL));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
//
|
||||
// This routine implements writes to virtualized configuration space.
|
||||
//
|
||||
// NOTES:
|
||||
// 1) Misaligned accesses are handled. If an access crosses a DWORD
|
||||
// boundary, only the bytes within the addressed DWORD are written.
|
||||
// 2) The variable Pci points to a PCI_HEADER_ENTRY entry that defines
|
||||
// the state and behavior of the accessed register.
|
||||
//
|
||||
//***********************************************************************
|
||||
ULONG pascal Virtual_PCI_Write_Handler(USHORT PCI_Address, UCHAR Size, ULONG NewData)
|
||||
{ UCHAR EnableFlag;
|
||||
ULONG Mask, Data, PreviousData;
|
||||
register PCI_HEADER_ENTRY * Pci;
|
||||
|
||||
|
||||
// Get ptr to virtualized table entry
|
||||
Pci = Get_Structure(PCI_Address);
|
||||
|
||||
// Unimplemented function ?
|
||||
if ((USHORT)Pci == UNIMPLEMENTED_FUNCTION) {
|
||||
return NewData;
|
||||
}
|
||||
|
||||
// Unimplemented register ?
|
||||
if ((USHORT)Pci == UNIMPLEMENTED_REGISTER) {
|
||||
// Removing an entire PCI function ?
|
||||
if (AlignedReg == 0x7C && NewData == 0xDEADBEEF) {
|
||||
UCHAR i, Link;
|
||||
DESCRIPTOR * Descr;
|
||||
|
||||
|
||||
#if SUPPORT_CAPABILITIES
|
||||
Pci = HdrPtr + BAR0/4;
|
||||
do {
|
||||
Pci++;
|
||||
// If this device is PCI PM-aware...
|
||||
if (Pci->Flag & PCI_PM) {
|
||||
// then set device to D3
|
||||
(UCHAR)PCI_Address = 0x44;
|
||||
Virtual_PCI_Write_Handler(PCI_Address, BYTE_IO, 0x03);
|
||||
break;
|
||||
}
|
||||
} while (!(Pci->Flag & EOL));
|
||||
#endif
|
||||
// Make function unimplemented
|
||||
IDSELs[Function] = 0x0000;
|
||||
|
||||
// Walk through all BARs and deallocate associated MSRs
|
||||
Pci = HdrPtr + BAR0/4;
|
||||
if (Pci->Reg != BAR0) {
|
||||
return NewData;
|
||||
}
|
||||
|
||||
for (i = BAR0; i <= BAR5; i += 4) {
|
||||
if (Pci->Flag & (MMIO_BAR | MEM_BAR | IO_BAR)) {
|
||||
Link = Pci->Link;
|
||||
|
||||
// For each linked item, update the associated MSR
|
||||
while (Link) {
|
||||
Descr = &MSRs[Link];
|
||||
|
||||
// Get link to next MSR
|
||||
Link = Descr->Link;
|
||||
|
||||
// Deallocate the descriptor & set MSR to default value
|
||||
Deallocate_Descriptor(Descr);
|
||||
}
|
||||
}
|
||||
if (Pci->Flag & EOL) {
|
||||
break;
|
||||
}
|
||||
Pci++;
|
||||
}
|
||||
}
|
||||
return NewData;
|
||||
}
|
||||
|
||||
// Save a copy of original value
|
||||
PreviousData = Pci->Value;
|
||||
|
||||
//
|
||||
// Generate mask to preserve read-only fields
|
||||
//
|
||||
switch (Size) {
|
||||
|
||||
case BYTE_IO:
|
||||
Mask = 0x000000FF;
|
||||
break;
|
||||
|
||||
case WORD_IO:
|
||||
Mask = 0x0000FFFF;
|
||||
break;
|
||||
|
||||
case DWORD_IO:
|
||||
Mask = 0xFFFFFFFF;
|
||||
break;
|
||||
|
||||
default:
|
||||
Mask = 0x00000000;
|
||||
break;
|
||||
}
|
||||
Mask = Pci->Mask & (Mask << Shift);
|
||||
|
||||
|
||||
//
|
||||
// Compute new register value
|
||||
// - preserves R/O fields
|
||||
// - handles misaligned accesses
|
||||
// - handles accesses smaller than dword
|
||||
//
|
||||
NewData <<= Shift;
|
||||
Data = (NewData & Mask) | (PreviousData & ~Mask);
|
||||
|
||||
|
||||
//
|
||||
// Record the new register value
|
||||
//
|
||||
Pci->Value = Data;
|
||||
|
||||
|
||||
// Handle Write-to-Clear bits
|
||||
if (NewData & Pci->WriteToClear) {
|
||||
Pci->Value &= ~(NewData & Pci->WriteToClear);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Update the MBus hardware
|
||||
//
|
||||
switch (AlignedReg) {
|
||||
|
||||
case COMMAND:
|
||||
|
||||
// Handle writes to Command register
|
||||
if ((USHORT)PreviousData != (USHORT)Data) {
|
||||
// If the Command register has changed, update the h/w
|
||||
Update_Command((USHORT)PreviousData, (USHORT)Data);
|
||||
}
|
||||
|
||||
// Handle writes to Status[15:11] (write-to-clear);
|
||||
if (NewData &= Pci->WriteToClear) {
|
||||
// Clear status bits in device's MSR
|
||||
Clear_MBus_Error(Pci, NewData);
|
||||
}
|
||||
|
||||
// Handle SMI on EHCI COMMAND write
|
||||
if (Pci->Flag & PCI_EHCI) {
|
||||
Handle_EHCI_Wr(Pci);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case CACHE_LINE:
|
||||
// PCI Spec: if an unsupported Cache Line value is written, treat as 0x00
|
||||
if ((UCHAR)Data ^ (UCHAR)Pci->Mask) {
|
||||
Pci->CacheLineSize = 0x00;
|
||||
}
|
||||
Set_Latency((UCHAR)(Data >> 8));
|
||||
break;
|
||||
|
||||
|
||||
|
||||
// Emulation of CS5530 software SMI mechanism
|
||||
case SW_SMI: // 0xD0
|
||||
SMINT_Handler((USHORT)Data);
|
||||
break;
|
||||
|
||||
case (PCI_PM_REG+4): // 0x44
|
||||
#if SUPPORT_CAPABILITIES
|
||||
if (Pci->Flag & PCI_PM) {
|
||||
Handle_PCI_PM_Wr(Pci, (USHORT)PreviousData);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case IDE_CFG:
|
||||
// Don't write IDE_CFG if this is a IDE-to-Flash switch
|
||||
if (NewData == 0xDEADBEEF && Pci->LBar) {
|
||||
return NewData;
|
||||
}
|
||||
case IDE_DTC: // 0x48
|
||||
case IDE_CAST: // 0x4C
|
||||
case IDE_ETC: // 0x50
|
||||
// Thor ATA vendor-specific registers:
|
||||
if (Pci->LBar) {
|
||||
ULONG MsrAddr = ATA_Error;
|
||||
|
||||
(USHORT)MsrAddr = (USHORT)Pci->LBar;
|
||||
|
||||
// Sync with the current MSR value
|
||||
PreviousData = Read_MSR_LO(MsrAddr);
|
||||
|
||||
// Update Thor ATA MSR with the new value
|
||||
Pci->Value = (NewData & Mask) | (PreviousData & ~Mask);
|
||||
Write_MSR_LO(MsrAddr, Pci->Value);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
#if SUPPORT_CAPABILITIES
|
||||
case BAR0:
|
||||
case USBLEGCTLSTS:
|
||||
case SRBN_REG:
|
||||
if (Pci->Flag & PCI_EHCI) {
|
||||
Handle_EHCI_Wr(Pci);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
default:
|
||||
// Is it a BAR ?
|
||||
if (Pci->Flag & (MMIO_BAR | MEM_BAR | IO_BAR)) {
|
||||
// If value has changed, update the MBus descriptor
|
||||
if (PreviousData != Data) {
|
||||
// I/O BAR and Memory BAR ?
|
||||
EnableFlag = (Pci->Flag & IO_BAR) ? IO_SPACE : MEM_SPACE;
|
||||
EnableFlag &= (UCHAR)CommandPtr->Value;
|
||||
Update_BAR(Pci, EnableFlag);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
} // end switch(AlignedReg)
|
||||
|
||||
return Pci->Value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
387
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/port92.asm
vendored
Executable file
387
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/port92.asm
vendored
Executable file
@@ -0,0 +1,387 @@
|
||||
;
|
||||
; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
;
|
||||
; This library is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU Lesser General Public License as
|
||||
; published by the Free Software Foundation; either version 2.1 of the
|
||||
; License, or (at your option) any later version.
|
||||
;
|
||||
; This code is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
; Lesser General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU Lesser General
|
||||
; Public License along with this library; if not, write to the
|
||||
; Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
; Boston, MA 02111-1307 USA
|
||||
;
|
||||
|
||||
;*******************************************************************************
|
||||
;* Port 92h routines
|
||||
;*******************************************************************************
|
||||
|
||||
|
||||
include SYSMGR.INC
|
||||
include VSA2.INC
|
||||
include GX2.INC
|
||||
include CHIPSET.INC
|
||||
include CS5536.INC
|
||||
include ISA.INC
|
||||
include PCI.INC
|
||||
include MDD.INC
|
||||
include HCE.INC
|
||||
include SMIMAC.MAC
|
||||
|
||||
.model tiny,c
|
||||
.586p
|
||||
.CODE
|
||||
|
||||
|
||||
externdef VSA_Exit: proc
|
||||
externdef MDD_Base: dword
|
||||
externdef FooGlue: dword
|
||||
externdef OHCI1_Smi: dword
|
||||
externdef OHCI2_Smi: dword
|
||||
externdef Nested_Flag: dword
|
||||
externdef Saved_EAX: dword
|
||||
externdef Saved_EBX: dword
|
||||
externdef Saved_ECX: dword
|
||||
externdef Saved_EDX: dword
|
||||
externdef Saved_ESI: dword
|
||||
externdef Saved_EDI: dword
|
||||
externdef Saved_EBP: dword
|
||||
externdef Saved_ESP: dword
|
||||
externdef IDT_Base: dword
|
||||
externdef IDT_Limit: dword
|
||||
externdef IDT_Selector: dword
|
||||
externdef SMI_Sources: dword
|
||||
externdef SMM_Header: SmiHeader
|
||||
externdef Saved_SS: Descriptor
|
||||
externdef Data_Descriptor: Descriptor
|
||||
externdef HardwareInfo: Hardware
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
;
|
||||
; A20_Sync - synchronize port 92h and virtual A20 pin
|
||||
;
|
||||
;***********************************************************************
|
||||
A20_Sync proc uses si edi
|
||||
|
||||
; Determine if it is a nested access to port 92h
|
||||
btr word ptr [Nested_Flag], SMI_SRC_A20_INDEX
|
||||
jc short Get_A20_Data
|
||||
rsdc gs, cs:[Data_Descriptor]
|
||||
Get_A20_Data:
|
||||
ASSUME SI: ptr SmiHeader
|
||||
mov si, OFFSET VSM_Header.SysStuff.State
|
||||
mov bl, byte ptr gs:[si].write_data ; Get I/O data
|
||||
mov si, gs:[si].IO_addr ; Get I/O address
|
||||
ASSUME SI:NOTHING
|
||||
|
||||
; Set A20M in FooGlue appropriately
|
||||
mov ecx, [FooGlue]
|
||||
add cx, FG_A20M
|
||||
rdmsr
|
||||
and al, NOT A20M ; A20M = 0
|
||||
|
||||
and bl, 02h ; Check A20M setting
|
||||
jnz short Set_A20
|
||||
or al, A20M ; Force A20 low
|
||||
Set_A20:
|
||||
wrmsr
|
||||
|
||||
cmp si, 0092h ; If port 92h, no update necessary
|
||||
je short SyncHceControl
|
||||
|
||||
cmp si, KYBD_DATA ; If not 8042 data port, ignore
|
||||
jne Return
|
||||
|
||||
; Sync Port 92h to keyboard controller
|
||||
mov ecx, [MDD_Base] ; Disable Port 92h trapping
|
||||
mov cx, MBD_MSR_SMI
|
||||
rdmsr
|
||||
push ax
|
||||
and al, NOT A20_P_EN
|
||||
wrmsr
|
||||
|
||||
mov al, bl ; Update Port 92h A20 state
|
||||
out 92h, al
|
||||
|
||||
pop ax ; Restore Port 92h trapping
|
||||
wrmsr
|
||||
|
||||
; Synchronize HceControl[A20State] with port 92h
|
||||
SyncHceControl:
|
||||
mov ecx, [OHCI1_Smi] ; Read OHCI1 h/w BAR0
|
||||
test ecx, 0FFF00000h
|
||||
jnz short Get_HC_Base
|
||||
mov ecx, [OHCI2_Smi] ; Use OHCI2 if OHCI1 not used
|
||||
test ecx, 0FFF00000h
|
||||
jz Return
|
||||
Get_HC_Base:
|
||||
mov cx, 1000h + BAR0/4 ; 5536 Embedded PCI MSR
|
||||
cmp [HardwareInfo].Chipset_ID, DEVICE_ID_5536
|
||||
je short ReadBAR
|
||||
mov cx, USBMSROHCB ; 5536 OHCI MSR
|
||||
ReadBAR:
|
||||
rdmsr
|
||||
|
||||
mov bh, 0 ; Clear MSR restore flag
|
||||
or eax, eax ; Is BAR initialized ?
|
||||
jnz short SyncA20State
|
||||
mov bh, 1 ; Set MSR restore flag
|
||||
|
||||
push eax ; Save current OHCI MSR
|
||||
push edx
|
||||
push ecx
|
||||
|
||||
; OHCI BAR is not initialized or OHCI header is hidden.
|
||||
; Temporarily map the OHCI register set just above VSA
|
||||
; This range has been declared as OS-reserved in INT 15h E820h
|
||||
mov ecx, MSR_RCONF_SMM
|
||||
rdmsr
|
||||
lea edi, [edx+1000h]
|
||||
pop ecx
|
||||
push ecx
|
||||
|
||||
mov edx, 00000000Eh
|
||||
mov eax, edi
|
||||
wrmsr
|
||||
|
||||
mov ecx, [MDD_Base]
|
||||
mov cx, MSR_LBAR_KEL1
|
||||
rdmsr
|
||||
push eax ; Save current KEL LBAR
|
||||
push edx
|
||||
push ecx
|
||||
mov eax, edi
|
||||
mov edx, 0FFFFF001h
|
||||
wrmsr
|
||||
|
||||
; Synchronize HceControl.A20State
|
||||
SyncA20State:
|
||||
or ax, OFFSET (HCOR Ptr ds:[0]).HceControl
|
||||
mov dx, fs:[eax]
|
||||
cmp dx, 0FFFFh ; Is Memory Space enabled ?
|
||||
je short Exit
|
||||
CLEAR_A20 equ (A20_STATE OR IRQ1_ACTIVE OR IRQ12_ACTIVE)
|
||||
; SWAPSiF for SiBZ 3509/3571: KEL SMIs are level instead of edge-triggered
|
||||
; Manifests itself as PBZ 3878: PS/2 keyboard hangs after running PCIDIAG
|
||||
test dx, (IRQ1_ACTIVE OR IRQ12_ACTIVE)
|
||||
jz short NoIRQ
|
||||
or [SMI_Sources], SMI_SRC_KEL ; Fake another KEL SMI
|
||||
NoIRQ:
|
||||
and dx, NOT CLEAR_A20 ; Clear A20State
|
||||
test bl, 02h
|
||||
jz Update_HceControl
|
||||
or dx, A20_STATE ; Set A20State
|
||||
Update_HceControl:
|
||||
mov fs:[eax], dx
|
||||
|
||||
Exit:
|
||||
or bh, bh ; Do OHCI MSRs need to be restored?
|
||||
je short Return
|
||||
|
||||
pop ecx ; Restore KEL LBAR
|
||||
pop edx
|
||||
pop eax
|
||||
wrmsr
|
||||
|
||||
pop ecx ; Restore OHCI MSR
|
||||
pop edx
|
||||
pop eax
|
||||
wrmsr
|
||||
Return:
|
||||
ret
|
||||
|
||||
A20_Sync endp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Sets the top-level RSM state to the reset state:
|
||||
; 1) Real-mode IDT
|
||||
; 2) Real-mode descriptors; segment regisers = 0000
|
||||
; 3) CS:EIP = F000:FFF0
|
||||
; 4) CS base = FFFF0000
|
||||
; 5) CS limit = 64K
|
||||
; 6) DX = CPU ID
|
||||
;***********************************************************************
|
||||
set_reset_state proc uses si
|
||||
|
||||
; Check if user code is doing a 286-style shutdown
|
||||
in al, CMOS_INDEX ; Preserve CMOS index
|
||||
mov ah, al
|
||||
|
||||
mov al, 0Fh
|
||||
out CMOS_INDEX, al
|
||||
in al, CMOS_DATA
|
||||
|
||||
xchg al, ah
|
||||
out CMOS_INDEX, al ; Restore CMOS index
|
||||
|
||||
cmp ah, 09H
|
||||
je UserShutdown
|
||||
|
||||
cmp ah, 05H
|
||||
je UserShutdown
|
||||
|
||||
cmp ah, 0AH
|
||||
je UserShutdown
|
||||
|
||||
cmp ah, 0FFH ; JMP if no CMOS present
|
||||
je UserShutdown
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
CACHE_LINE_SIZE equ 32
|
||||
|
||||
; If cache is disabled, there is no way to guarantee that
|
||||
; the entire code sequence from DisableCKE to Pre_Fetch
|
||||
; will be fetched before CKE is disabled. It was decided
|
||||
; we'd rather see the original POST 0xBF hang rather than
|
||||
; a hang in SMM.
|
||||
mov ebp, [MDD_Base] ; Prepare reset MSR
|
||||
mov bp, MSR_SOFT_RESET
|
||||
mov eax, CR0 ; Is cache disabled ?
|
||||
test eax, 40000000h
|
||||
jnz Reset
|
||||
|
||||
lea si, [DisableCKE] ; Move code to start of a cache line
|
||||
mov di, si
|
||||
and di, NOT (CACHE_LINE_SIZE-1)
|
||||
mov bx, di ; Remember where we moved it to
|
||||
cld
|
||||
@@: lodsd
|
||||
mov [di], eax
|
||||
add di, 4
|
||||
cmp si, OFFSET Pre_Fetch
|
||||
jb @b
|
||||
|
||||
mov ecx, 2000001Dh ; Memory controller
|
||||
rdmsr
|
||||
or ah, 3 ; Set CKE Mask = 11b
|
||||
|
||||
jmp Pre_Fetch
|
||||
|
||||
|
||||
|
||||
; Bug #118.226 - Some DIMMs hang at POST 0xBF on a reboot
|
||||
;
|
||||
; Need to de-assert CKE off before command signals are tri-stated.
|
||||
; There can be no memory accesses after the following WRMSR.
|
||||
; If cache is disabled, there is no way to satisfy this condition,
|
||||
; so some DIMMs with cache disabled is not supported with
|
||||
; respect to resets.
|
||||
db CACHE_LINE_SIZE dup (90h)
|
||||
DisableCKE:
|
||||
wrmsr
|
||||
|
||||
; Reset the CPU via MDD MSR_SOFT_RESET
|
||||
Reset: mov ecx, ebp
|
||||
mov al, 1
|
||||
wrmsr
|
||||
jmp $
|
||||
Pre_Fetch:
|
||||
; Prefetch 4 cache lines of NOPs so there won't be any
|
||||
; prefetching to memory after the MC MSR is written.
|
||||
db 4*CACHE_LINE_SIZE dup (90h) ; 4 cache lines
|
||||
jmp bx
|
||||
|
||||
UserShutdown:
|
||||
|
||||
mov ecx, [FooGlue] ; Disable A20 mask
|
||||
add cx, FG_A20M
|
||||
rdmsr
|
||||
and al, NOT A20M ; A20M = 0
|
||||
wrmsr
|
||||
|
||||
; Disable the cache & flush it
|
||||
mov eax, CR0
|
||||
or eax, 60000000h
|
||||
mov CR0, eax
|
||||
wbinvd
|
||||
|
||||
; Set real-mode IDT
|
||||
mov [IDT_Limit], 0FFFFh ; Limit
|
||||
mov [IDT_Base], 00000000h ; Base
|
||||
mov [IDT_Selector], 00920000h ; Selector & Attributes
|
||||
|
||||
|
||||
; INIT is broken on LX 2.x and 3.0
|
||||
cmp [HardwareInfo].CPU_ID, DEVICE_ID_LX
|
||||
jne short Set_INIT
|
||||
mov ax, [HardwareInfo].CPU_Revision
|
||||
cmp al, 30h ; Is it 3.0?
|
||||
jae short FakeInit
|
||||
and al, 0F0h ; Is it 2.x?
|
||||
cmp al, 20h
|
||||
je short FakeInit
|
||||
|
||||
call VSA_Exit
|
||||
|
||||
; Reset via INIT MSR
|
||||
Set_INIT:
|
||||
mov ecx, [FooGlue] ; Reset the CPU
|
||||
add cx, FG_INIT
|
||||
xor eax, eax
|
||||
wrmsr
|
||||
mov al, INIT
|
||||
wrmsr
|
||||
|
||||
; Fake an INIT by setting up initial CPU state
|
||||
FakeInit:
|
||||
lea si, [Saved_SS] ; Set descriptors to 64K real-mode
|
||||
mov cx, 5 ; # descriptors to fill
|
||||
mov eax, 0000FFFFh ; limit_15_0 & base_15_0
|
||||
DescrLoop:
|
||||
mov [si+0], eax ; limit_15_0 & base_15_0
|
||||
mov dword ptr [si+4], 00009200h ; base_23_16, attr, limit_19_16 & base_31_24
|
||||
mov word ptr [si+8], 0000h ; selector
|
||||
add si, sizeof (Descriptor) ; Advance ptr to next descriptor
|
||||
loop DescrLoop
|
||||
|
||||
|
||||
; Set top-level SMM header to reset state
|
||||
mov bx, OFFSET SMM_Header
|
||||
ASSUME BX: PTR SmiHeader
|
||||
mov [bx]._CS.limit, eax
|
||||
mov [bx]._CS.base, 0FFFF0000h
|
||||
mov [bx]._CS.selector, 0F000h
|
||||
mov [bx]._CS.attr, 92h
|
||||
|
||||
mov [bx].Next_EIP, 0000FFF0h
|
||||
mov [bx].r_CR0, 60000010h ; Real-mode; cache disabled
|
||||
mov [bx].r_DR7, 00000400h
|
||||
mov [bx].EFLAGS, 00000002h
|
||||
mov [bx].SMI_Flags, 8001h ; CS is R/W
|
||||
|
||||
mov [bx].SS_Flags, DATA_ATTR
|
||||
|
||||
; Initialize general purpose register
|
||||
mov [Saved_EDX], 00000540h ; CPU ID
|
||||
xor eax, eax
|
||||
mov [Saved_EAX], eax
|
||||
mov [Saved_EBX], eax
|
||||
mov [Saved_ECX], eax
|
||||
mov [Saved_EDI], eax
|
||||
mov [Saved_ESI], eax
|
||||
mov [Saved_EBP], eax
|
||||
mov [Saved_ESP], eax
|
||||
|
||||
ret
|
||||
|
||||
set_reset_state endp
|
||||
|
||||
end
|
||||
91
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/protos.h
vendored
Executable file
91
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/protos.h
vendored
Executable file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
typedef unsigned short EVENT;
|
||||
typedef unsigned short MSG;
|
||||
typedef unsigned short PRIORITY;
|
||||
typedef unsigned long VSM;
|
||||
typedef void (* GPIO_FUNCTION)(unsigned long, unsigned long, unsigned char);
|
||||
|
||||
|
||||
|
||||
void pascal out_8(unsigned short, unsigned char);
|
||||
void pascal out_16(unsigned short, unsigned short);
|
||||
void pascal out_32(unsigned short, unsigned long);
|
||||
unsigned char pascal in_8(unsigned short);
|
||||
unsigned short pascal in_16(unsigned short);
|
||||
unsigned long pascal in_32(unsigned short);
|
||||
|
||||
void pascal Hex_8(unsigned char);
|
||||
void pascal Hex_16(unsigned short);
|
||||
void pascal Hex_32(unsigned long);
|
||||
|
||||
|
||||
|
||||
extern void pascal Trap_PCI_IDSEL(unsigned short, unsigned char);
|
||||
extern unsigned char pascal Init_Descr(unsigned char, unsigned long);
|
||||
extern unsigned char pascal BitScanReverse(unsigned long);
|
||||
extern unsigned char pascal BitScanForward(unsigned long);
|
||||
extern unsigned long pascal read_flat(unsigned long);
|
||||
extern unsigned long pascal Read_MSR_LO(unsigned long);
|
||||
extern unsigned long pascal Read_MSR_HI(unsigned long);
|
||||
extern unsigned long pascal Virtual_PCI_Read_Handler(unsigned short);
|
||||
extern unsigned long pascal GetFlink(unsigned long);
|
||||
extern unsigned char pascal Get_VSM_Type(unsigned long);
|
||||
extern unsigned char pascal IsPowerOfTwo(unsigned long);
|
||||
extern unsigned short pascal Send_Event(EVENT, VSM);
|
||||
extern unsigned char pascal Find_Matching_IO_Descriptor(unsigned long *, unsigned short *, unsigned char);
|
||||
extern unsigned char pascal Setup_IO_Descriptor(unsigned long *, unsigned short *, unsigned char);
|
||||
extern void pascal Init_MBIU(unsigned char *, unsigned long);
|
||||
extern void pascal Get_Descriptor_Default(unsigned char, unsigned long *);
|
||||
extern unsigned long pascal Virtual_PCI_Write_Handler(unsigned short, unsigned char, unsigned long);
|
||||
extern void pascal write_flat(unsigned long, unsigned long);
|
||||
extern void pascal Read_MSR(unsigned long, unsigned long *);
|
||||
extern void pascal Write_MSR(unsigned long, unsigned long *);
|
||||
extern void pascal Write_MSR_LO(unsigned long, unsigned long);
|
||||
extern void pascal Write_MSR_HI(unsigned long, unsigned long);
|
||||
extern void pascal Store_Timestamp(void *);
|
||||
extern void pascal Schedule_VSM(unsigned long);
|
||||
extern void pascal Report_Error(unsigned char, unsigned long, unsigned long);
|
||||
extern void pascal Report_VSM_Error(unsigned char, unsigned long, unsigned long);
|
||||
extern void pascal Send_Message(VSM, VSM, unsigned long);
|
||||
extern void pascal Broadcast_Message(MSG, unsigned short, unsigned long);
|
||||
extern void pascal Register_Event(EVENT, PRIORITY, VSM, unsigned long, unsigned long);
|
||||
extern void pascal Enable_Event(EVENT, unsigned short, unsigned char);
|
||||
extern void pascal Disable_Event(EVENT, unsigned short);
|
||||
extern void pascal Unregister_VSM_Events(VSM);
|
||||
|
||||
extern void pascal IRQY_Mapper(unsigned char, unsigned char);
|
||||
extern void pascal IRQZ_Mapper(unsigned char, unsigned char);
|
||||
|
||||
|
||||
extern void Keep_History(EVENT, EVENT);
|
||||
extern unsigned short pascal Unregister_Event(EVENT, VSM, unsigned long, unsigned long);
|
||||
extern unsigned short pascal Allocate_BAR(unsigned char, unsigned short, unsigned long, unsigned short, unsigned short);
|
||||
|
||||
extern unsigned long Current_VSM;
|
||||
extern unsigned long SysMgr_VSM;
|
||||
|
||||
|
||||
extern void Log_Error(const char *format, ...);
|
||||
extern unsigned long pascal Compute_IOD_SC(unsigned long *, unsigned short *, unsigned char);
|
||||
extern void pascal MBus_IO_Trap(unsigned long, unsigned long, unsigned char);
|
||||
|
||||
|
||||
|
||||
209
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/smimac.mac
vendored
Executable file
209
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/smimac.mac
vendored
Executable file
@@ -0,0 +1,209 @@
|
||||
;
|
||||
; Copyright (c) 2006 Advanced Micro Devices,Inc. ("AMD").
|
||||
;
|
||||
; This library is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU Lesser General Public License as
|
||||
; published by the Free Software Foundation; either version 2.1 of the
|
||||
; License, or (at your option) any later version.
|
||||
;
|
||||
; This code is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
; Lesser General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU Lesser General
|
||||
; Public License along with this library; if not, write to the
|
||||
; Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
; Boston, MA 02111-1307 USA
|
||||
;
|
||||
|
||||
|
||||
smint macro
|
||||
db 0Fh, 38h
|
||||
endm
|
||||
|
||||
|
||||
|
||||
EREG macro Reg
|
||||
ifidni <Reg>, <eax>
|
||||
db 0C8h
|
||||
elseifidni <Reg>, <ecx>
|
||||
db 0C9h
|
||||
elseifidni <Reg>, <edx>
|
||||
db 0CAh
|
||||
elseifidni <Reg>, <ebx>
|
||||
db 0CBh
|
||||
elseifidni <Reg>, <esp>
|
||||
db 0CCh
|
||||
elseifidni <Reg>, <ebp>
|
||||
db 0CDh
|
||||
elseifidni <Reg>, <esi>
|
||||
db 0CEh
|
||||
elseifidni <Reg>, <edi>
|
||||
db 0CFh
|
||||
else
|
||||
.err
|
||||
|
||||
endif
|
||||
|
||||
endm
|
||||
|
||||
|
||||
RDSHR macro Reg
|
||||
db 0Fh, 36h
|
||||
EREG Reg
|
||||
endm
|
||||
|
||||
WRSHR macro Reg
|
||||
db 0Fh, 37h
|
||||
EREG Reg
|
||||
endm
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
MOV_EAX_CR4 macro
|
||||
db 0Fh, 20h, 0E0h ; mov eax, CR4
|
||||
ENDM
|
||||
|
||||
MOV_CR4_EAX macro
|
||||
db 0Fh, 22h, 0E0h ; mov CR4, eax
|
||||
ENDM
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
SMM_Instr macro Reg:REQ, Addr:REQ, Opcode:REQ
|
||||
Local Place1, Place2, Attr, InstrLen
|
||||
|
||||
|
||||
|
||||
Place1:
|
||||
|
||||
|
||||
ifidni <Reg>, <ES>
|
||||
LFS ax, dword ptr Addr
|
||||
elseifidni <Reg>, <SS>
|
||||
LFS dx, dword ptr Addr
|
||||
elseifidni <Reg>, <DS>
|
||||
LFS bx, dword ptr Addr
|
||||
elseifidni <Reg>, <FS>
|
||||
LFS sp, dword ptr Addr
|
||||
elseifidni <Reg>, <GS>
|
||||
LFS bp, dword ptr Addr
|
||||
elseifidni <Reg>, <CS>
|
||||
LFS cx, dword ptr Addr
|
||||
else
|
||||
.err "Error in RSDC macro"
|
||||
endif
|
||||
|
||||
Place2:
|
||||
|
||||
Extras = 1
|
||||
SegOverride INSTR <Addr>, <:>
|
||||
if SegOverride
|
||||
Extras = Extras + 1
|
||||
endif
|
||||
|
||||
AddrOverride INSTR <Addr>, <eax>
|
||||
if AddrOverride
|
||||
Extras = Extras + 1
|
||||
else
|
||||
AddrOverride INSTR <Addr>, <EAX>
|
||||
if AddrOverride
|
||||
Extras = Extras + 1
|
||||
else
|
||||
AddrOverride INSTR <Addr>, <ebx>
|
||||
if AddrOverride
|
||||
Extras = Extras + 1
|
||||
else
|
||||
AddrOverride INSTR <Addr>, <EBX>
|
||||
if AddrOverride
|
||||
Extras = Extras + 1
|
||||
else
|
||||
AddrOverride INSTR <Addr>, <ecx>
|
||||
if AddrOverride
|
||||
Extras = Extras + 1
|
||||
else
|
||||
AddrOverride INSTR <Addr>, <ECX>
|
||||
if AddrOverride
|
||||
Extras = Extras + 1
|
||||
else
|
||||
AddrOverride INSTR <Addr>, <edx>
|
||||
if AddrOverride
|
||||
Extras = Extras + 1
|
||||
else
|
||||
AddrOverride INSTR <Addr>, <EDX>
|
||||
if AddrOverride
|
||||
Extras = Extras + 1
|
||||
else
|
||||
AddrOverride INSTR <Addr>, <esi>
|
||||
if AddrOverride
|
||||
Extras = Extras + 1
|
||||
else
|
||||
AddrOverride INSTR <Addr>, <ESI>
|
||||
if AddrOverride
|
||||
Extras = Extras + 1
|
||||
else
|
||||
AddrOverride INSTR <Addr>, <edi>
|
||||
if AddrOverride
|
||||
Extras = Extras + 1
|
||||
else
|
||||
AddrOverride INSTR <Addr>, <EDI>
|
||||
if AddrOverride
|
||||
Extras = Extras + 1
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ORG Place1 + Extras
|
||||
db Opcode
|
||||
ORG Place2
|
||||
|
||||
endm
|
||||
|
||||
svdc macro Addr:REQ, Reg:REQ
|
||||
SMM_Instr Reg, Addr, 78h
|
||||
endm
|
||||
|
||||
rsdc macro Reg:REQ, Addr:REQ
|
||||
SMM_Instr Reg, Addr, 79h
|
||||
endm
|
||||
|
||||
|
||||
svldt macro Addr:REQ
|
||||
SMM_Instr <ES>, Addr, 7Ah
|
||||
endm
|
||||
|
||||
|
||||
rsldt macro Addr:REQ
|
||||
SMM_Instr <ES>, Addr, 7Bh
|
||||
endm
|
||||
|
||||
svts macro Addr:REQ
|
||||
SMM_Instr <ES>, Addr, 7Ch
|
||||
endm
|
||||
|
||||
|
||||
rsts macro Addr:REQ
|
||||
SMM_Instr <ES>, Addr, 7Dh
|
||||
endm
|
||||
|
||||
|
||||
354
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/smis.asm
vendored
Executable file
354
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/smis.asm
vendored
Executable file
@@ -0,0 +1,354 @@
|
||||
;
|
||||
; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
;
|
||||
; This library is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU Lesser General Public License as
|
||||
; published by the Free Software Foundation; either version 2.1 of the
|
||||
; License, or (at your option) any later version.
|
||||
;
|
||||
; This code is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
; Lesser General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU Lesser General
|
||||
; Public License along with this library; if not, write to the
|
||||
; Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
; Boston, MA 02111-1307 USA
|
||||
;
|
||||
;********************************************************************************
|
||||
;* This file contains the code for reading the source of SMIs.
|
||||
;********************************************************************************
|
||||
|
||||
|
||||
include GX2.INC
|
||||
include VSA2.INC
|
||||
include SYSMGR.INC
|
||||
include CS5536.INC
|
||||
include CHIPSET.INC
|
||||
include MDD.INC
|
||||
include PCI.INC
|
||||
|
||||
.model tiny,c
|
||||
.586p
|
||||
.CODE
|
||||
ASSUME DS:_TEXT
|
||||
|
||||
SYNCHRONOUS equ (SMI_SRC_PCI_TRAP OR SMI_SRC_DESCR_HIT OR SMI_SRC_PM OR SMI_SRC_RESET OR SMI_SRC_BLOCKIO OR SMI_SRC_A20)
|
||||
SMI_Sources dd 0
|
||||
Video_Sources dd 0
|
||||
Audio_Sources dw 0
|
||||
Stats_Sources dd 0
|
||||
SynchEvents dd SYNCHRONOUS
|
||||
HiPrioritySMIs dd SMI_SRC_AUDIO OR SMI_SRC_USB1 OR SMI_SRC_USB2
|
||||
|
||||
public SynchEvents, HiPrioritySMIs
|
||||
public SMI_Sources, Audio_Sources, Stats_Sources, Video_Sources
|
||||
|
||||
externdef pascal Hex_8:proc
|
||||
externdef pascal Hex_16:proc
|
||||
externdef pascal Hex_32:proc
|
||||
externdef pascal Generate_IRQ_5536: proc
|
||||
|
||||
externdef SMI_Base: dword
|
||||
externdef Mbiu0: dword
|
||||
externdef Mbiu1: dword
|
||||
externdef Mbiu2: dword
|
||||
externdef MPCI_NB: dword
|
||||
externdef MPCI_SB: dword
|
||||
externdef MDD_Base: dword
|
||||
externdef MCP_NB: dword
|
||||
externdef ATA_Error: dword
|
||||
externdef OHCI1_Smi: dword
|
||||
externdef OHCI2_Smi: dword
|
||||
externdef HardwareInfo: Hardware
|
||||
|
||||
|
||||
|
||||
;*************************************************************************
|
||||
; Installs the SMI routine(s) appropriate to the chipset.
|
||||
; The default routine(s) are for CS5536.
|
||||
;*************************************************************************
|
||||
Install_SMI_Routines proc
|
||||
|
||||
;5536 already set, do nothing. mov [OHCI_SMI], OHCSSTAT
|
||||
Exit: ret
|
||||
|
||||
Install_SMI_Routines endp
|
||||
|
||||
|
||||
|
||||
|
||||
;************************************************************************
|
||||
; Asserts/deasserts internal IRQs
|
||||
; On Entry:
|
||||
; ECX = IRQ mask
|
||||
; 16 LSBs - enable
|
||||
; 16 MSBs - disable
|
||||
;************************************************************************
|
||||
Generate_IRQ proc
|
||||
|
||||
push cx
|
||||
call word ptr [IRQ_Routine]
|
||||
ret
|
||||
|
||||
IRQ_Routine::
|
||||
dw OFFSET Generate_IRQ_5536
|
||||
|
||||
Generate_IRQ endp
|
||||
|
||||
|
||||
|
||||
|
||||
;*************************************************************************
|
||||
; Reads & clears all SMI source registers (MSRs & Southbridge)
|
||||
; On Exit:
|
||||
; EBX = SMI sources
|
||||
; All other registers may be destroyed
|
||||
;*************************************************************************
|
||||
Get_SMI_Sources proc
|
||||
|
||||
mov ebx, [SMI_Sources] ; Get SMIs that have not yet been handled
|
||||
call Get_Northbridge_SMIs
|
||||
or ebx, ebx ; If any NB SMIs, handle them quickly
|
||||
jz short Get_SB_SMIs
|
||||
ret
|
||||
Get_SB_SMIs:
|
||||
|
||||
jmp word ptr [SMI_Routine] ; Get Southbridge SMI(s)
|
||||
|
||||
SMI_Routine::
|
||||
dw OFFSET Get_5536_SMIs
|
||||
|
||||
Get_SMI_Sources endp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Gets SMI sources from Northbridge
|
||||
; On Entry:
|
||||
; EBX = pending SMI sources
|
||||
; NOTES:
|
||||
; - May set SMI source bits in EBX.
|
||||
;***********************************************************************
|
||||
MPCI_ERROR equ (MARE + TARE + PARE + BME + SYSE)
|
||||
VGA_BLANK equ 08h
|
||||
VG_BLANK equ 01h
|
||||
VERT_BLANK equ (VGA_BLANK OR VG_BLANK)
|
||||
|
||||
Get_Northbridge_SMIs proc
|
||||
|
||||
mov ecx, [MPCI_NB] ; MBIU1.MPCI.0.0.0.0
|
||||
mov cx, MBD_MSR_SMI
|
||||
rdmsr
|
||||
wrmsr ; Clear the MPCI SMI event(s)
|
||||
|
||||
mov dl, al ; Only record enabled events
|
||||
not dl
|
||||
shr eax, 16
|
||||
and al, dl ; Only consider unmasked events
|
||||
jz short Graphics_SMIs ; Jmp if no MPCI SMI is pending
|
||||
|
||||
test al, VPHE SHR 16 ; Is it a virtualized PCI header ?
|
||||
jz short CheckMPCI
|
||||
or ebx, SMI_SRC_PCI_TRAP ; Yes, record the event
|
||||
|
||||
cmp al, VPHE SHR 16 ; Is VPHE the only SMI pending ?
|
||||
je short Exit ; Yes, do a quick exit
|
||||
|
||||
|
||||
CheckMPCI:
|
||||
test ax, MPCI_ERROR SHR 16 ; Is it an MPCI error ?
|
||||
jz short Graphics_SMIs
|
||||
or ebx, SMI_SRC_MPCI ; Yes
|
||||
|
||||
mov cx, MBD_MSR_ERROR ; Clear the MPCI error(s)
|
||||
rdmsr
|
||||
wrmsr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;*******************************************
|
||||
; Check for graphics SMIs
|
||||
;*******************************************
|
||||
|
||||
; Value in Video_Sources:
|
||||
;
|
||||
; Bit Description
|
||||
; ----- -----------------------------------
|
||||
; 0 DF: SMI #1 (TBD)
|
||||
; 1 DF: SMI #2 (TBD)
|
||||
; 2 GP: SMI (address or type violation)
|
||||
; 3 reserved
|
||||
; 4 VG: Miscellaneous Output SMI
|
||||
; 5 VG: Input Status register SMI
|
||||
; 6 reserved
|
||||
; 7 VG: CRTC invalid I/O SMI
|
||||
Graphics_SMIs:
|
||||
; Video Generator
|
||||
mov ecx, VG_SMI_MSR
|
||||
rdmsr
|
||||
wrmsr ; Clear SMI(s)
|
||||
|
||||
; Because the VG records all events that occur in the upper half of the MSR
|
||||
; regardless of whether or not they generate SMIs, we need to clear out the
|
||||
; events that aren't generating SMIs and only look for valid ones.
|
||||
not eax ; NOT the SMI mask
|
||||
and edx,eax ; Clear out untrapped events
|
||||
|
||||
test dl, VERT_BLANK ; Is a vertical blank pending ?
|
||||
jz short SaveVideoSources
|
||||
and dl, NOT (VERT_BLANK)
|
||||
or ebx, SMI_SRC_RETRACE ; Yes, record EVENT_VBLANK
|
||||
SaveVideoSources:
|
||||
or [Video_Sources], edx
|
||||
jz short Statistic_SMIs
|
||||
or ebx, SMI_SRC_VG ; Yes, then record EVENT_GRAPHICS
|
||||
|
||||
|
||||
;*******************************************
|
||||
; Check for Statistic Counter SMI(s)
|
||||
;*******************************************
|
||||
Statistic_SMIs:
|
||||
mov ecx, [Mbiu0] ; Check MBIU0 Statistics Counters
|
||||
call Get_MBD_SMIs
|
||||
or byte ptr [Stats_Sources+0], dl
|
||||
|
||||
mov ecx, [Mbiu1] ; Check MBIU1 Statistics Counters
|
||||
call Get_MBD_SMIs
|
||||
or byte ptr [Stats_Sources+1], dl
|
||||
Exit:
|
||||
ret
|
||||
|
||||
Get_Northbridge_SMIs endp
|
||||
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Checks for events in MBD_MSR_SMI:
|
||||
; - descriptor traps
|
||||
; - statistic counters
|
||||
; On entry: ECX = base address of GLIU
|
||||
; Returns: DL = statistic event mask
|
||||
;***********************************************************************
|
||||
Get_MBD_SMIs proc
|
||||
|
||||
mov cx, MBD_MSR_ERROR ; Clear errors
|
||||
rdmsr
|
||||
wrmsr
|
||||
|
||||
mov cx, MBD_MSR_SMI
|
||||
rdmsr
|
||||
|
||||
and dl, 1Fh ; Any SMIs pending ?
|
||||
jz short Exit ; No, just exit
|
||||
wrmsr
|
||||
|
||||
btr dx, 0 ; Is it a MBIU descriptor hit ?
|
||||
jnc short StatCntrs
|
||||
or ebx, SMI_SRC_DESCR_HIT ; Yes
|
||||
|
||||
StatCntrs:
|
||||
or dl, dl ; Any hits on statistic counters ?
|
||||
jz short Exit
|
||||
or ebx, SMI_SRC_STAT ; Yes, record the event
|
||||
or al, dl ; Disable further events
|
||||
|
||||
wrmsr
|
||||
|
||||
shr dl, 1
|
||||
Exit:
|
||||
ret
|
||||
|
||||
Get_MBD_SMIs endp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;*************************************************************************
|
||||
; Reads and clears CS5536 SMI source registers
|
||||
;*************************************************************************
|
||||
Get_5536_SMIs proc
|
||||
|
||||
mov ecx, [MDD_Base] ; Check for MDD SMIs
|
||||
mov cx, MBD_MSR_SMI
|
||||
rdmsr
|
||||
wrmsr ; Clear any pending SMI(s)
|
||||
or dx, dx ; Any MDD SMIs pending ?
|
||||
jz short Get_MPCI_SB ; No
|
||||
|
||||
xor eax, eax
|
||||
MDD_Loop:
|
||||
bsf ax, dx ; Determine next pending event
|
||||
jz Exit
|
||||
btr dx, ax ; Clear the status bit
|
||||
or ebx, dword ptr [eax*4+MDD_Sources]
|
||||
jmp short MDD_Loop
|
||||
|
||||
|
||||
; MDD SMI sources
|
||||
MDD_Sources:
|
||||
dd 0 ; HLT_ASMI_STAT
|
||||
dd 0 ; SHUTDOWN_ASMI_STAT
|
||||
dd SMI_SRC_KEL ; KEL_ASMI_STAT
|
||||
dd SMI_SRC_PIC ; PIC_ASMI_STAT
|
||||
dd SMI_SRC_PME ; PM_ASMI_STAT
|
||||
dd SMI_SRC_RESET ; INIT_K_STAT
|
||||
dd SMI_SRC_A20 ; A20_P_STAT
|
||||
dd SMI_SRC_RESET ; INIT_P_STAT
|
||||
dd 0 ; UART1_SSMI_STAT
|
||||
dd 0 ; UART2_SSMI_STAT
|
||||
dd 0 ; RESERVED_STAT
|
||||
dd 0 ; LPC_SSMI_STAT
|
||||
dd 0 ; DMA_SSMI_STAT
|
||||
dd SMI_SRC_A20 ; A20_K_STAT
|
||||
dd SMI_SRC_ACPI ; PM2_CNT_SSMI_STAT
|
||||
dd SMI_SRC_ACPI ; PM1_CNT_SSMI_STAT
|
||||
|
||||
|
||||
|
||||
Get_MPCI_SB:
|
||||
mov ecx, [MPCI_SB] ; Get Southbridge MPCI events
|
||||
mov cx, MBD_MSR_SMI
|
||||
rdmsr
|
||||
wrmsr ; Clear any pending SMI(s)
|
||||
|
||||
mov ecx, [Mbiu2] ; Check for MBIU2 SMIs
|
||||
call Get_MBD_SMIs
|
||||
or byte ptr [Stats_Sources+2], dl
|
||||
|
||||
mov ecx, [OHCI1_Smi] ; Check for USB #1 SMIs
|
||||
jcxz short Exit
|
||||
rdmsr
|
||||
test dl, [OHCI_SMI] ; OHCI SMI pending ?
|
||||
jz short Exit ; JMP if not
|
||||
wrmsr ; Yes, clear the SMI
|
||||
or ebx, SMI_SRC_USB1 ; Record the SMI event
|
||||
|
||||
Exit: ret
|
||||
|
||||
Get_5536_SMIs endp
|
||||
|
||||
|
||||
OHCSSTAT equ 10h ; 5536
|
||||
OHCI_SMI db OHCSSTAT ; Assume 5536; could patched by Install_SMI_Routines() if other
|
||||
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
502
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/sw_int.asm
vendored
Executable file
502
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/sw_int.asm
vendored
Executable file
@@ -0,0 +1,502 @@
|
||||
;
|
||||
; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
;
|
||||
; This library is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU Lesser General Public License as
|
||||
; published by the Free Software Foundation; either version 2.1 of the
|
||||
; License, or (at your option) any later version.
|
||||
;
|
||||
; This code is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
; Lesser General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU Lesser General
|
||||
; Public License along with this library; if not, write to the
|
||||
; Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
; Boston, MA 02111-1307 USA
|
||||
;
|
||||
;********************************************************************************
|
||||
;* Implementation of BIOS callbacks
|
||||
;********************************************************************************
|
||||
|
||||
|
||||
include SYSMGR.INC
|
||||
include VSA2.INC
|
||||
include SMIMAC.MAC
|
||||
include GX2.INC
|
||||
include ISA.INC
|
||||
|
||||
.model tiny,c
|
||||
.586p
|
||||
.ALPHA
|
||||
DGROUP GROUP _CODE, _TEXT
|
||||
_CODE SEGMENT PUBLIC use16 'CODE'
|
||||
ASSUME DS:_CODE
|
||||
|
||||
public VSM_Buffer
|
||||
|
||||
SMINT_SEGMENT equ 0E000h ; Segment to store SMINT instruction & ISR stack
|
||||
ALLOW_SMM_SEGMENTS equ 0 ; 1 = ES segment allowed to point to SMM memory
|
||||
|
||||
|
||||
externdef pascal Report_VSM_Error: proc
|
||||
externdef pascal Schedule_VSM: proc
|
||||
externdef Sys_Exit: proc
|
||||
externdef pascal Hex_8: proc
|
||||
externdef pascal Hex_16: proc
|
||||
externdef pascal Hex_32: proc
|
||||
|
||||
externdef BracketFlag: byte
|
||||
externdef SchedulerStack: word
|
||||
externdef INT_Vectors: dword
|
||||
externdef Current_VSM: dword
|
||||
externdef StartSaveArea: dword
|
||||
externdef EndSaveArea: dword
|
||||
externdef SysMgr_VSM: dword
|
||||
externdef Header_Addr: dword
|
||||
externdef SMM_Header: SmiHeader
|
||||
|
||||
;************************************************************************
|
||||
; Implements the SYS_STATE macro
|
||||
;
|
||||
; Input:
|
||||
; CX = Flag: 0 = Save 1 = Restore
|
||||
; EDI = Offset to VSM's register buffer
|
||||
; DS = System Manager's data segment
|
||||
;************************************************************************
|
||||
Sys_State proc
|
||||
|
||||
cld
|
||||
mov eax, [Current_VSM] ; Create flat ptr to calling VSM
|
||||
add edi, eax
|
||||
|
||||
push eax ; Re-schedule the calling VSM
|
||||
call Schedule_VSM
|
||||
|
||||
|
||||
lea esi, [StartSaveArea]
|
||||
add esi, [SysMgr_VSM]
|
||||
|
||||
jcxz CopyState ; Save or Restore ?
|
||||
|
||||
xchg esi, edi ; Restore
|
||||
|
||||
; Copy the non-SMM state
|
||||
CopyState:
|
||||
mov ecx, OFFSET EndSaveArea
|
||||
sub cx, OFFSET StartSaveArea
|
||||
shr cx, 1
|
||||
|
||||
rep movsw [edi], fs:[esi]
|
||||
jmp Sys_Exit
|
||||
|
||||
Sys_State endp
|
||||
|
||||
|
||||
|
||||
|
||||
;************************************************************************
|
||||
; Implements the SYS_SW_INTERRUPT macro
|
||||
;
|
||||
; Input:
|
||||
; EBX = 4 * INT number
|
||||
; ECX = Offset to VSM's register buffer
|
||||
;************************************************************************
|
||||
Sys_SW_INT proc
|
||||
|
||||
cld
|
||||
mov esi, [Current_VSM]
|
||||
push esi ; Re-schedule the calling VSM
|
||||
call Schedule_VSM
|
||||
|
||||
cmp bx, 4*MAX_INT ; Validate INT vector
|
||||
ja Unsupported_INT
|
||||
mov edx, [INT_Vectors+bx]
|
||||
or edx, edx
|
||||
jz Illegal_INT
|
||||
|
||||
mov [Saved_INT], ebx ; Save current vector &
|
||||
mov edi, edx ; patch with the original vector
|
||||
xchg fs:[ebx], edi
|
||||
mov [Saved_Vector], edi
|
||||
|
||||
xor edi, edi ; Don't allow calling VSM to execute
|
||||
push edi
|
||||
call Schedule_VSM
|
||||
|
||||
ASSUME di:PTR VSM_Header ; Mark the requesting VSM blocked
|
||||
mov gs:[di].SysStuff.RunFlag, RUN_FLAG_BLOCKED
|
||||
|
||||
|
||||
; Handle PIC masks
|
||||
in al, PIC1_MASK ; Save PIC masks & set user-defined masks
|
||||
mov ah, al
|
||||
in al, PIC2_MASK
|
||||
mov [Saved_PIC], ax
|
||||
|
||||
ASSUME di:PTR INT_REGS
|
||||
mov di, cx
|
||||
mov ax, word ptr gs:[di].PIC0_Mask
|
||||
not ax ; PIC masks are 0=enable
|
||||
cmp ah, 0FFh ; Any PIC1 IRQs enabled ?
|
||||
je short SetPIC
|
||||
and al, NOT 04h ; Yes, enable IRQ2
|
||||
SetPIC:
|
||||
or al, 01h ; Always disable IRQ0
|
||||
out PIC1_MASK, al
|
||||
mov al, ah
|
||||
out PIC2_MASK, al
|
||||
|
||||
cmp ax, 0FFFFh ; Are any IRQs enabled ?
|
||||
je short RealMode
|
||||
or gs:[di].Flags, EFLAGS_IF ; Yes, enable interrupts
|
||||
|
||||
;
|
||||
; Initialize real-mode state
|
||||
;
|
||||
RealMode:
|
||||
mov ax, gs:[di].Reg_ES ; Set up ES descriptor
|
||||
push OFFSET BIOS_ES
|
||||
call Set_Descriptor
|
||||
|
||||
mov ax, gs:[di].Reg_DS ; Set up DS descriptor
|
||||
push OFFSET BIOS_DS
|
||||
call Set_Descriptor
|
||||
|
||||
add esi, ecx ; Create flat ptr to calling VSM's registers
|
||||
mov [VSM_Buffer], esi
|
||||
|
||||
|
||||
ASSUME di:PTR SmiHeader
|
||||
|
||||
lea edi, [BIOS_Header] ; Set up CS descriptor & Next_EIP
|
||||
mov word ptr [di].SS_Flags, DATA_ATTR
|
||||
mov [di].SMI_Flags, SMI_FLAGS_CS_WRITABLE + SMI_FLAGS_CS_READABLE
|
||||
mov word ptr [di].Next_EIP, dx ; IP
|
||||
shr edx, 16 ; Convert segment to linear address
|
||||
mov [di]._CS.selector, dx ; CS selector
|
||||
shl edx, 4
|
||||
mov [di]._CS.base, edx ; CS descriptor
|
||||
mov [di]._CS.limit, 0FFFFh
|
||||
mov [di]._CS.attr, CODE_ATTR ; CS attribute
|
||||
mov eax, CR0 ; Preserve the CD & NW bits
|
||||
and eax, 60000000h
|
||||
or eax, VSM_CR0
|
||||
mov [di].r_CR0, eax
|
||||
|
||||
if ALLOW_SMM_SEGMENTS
|
||||
mov ecx, MSR_RCONF_SMM ; Make SMM memory writeable by interrupt code
|
||||
rdmsr
|
||||
mov [OldRCONF], al
|
||||
and al, NOT REGION_WP
|
||||
wrmsr
|
||||
endif
|
||||
|
||||
ASSUME DI: NOTHING
|
||||
|
||||
|
||||
|
||||
mov ecx, 1000002Ch ; Save P2D_SC value & make UMBs R/W
|
||||
rdmsr
|
||||
mov [ShadowMSR], dx
|
||||
or dx, 0FFFFh
|
||||
wrmsr
|
||||
|
||||
mov ebx, SMINT_SEGMENT ; Patch SS descriptor
|
||||
mov word ptr [BIOS_SS+8], bx
|
||||
shl ebx, 4
|
||||
mov dword ptr [BIOS_SS+2], ebx
|
||||
mov byte ptr [BIOS_SS+5], DATA_ATTR
|
||||
add ebx, 0FFF0h
|
||||
mov [ShadowAddr], ebx
|
||||
mov word ptr [BIOS_ESP], bx
|
||||
|
||||
; Build a stack frame:
|
||||
; SMINT_SEGMENT:FFF0 SMINT_SEGMENT:FFF6 - return addresss
|
||||
; SMINT_SEGMENT:FFF4 Flags
|
||||
; SMINT_SEGMENT:FFF6 SMINT instruction
|
||||
mov eax, SMINT_SEGMENT SHL 16 ; Segment
|
||||
lea ax, [bx+6] ; Offset (SP+6)
|
||||
xchg eax, dword ptr fs:[ebx]
|
||||
mov [ShadowMemory], eax
|
||||
mov eax, 380F0000h ; FLAGS & SMINT
|
||||
xchg eax, fs:[ebx+4]
|
||||
mov [ShadowMemory+4], eax
|
||||
|
||||
mov eax, [Header_Addr] ; Copy top-level header address
|
||||
mov [Hdr_Address], eax
|
||||
|
||||
|
||||
call VSM_Registers ; Get registers for ISR
|
||||
|
||||
|
||||
call Swap_States ; S wap top-level state with BIOS state
|
||||
|
||||
Exit: jmp Sys_Exit
|
||||
|
||||
|
||||
|
||||
Unsupported_INT:
|
||||
Illegal_INT:
|
||||
|
||||
|
||||
mov ax, ERR_BAD_INTERRUPT
|
||||
push ax ; Push error code
|
||||
shr ebx, 2
|
||||
push ebx ; Info1 = Interrupt #
|
||||
push dword ptr 0 ; Info2 = 0x00000000
|
||||
call Report_VSM_Error
|
||||
jmp Exit
|
||||
|
||||
Sys_SW_INT endp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;********************************************************************************
|
||||
; Returns here from INT callback
|
||||
;********************************************************************************
|
||||
INT_Return proc
|
||||
|
||||
mov ebx, [Saved_INT] ; Restore the INT vector
|
||||
mov edx, [Saved_Vector]
|
||||
mov fs:[ebx], edx
|
||||
|
||||
|
||||
if ALLOW_SMM_SEGMENTS
|
||||
mov ecx, MSR_RCONF_SMM ; Restore SMM region properties
|
||||
rdmsr
|
||||
mov al, [OldRCONF]
|
||||
wrmsr
|
||||
endif
|
||||
|
||||
mov esi, [Current_VSM] ; Mark the requesting VSM ready to run
|
||||
mov fs:(VSM_Header PTR [esi]).SysStuff.RunFlag, RUN_FLAG_READY
|
||||
|
||||
call Swap_States ; Restore the original non-SMM state
|
||||
|
||||
call VSM_Registers ; Return register values & flags
|
||||
|
||||
|
||||
xor eax, eax
|
||||
mov [VSM_Buffer], eax
|
||||
|
||||
sub [SchedulerStack], 4 ; Pop the scheduler sentinel
|
||||
|
||||
mov ebx, [ShadowAddr] ; Restore shadow memory
|
||||
mov eax, [ShadowMemory]
|
||||
mov fs:[ebx], eax
|
||||
mov eax, [ShadowMemory+4]
|
||||
mov fs:[ebx+4], eax
|
||||
|
||||
mov ecx, 1000002Ch ; Restore R/W attributes of UMBs
|
||||
rdmsr
|
||||
mov dx, [ShadowMSR]
|
||||
wrmsr
|
||||
|
||||
mov ax, [Saved_PIC] ; Restore PIC masks
|
||||
out PIC2_MASK, al
|
||||
mov al, ah
|
||||
out PIC1_MASK, al
|
||||
ret
|
||||
|
||||
INT_Return endp
|
||||
|
||||
|
||||
|
||||
;************************************************************************
|
||||
; Swaps the top-level state with the BIOS callback state.
|
||||
; Info to be saved:
|
||||
; - SMM header & pointer
|
||||
; - Descriptors
|
||||
; - GP registers
|
||||
; - IDT ptr
|
||||
; - PCI config address
|
||||
;************************************************************************
|
||||
Swap_States proc
|
||||
|
||||
lea si, [StartSaveArea] ; Swap thread states
|
||||
lea di, [Saved_State]
|
||||
mov cx, OFFSET EndSaveArea ; Compute # dwords of state
|
||||
sub cx, si
|
||||
shr cx, 2
|
||||
StateLoop:
|
||||
lodsd ; Exchange a dword
|
||||
xchg [di], eax
|
||||
mov dword ptr [si-4], eax
|
||||
add di, 4
|
||||
loop StateLoop
|
||||
|
||||
lea si, [SMM_Header] ; Now do the top-level SMM header
|
||||
lea di, [BIOS_Header]
|
||||
mov cl, sizeof(SmiHeader)/4
|
||||
Hdr_Loop:
|
||||
lodsd
|
||||
xchg [di], eax
|
||||
mov [si-4], eax
|
||||
add di, 4
|
||||
loop Hdr_Loop
|
||||
|
||||
ret
|
||||
|
||||
Swap_States endp
|
||||
|
||||
|
||||
;************************************************************************
|
||||
; Swaps the VSM's registers with the local state
|
||||
;************************************************************************
|
||||
VSM_Registers proc
|
||||
|
||||
mov esi, [VSM_Buffer] ; Caller's register buffer
|
||||
mov ax, word ptr [BIOS_Header].EFLAGS
|
||||
xchg fs:(INT_REGS PTR [esi]).Flags, ax
|
||||
mov word ptr [BIOS_Header].EFLAGS, ax
|
||||
|
||||
lea bx, [Reg_Table]
|
||||
mov cx, (End_Reg_Table-Reg_Table)/2
|
||||
Reg_Loop:
|
||||
mov di, [bx] ; Get offset of register
|
||||
mov eax, [di] ; Swap with register structure
|
||||
xchg eax, fs:[esi]
|
||||
mov [di], eax
|
||||
add bx, 2 ; Increment ptrs
|
||||
add esi, 4
|
||||
loop Reg_Loop
|
||||
|
||||
ret
|
||||
|
||||
; This table translates between a INT_REGS structure and the PUSHA/POPA ordering
|
||||
Reg_Table:
|
||||
dw OFFSET BIOS_EAX
|
||||
dw OFFSET BIOS_EBX
|
||||
dw OFFSET BIOS_ECX
|
||||
dw OFFSET BIOS_EDX
|
||||
dw OFFSET BIOS_EBP
|
||||
dw OFFSET BIOS_ESI
|
||||
dw OFFSET BIOS_EDI
|
||||
End_Reg_Table:
|
||||
|
||||
VSM_Registers endp
|
||||
|
||||
|
||||
;************************************************************************
|
||||
; Sets a descriptor to a real-mode descriptor
|
||||
; Input:
|
||||
; AX = selector
|
||||
; If selector = 0x0000, a 4 GB descriptor (big-real) is used
|
||||
; If selector = 0xFFFF, the calling VSM's base/limit is used
|
||||
; DI = ptr to descriptor
|
||||
;************************************************************************
|
||||
Set_Descriptor proc pascal uses di \
|
||||
DescrPtr: PTR Descriptor
|
||||
|
||||
ASSUME di: PTR Descriptor
|
||||
mov di, [DescrPtr]
|
||||
|
||||
mov ebx, 0FFFFh ; 64K limit
|
||||
|
||||
or ax, ax ; Selector = 0000h?
|
||||
jnz short SetSelector
|
||||
mov ebx, 008FFFFFh ; Yes, then use 4 GB limit (big-real mode)
|
||||
SetSelector:
|
||||
|
||||
movzx eax, ax
|
||||
mov [di].selector, ax
|
||||
shl eax, 4
|
||||
|
||||
|
||||
if ALLOW_SMM_SEGMENTS
|
||||
; If ES == 0xFFFF, use VSM's base
|
||||
cmp ax, bx
|
||||
jne short Set_Limit
|
||||
mov eax, [Current_VSM] ; No, use VSM's base & limit
|
||||
mov bx, ax
|
||||
shr bx, 4
|
||||
mov [di].selector, bx
|
||||
mov ebx, (VSM_Header PTR fs:[eax]).DS_Limit
|
||||
endif
|
||||
|
||||
Set_Limit:
|
||||
; EAX = base
|
||||
; EBX = limit
|
||||
mov [di].limit_15_0, bx ; Store 24-bit limit
|
||||
shr ebx, 16
|
||||
mov [di].limit_19_16, bl
|
||||
|
||||
mov [di].base_15_0, ax ; Store 32-bit base
|
||||
shr eax, 16
|
||||
mov [di].base_23_16, al
|
||||
mov [di].base_31_24, ah
|
||||
ret
|
||||
|
||||
ASSUME di: NOTHING
|
||||
|
||||
Set_Descriptor endp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
align 4
|
||||
Saved_State:
|
||||
;******************************************************************************
|
||||
; The following must match the structure at StartSaveArea in SYSMGR.ASM
|
||||
BIOS_PCI dd 80000000h
|
||||
BIOS_EDI dd 0
|
||||
BIOS_ESI dd 0
|
||||
BIOS_EBP dd 0
|
||||
dd 0 ; ESP (not used)
|
||||
BIOS_EBX dd 0
|
||||
BIOS_EDX dd 0
|
||||
BIOS_ECX dd 0
|
||||
BIOS_EAX dd 0
|
||||
|
||||
BIOS_ESP dd 0
|
||||
|
||||
BIOS_SS Descriptor {0FFFFh, 0, 0, DATA_ATTR, 0, 0, 0}
|
||||
BIOS_DS Descriptor {0FFFFh, 0, 0, DATA_ATTR, 0, 0, 0}
|
||||
BIOS_ES Descriptor {0FFFFh, 0, 0, DATA_ATTR, 0, 0, 0}
|
||||
BIOS_FS Descriptor {0FFFFh, 0, 0, DATA_ATTR, 0, 0, 0}
|
||||
BIOS_GS Descriptor {0FFFFh, 0, 0, DATA_ATTR, 0, 0, 0}
|
||||
|
||||
Hdr_Address dd 0
|
||||
|
||||
IDT_Selector dd 00920000h
|
||||
IDT_Base dd 00000000h
|
||||
IDT_Limit dd 0000FFFFh
|
||||
|
||||
|
||||
dw 0 ; Pad
|
||||
|
||||
;******************************************************************************
|
||||
SMM_CONTROL equ EXTL_SMI_EN + INTL_SMI_EN + SMM_INST_EN + NEST_SMI_EN
|
||||
|
||||
BIOS_Header SmiHeader {,SMM_CONTROL,,,,,,,,,VSM_CR0, VSM_EFLAGS, VSM_DR7}
|
||||
|
||||
ShadowMemory dd 0, 0
|
||||
ShadowAddr dd 0
|
||||
ShadowMSR dw 0
|
||||
|
||||
VSM_Buffer dd 0
|
||||
|
||||
|
||||
Saved_PIC dw 0
|
||||
Saved_INT dd 0
|
||||
Saved_Vector dd 0
|
||||
OldRCONF db 0
|
||||
|
||||
_CODE ENDS
|
||||
|
||||
|
||||
END
|
||||
316
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/swapsif.c
vendored
Executable file
316
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/swapsif.c
vendored
Executable file
@@ -0,0 +1,316 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//*****************************************************************************
|
||||
//* SWAPSiFs routines
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
|
||||
#include "VSA2.H"
|
||||
#include "SYSMGR.H"
|
||||
#include "PROTOS.H"
|
||||
#include "VPCI.H"
|
||||
#include "PCI.H"
|
||||
|
||||
|
||||
// External Functions:
|
||||
extern void pascal Return_Virtual_Value(SmiHeader *, ULONG);
|
||||
|
||||
|
||||
// External Variables:
|
||||
extern PCI_HEADER_ENTRY ISA_Hdr[];
|
||||
extern DESCRIPTOR MSRs[];
|
||||
|
||||
|
||||
|
||||
#define ACPI_FLAGS (0)
|
||||
#define ACPI_RANGE 0x20
|
||||
#define PMS_RANGE 0x80
|
||||
#define PMS_FLAGS (NOT_GLIU1)
|
||||
|
||||
ULONG ACPI_Timer_MSR;
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Enables/disables trapping of PMS or ACPI registers
|
||||
//***********************************************************************
|
||||
UCHAR pascal PM_Trapping(USHORT EnableFlag, USHORT Bar)
|
||||
{ ULONG DescrDefault[2];
|
||||
UCHAR Link, i=0;
|
||||
register DESCRIPTOR * Descr;
|
||||
|
||||
// For each linked item, update the associated MSR
|
||||
Link = ISA_Hdr[Bar/4].Link;
|
||||
while (Link) {
|
||||
Descr = &MSRs[Link];
|
||||
|
||||
// Get link to next MSR
|
||||
Link = Descr->Link;
|
||||
|
||||
// Ignore this MSR if not an I/O trap
|
||||
if ((Descr->Flag & IO_TRAP) != IO_TRAP) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (EnableFlag) {
|
||||
// Restore descriptor to original value (re-enable trapping)
|
||||
Write_MSR(Descr->MsrAddr, Descr->MsrData);
|
||||
} else {
|
||||
i++;
|
||||
// Set descriptor to default (disable trapping)
|
||||
Get_Descriptor_Default(Descr->Type, DescrDefault);
|
||||
Write_MSR(Descr->MsrAddr, DescrDefault);
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Enables/disables trapping of PM Support registers
|
||||
//***********************************************************************
|
||||
UCHAR pascal PMS_Trapping(USHORT EnableFlag)
|
||||
{
|
||||
return PM_Trapping(EnableFlag, BAR4);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Enables/disables trapping of ACPI registers
|
||||
//***********************************************************************
|
||||
UCHAR pascal ACPI_Trapping(USHORT EnableFlag)
|
||||
{
|
||||
return PM_Trapping(EnableFlag, BAR5);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Workaround for ACPI issues with A3 parts:
|
||||
// 1) Hang on byte accesses to ACPI registers 0x00-0x03
|
||||
// 2) Improper sharing of shadow register
|
||||
// Flag:
|
||||
// = 0 if PM Support registers
|
||||
// = 1 if ACPI registers
|
||||
//***********************************************************************
|
||||
void ACPI_Workaround(SmiHeader * SmiHdr, USHORT Flag)
|
||||
{ USHORT Address;
|
||||
UCHAR Alignment, Size;
|
||||
ULONG WriteToClearMask, Mask, Data, SrcData;
|
||||
static ULONG WriteToClearMasks[] = {
|
||||
0xFFFF0000, // 00 PM1_STS
|
||||
0xFFFFFFFF, // 04 PM1_EN
|
||||
0xFFFFFDFF, // 08 PM1_CNT
|
||||
0xFFFFFFFF, // 0C PM2_CNT
|
||||
0xFFFFFFFF, // 10 PM_TMR
|
||||
0xFFFFFFFF, // 14 Reserved
|
||||
0x00000000, // 18 GPE0_STS
|
||||
0xFFFFFFFF, // 1C GPE0_EN
|
||||
};
|
||||
|
||||
|
||||
// Get info about the I/O from the SMM header
|
||||
Data = SmiHdr->write_data;
|
||||
Address = SmiHdr->IO_addr;
|
||||
Size = (UCHAR)SmiHdr->data_size;
|
||||
|
||||
Alignment = (UCHAR)((Address & 3) << 3);
|
||||
// Make Address dword-aligned
|
||||
Address &= ~3;
|
||||
|
||||
if (Flag) {
|
||||
|
||||
// Get write-to-clear mask for ACPI registers
|
||||
WriteToClearMask = WriteToClearMasks[(Address & 0x1F) >> 2];
|
||||
|
||||
// Disable I/O trapping
|
||||
ACPI_Trapping(0);
|
||||
|
||||
} else {
|
||||
|
||||
// Get write-to-clear mask for PM Support registers
|
||||
switch ((UCHAR)Address) {
|
||||
|
||||
case 0x00:
|
||||
WriteToClearMask = 0xFFFF7FFF;
|
||||
break;
|
||||
|
||||
case 0x54:
|
||||
WriteToClearMask = 0xFFFF0000;
|
||||
break;
|
||||
|
||||
default:
|
||||
WriteToClearMask = 0xFFFFFFFF;
|
||||
break;
|
||||
}
|
||||
// Disable I/O trapping
|
||||
PMS_Trapping(0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Read initial value
|
||||
SrcData = in_32(Address);
|
||||
|
||||
if (SmiHdr->SMI_Flags.IO_Write) {
|
||||
// I/O WRITE
|
||||
|
||||
// Get mask appropriate to I/O size
|
||||
switch (Size) {
|
||||
case BYTE_IO:
|
||||
Mask = 0x000000FF;
|
||||
break;
|
||||
|
||||
case WORD_IO:
|
||||
Mask = 0x0000FFFF;
|
||||
break;
|
||||
|
||||
case DWORD_IO:
|
||||
Mask = 0xFFFFFFFF;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Data &= Mask;
|
||||
Data <<= Alignment;
|
||||
SrcData &= ~(Mask << Alignment);
|
||||
|
||||
// Write final data out; Don't rewrite write-to-clear bits
|
||||
Data |= (SrcData & WriteToClearMask);
|
||||
out_32(Address, Data);
|
||||
|
||||
} else {
|
||||
|
||||
// I/O READ
|
||||
Data = (SrcData >> Alignment);
|
||||
|
||||
// Return value to the right environment
|
||||
Return_Virtual_Value(SmiHdr, Data);
|
||||
}
|
||||
|
||||
// Re-enable I/O trapping
|
||||
if (Flag) {
|
||||
ACPI_Trapping(1);
|
||||
} else {
|
||||
PMS_Trapping(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// An I/O BAR for devices in the MDD (e.g. PMS and ACPI) doesn't require
|
||||
// a GLIU descriptor since the MDD is the subtractive decode. Therefore,
|
||||
// if these registers are trapped, they are not linked to the BARs.
|
||||
// This function adds the linkages so when the BAR is changed, the
|
||||
// descriptor(s) generating the I/O trap are also changed.
|
||||
// NOTES:
|
||||
// 1) The descriptors must be linked in order of increasing address.
|
||||
// Increasing address does not imply increasing MSRs[] index, so the
|
||||
// search index starts over at 1 on an address hit.
|
||||
// 2) This function must handle the case where the BAR is of one size but
|
||||
// the trapped range is another (either longer or shorter).
|
||||
//***********************************************************************
|
||||
void pascal FixupLinkages(USHORT Bar)
|
||||
{ USHORT IO_Address;
|
||||
UCHAR First = 0, Previous=0, Index;
|
||||
register DESCRIPTOR * Descr;
|
||||
|
||||
IO_Address = ISA_Hdr[Bar/4].Value_LO;
|
||||
|
||||
// Walk through all the descriptors
|
||||
for (Index=1; Index<MAX_DESCR ; Index++ ) {
|
||||
Descr = &MSRs[Index];
|
||||
|
||||
// Only examine descriptors used for I/O traps
|
||||
if ((Descr->Flag & (AVAILABLE | IO_TRAP)) != IO_TRAP) {
|
||||
continue;
|
||||
}
|
||||
// Does this descriptor map the region covered by the BAR?
|
||||
if (Descr->Address == IO_Address) {
|
||||
// Yes
|
||||
if (Previous) {
|
||||
// Link it
|
||||
MSRs[Previous].Link = Index;
|
||||
} else {
|
||||
First = Index;
|
||||
}
|
||||
Previous = Index;
|
||||
|
||||
// Mark it unavailable so we don't 'hit' again
|
||||
Descr->Flag &= ~AVAILABLE;
|
||||
|
||||
// Advance the address
|
||||
IO_Address += (USHORT)Descr->Range;
|
||||
|
||||
// Skip the ACPI timer register
|
||||
if (Bar == BAR5) {
|
||||
switch (IO_Address & (ACPI_RANGE-1)) {
|
||||
case 0x10:
|
||||
(UCHAR)IO_Address += 4;
|
||||
break;
|
||||
case 0x18:
|
||||
// Record descriptor that skips ACPI timer
|
||||
ACPI_Timer_MSR = Descr->MsrAddr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Re-start search at beginning of MSR array
|
||||
Index = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (First) {
|
||||
// Re-link the 'expanded' list to the BAR's linkages
|
||||
MSRs[Previous].Link = ISA_Hdr[Bar/4].Link;
|
||||
ISA_Hdr[Bar/4].Link = First;
|
||||
} else {
|
||||
Log_Error("No links found by FixupLinkages()");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Installs the trapping for ACPI and PMS register SWAPSiF
|
||||
//***********************************************************************
|
||||
void ACPI_PMS_SWAPSiF(void)
|
||||
{ USHORT IO_Address;
|
||||
|
||||
// Trap PMC registers (F0 BAR4)
|
||||
IO_Address = ISA_Hdr[BAR4/4].IO_Base;
|
||||
if (IO_Address) {
|
||||
Register_Event(EVENT_IO_TRAP, 0, SysMgr_VSM, IO_Address, PMS_FLAGS | PMS_RANGE);
|
||||
// Link the descriptors used for trapping the PMS registers
|
||||
FixupLinkages(BAR4);
|
||||
}
|
||||
|
||||
// Trap ACPI registers (F0 BAR5)
|
||||
IO_Address = ISA_Hdr[BAR5/4].IO_Base;
|
||||
if (IO_Address) {
|
||||
Register_Event(EVENT_IO_TRAP, 0, SysMgr_VSM, IO_Address, ACPI_FLAGS | 0x10);
|
||||
// Skip the ACPI Timer register
|
||||
Register_Event(EVENT_IO_TRAP, 0, SysMgr_VSM, IO_Address+0x14, ACPI_FLAGS | 0x0C);
|
||||
// Link the descriptors used for trapping the ACPI registers
|
||||
FixupLinkages(BAR5);
|
||||
}
|
||||
}
|
||||
772
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/syscalls.asm
vendored
Executable file
772
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/syscalls.asm
vendored
Executable file
@@ -0,0 +1,772 @@
|
||||
;
|
||||
; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
;
|
||||
; This library is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU Lesser General Public License as
|
||||
; published by the Free Software Foundation; either version 2.1 of the
|
||||
; License, or (at your option) any later version.
|
||||
;
|
||||
; This code is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
; Lesser General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU Lesser General
|
||||
; Public License along with this library; if not, write to the
|
||||
; Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
; Boston, MA 02111-1307 USA
|
||||
;
|
||||
;*******************************************************************************
|
||||
;* Implements several system calls
|
||||
;*******************************************************************************
|
||||
|
||||
|
||||
include SYSMGR.INC
|
||||
include VSA2.INC
|
||||
include PCI.INC
|
||||
include SMIMAC.MAC
|
||||
include CHIPSET.INC
|
||||
include VR.INC
|
||||
|
||||
|
||||
|
||||
|
||||
.model tiny,c
|
||||
.586p
|
||||
.CODE
|
||||
|
||||
public SysCall_Table
|
||||
public ReturnULONG
|
||||
|
||||
|
||||
externdef Sys_SW_INT: proc
|
||||
externdef Sys_Broadcast: proc
|
||||
externdef Sys_PassEvent: proc
|
||||
externdef Sys_State: proc
|
||||
externdef EmptyMsgQueue: proc
|
||||
externdef ExitSysCall: proc
|
||||
externdef Dispatcher: proc
|
||||
externdef Sys_Exit: proc
|
||||
externdef Record_VSM_Locations: proc
|
||||
externdef pascal Lookup_PCI: proc
|
||||
externdef pascal Lookup_IO: proc
|
||||
externdef pascal Find_MBus_ID: proc
|
||||
externdef pascal Send_Event: proc
|
||||
externdef pascal Schedule_VSM: proc
|
||||
externdef pascal Allocate_BAR: proc
|
||||
externdef pascal Register_Event: proc
|
||||
externdef pascal Report_VSM_Error: proc
|
||||
externdef pascal Allocate_Resource: proc
|
||||
externdef pascal Set_Address_Decode: proc
|
||||
externdef pascal Enable_PCI_Trapping: proc
|
||||
externdef pascal Unregister_VSM_Events: proc
|
||||
externdef pascal IRQY_Mapper: proc
|
||||
externdef pascal Return_Virtual_Value: proc
|
||||
|
||||
externdef SysMgr_VSM: dword
|
||||
externdef VSM_ListHead: dword
|
||||
externdef Current_VSM: dword
|
||||
externdef MsgPacket: dword
|
||||
externdef SMI_Base: dword
|
||||
externdef IRQ_Base: dword
|
||||
externdef VSM_Ptrs: dword
|
||||
externdef Events: EVENT_ENTRY
|
||||
externdef HardwareInfo: Hardware
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
align 2
|
||||
SysCall_Table:
|
||||
dw OFFSET Sys_Register ; 00 - SYS_CODE_EVENT
|
||||
dw OFFSET Sys_Yield ; 01 - SYS_CODE_YIELD
|
||||
dw OFFSET Sys_SW_INT ; 02 - SYS_CODE_SW_INT
|
||||
dw OFFSET Sys_PassEvent ; 03 - SYS_CODE_PASS_EVENT
|
||||
dw OFFSET Sys_Unload ; 04 - SYS_CODE_UNLOAD
|
||||
dw OFFSET Sys_Registers ; 05 - SYS_CODE_REGISTER
|
||||
dw OFFSET Sys_RdWrPCI ; 06 - SYS_CODE_PCI_ACCESS
|
||||
dw OFFSET Sys_SetVirtual ; 07 - SYS_CODE_SET_VIRTUAL
|
||||
dw OFFSET Sys_GetVirtual ; 08 - SYS_CODE_GET_VIRTUAL
|
||||
dw OFFSET Sys_Broadcast ; 09 - SYS_CODE_BROADCAST
|
||||
dw OFFSET Sys_State ; 0A - SYS_CODE_STATE
|
||||
dw OFFSET Sys_Report_Error ; 0B - SYS_CODE_ERROR
|
||||
dw OFFSET Sys_Resource ; 0C - SYS_CODE_RESOURCE
|
||||
dw OFFSET Sys_Decode ; 0D - SYS_CODE_DECODE
|
||||
dw OFFSET Sys_GetDescr ; 0E - SYS_CODE_DESCRIPTOR
|
||||
dw OFFSET Sys_Lookup ; 0F - SYS_CODE_LOOKUP
|
||||
dw OFFSET Sys_IRQ_Mapper ; 10 - SYS_CODE_IRQ_MAPPER
|
||||
dw OFFSET Sys_Result ; 11 - SYS_CODE_RESULT
|
||||
dw OFFSET Sys_Duplicate ; 12 - SYS_CODE_DUPLICATE
|
||||
dw OFFSET EmptyMsgQueue ; 13 - SYS_CODE_EXIT
|
||||
|
||||
|
||||
;************************************************************************
|
||||
; Implements the WRITE_PCI_NO_TRAP macros
|
||||
;
|
||||
; On Entry:
|
||||
; SI = data size (bit 7 = 1 if I/O write);
|
||||
; EBX = PCI configuration address
|
||||
; ECX = data (if write)
|
||||
;************************************************************************
|
||||
Sys_RdWrPCI proc
|
||||
|
||||
push ebx ; Save PCI address
|
||||
push ecx ; Save data
|
||||
|
||||
; Disable trapping of PCI address
|
||||
push bx ; PCI_Address
|
||||
push word ptr 0000
|
||||
call Enable_PCI_Trapping
|
||||
|
||||
movzx bp, al ; Save previous trap setting
|
||||
|
||||
pop ecx ; Restore data
|
||||
pop ebx ; Restore PCI address
|
||||
|
||||
; Write the PCI address
|
||||
mov dx, PCI_CONFIG_ADDRESS
|
||||
mov eax, ebx
|
||||
out dx, eax
|
||||
add dl, 4
|
||||
and al, 3
|
||||
add dl, al
|
||||
|
||||
btr si, 7 ; Read or write ?
|
||||
jc PCI_Write ; Jmp if write
|
||||
|
||||
cmp si, BYTE_IO ; Byte, Word, or Dword ?
|
||||
je Read_Byte
|
||||
cmp si, WORD_IO
|
||||
je Read_Word
|
||||
|
||||
|
||||
Read_Dword:
|
||||
db 66h ; Force next instruction to be IN EAX,DX
|
||||
Read_Word:
|
||||
in ax, dx
|
||||
jmp short ReturnValue
|
||||
|
||||
|
||||
Read_Byte:
|
||||
in al, dx
|
||||
ReturnValue:
|
||||
|
||||
push eax ; Save return value
|
||||
|
||||
call Restore_Trapping ; Re-enable PCI trapping
|
||||
|
||||
pop ax ; Restore return value
|
||||
pop dx
|
||||
|
||||
ReturnULONG::
|
||||
mov bx, word ptr gs:(VSM_Header).SysStuff.SavedESP
|
||||
mov word ptr gs:[bx+8*4], ax
|
||||
mov word ptr gs:[bx+6*4], dx
|
||||
jmp ExitSysCall
|
||||
|
||||
|
||||
|
||||
;************************************************************************
|
||||
PCI_Write:
|
||||
|
||||
mov eax, ecx ; Get data to be written
|
||||
cmp si, WORD_IO ; Byte, Word, or Dword ?
|
||||
je short Write_Word
|
||||
cmp si, DWORD_IO
|
||||
je short Write_Dword
|
||||
cmp si, BYTE_IO
|
||||
jne short Ignore ; Ignore if error in parameter
|
||||
|
||||
Write_Byte:
|
||||
out dx, al
|
||||
jmp short Restore_PCI_Trap
|
||||
|
||||
|
||||
Write_Dword:
|
||||
db 66h ; Force next instruction to be OUT DX,EAX
|
||||
Write_Word:
|
||||
out dx, ax
|
||||
|
||||
Restore_PCI_Trap:
|
||||
call Restore_Trapping ; Re-enable PCI trapping
|
||||
|
||||
Ignore:
|
||||
jmp ExitSysCall
|
||||
|
||||
|
||||
Sys_RdWrPCI endp
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Restores PCI trapping
|
||||
; On entry:
|
||||
; BP = 1 means re-enable PCI trapping
|
||||
;***********************************************************************
|
||||
Restore_Trapping proc
|
||||
|
||||
; Is trapping to be re-enabled ?
|
||||
cmp bp, 1
|
||||
jne short Exit
|
||||
|
||||
; Yes, restore PCI trapping on this address
|
||||
; Enable_PCI_Trapping(PCI_Address, EnableFlag);
|
||||
push bx ; PCI address
|
||||
push bp ; EnableFlag
|
||||
call Enable_PCI_Trapping
|
||||
Exit: ret
|
||||
|
||||
Restore_Trapping endp
|
||||
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
;
|
||||
; Register an event to the calling VSM
|
||||
;
|
||||
; On entry:
|
||||
; EBX = Event::Priority
|
||||
; ECX = Parameter 1
|
||||
; EDI = Parameter 2
|
||||
;***********************************************************************
|
||||
Sys_Register proc
|
||||
|
||||
; Register_Event(Event, Priority, VSM, Param1, Param2);
|
||||
push ebx ; Event::Priority
|
||||
push [Current_VSM] ; VSM ptr
|
||||
push ecx ; Param1
|
||||
push edi ; Param2
|
||||
call Register_Event
|
||||
jmp ExitSysCall
|
||||
|
||||
Sys_Register endp
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Input:
|
||||
; BX = Virtual register index
|
||||
; Output:
|
||||
; AX = returned data
|
||||
;***********************************************************************
|
||||
Sys_GetVirtual proc
|
||||
|
||||
xor cx, cx ; Data = 0000
|
||||
xor di, di ; 0 = read
|
||||
jmp VirtualCommon
|
||||
|
||||
Sys_GetVirtual endp
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Input:
|
||||
; BX = Virtual register index
|
||||
; CX = Data
|
||||
;***********************************************************************
|
||||
Sys_SetVirtual proc
|
||||
|
||||
call Handle_PM
|
||||
|
||||
mov di, 1 ; 1 = write
|
||||
VirtualCommon::
|
||||
cmp bh, VRC_KEYBOARD ; Allow VRC_KEYBOARD to pass 32-bits
|
||||
je Reschedule
|
||||
movzx ecx, cx
|
||||
Reschedule:
|
||||
mov edx, [Current_VSM] ; Re-schedule calling VSM
|
||||
push edx
|
||||
call Schedule_VSM
|
||||
|
||||
call VirtualRegisterEvent
|
||||
|
||||
mov ax, 0FFFFh ; Value of an undefined virtual register
|
||||
mov bx, word ptr gs:(VSM_Header).SysStuff.SavedESP
|
||||
mov word ptr gs:[bx+8*4], ax
|
||||
jmp Dispatcher
|
||||
|
||||
|
||||
|
||||
|
||||
Sys_SetVirtual endp
|
||||
|
||||
|
||||
Handle_PM proc
|
||||
|
||||
if 0;SUPPORT_PM ; requires 78 bytes
|
||||
; If OHCI VSM is sending a USB event to KBD VSM, send an EVENT_IO_TRAP
|
||||
; to the PM VSM so system will exit DOZE mode.
|
||||
cmp bh, VRC_KEYBOARD
|
||||
jne short Exit
|
||||
mov eax, [VSM_Ptrs+4*VSM_PM]; Is PM installed ?
|
||||
or eax, eax
|
||||
jz short Exit
|
||||
|
||||
|
||||
; Is PM VSM registered for the I/O trap ?
|
||||
mov al, EVENT_IO_TRAP
|
||||
FindPM:
|
||||
mov ah, sizeof(EVENT_ENTRY)
|
||||
mul ah
|
||||
mov si, ax
|
||||
mov eax, (EVENT_ENTRY PTR [Events+si]).Vsm
|
||||
or eax, eax
|
||||
jz short Exit
|
||||
cmp eax, edi ; Is it the PM VSM ?
|
||||
jne short Next_VSM
|
||||
cmp (EVENT_ENTRY PTR [Events+si]).Param1, 0060h
|
||||
je short PM_Is_Dozing
|
||||
Next_VSM:
|
||||
mov al, (EVENT_ENTRY PTR [Events+si]).Link
|
||||
or al, al
|
||||
jnz FindPM
|
||||
jmp short Exit
|
||||
|
||||
|
||||
PM_Is_Dozing:
|
||||
push bx ; Yes, save virtual register info
|
||||
push cx
|
||||
|
||||
mov eax, MSG_EVENT ; Send the PM VSM an EVENT_IO_TRAP[0x60] message
|
||||
mov ebx, [SysMgr_VSM]
|
||||
lea si, [PM_Packet]
|
||||
call Insert_Msg
|
||||
|
||||
pop cx ; Restore virtual register info
|
||||
pop bx
|
||||
|
||||
endif
|
||||
|
||||
Exit: ret
|
||||
|
||||
PM_Packet dd EVENT_IO_TRAP, 0, 0060h
|
||||
|
||||
Handle_PM endp
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Sends an EVENT_VIRTUAL_REGISTER to VSM(s)
|
||||
; On entry:
|
||||
; BX = Class::Index
|
||||
; CX = write data
|
||||
; DI = 0 (read) or 1 (write)
|
||||
; EDX = From_VSM
|
||||
;***********************************************************************
|
||||
VirtualRegisterEvent proc
|
||||
|
||||
lea si, [MsgPacket] ; Fill the message packet
|
||||
movzx eax, bx
|
||||
mov [si+1*4], eax ; MsgPacket[1] : virtual register index
|
||||
mov ax, di
|
||||
mov [si+2*4], eax ; MsgPacket[2] : 0=read 1=write
|
||||
mov [si+3*4], ecx ; MsgPacket[3] : write data
|
||||
|
||||
mov ax, EVENT_VIRTUAL_REGISTER ; No, so it's a VR access
|
||||
push ax ; Event
|
||||
push edx ; From_VSM
|
||||
call Send_Event
|
||||
ret
|
||||
|
||||
VirtualRegisterEvent endp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Implements the SYS_UNLOAD_VSM macro
|
||||
;***********************************************************************
|
||||
Sys_Unload proc
|
||||
|
||||
; Find prior VSM to current VSM
|
||||
mov eax, [Current_VSM]
|
||||
or eax, eax
|
||||
jz short Exit
|
||||
|
||||
; Remove current VSM from linked list
|
||||
mov ebx, (VSM_Header PTR fs:[eax]).SysStuff.Blink
|
||||
mov ecx, (VSM_Header PTR fs:[eax]).SysStuff.Flink
|
||||
or ebx, ebx ; Is there a previous VSM ?
|
||||
jnz short IsBackLink
|
||||
mov [VSM_ListHead], ecx ; No, update VSM_ListHead with VSM at Flink
|
||||
jmp short FixupBlink
|
||||
IsBackLink:
|
||||
mov (VSM_Header PTR fs:[ebx]).SysStuff.Flink, ecx
|
||||
FixupBlink:
|
||||
or ecx, ecx
|
||||
jz short Unregister
|
||||
mov (VSM_Header PTR fs:[ecx]).SysStuff.Blink, ebx
|
||||
|
||||
; Unregister events registered to this VSM
|
||||
Unregister:
|
||||
push eax
|
||||
call Unregister_VSM_Events
|
||||
|
||||
call Record_VSM_Locations
|
||||
Exit: jmp Sys_Exit ; Exit to SysMgr
|
||||
|
||||
Sys_Unload endp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Implements the SYS_ALLOCATE_RESOURCE macro
|
||||
; Input:
|
||||
; BL - Resource type
|
||||
; Other registers - various parameters
|
||||
;***********************************************************************
|
||||
Sys_Resource proc
|
||||
|
||||
; Only BAR types are implemented at this time
|
||||
cmp bl, RESOURCE_MEMORY
|
||||
je short BAR_Resource
|
||||
cmp bl, RESOURCE_MMIO
|
||||
je short BAR_Resource
|
||||
cmp bl, RESOURCE_IO
|
||||
je short BAR_Resource
|
||||
cmp bl, RESOURCE_SCIO
|
||||
je short BAR_Resource
|
||||
|
||||
; Not a BAR resource
|
||||
push bx ; Resource
|
||||
push ecx ; Param
|
||||
call Allocate_Resource
|
||||
jmp ExitSysCall
|
||||
|
||||
|
||||
BAR_Resource:
|
||||
push bx ; BAR type
|
||||
push si ; BAR offset
|
||||
push ecx ; Range
|
||||
|
||||
ror edi, 16
|
||||
push di ; MBus_ID
|
||||
ror edi, 16
|
||||
push di ; PCI Device_ID
|
||||
call Allocate_BAR
|
||||
|
||||
jmp ReturnULONG
|
||||
|
||||
Sys_Resource endp
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Implements the SYS_REPORT_ERROR macro
|
||||
; DI = Error code
|
||||
; EBX = Info1
|
||||
; ECX = Info2
|
||||
;***********************************************************************
|
||||
Sys_Report_Error proc
|
||||
|
||||
push di
|
||||
push ebx
|
||||
push ecx
|
||||
call Report_VSM_Error
|
||||
|
||||
jmp ExitSysCall
|
||||
|
||||
|
||||
Sys_Report_Error endp
|
||||
|
||||
|
||||
YIELD_HANDLE equ (ONE_SHOT OR SYS_YIELD OR 0000BEEFh)
|
||||
|
||||
;***********************************************************************
|
||||
; Implements the SYS_YIELD macro
|
||||
;
|
||||
; Input:
|
||||
; ECX = milliseconds to suspend the VSM
|
||||
;***********************************************************************
|
||||
Sys_Yield proc
|
||||
|
||||
mov eax, [Current_VSM] ; VSM that is yielding control
|
||||
mov fs:(VSM_Header PTR [eax]).SysStuff.RunFlag, RUN_FLAG_WAITING
|
||||
|
||||
push word ptr EVENT_TIMER ; Event
|
||||
push word ptr 0000 ; Priority
|
||||
push eax ; Vsm
|
||||
push ecx ; Param1 (ms)
|
||||
push dword ptr YIELD_HANDLE ; Param2 (handle)
|
||||
call Register_Event
|
||||
|
||||
jmp Sys_Exit ; Exit to SysMgr. Don't return to VSM
|
||||
|
||||
Sys_Yield endp
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; This system call is obsolete
|
||||
; Input:
|
||||
; BH = 0 for Set, 1 for Get
|
||||
; BL = register definition
|
||||
; ECX = data if Set
|
||||
;***********************************************************************
|
||||
Sys_Registers proc
|
||||
|
||||
jmp ExitSysCall
|
||||
|
||||
Sys_Registers endp
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Implements the SYS_MAP_IRQ macro
|
||||
; Maps IRQ source to specified IRQ
|
||||
; Input:
|
||||
; BL = Unrestricted Y source (0x00-0x0F)
|
||||
; CL = IRQ setting
|
||||
;***********************************************************************
|
||||
Sys_IRQ_Mapper proc
|
||||
|
||||
push bx
|
||||
push cx
|
||||
call IRQY_Mapper
|
||||
jmp ExitSysCall
|
||||
|
||||
Sys_IRQ_Mapper endp
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Input:
|
||||
; BX = Address
|
||||
; CX = Decode flag
|
||||
;***********************************************************************
|
||||
Sys_Decode proc
|
||||
|
||||
push bx ; Address
|
||||
push cx ; Decode (POSITIVE_DECODE or SUBTRACTIVE_DECODE)
|
||||
call Set_Address_Decode
|
||||
|
||||
jmp ExitSysCall
|
||||
|
||||
Sys_Decode endp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Implements the SYS_MBUS_DESCRIPTOR & SYS_IO_DESCRIPTOR macros
|
||||
;
|
||||
; On entry:
|
||||
; BX = Address
|
||||
; CX = 0 if PCI else I/O
|
||||
; Returns:
|
||||
; MSR address of corresponding resource
|
||||
;***********************************************************************
|
||||
Sys_GetDescr proc
|
||||
|
||||
jcxz PCI
|
||||
|
||||
; MSR_Address = Lookup_IO(Address);
|
||||
push bx
|
||||
call Lookup_IO
|
||||
|
||||
mov bl, 2 ; Restore IO_Flag
|
||||
jmp Common
|
||||
|
||||
; MSR_Address = Lookup_PCI(Address);
|
||||
PCI: push bx
|
||||
call Lookup_PCI
|
||||
|
||||
xor bx, bx
|
||||
Common:
|
||||
mov cx, dx ; Was resource found ?
|
||||
shl ecx, 16
|
||||
mov cx, ax
|
||||
xor eax, eax ; EDX:EAX = 00000000:00000000
|
||||
xor edx, edx
|
||||
jecxz ReturnMSRInfo
|
||||
|
||||
rdmsr ; Yes, read MSR
|
||||
|
||||
test bl, 2 ; Set MSR to default ?
|
||||
jz ReturnMSRInfo
|
||||
push edx ; Yes, save current value
|
||||
push eax
|
||||
|
||||
test eax, 000F0000h ; IOD_BM or IOD_SC ?
|
||||
mov eax, 00000000h ; Default for IOD_SC
|
||||
mov edx, eax
|
||||
jz SetDefault
|
||||
mov eax, 0FFF00000h ; Default for IOD_BM
|
||||
mov edx, 0000000FFh
|
||||
SetDefault:
|
||||
wrmsr ; Set MSR to default value
|
||||
|
||||
pop eax ; Restore original MSR value
|
||||
pop edx
|
||||
|
||||
; Return MSR address in ECX and MSR value in EDX:EAX
|
||||
ReturnMSRInfo:
|
||||
mov bx, word ptr gs:(VSM_Header).SysStuff.SavedESP
|
||||
mov gs:[bx+7*4], ecx ; Return MSR address in ECX
|
||||
mov gs:[bx+8*4], eax ; Return MSR value in EDX:EAX
|
||||
mov gs:[bx+6*4], edx
|
||||
jmp ExitSysCall
|
||||
|
||||
Sys_GetDescr endp
|
||||
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Implements the SYS_LOOKUP_DEVICE macro
|
||||
;
|
||||
; On entry:
|
||||
; BX = MBus Device_ID
|
||||
; CX = Instance
|
||||
; Returns:
|
||||
; DX:AX = MSR routing address to MBus device
|
||||
;***********************************************************************
|
||||
Sys_Lookup proc
|
||||
|
||||
; Find_MBus_ID(USHORT MBus_ID, UCHAR Instance);
|
||||
push bx
|
||||
push cx
|
||||
call Find_MBus_ID
|
||||
xor ax, ax
|
||||
|
||||
jmp ReturnULONG
|
||||
|
||||
Sys_Lookup endp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Implements the SYS_RETURN_RESULT macro
|
||||
; Returns a byte/word/dword result to the correct context.
|
||||
; Input:
|
||||
; EBX = Result to be returned
|
||||
;***********************************************************************
|
||||
Sys_Result proc
|
||||
|
||||
push OFFSET VSM_Header.SysStuff.State
|
||||
push ebx ; Value
|
||||
call Return_Virtual_Value
|
||||
|
||||
jmp ExitSysCall
|
||||
|
||||
Sys_Result endp
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Implements the SYS_DUPLICATE_VSM macro
|
||||
; On entry: BX = memory model
|
||||
; Legend: (C=copy of parent VSM) (N=new copy)
|
||||
; CS DS SS
|
||||
; 0: N N N
|
||||
; 1: C N N
|
||||
;***********************************************************************
|
||||
Sys_Duplicate proc
|
||||
|
||||
; mov [MemoryModel], bx ; Ignore parameter for new
|
||||
|
||||
; Find end of VSMs in memory
|
||||
mov esi, [Current_VSM]
|
||||
mov ebx, esi
|
||||
FindLastVSM:
|
||||
mov edi, ebx
|
||||
mov ebx, (VSM_Header PTR fs:[ebx]).SysStuff.Flink
|
||||
or ebx, ebx
|
||||
jnz FindLastVSM
|
||||
|
||||
; EDI points to last VSM in memory. Find end of last VSM.
|
||||
mov edx, edi
|
||||
add edi, (VSM_Header PTR fs:[edi]).DS_Limit
|
||||
|
||||
|
||||
; Copy this VSM's image
|
||||
mov ecx, (VSM_Header PTR fs:[esi]).DS_Limit
|
||||
cmp [MemoryModel], 0 ; Use same Code segment ?
|
||||
je short CopyImage
|
||||
mov ecx, sizeof(VSM_Header) + VSM_STACK_SIZE
|
||||
CopyImage:
|
||||
push edi
|
||||
push esi
|
||||
push ecx
|
||||
shr ecx, 2 ; Convert BYTE count to DWORDs
|
||||
rep movsd [edi], es:[esi]
|
||||
pop ecx
|
||||
pop esi
|
||||
pop edi
|
||||
|
||||
; Patch descriptors
|
||||
mov (VSM_Header PTR fs:[edi])._DS.base_15_0, di
|
||||
mov (VSM_Header PTR fs:[edi])._SS.base_15_0, di
|
||||
mov eax, edi
|
||||
shr eax, 16
|
||||
mov (VSM_Header PTR fs:[edi])._DS.base_31_24, ah
|
||||
mov (VSM_Header PTR fs:[edi])._DS.base_23_16, al
|
||||
mov (VSM_Header PTR fs:[edi])._SS.base_31_24, ah
|
||||
mov (VSM_Header PTR fs:[edi])._SS.base_23_16, al
|
||||
|
||||
mov (VSM_Header PTR fs:[edi])._DS.limit_15_0, cx
|
||||
mov (VSM_Header PTR fs:[edi])._SS.limit_15_0, cx
|
||||
; Required for segments > 64K
|
||||
; shr ecx, 16
|
||||
; mov (VSM_Header PTR fs:[edi])._DS.limit_19_16, cl
|
||||
; mov (VSM_Header PTR fs:[edi])._SS.limit_19_16, cl
|
||||
|
||||
|
||||
cmp [MemoryModel], 0 ; Use same Code segment ?
|
||||
jne short LinkNewVSM
|
||||
mov (VSM_Header PTR fs:[edi]).SysStuff.State._CS.base, edi
|
||||
|
||||
LinkNewVSM:
|
||||
; Link the new VSM into the VSM list
|
||||
mov (VSM_Header PTR fs:[edx]).SysStuff.Flink, edi
|
||||
mov (VSM_Header PTR fs:[edi]).SysStuff.Blink, edx
|
||||
mov (VSM_Header PTR fs:[edi]).SysStuff.Flink, 0
|
||||
|
||||
; Init EIP
|
||||
movzx eax, (VSM_Header PTR fs:[edi]).EntryPoint
|
||||
mov (VSM_Header PTR fs:[edi]).SysStuff.State.Next_EIP, eax
|
||||
|
||||
; Init ESP & create the initial stack frame
|
||||
mov eax, (VSM_Header PTR fs:[edi]).DS_Limit
|
||||
sub ax, VSM_STACK_FRAME
|
||||
mov (VSM_Header PTR fs:[edi]).SysStuff.SavedESP, eax
|
||||
|
||||
; Schedule the new VSM
|
||||
push edi
|
||||
call Schedule_VSM
|
||||
|
||||
jmp ExitSysCall
|
||||
ret ; Gets rid of assembler warning
|
||||
|
||||
; Warning: don't make MemoryModel a variable on the stack
|
||||
; The JMP ExitSysCall bypasses the LEAVE instruction and BP is trashed
|
||||
MemoryModel dw 0
|
||||
|
||||
Sys_Duplicate endp
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Returns TRUE if the VSM is currently yielded
|
||||
;***********************************************************************
|
||||
VSM_Is_Yielded proc Vsm: dword
|
||||
|
||||
mov ebx, [Vsm]
|
||||
mov al, 0 ; return FALSE
|
||||
cmp fs:(VSM_Header PTR [ebx]).SysStuff.RunFlag, RUN_FLAG_WAITING
|
||||
jne short Exit
|
||||
mov al, 1 ; return TRUE
|
||||
Exit:
|
||||
ret
|
||||
|
||||
VSM_Is_Yielded endp
|
||||
|
||||
|
||||
END
|
||||
|
||||
|
||||
|
||||
804
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/sysmgr.asm
vendored
Executable file
804
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/sysmgr.asm
vendored
Executable file
@@ -0,0 +1,804 @@
|
||||
;
|
||||
; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
;
|
||||
; This library is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU Lesser General Public License as
|
||||
; published by the Free Software Foundation; either version 2.1 of the
|
||||
; License, or (at your option) any later version.
|
||||
;
|
||||
; This code is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
; Lesser General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU Lesser General
|
||||
; Public License along with this library; if not, write to the
|
||||
; Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
; Boston, MA 02111-1307 USA
|
||||
;
|
||||
;* Function: *
|
||||
;* This file contains the entry point to the SMM code. *
|
||||
;* This code performs the following: *
|
||||
;* 1) saves the processor state *
|
||||
;* 2) reads the top-level SMI source register(s) *
|
||||
;* 3) issues message(s) to the appropriate VSM(s) *
|
||||
;* 4) dispatches to VSM(s) until all messages are handled *
|
||||
;* 5) restores the processor state
|
||||
|
||||
include SYSMGR.INC
|
||||
include VSA2.INC
|
||||
include PCI.INC
|
||||
include SMIMAC.MAC
|
||||
include CHIPSET.INC
|
||||
include CS5536.INC
|
||||
include GX2.INC
|
||||
|
||||
.model tiny,c
|
||||
.586p
|
||||
|
||||
.ALPHA
|
||||
DGROUP GROUP _CODE, _TEXT
|
||||
_CODE SEGMENT PUBLIC use16 'CODE'
|
||||
ASSUME DS:_CODE
|
||||
|
||||
|
||||
BRACKETS equ 0
|
||||
|
||||
public SysMgr_Entry
|
||||
public Nested_SMI
|
||||
public Saved_EAX, Saved_AX
|
||||
public Saved_EBX, Saved_ECX, Saved_EDX, Saved_PCI
|
||||
public Saved_ESI, Saved_EDI, Saved_EBP, Saved_ESP
|
||||
public Saved_SS, Saved_ES, Saved_DS, Saved_FS, Saved_GS
|
||||
public IDT_Selector, IDT_Base, IDT_Limit
|
||||
public VSMs_EAX
|
||||
public Nested_PCI, Nested_EDI, Nested_EAX, Nested_ES
|
||||
public StartSaveArea, EndSaveArea
|
||||
public SchedulerStack
|
||||
public Sys_Exit
|
||||
public VSM_ListHead
|
||||
public SMM_Header
|
||||
public SysMgr_VSM
|
||||
public Data_Descriptor
|
||||
public Flat_Descriptor
|
||||
public Current_VSM
|
||||
public Nested_Flag
|
||||
public HardwareInfo
|
||||
public SMI_Base
|
||||
public IRQ_Base, IRQ_Mask
|
||||
public Header_Addr
|
||||
public BracketFlag
|
||||
public ExitSysCall
|
||||
public EmptyMsgQueue
|
||||
public Dispatcher
|
||||
public Trap_Code
|
||||
|
||||
externdef Trap_Common: proc
|
||||
externdef Trap7: proc
|
||||
externdef Get_SMI_Sources: proc
|
||||
externdef VSA_Entry: proc
|
||||
externdef VSA_Exit: proc
|
||||
externdef Show_SMI_Source: proc
|
||||
externdef Generate_IRQ: proc
|
||||
externdef pascal Hex_8: proc
|
||||
externdef pascal Hex_16: proc
|
||||
externdef pascal Hex_32: proc
|
||||
externdef pascal SMINT_Handler:proc
|
||||
|
||||
externdef INT_Vectors: dword
|
||||
externdef SMI_Sources: dword
|
||||
externdef SynchEvents: dword
|
||||
externdef HiPrioritySMIs: dword
|
||||
externdef MSRs: dword
|
||||
|
||||
externdef SysCall_Table: word
|
||||
|
||||
externdef NumDescriptors: byte
|
||||
externdef Events: byte
|
||||
externdef MSRs: byte
|
||||
externdef _end: byte
|
||||
externdef edata: byte
|
||||
|
||||
externdef Handler_Table: SMI_ENTRY
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; NOTE: "#define EXTRA_SAVE" in SYSMGR.H must match the number of bytes
|
||||
; of state (over and above the registers) that is saved by the
|
||||
; following two macros:
|
||||
SAVE_STATE macro
|
||||
pushad ; Save general purpose registers
|
||||
mov dx, PCI_CONFIG_ADDRESS ; Save PCI Configuration Address
|
||||
in eax, dx
|
||||
push eax
|
||||
|
||||
endm
|
||||
|
||||
|
||||
RESTORE_STATE macro
|
||||
pop eax ; PCI Configuration Address
|
||||
mov dx, PCI_CONFIG_ADDRESS
|
||||
out dx, eax
|
||||
popad ; Restore general purpose registers
|
||||
|
||||
endm
|
||||
|
||||
|
||||
|
||||
|
||||
Start:
|
||||
; NOTE: The VSA II installer patches a "JMP SysMgr_Entry" over the signature field
|
||||
dd VSM_SIGNATURE ; VSM signature
|
||||
db VSM_SYS_MGR ; VSM type
|
||||
db 0FFh ; Any CPU
|
||||
dw DEVICE_ID_5536 ; VSA for CS5536
|
||||
dw VSA_VERSION ; System Manager version
|
||||
dd OFFSET edata ; Size of System Manager
|
||||
dw OFFSET SysMgr_Entry ; EntryPoint
|
||||
dd OFFSET _end ; DS Limit
|
||||
dw 0007h ; Requirements: 4096-byte boundary
|
||||
dw VSA_VERSION ; VSA version
|
||||
|
||||
Stack_Descriptor:
|
||||
Descriptor {_end, 0000h, 00h, DATA_ATTR, 00h, 00h, 0000h}
|
||||
Data_Descriptor:
|
||||
Descriptor {_end, 0000h, 00h, DATA_ATTR, 00h, 00h, 0000h}
|
||||
|
||||
Flat_Descriptor:
|
||||
Descriptor {0FFFFh, 0000h, 00h, DATA_ATTR, 8Fh, 00h, 0000h}
|
||||
|
||||
|
||||
dw 0 ; .AlignSystem
|
||||
SMM_Header SmiHeader {} ; .State
|
||||
VSM_ListHead dd 0 ; .Flink (ptr to 1st VSM; zero if no VSMs)
|
||||
|
||||
Trap macro Trap_Num
|
||||
ORG Trap_Code + (Trap_Num * 8)
|
||||
mov bx, Trap_Num
|
||||
jmp Trap_Common
|
||||
endm
|
||||
|
||||
ORG sizeof(VSM_Header)
|
||||
align 16
|
||||
|
||||
;***********************************************************************
|
||||
; Exception vectors
|
||||
;***********************************************************************
|
||||
Trap_Code:
|
||||
Trap 0
|
||||
Trap 1
|
||||
Trap 2
|
||||
Trap 3
|
||||
Trap 4
|
||||
Trap 5
|
||||
Trap 6
|
||||
|
||||
ORG Trap_Code + (7 * 8)
|
||||
jmp Trap7
|
||||
|
||||
Trap 8
|
||||
Trap 9
|
||||
Trap 0Ah
|
||||
Trap 0Bh
|
||||
Trap 0Ch
|
||||
Trap 0Dh
|
||||
Trap 0Eh
|
||||
Trap 0Fh
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Non-nested VSA entry point *
|
||||
;***********************************************************************
|
||||
SysMgr_Entry:
|
||||
|
||||
;
|
||||
; Save state of interrupted task & initialize VSA environment
|
||||
;
|
||||
svdc cs:[Saved_DS], ds ; Save DS descriptor & set to SysMgr segment
|
||||
rsdc ds, cs:[Data_Descriptor]
|
||||
ASSUME DS:_CODE
|
||||
|
||||
svdc [Saved_ES], es ; Save ES descriptor
|
||||
svdc [Saved_FS], fs ; Save FS descriptor
|
||||
svdc [Saved_GS], gs ; Save GS descriptor
|
||||
|
||||
svdc [Saved_SS], ss ; Save SS descriptor & set to SysMgr segment
|
||||
rsdc ss, [Stack_Descriptor]
|
||||
mov [Saved_ESP], esp ; Save ESP & set up SysMgr stack
|
||||
mov esp, OFFSET SysMgrStack
|
||||
|
||||
SAVE_STATE ; Save the general purpose registers on SysMgr's stack
|
||||
|
||||
|
||||
rdtsc ; Get start time of this SMI
|
||||
mov (VSM_Header PTR ds:[0]).SysStuff.StartTime, eax
|
||||
mov (VSM_Header PTR ds:[4]).SysStuff.StartTime, edx
|
||||
|
||||
rsdc fs, [Flat_Descriptor] ; Set FS descriptor to a 4 GB flat segment
|
||||
rsdc es, [Flat_Descriptor] ; Set ES descriptor to a 4 GB flat segment
|
||||
|
||||
if BRACKETS
|
||||
cmp [BracketFlag], 0
|
||||
je short NoBracket
|
||||
mov dx, DBG_PORT
|
||||
mov al, '['
|
||||
out dx, al
|
||||
|
||||
NoBracket:
|
||||
endif
|
||||
|
||||
|
||||
call VSA_Entry ; Perform VSA entry setup
|
||||
|
||||
xor eax, eax
|
||||
mov [Nested_Flag], eax
|
||||
|
||||
;
|
||||
; Check for SMINT
|
||||
;
|
||||
test [SMM_Header].SMI_Flags, 1000b
|
||||
jz short Main_SMI_Loop
|
||||
|
||||
push word ptr [Saved_EAX]
|
||||
call SMINT_Handler
|
||||
jmp Dispatcher
|
||||
|
||||
;***********************************************************************
|
||||
;***********************************************************************
|
||||
;***********************************************************************
|
||||
; *
|
||||
; Main SMI Loop *
|
||||
; *
|
||||
; 1) Read the top-level SMI sources. *
|
||||
; 2) If no SMIs are pending, exit SMM. *
|
||||
; 3) Call an SMI handler for each pending SMI source. *
|
||||
; 4) Dispatch to VSMs that have non-empty message queues. *
|
||||
; 5) Rinse and repeat. *
|
||||
; *
|
||||
;***********************************************************************
|
||||
;***********************************************************************
|
||||
;***********************************************************************
|
||||
Main_SMI_Loop:
|
||||
|
||||
call Get_SMI_Sources ; Get source(s) of external SMIs
|
||||
test ebx, ebx ; If no SMIs pending, exit SMM
|
||||
jz SMI_Resume
|
||||
|
||||
|
||||
;
|
||||
; Invoke the handler for each pending SMI source
|
||||
;
|
||||
mov [SMI_Sources], ebx
|
||||
RunHandlers:
|
||||
lea di, Handler_Table - sizeof (SMI_ENTRY)
|
||||
NextHandler:
|
||||
add di, sizeof (SMI_ENTRY) ; Advance ptr to next handler entry
|
||||
|
||||
mov eax, (SMI_ENTRY PTR [di]).SMI_Mask
|
||||
and eax, [SMI_Sources] ; Sources = TopLevelSources & Handler_Table.SMI_Mask
|
||||
jz NextHandler
|
||||
|
||||
push eax ; call Handler_Table.Handler(Sources)
|
||||
call (SMI_ENTRY PTR [di]).Handler
|
||||
pop eax
|
||||
|
||||
not eax ; TopLevelSources &= ~Sources;
|
||||
and [SMI_Sources], eax
|
||||
jnz NextHandler ; if (!TopLevelSources) break;
|
||||
|
||||
|
||||
|
||||
|
||||
;
|
||||
; Dispatch to the VSM on top of the scheduler's stack
|
||||
;
|
||||
Dispatcher:
|
||||
mov si, [SchedulerStack] ; Get scheduler's ptr
|
||||
mov ebx, [si] ; Pop next VSM
|
||||
sub si, 4
|
||||
|
||||
test ebx, 0FFFF0000h ; Is it a VSM ?
|
||||
jnz RunTask
|
||||
test bx, bx ; Callback routine ?
|
||||
je Main_SMI_Loop
|
||||
mov [SchedulerStack], si ; Yes, update scheduler ptr
|
||||
call bx ; Go to callback routine
|
||||
jmp Dispatcher
|
||||
|
||||
|
||||
RunTask:
|
||||
mov [SchedulerStack], si ; Save scheduler's ptr
|
||||
mov [Current_VSM], ebx ; Save ptr to the current VSM
|
||||
ExecuteTask:
|
||||
;
|
||||
; Point SMHR to the VSM's SMM header.
|
||||
;
|
||||
lea eax, (VSM_Header PTR [ebx+sizeof(SmiHeader)]).SysStuff.State
|
||||
mov ecx, MSR_SMM_HDR
|
||||
wrmsr
|
||||
;
|
||||
; Restore the VSM's state
|
||||
;
|
||||
rsdc ds, fs:(VSM_Header PTR [ebx])._DS
|
||||
|
||||
xor edi, edi
|
||||
ASSUME di:PTR VSM_Header
|
||||
rsdc gs, [di]._DS
|
||||
rsdc ss, [di]._SS ; Restore VSM's SS:SP
|
||||
lea bx, [di].SysStuff
|
||||
ASSUME bx:PTR System
|
||||
mov sp, word ptr [bx].SavedESP
|
||||
|
||||
|
||||
;
|
||||
; Update statistics
|
||||
;
|
||||
rdtsc ; Record start time of the VSM
|
||||
mov [bx+0].StartTime, eax
|
||||
add [bx+0].NumSMIs, 1 ; Increment SMI count
|
||||
adc [bx+4].NumSMIs, edi
|
||||
|
||||
;
|
||||
; Mark VSM active unless it is sleeping
|
||||
;
|
||||
mov al, RUN_FLAG_ACTIVE
|
||||
SetRunFlag:
|
||||
xchg [bx].RunFlag, al
|
||||
cmp al, RUN_FLAG_SLEEPING
|
||||
je SetRunFlag
|
||||
|
||||
RESTORE_STATE ; No, restore registers
|
||||
|
||||
rsm ; Resume to the VSM
|
||||
|
||||
|
||||
ASSUME DI: NOTHING
|
||||
ASSUME BX: NOTHING
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Restore state & resume to non-SMM code *
|
||||
;***********************************************************************
|
||||
align 16
|
||||
SMI_Resume:
|
||||
|
||||
|
||||
; Generate internal IRQ(s)
|
||||
xor ecx, ecx
|
||||
xchg ecx, [IRQ_Mask]
|
||||
jecxz NoIRQ
|
||||
call Generate_IRQ
|
||||
NoIRQ:
|
||||
|
||||
|
||||
call VSA_Exit ; Perform VSA exit
|
||||
jc Main_SMI_Loop
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; Increment count of SMIs
|
||||
mov si, OFFSET VSM_Header.SysStuff
|
||||
ASSUME SI: PTR System
|
||||
xor ecx, ecx
|
||||
add [si+0].NumSMIs, 1
|
||||
adc [si+4].NumSMIs, ecx
|
||||
|
||||
; Compute total clocks for this SMI
|
||||
rdtsc
|
||||
sub eax, [si+0].StartTime
|
||||
; Accumulate total clocks spent executing VSA code
|
||||
add [si+0].Clocks, eax
|
||||
adc [si+4].Clocks, ecx
|
||||
|
||||
ASSUME SI:NOTHING
|
||||
|
||||
|
||||
|
||||
|
||||
if BRACKETS
|
||||
cmp [BracketFlag], 0
|
||||
je @f
|
||||
mov dx, DBG_PORT
|
||||
mov al, ']'
|
||||
out dx, al
|
||||
@@:
|
||||
endif
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Restore the state of the interrupted task *
|
||||
;***********************************************************************
|
||||
RESTORE_STATE ; Restore GP registers & PCI addr
|
||||
|
||||
mov esp, [Saved_ESP] ; Restore ESP
|
||||
rsdc ss, [Saved_SS] ; Restore descriptors
|
||||
rsdc es, [Saved_ES]
|
||||
rsdc fs, [Saved_FS]
|
||||
rsdc gs, [Saved_GS]
|
||||
rsdc ds, [Saved_DS] ; Must be restored last
|
||||
rsm ; Resume to non-SMM thread
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; An SMI has occurred that is not a system call: *
|
||||
; *
|
||||
; If synchronous SMI: *
|
||||
; - Save the state of the interrupted VSM *
|
||||
; - Reschedule the interrupted VSM *
|
||||
; - Execute SMI handlers *
|
||||
; If asynchronous SMI: *
|
||||
; - If event is not high priority or VSM is marked no-preempt, *
|
||||
; return to interrupted VSM immediately. *
|
||||
; - Otherwise, execute SMI handlers *
|
||||
;***********************************************************************
|
||||
align 16
|
||||
NotSysCall:
|
||||
|
||||
;
|
||||
; Save VSM's state and set up SysMgr stack
|
||||
;
|
||||
SAVE_STATE ; Save the VSM's state
|
||||
mov word ptr gs:(VSM_Header).SysStuff.SavedESP, sp
|
||||
|
||||
rsdc ss, [Stack_Descriptor] ; Setup System Manager's stack
|
||||
lea sp, [StartSaveArea]
|
||||
|
||||
|
||||
call Get_SMI_Sources ; Get source(s) of nested SMIs
|
||||
|
||||
mov [SMI_Sources], ebx ; Record the pending SMI sources
|
||||
test ebx, [SynchEvents] ; Is nested SMI a syncronous event ?
|
||||
jz short AsyncSMI
|
||||
|
||||
;
|
||||
; The SMI is synchronous (I/O or virtualized PCI trap)
|
||||
;
|
||||
and ebx, [SynchEvents] ; Record the nested SMI source
|
||||
or [Nested_Flag], ebx
|
||||
|
||||
; It's a trapped or virtualized PCI.
|
||||
; Record some info about the event.
|
||||
svdc [Nested_ES], gs ; Save GS descriptor
|
||||
mov esi, gs:(VSM_Header).SysStuff.SavedESP
|
||||
mov eax, gs:[si+0] ; Get VSM's PCI address
|
||||
mov edi, gs:[si+4] ; Get VSM's EDI
|
||||
mov [Nested_PCI], eax ; Required by PCI_Handler
|
||||
mov [Nested_EDI], edi ; Required if INS
|
||||
add esi, VSM_STACK_FRAME - 4
|
||||
add esi, [Current_VSM] ; Ptr to EAX on VSM's stack
|
||||
mov [Nested_EAX], esi
|
||||
|
||||
ServiceNow:
|
||||
|
||||
mov gs:(VSM_Header).SysStuff.RunFlag, RUN_FLAG_READY
|
||||
Reschedule:
|
||||
add [SchedulerStack], 4 ; Re-schedule the interrupted VSM
|
||||
|
||||
mov ebp, [SMI_Sources] ; Needed by RunHandlers
|
||||
|
||||
; Update the clock count used by the VSM
|
||||
rdtsc
|
||||
sub eax, gs:(VSM_Header).SysStuff.StartTime
|
||||
xor edx, edx
|
||||
add gs:(VSM_Header).SysStuff.Clocks+0, eax
|
||||
adc gs:(VSM_Header).SysStuff.Clocks+4, edx
|
||||
|
||||
jmp RunHandlers
|
||||
|
||||
|
||||
;
|
||||
; The SMI is asynchronous
|
||||
;
|
||||
AsyncSMI:
|
||||
or ebx, ebx ; If null SMI, just return to VSM
|
||||
jz short NoPreempt
|
||||
|
||||
cmp gs:(VSM_Header).SysStuff.RunFlag, RUN_FLAG_SLEEPING
|
||||
je Reschedule
|
||||
|
||||
jmp ServiceNow
|
||||
|
||||
; Is this a high priority SMI ?
|
||||
; test ebx, [HiPrioritySMIs]
|
||||
; jnz short ServiceNow ; Yes, execute SMI handlers
|
||||
|
||||
|
||||
;
|
||||
; Resumes to a VSM from an low-priority asynchronous SMI
|
||||
;
|
||||
NoPreempt:
|
||||
;
|
||||
; Resumes to a VSM from a system call
|
||||
;
|
||||
ExitSysCall: ; Return to caller
|
||||
rsdc ss, gs:(VSM_Header)._SS
|
||||
mov sp, word ptr gs:(VSM_Header).SysStuff.SavedESP
|
||||
rsdc ds, gs:(VSM_Header)._DS
|
||||
RESTORE_STATE
|
||||
rsm
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; The current VSM has emptied its message queue. It will not be *
|
||||
; executed again until a new message is entered into its queue. *
|
||||
; NOTE: SysMgr will be using the last VSM's stack. *
|
||||
;***********************************************************************
|
||||
EmptyMsgQueue:
|
||||
|
||||
|
||||
mov gs:(VSM_Header).SysStuff.RunFlag, RUN_FLAG_INACTIVE
|
||||
jmp short UpdateClocks
|
||||
|
||||
Sys_Exit:
|
||||
; System calls should not count as an SMI
|
||||
sub gs:(VSM_Header).SysStuff.NumSMIs+0, 1 ; Decrement number of SMIs
|
||||
sbb gs:(VSM_Header).SysStuff.NumSMIs+4, 0
|
||||
UpdateClocks:
|
||||
|
||||
|
||||
; Update the clock count used by the VSM
|
||||
rdtsc
|
||||
sub eax, gs:(VSM_Header).SysStuff.StartTime
|
||||
xor edx, edx
|
||||
add gs:(VSM_Header).SysStuff.Clocks+0, eax
|
||||
adc gs:(VSM_Header).SysStuff.Clocks+4, edx
|
||||
|
||||
jmp Dispatcher
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; Schedules a VSM to execute
|
||||
;***********************************************************************
|
||||
Schedule_VSM proc pascal uses bx \
|
||||
Vsm: DWORD
|
||||
|
||||
mov eax, [Vsm]
|
||||
test eax, 0FFFF0000h ; Is it a callback ?
|
||||
jz Schedule
|
||||
|
||||
; Mark VSM ready, if not already on scheduler's stack
|
||||
mov bl, RUN_FLAG_READY
|
||||
xchg bl, fs:(VSM_Header PTR [eax]).SysStuff.RunFlag
|
||||
; cmp bl, RUN_FLAG_READY
|
||||
; je short Exit
|
||||
|
||||
Schedule:
|
||||
mov bx, [SchedulerStack] ; Get scheduler's ptr
|
||||
add bx, 4 ; Push the VSM
|
||||
mov [bx], eax
|
||||
mov [SchedulerStack], bx ; Update scheduler's ptr
|
||||
Exit: ret
|
||||
|
||||
Schedule_VSM endp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
;***********************************************************************
|
||||
;***********************************************************************
|
||||
;* *
|
||||
;* Nested SMI Entry Point *
|
||||
;* *
|
||||
;* A nested SMI can occur for one of four reasons: *
|
||||
;* 1) A system call *
|
||||
;* 2) An asynchronous event (timer, GPIO, etc.) *
|
||||
;* 3) A trapped I/O from a VSM (virtual register, PCI access) *
|
||||
;* 4) Return from a BIOS callback *
|
||||
;* *
|
||||
;***********************************************************************
|
||||
;***********************************************************************
|
||||
;***********************************************************************
|
||||
align 16
|
||||
Nested_SMI:
|
||||
|
||||
; Set DS descriptor to System Manager's
|
||||
rsdc ds, cs:[Data_Descriptor]
|
||||
|
||||
|
||||
; Is it a system call (SMINT) ?
|
||||
test byte ptr gs:(VSM_Header).SysStuff.State.SMI_Flags, 1000b
|
||||
jz NotSysCall
|
||||
|
||||
;*************************************************************************
|
||||
;*************************************************************************
|
||||
;*************************************************************************
|
||||
; *
|
||||
; SMI is a system call *
|
||||
; *
|
||||
; The VSM's registers are saved on the VSM's stack. *
|
||||
; DS: and SS:SP are initialized to SysMgr's environment. *
|
||||
; *
|
||||
; On Entry: *
|
||||
; AX = System call code *
|
||||
; Other registers, depending on the system call *
|
||||
; *
|
||||
;*************************************************************************
|
||||
;*************************************************************************
|
||||
;*************************************************************************
|
||||
SystemCall:
|
||||
cmp ax, SYS_CODE_EXIT ; Check for valid system code
|
||||
ja short IllegalSysCall ; If invalid, record an error
|
||||
|
||||
|
||||
mov [VSMs_EAX], eax
|
||||
SAVE_STATE ; Save the VSM's state
|
||||
mov word ptr gs:(VSM_Header).SysStuff.SavedESP, sp
|
||||
|
||||
; Setup System Manager's stack
|
||||
rsdc ss, [Stack_Descriptor]
|
||||
lea sp, [StartSaveArea]
|
||||
|
||||
; Dispatch to system call routine
|
||||
movzx eax, word ptr [VSMs_EAX]
|
||||
jmp [SysCall_Table + eax*2]
|
||||
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; An illegal system call was detected
|
||||
;***********************************************************************
|
||||
IllegalSysCall:
|
||||
; Is it ResumeFromRAM ?
|
||||
cmp ax, SYS_RESUME_FROM_RAM
|
||||
je ResumeFromRAM
|
||||
|
||||
mov di, ERR_UNDEF_SYS_CALL
|
||||
mov ebx, eax ; Info1 = system call code
|
||||
mov ecx, [Current_VSM] ; Info2 = offending VSM
|
||||
mov ax, SYS_CODE_ERROR ; Fake a SYS_CODE_ERROR
|
||||
jmp SystemCall
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
; BIOS is resuming after a Save-to-RAM:
|
||||
; 1) Re-init VSA state
|
||||
; 2) Re-schedule the suspended VSM
|
||||
; 3) Go to VSM dispatcher
|
||||
;***********************************************************************
|
||||
ResumeFromRAM:
|
||||
rsdc fs, [Flat_Descriptor] ; Set FS to a 4 GB flat segment
|
||||
rsdc es, [Flat_Descriptor] ; Set ES to a 4 GB flat segment
|
||||
|
||||
mov ebx, [Current_VSM]
|
||||
mov ax, fs:(VSM_Header PTR [ebx]).SysStuff.ResumeVector
|
||||
mov fs:(VSM_Header PTR [ebx]).SysStuff.State.Next_IP, ax
|
||||
mov fs:(VSM_Header PTR [ebx]).SysStuff.RunFlag, RUN_FLAG_READY
|
||||
jmp ExecuteTask
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
align 4
|
||||
Current_VSM dd 0
|
||||
HardwareInfo Hardware { }
|
||||
BracketFlag db 0
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;*************************************************************************************
|
||||
;
|
||||
; IMPLEMENTATION NOTES:
|
||||
;
|
||||
; - The scheduler's stack and System Manager's stack grow toward each other.
|
||||
;
|
||||
; - The variables at StartSaveArea are grouped together because they, along with
|
||||
; the SMM header, represent the entire state of the interrupted task. This is
|
||||
; important since this state must be saved & restored across a BIOS callback.
|
||||
;
|
||||
;*************************************************************************************
|
||||
align 2
|
||||
SchedulerStack dw OFFSET Scheduled_VSMs
|
||||
|
||||
align 4
|
||||
Scheduled_VSMs dd 0 ; Marks bottom of scheduler's stack
|
||||
|
||||
|
||||
|
||||
ORG SYSMGRS_STACK
|
||||
StartSaveArea:
|
||||
Saved_PCI dd ?
|
||||
|
||||
; NOTE: the following 8 variables must be in the correct order for PUSHAD/POPAD
|
||||
Saved_EDI dd ?
|
||||
Saved_ESI dd ?
|
||||
Saved_EBP dd ?
|
||||
dd ? ; ESP (not used)
|
||||
Saved_EBX dd ?
|
||||
Saved_EDX dd ?
|
||||
Saved_ECX dd ?
|
||||
Saved_AX:
|
||||
Saved_EAX dd ?
|
||||
SysMgrStack: ; <==== System Manager's stack begins here
|
||||
|
||||
Saved_ESP dd OFFSET SysMgrStack ; DO NOT MOVE !!!
|
||||
|
||||
|
||||
;
|
||||
; NOTE: The SET_REGISTER, GET_REGISTER, GET_DESCRIPTOR, & SET_DESCRIPTOR
|
||||
; macros assume these are in this exact location and order:
|
||||
Saved_SS Descriptor { }
|
||||
Saved_DS Descriptor { }
|
||||
Saved_ES Descriptor { }
|
||||
Saved_FS Descriptor { }
|
||||
Saved_GS Descriptor { }
|
||||
|
||||
Header_Addr dd 0 ; Ptr to end of SMM header
|
||||
|
||||
IDT_Selector dd 0 ; Saved IDT state
|
||||
IDT_Base dd 0
|
||||
IDT_Limit dd 0
|
||||
|
||||
|
||||
|
||||
dw 0 ; Pad
|
||||
EndSaveArea label byte
|
||||
;
|
||||
; This table contains System Manager structures accesses by INIT.EXE and INFO.EXE.
|
||||
; Must match the InfoStuff structure in VSA2.H
|
||||
;
|
||||
ORG SPECIAL_LOC
|
||||
|
||||
dw OFFSET Events
|
||||
dw OFFSET MSRs
|
||||
dw OFFSET INT_Vectors
|
||||
dw OFFSET HardwareInfo
|
||||
IRQ_Base dd 0 ; Memory-mapped location of Internal IRQs
|
||||
IRQ_Mask dd 0 ; Mask of IRQs to be generated
|
||||
; NOTE: The following fields are not referenced by VSMs.
|
||||
; They are in this structure so INIT.ASM can initialize them.
|
||||
SysMgr_VSM dd 0 ; Logical address of System Manager
|
||||
SMI_Base dd 0 ; Memory-mapped location of SMI sources
|
||||
dw OFFSET Header_Addr ; Offset of SysMgr.SysStuff.State
|
||||
dw OFFSET StartSaveArea ; Initial value of SysMgr.SysStuff.SavedESP
|
||||
dw OFFSET MSRs
|
||||
dw OFFSET NumDescriptors
|
||||
|
||||
Nested_EAX dd 0 ; Flat ptr to interrupted VSM's EAX
|
||||
Nested_EDI dd 0 ; Value of interrupted VSM's EDI
|
||||
Nested_PCI dd 0 ; PCI config address of interrupted VSM
|
||||
Nested_Flag dd 0
|
||||
|
||||
VSMs_EAX dd 0
|
||||
Nested_ES Descriptor {}
|
||||
|
||||
|
||||
_CODE ENDS
|
||||
|
||||
END Start
|
||||
|
||||
207
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/sysmgr.h
vendored
Executable file
207
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/sysmgr.h
vendored
Executable file
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// Build flags for various optional features
|
||||
#define HISTORY 0 // History support (value determines size of history buffer; 0=disabled)
|
||||
#define CHECKED_BUILD 1 // Perform internal sanity checks
|
||||
|
||||
#define SUPPORT_CAPABILITIES 1 // Enables support for PCI capabilities list
|
||||
#define SUPPORT_PRIORITY 0 // Enables message priority logic
|
||||
#define SUPPORT_FS2 1 // Enables MBIU1 descriptors so FS2 sees same map as GX2
|
||||
|
||||
#define USB_FIX 0 // 0=none 1=old 2=new
|
||||
#define MAX_INT 0x1B // Maximum INT vector supported for BIOS callbacks
|
||||
|
||||
|
||||
#define SYS_YIELD 0x40000000L // Must be >= bit 24
|
||||
|
||||
#define DBG_PORT 0x84
|
||||
#define VSA_POST 0x84 // I/O port for VSA POST codes
|
||||
|
||||
#define EXTRA_SAVE 4 // State saved other than registers
|
||||
#define VSM_STACK_FRAME (8*4+EXTRA_SAVE)// PUSHAD + EXTRA_SAVE
|
||||
|
||||
#define SPECIAL_LOC 0xA80 // Determines depth of SysMgr's stack
|
||||
#define STACK_OFFSET 0x94 // Should be: EndSaveArea - StartSaveArea
|
||||
#define SYSMGRS_STACK (SPECIAL_LOC-STACK_OFFSET)
|
||||
|
||||
#define MAX_REGISTRATIONS 100 // # entries in Events[]
|
||||
|
||||
// VSM specific definitions
|
||||
#define CODE_ATTR 0x9B
|
||||
#define DATA_ATTR 0x93
|
||||
#define VSM_CR0 0x00000014
|
||||
#define VSM_EFLAGS 0x00000002
|
||||
#define VSM_DR7 0x00000400
|
||||
#define VSM_STACK_SIZE 0x300 // Size of allocated stack in bytes
|
||||
#define BIOS_STACK_SIZE 0x100
|
||||
|
||||
// VSM States
|
||||
#define RUN_FLAG_INACTIVE 0x00 // VSM is idle
|
||||
#define RUN_FLAG_SLEEPING 0x55 // VSM is in Standby/Suspend
|
||||
#define RUN_FLAG_ACTIVE 0xAA // VSM is running or scheduled to run
|
||||
#define RUN_FLAG_WAITING 0xEE // VSM has yielded control
|
||||
#define RUN_FLAG_BLOCKED 0xBB // VSM is blocked
|
||||
#define RUN_FLAG_READY 0x77 // VSM is ready to execute
|
||||
|
||||
|
||||
// System calls
|
||||
#define SYS_CODE_EVENT 0x0000 // Event registration
|
||||
#define SYS_CODE_YIELD 0x0001 // VSM is yielding control
|
||||
#define SYS_CODE_SW_INT 0x0002 // Software Interrupt (INT xx)
|
||||
#define SYS_CODE_PASS_EVENT 0x0003 // VSM did not handle an event
|
||||
#define SYS_CODE_UNLOAD 0x0004 // Unload VSM
|
||||
#define SYS_CODE_REGISTER 0x0005 // Get/Set special registers
|
||||
#define SYS_CODE_PCI_ACCESS 0x0006 // Access a PCI dword with trapping disabled
|
||||
#define SYS_CODE_SET_VIRTUAL 0x0007 // Set virtual register
|
||||
#define SYS_CODE_GET_VIRTUAL 0x0008 // Get virtual register
|
||||
#define SYS_CODE_BROADCAST 0x0009 // Broadcast a message to one or more VSMs
|
||||
#define SYS_CODE_STATE 0x000A // Save/Restore non-SMM state
|
||||
#define SYS_CODE_ERROR 0x000B // Report error
|
||||
#define SYS_CODE_RESOURCE 0x000C // Reserve resource
|
||||
#define SYS_CODE_DECODE 0x000D // Set resource to be subtractive/positive decode
|
||||
#define SYS_CODE_DESCRIPTOR 0x000E // Get descriptor of virtualized PCI BAR
|
||||
#define SYS_CODE_LOOKUP 0x000F // Lookup routing for MBus device
|
||||
#define SYS_CODE_IRQ_MAPPER 0x0010 // Set IRQ mapping (CS5535 only)
|
||||
#define SYS_CODE_RESULT 0x0011 // Return virtualized result
|
||||
#define SYS_CODE_DUPLICATE 0x0012 // Duplicate a VSM
|
||||
#define SYS_CODE_EXIT 0x0013 // Exit to System Manager
|
||||
|
||||
#define GET_REG 0x80
|
||||
#define SET_REG 0x81
|
||||
#define GET_HDR 0x82
|
||||
#define SET_HDR 0x83
|
||||
#define GET_DESCR 0x84
|
||||
#define SET_DESCR 0x85
|
||||
|
||||
|
||||
// Fields in SMM header flag
|
||||
#define SMI_FLAGS_CS_WRITABLE 0x0001 // "Cw" bit CS is writable
|
||||
#define SMI_FLAGS_OUTPUT 0x0002 // "I" bit I/O indicator
|
||||
#define SMI_FLAGS_REP 0x0004 // "P" bit REP indicator
|
||||
#define SMI_FLAGS_SMINT 0x0008 // "S" bit SMI occured due to a SMINT
|
||||
#define SMI_FLAGS_HALT 0x0010 // "H" bit SMI occured during CPU halt
|
||||
#define SMI_FLAGS_MEMORY 0x0020 // "M" bit 0=I/O, 1=memory
|
||||
#define SMI_FLAGS_EXT 0x0040 // "X" bit External SMI source
|
||||
#define SMI_FLAGS_VGA 0x0080 // "V" bit VGA emulation source
|
||||
#define SMI_FLAGS_NESTED 0x0100 // "N" bit Nested SMI
|
||||
#define SMI_FLAGS_CS_READABLE 0x8000 // "Cr" bit CS is writable
|
||||
|
||||
|
||||
|
||||
|
||||
typedef void (* SMI_Handler)(void);
|
||||
|
||||
typedef struct {
|
||||
SMI_Handler Handler;
|
||||
unsigned long SMI_Mask;
|
||||
} SMI_ENTRY;
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned long Vsm;
|
||||
|
||||
union {
|
||||
struct {
|
||||
unsigned long Param1;
|
||||
unsigned long Param2;
|
||||
unsigned long Param3;
|
||||
};
|
||||
struct { // Timers
|
||||
unsigned long Interval;
|
||||
unsigned short Handle;
|
||||
unsigned char Timer;
|
||||
unsigned char Attr;
|
||||
unsigned long RemainingInterval;
|
||||
};
|
||||
struct { // GPIOs
|
||||
unsigned short Pin;
|
||||
unsigned short Pme;
|
||||
unsigned short Attributes;
|
||||
unsigned short Pm1;
|
||||
unsigned long CurrentEdge;
|
||||
};
|
||||
struct { // PCI header
|
||||
unsigned short PCI_Addr;
|
||||
unsigned short Unused;
|
||||
unsigned short PCI_Mask;
|
||||
unsigned short Flags;
|
||||
};
|
||||
struct { // I/O trap & timeout
|
||||
unsigned short IO_Base;
|
||||
unsigned short IO_Timeout;
|
||||
unsigned short IO_Range;
|
||||
};
|
||||
struct { // Virtual Register
|
||||
unsigned long ClassLow;
|
||||
unsigned long ClassHigh;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
unsigned long Timestamp[2];
|
||||
unsigned char Index;
|
||||
unsigned char Link;
|
||||
unsigned short Priority;
|
||||
} EVENT_ENTRY;
|
||||
|
||||
typedef struct {
|
||||
unsigned long Vsm;
|
||||
unsigned long Event;
|
||||
unsigned long Param1;
|
||||
unsigned long Param2;
|
||||
unsigned long Count;
|
||||
unsigned long TimeStamp[2];
|
||||
} EVENT_HISTORY;
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned short History_Array;
|
||||
int * History_Start;
|
||||
int * History_End;
|
||||
int * History_Wrap;
|
||||
unsigned short HistoryEntries;
|
||||
} HISTORY_INFO;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// An instance of this structure is found in the System Manager at offset SPECIAL_LOC
|
||||
//
|
||||
typedef struct {
|
||||
unsigned short Events; // Events array
|
||||
unsigned short Descriptors; // MBus Descriptors array
|
||||
unsigned short Vectors; // INT vectors
|
||||
unsigned short HardwareInfo; // Hardware structure
|
||||
unsigned long IRQ_Base; // Used by SYS_GENERATE_IRQ
|
||||
unsigned long IRQ_Mask; // Used by SYS_GENERATE_IRQ
|
||||
unsigned long SysMgr_VSM; // Used in SysMgr only
|
||||
unsigned long SMI_Base; // Used in SysMgr only
|
||||
unsigned short Header_Addr; // Used in SysMgr only
|
||||
unsigned short SysMgr_Stack; // Used in SysMgr only
|
||||
unsigned short MSRs; // Used for DOS_BUILD
|
||||
unsigned short NumDescrs; // Used for DOS_BUILD
|
||||
} InfoStuff;
|
||||
729
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/timeout.c
vendored
Executable file
729
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/timeout.c
vendored
Executable file
@@ -0,0 +1,729 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//******************************************************************************
|
||||
//* - Handles I/O inactivity counters
|
||||
//******************************************************************************
|
||||
|
||||
|
||||
|
||||
#include "VSA2.H"
|
||||
#include "PROTOS.H"
|
||||
#include "GX2.H"
|
||||
#include "VPCI.H"
|
||||
#include "DESCR.H"
|
||||
#include "CS5536.H"
|
||||
|
||||
// External prototypes:
|
||||
void Deallocate_Descriptor(DESCRIPTOR *);
|
||||
|
||||
|
||||
// External variables:
|
||||
extern ULONG LookupMbiu;
|
||||
extern ULONG ClocksPerMs;
|
||||
extern DESCRIPTOR MSRs[];
|
||||
extern UCHAR NumDescriptors;
|
||||
extern ULONG Mbiu2;
|
||||
extern UCHAR NumMbius;
|
||||
extern MBIU_INFO MbiuInfo[MAX_MBIU];
|
||||
extern ULONG MbiuSkipFlags[];
|
||||
extern Hardware HardwareInfo;
|
||||
|
||||
#define NUM_PHYSICAL_COUNTERS 7 // Number of physical statistic counters
|
||||
#define NUM_LOGICAL_COUNTERS 20 // Number of logical statistic counters
|
||||
#define NUM_LINKED_DESCRIPTORS 3 // Number of descriptors per logical counter
|
||||
|
||||
// Local variables:
|
||||
UCHAR NumPhysCounters= 0;
|
||||
|
||||
typedef struct {
|
||||
ULONG MsrAddr; // MSR address of STATISTICS_CNT
|
||||
ULONG Prescaler;
|
||||
ULONG Mask; // IOD_MASK field
|
||||
ULONG SFlags;
|
||||
USHORT StandbyFlag;
|
||||
USHORT Timeout;
|
||||
USHORT MbiuNumber;
|
||||
} PHYSICAL_COUNTERS;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ULONG Mask;
|
||||
USHORT Address;
|
||||
USHORT DeviceID;
|
||||
USHORT Timeout;
|
||||
UCHAR PhysIndex; // Index to physical counter
|
||||
UCHAR DescrIndex[NUM_LINKED_DESCRIPTORS]; // Indices to descriptors
|
||||
} LOGICAL_COUNTERS;
|
||||
|
||||
PHYSICAL_COUNTERS PhysCounter[NUM_PHYSICAL_COUNTERS];
|
||||
LOGICAL_COUNTERS LogCounter[NUM_LOGICAL_COUNTERS];
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Initializes a logical timeout counter
|
||||
//***********************************************************************
|
||||
void InitLogicalCounter(LOGICAL_COUNTERS * LogicalPtr)
|
||||
{ int i;
|
||||
|
||||
LogicalPtr->Mask = 0x00000000;
|
||||
for (i = 0; i < NUM_LINKED_DESCRIPTORS; i++) {
|
||||
LogicalPtr->DescrIndex[i] = 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Deallocates a logical counter.
|
||||
// Deallocates all descriptors associated with a logical counter,
|
||||
// unless the descriptor is also being used for an I/O trap.
|
||||
//***********************************************************************
|
||||
void DeallocateLogicalCounter(LOGICAL_COUNTERS * LogicalPtr)
|
||||
{ int i, j;
|
||||
|
||||
|
||||
for (i = 0; i < NUM_LINKED_DESCRIPTORS; i++) {
|
||||
// Get index of I/O descriptor used for this logical counter
|
||||
j = LogicalPtr->DescrIndex[i];
|
||||
if (j == 0xFF) {
|
||||
// No more linked descriptors
|
||||
break;
|
||||
}
|
||||
|
||||
// If not used for I/O trap or virtualized PCI BAR
|
||||
if (!(MSRs[j].Flag & IO_TRAP) && !(MSRs[j].Owner)) {
|
||||
Deallocate_Descriptor(&MSRs[j]);
|
||||
}
|
||||
}
|
||||
|
||||
// Deallocate logical counter
|
||||
InitLogicalCounter(LogicalPtr);
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Initializes the logical timeout counter structures
|
||||
//***********************************************************************
|
||||
void InitLogicalCounters(void)
|
||||
{ int i;
|
||||
register LOGICAL_COUNTERS * LogicalPtr;
|
||||
|
||||
// Initialize logical counters
|
||||
LogicalPtr = &LogCounter[0];
|
||||
for (i=0; i < NUM_LOGICAL_COUNTERS; i++) {
|
||||
InitLogicalCounter(LogicalPtr++);
|
||||
}
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
// Initializes the physical timeout counter structures & MSRs
|
||||
// Called from Init_MBIU().
|
||||
//***********************************************************************
|
||||
void InitStatCounters(ULONG Msr, UCHAR NumStatCntrs)
|
||||
{ int i;
|
||||
ULONG MsrData[2], SFlags;
|
||||
register PHYSICAL_COUNTERS * PhysPtr;
|
||||
static UCHAR Shift=0;
|
||||
|
||||
// Initialize physical counters
|
||||
MsrData[0] = MsrData[1] = 0x00000000;
|
||||
(USHORT)Msr = MSR_STATISTICS_CNT;
|
||||
SFlags = 1L << Shift;
|
||||
|
||||
// Prepare shift count for next MBIU
|
||||
Shift += 8;
|
||||
for (i = 0; i < NumStatCntrs; i++) {
|
||||
|
||||
// Initialize the statistic MSR
|
||||
Write_MSR(Msr+0, MsrData); // MSR_STATISTICS_CNT
|
||||
Write_MSR(Msr+1, MsrData); // MSR_STATISTICS_MASK
|
||||
Write_MSR(Msr+2, MsrData); // MSR_STATISTICS_ACTION
|
||||
|
||||
// Initialize next physical counter
|
||||
if (NumPhysCounters < NUM_PHYSICAL_COUNTERS) {
|
||||
|
||||
PhysPtr = &PhysCounter[NumPhysCounters];
|
||||
PhysPtr->MbiuNumber = NumMbius;
|
||||
PhysPtr->MsrAddr = Msr;
|
||||
PhysPtr->Mask = 0x00000000;
|
||||
PhysPtr->StandbyFlag = 0;
|
||||
PhysPtr->SFlags = SFlags;
|
||||
SFlags <<= 1;
|
||||
|
||||
// Determine 16-bit prescaler
|
||||
if ((Msr & ROUTING) == Mbiu2) {
|
||||
// Clock to Southbridge statistic counters is 66 MHz.
|
||||
PhysPtr->Prescaler = 66000L/8;
|
||||
} else {
|
||||
// Clock to Northbridge statistic counters is DRAM clock.
|
||||
PhysPtr->Prescaler = HardwareInfo.DRAM_MHz * 1000L/8;
|
||||
// If memory is DDR, DRAM clock is running at 1/2 MBUS frequency
|
||||
if (!(Read_MSR_LO(0x4C000014) & 0x400)) {
|
||||
// so adjust the prescaler
|
||||
PhysPtr->Prescaler >>= 1;
|
||||
}
|
||||
}
|
||||
// Shift into PREDIV field
|
||||
PhysPtr->Prescaler <<= 8;
|
||||
// Set counter attributes
|
||||
(UCHAR)PhysPtr->Prescaler = (ALWAYS_DEC | HIT_LDEN | ZERO_SMI);
|
||||
|
||||
// Increment number of statistics counters.
|
||||
NumPhysCounters++;
|
||||
|
||||
} else {
|
||||
Log_Error("The PhysCounter structure has fewer entries than # of h/w counters");
|
||||
// Continue initializing, but don't record MSR in array
|
||||
}
|
||||
|
||||
// Advance to next statistic MSR
|
||||
Msr += 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Finds the Address corresponding to a bit set in MBD_MSR_SMI.
|
||||
// Clears the next set bit in the EventMask variable.
|
||||
//***********************************************************************
|
||||
USHORT Get_Timeout(ULONG SFlag, UCHAR * StartIndex)
|
||||
{ UCHAR i, j;
|
||||
USHORT Address = 0x0000;
|
||||
register PHYSICAL_COUNTERS * PhysPtr;
|
||||
register LOGICAL_COUNTERS * LogicalPtr;
|
||||
|
||||
// Find the correct logical counter & return the associated address
|
||||
LogicalPtr = &LogCounter[* StartIndex];
|
||||
for (i = * StartIndex; i < NUM_LOGICAL_COUNTERS; i++) {
|
||||
// Is logical counter in use ?
|
||||
if (LogicalPtr->Mask != 0x00000000) {
|
||||
|
||||
// Get physical counter to which it is linked
|
||||
j = LogicalPtr->PhysIndex;
|
||||
PhysPtr = &PhysCounter[j];
|
||||
|
||||
// Is this counter generating an event ?
|
||||
if (PhysPtr->SFlags & SFlag) {
|
||||
|
||||
// Yes, return either the DeviceID or the Inactive Address
|
||||
Address = LogicalPtr->DeviceID;
|
||||
if (!Address) {
|
||||
Address = LogicalPtr->Address;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
LogicalPtr++;
|
||||
}
|
||||
|
||||
// Return logical index
|
||||
* StartIndex = i+1;
|
||||
|
||||
return Address;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Enables/Disables SMIs for a statistic counter
|
||||
//***********************************************************************
|
||||
void pascal StatCntrSMI(ULONG MsrAddr, UCHAR EnableFlag)
|
||||
{ ULONG MsrData[2], Mask;
|
||||
int j;
|
||||
|
||||
MsrData[0] = MsrData[1] = 0x00000000;
|
||||
if (!EnableFlag) {
|
||||
Write_MSR(MsrAddr, MsrData);
|
||||
Write_MSR(MsrAddr+2, MsrData);
|
||||
}
|
||||
|
||||
j = ((UCHAR)MsrAddr - MSR_STATISTICS_CNT) / 4;
|
||||
j++; // HW Emulation is bit 0
|
||||
|
||||
|
||||
(USHORT)MsrAddr = MBD_MSR_SMI;
|
||||
|
||||
Read_MSR(MsrAddr, MsrData);
|
||||
Mask = 1L << j;
|
||||
if (EnableFlag) {
|
||||
MsrData[0] &= ~Mask;
|
||||
} else {
|
||||
MsrData[0] |= Mask;
|
||||
}
|
||||
Write_MSR(MsrAddr, MsrData);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Sets the IOD_MASK field of STATISTIC_MASK
|
||||
//***********************************************************************
|
||||
void pascal Set_IOD_MASK(PHYSICAL_COUNTERS * PhysPtr)
|
||||
{
|
||||
Write_MSR_HI(PhysPtr->MsrAddr | 1, PhysPtr->Mask);
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Disables an inactivity timer for the specified parameters.
|
||||
// Param1:
|
||||
// 31:16 = Timeout in seconds
|
||||
// 15:00 = I/O Base
|
||||
// Param2:
|
||||
// 31:16 = Flags (ONE_SHOT, WRITES_ONLY, READS_ONLY)
|
||||
// 15:00 = I/O Range
|
||||
//***********************************************************************
|
||||
void pascal Clr_MBus_IO_Timeout(ULONG Param1, ULONG Param2)
|
||||
{ int i;
|
||||
USHORT Address, Range, Timeout;
|
||||
MBIU_INFO * MbiuPtr;
|
||||
register PHYSICAL_COUNTERS * PhysPtr;
|
||||
register LOGICAL_COUNTERS * LogicalPtr;
|
||||
|
||||
// Unpack parameters
|
||||
Range = (USHORT)Param2;
|
||||
Address = (USHORT)Param1;
|
||||
Timeout = (USHORT)(Param1 >> 16);
|
||||
|
||||
// Find the corresponding logical counter
|
||||
LogicalPtr = &LogCounter[0];
|
||||
for (i = 0; i < NUM_LOGICAL_COUNTERS; i++) {
|
||||
if (LogicalPtr->Address == Address) {
|
||||
break;
|
||||
}
|
||||
LogicalPtr++;
|
||||
}
|
||||
|
||||
if (i >= NUM_LOGICAL_COUNTERS) {
|
||||
// ERROR: VSM is unregistering a non-existent timeout.
|
||||
Report_VSM_Error(ERR_UNREGISTRATION, Address, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get physical counter corresponding to this logical counter
|
||||
PhysPtr = &PhysCounter[LogicalPtr->PhysIndex];
|
||||
|
||||
// Clear IOD_MASK in the corresponding physical counter
|
||||
PhysPtr->Mask &= ~LogicalPtr->Mask;
|
||||
Set_IOD_MASK(PhysPtr);
|
||||
|
||||
// Decrement timer count on this MBIU
|
||||
MbiuPtr = &MbiuInfo[PhysPtr->MbiuNumber];
|
||||
if (MbiuPtr->ActiveCounters) {
|
||||
MbiuPtr->ActiveCounters--;
|
||||
}
|
||||
|
||||
|
||||
// If no more timeouts for this physical counter...
|
||||
if (PhysPtr->Mask == 0x00000000) {
|
||||
PhysPtr->StandbyFlag = 0;
|
||||
|
||||
// Disable the statistics counter
|
||||
StatCntrSMI(PhysPtr->MsrAddr, 0);
|
||||
|
||||
|
||||
if (MbiuPtr->ActiveCounters == 0) {
|
||||
// Restore clock gating on this MBIU
|
||||
if (MbiuPtr->ActiveCounters == 0) {
|
||||
Write_MSR_LO(MbiuPtr->Mbiu + MBD_MSR_PM, MbiuPtr->ClockGating);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (MbiuPtr->ActiveCounters == 0) {
|
||||
Log_Error("MbiuInfo->ActiveCounters is out of sync");
|
||||
}
|
||||
}
|
||||
|
||||
// Deallocate descriptor(s)
|
||||
DeallocateLogicalCounter(LogicalPtr);
|
||||
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
// Enables an inactivity timer for the specified I/O Range
|
||||
// Param1:
|
||||
// 31:16 = Timeout in seconds
|
||||
// 15:00 = I/O Base
|
||||
// Param2:
|
||||
// 31:16 = Flags (NOT_GLIUx, ONE_SHOT, WRITES_ONLY, READS_ONLY)
|
||||
// 15:00 = I/O Range
|
||||
//***********************************************************************
|
||||
void pascal Set_MBus_IO_Timeout(USHORT Address, USHORT Timeout, USHORT Range, USHORT Attr, USHORT DeviceID)
|
||||
{ ULONG MsrAddr, MsrData[2], Addr, Candidate, Flags;
|
||||
UCHAR i, j, k;
|
||||
MBIU_INFO * MbiuPtr;
|
||||
register DESCRIPTOR * Descr;
|
||||
register PHYSICAL_COUNTERS * PhysPtr;
|
||||
register LOGICAL_COUNTERS * LogicalPtr;
|
||||
|
||||
Flags = (ULONG)Attr << 16;
|
||||
|
||||
// Find an available logical counter
|
||||
LogicalPtr = &LogCounter[0];
|
||||
for (i=0; i < NUM_LOGICAL_COUNTERS; i++) {
|
||||
if (LogicalPtr->Mask == 0x00000000) {
|
||||
break;
|
||||
}
|
||||
LogicalPtr++;
|
||||
}
|
||||
|
||||
if (i >= NUM_LOGICAL_COUNTERS) {
|
||||
Log_Error("The LogCounter structure is not large enough");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Record info about this timeout
|
||||
LogicalPtr->Address = Address;
|
||||
LogicalPtr->DeviceID = DeviceID;
|
||||
LogicalPtr->Timeout = Timeout;
|
||||
|
||||
|
||||
// Set Flags:NOT_GLIUx for GLIUs with no available counters
|
||||
for (k=0; k < NumMbius; k++) {
|
||||
|
||||
// Skip this MBIU ?
|
||||
if (Flags & MbiuSkipFlags[k]) {
|
||||
continue;
|
||||
}
|
||||
MbiuPtr = &MbiuInfo[k];
|
||||
j = MbiuPtr->NumCounters;
|
||||
|
||||
//
|
||||
PhysPtr = &PhysCounter[0];
|
||||
for (i=0; i < NumPhysCounters; i++) {
|
||||
// Is this counter on the current GLIU ?
|
||||
if ((MbiuPtr->Mbiu & ROUTING) == (PhysPtr->MsrAddr & ROUTING)) {
|
||||
// Is it available ?
|
||||
if (PhysPtr->Mask) {
|
||||
// No, is it the last counter on this GLIU ?
|
||||
if (--j == 0) {
|
||||
// Yes, then exclude from search
|
||||
Flags |= MbiuSkipFlags[k];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
PhysPtr++;
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate descriptor(s) for address range
|
||||
Addr = Flags; // Set Addr = Flags::Address
|
||||
(USHORT)Addr = Address;
|
||||
k = 0;
|
||||
while (Range) {
|
||||
|
||||
// Find existing descriptor(s) that match Address
|
||||
j = Find_Matching_IO_Descriptor(&Addr, &Range, 1);
|
||||
if (j == DESCRIPTOR_NOT_FOUND) {
|
||||
// No compatible descriptor exists, so create one
|
||||
// and route it to the subtractive port.
|
||||
j = Setup_IO_Descriptor(&Addr, &Range, 1);
|
||||
if (j == DESCRIPTOR_NOT_FOUND) {
|
||||
// Error: No free descriptors
|
||||
k = 0xFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Descr = &MSRs[j];
|
||||
|
||||
// Record the descriptor index
|
||||
LogicalPtr->DescrIndex[k] = j;
|
||||
|
||||
if (k++ == 0) {
|
||||
// Record 1st descriptor
|
||||
MsrAddr = Descr->MsrAddr;
|
||||
} else {
|
||||
// Check that all descriptors are on same MBIU
|
||||
if ((MsrAddr & ROUTING) != (Descr->MsrAddr & ROUTING)) {
|
||||
// No free descriptors on same MBIU
|
||||
k = 0xFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Add the new descriptor to IOD_MASK
|
||||
LogicalPtr->Mask |= 1L << ((UCHAR)Descr->MsrAddr - MSR_IO_DESCR);
|
||||
}
|
||||
|
||||
|
||||
// If no descriptor found...
|
||||
if (k == 0xFF) {
|
||||
// ERROR: Not enough descriptors to handle request
|
||||
Report_VSM_Error(ERR_NO_MORE_DESCRIPTORS, Address, 0);
|
||||
|
||||
// Deallocate descriptor(s) and logical counter
|
||||
DeallocateLogicalCounter(LogicalPtr);
|
||||
return;
|
||||
}
|
||||
|
||||
// Find an appropriate hardware statistic counter
|
||||
Candidate = 0;
|
||||
for (i=0; i < NumPhysCounters; i++) {
|
||||
|
||||
PhysPtr = &PhysCounter[i];
|
||||
|
||||
// Physical counter must be on the same MBIU as the I/O descriptor
|
||||
if ((PhysPtr->MsrAddr & ROUTING) != (Descr->MsrAddr & ROUTING)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (PhysPtr->Timeout == Timeout) {
|
||||
// If same timeout, the leverage same counter
|
||||
break;
|
||||
}
|
||||
|
||||
// Is this counter being used for Standby inactivity detection ?
|
||||
if (PhysPtr->StandbyFlag) {
|
||||
// Yes, is the request for Standby ?
|
||||
if (Flags & FOR_STANDBY) {
|
||||
// Yes, then must use the same physical counter
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Mark physical counter as a candidate
|
||||
Candidate |= 1L << i;
|
||||
}
|
||||
|
||||
// If an existing counter can't be leveraged, find a new one
|
||||
if (i >= NumPhysCounters) {
|
||||
// Among the candidates, find an unused counter
|
||||
for (i=0; i < NumPhysCounters; i++) {
|
||||
if (Candidate & (1L << i)) {
|
||||
PhysPtr = &PhysCounter[i];
|
||||
if (!(PhysPtr->Mask)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If physical counter is found, link it to the descriptor
|
||||
if (i < NumPhysCounters) {
|
||||
|
||||
// Increment timer count on this MBIU
|
||||
MbiuPtr = &MbiuInfo[PhysPtr->MbiuNumber];
|
||||
MbiuPtr->ActiveCounters++;
|
||||
// Turn off clock gating on this MBIU
|
||||
Write_MSR_LO(MbiuPtr->Mbiu + MBD_MSR_PM, Read_MSR_LO(MbiuPtr->Mbiu + MBD_MSR_PM) & 0xFFFFFFF0);
|
||||
|
||||
// Record physical counter used for the logical counter
|
||||
LogicalPtr->PhysIndex = i;
|
||||
|
||||
// Mark descriptor as used for I/O timeout
|
||||
Descr->Flag |= IO_TIMEOUT;
|
||||
|
||||
// Record info about this timer
|
||||
PhysPtr->Timeout = Timeout;
|
||||
PhysPtr->Mask |= LogicalPtr->Mask;
|
||||
|
||||
// Set flag if counter is being used for Standby inactivity detection
|
||||
if (Flags & FOR_STANDBY) {
|
||||
PhysPtr->StandbyFlag = 1;
|
||||
}
|
||||
|
||||
// Set STATISTIC_CNT[LOAD_VAL]
|
||||
MsrAddr = PhysPtr->MsrAddr;
|
||||
MsrData[0] = MsrData[1] = Timeout * 8*1000L;
|
||||
Write_MSR(MsrAddr, MsrData);
|
||||
|
||||
// Link counter to the descriptor
|
||||
Set_IOD_MASK(PhysPtr);
|
||||
|
||||
// Set STATISTIC_ACTION[PREDIV]
|
||||
// Set Prescaler to decrement Count every ms
|
||||
Write_MSR_LO(MsrAddr+2, PhysPtr->Prescaler);
|
||||
|
||||
|
||||
// Enable the statistics counter in MBD_MSR_SMI
|
||||
StatCntrSMI(MsrAddr, 1);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// ERROR: Not enough statistics counter to handle request
|
||||
Report_VSM_Error(ERR_NO_MORE_DESCRIPTORS, (ULONG)Address, NumPhysCounters);
|
||||
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
ULONG dword;
|
||||
struct {
|
||||
USHORT IO_Base;
|
||||
USHORT Timeout;
|
||||
};
|
||||
};
|
||||
} TIMEOUT_P1;
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
ULONG Flags;
|
||||
struct {
|
||||
union {
|
||||
USHORT Range;
|
||||
UCHAR Instance;
|
||||
};
|
||||
USHORT Attributes;
|
||||
};
|
||||
};
|
||||
} TIMEOUT_P2;
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Enables/disables an inactivity timer for an I/O Range or GLIU device.
|
||||
// Param1:
|
||||
// 31:16 = Timeout in seconds
|
||||
// 15:00 = I/O Base
|
||||
// = GLIU DeviceID if Flags[GLIU_ID] is set
|
||||
// Param2:
|
||||
// 31:16 = Flags
|
||||
// 15:00 = Length of I/O range
|
||||
// = Instance if Flags[GLIU_ID] is set
|
||||
// EnableFlag:
|
||||
// 0 = disable
|
||||
// 1 = enable
|
||||
//***********************************************************************
|
||||
void pascal MBus_IO_Timeout(ULONG Param1, ULONG Param2, UCHAR EnableFlag)
|
||||
{ UCHAR Port, ByteEnables, i, Hit;
|
||||
USHORT Address, DeviceID = 0x0000;
|
||||
ULONG MsrAddr;
|
||||
register DESCRIPTOR * Descr;
|
||||
TIMEOUT_P1 p1;
|
||||
TIMEOUT_P2 p2;
|
||||
|
||||
|
||||
// Force use of descriptors in Southbridge
|
||||
if (!(Param2 & FOR_STANDBY)) {
|
||||
Param2 |= NOT_GLIU0 | NOT_GLIU1;
|
||||
}
|
||||
|
||||
p1.dword = Param1;
|
||||
p2.Flags = Param2;
|
||||
|
||||
if (p2.Flags & GLIU_ID) {
|
||||
p2.Flags &= ~GLIU_ID;
|
||||
|
||||
DeviceID = p1.IO_Base;
|
||||
|
||||
// Don't allow stupid requests
|
||||
switch (DeviceID) {
|
||||
case ID_MBIU:
|
||||
case ID_MDD:
|
||||
case ID_MCP:
|
||||
case ID_VAIL:
|
||||
// Log an error
|
||||
Report_VSM_Error(ERR_BAD_PARAMETER, EVENT_IO_TIMEOUT, Param1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Find specified instance of the requested device
|
||||
MsrAddr = Find_MBus_ID(DeviceID, p2.Instance);
|
||||
Port = (UCHAR)MsrAddr;
|
||||
|
||||
if (!MsrAddr) {
|
||||
// Log an error
|
||||
Report_VSM_Error(ERR_HW_MISMATCH, EVENT_IO_TIMEOUT, Param2);
|
||||
return;
|
||||
}
|
||||
|
||||
MsrAddr = LookupMbiu & ROUTING; // LookupMbiu was set by Find_MBus_ID()
|
||||
|
||||
// Find all descriptors on this MBIU/Port
|
||||
Hit = 0;
|
||||
for (i = 1; i < NumDescriptors; i++) {
|
||||
|
||||
Descr = &MSRs[i];
|
||||
|
||||
// Is descriptor routing to a device ?
|
||||
Address = Descr->Address;
|
||||
if (Address == 0x0000) {
|
||||
continue;
|
||||
}
|
||||
// Is descriptor on correct MBIU ?
|
||||
if (MsrAddr != (Descr->MsrAddr & ROUTING)) {
|
||||
continue;
|
||||
}
|
||||
// Is descriptor routing to the requested device ?
|
||||
if (Port == (Descr->MsrData[1] >> 29)) {
|
||||
|
||||
// Yes, determine start address of descriptor
|
||||
switch (Descr->Type) {
|
||||
case IOD_SC:
|
||||
// Determine start address of IOD_SC descriptor
|
||||
ByteEnables = (UCHAR)(Descr->MsrData[0] >> 24);
|
||||
while (ByteEnables) {
|
||||
if (ByteEnables & 1) {
|
||||
break;
|
||||
} else {
|
||||
Address++;
|
||||
}
|
||||
ByteEnables >>= 1;
|
||||
}
|
||||
// Fall through intended
|
||||
|
||||
case IOD_BM:
|
||||
// Recursive call
|
||||
p1.IO_Base = Address;
|
||||
p2.Range = 1;
|
||||
MBus_IO_Timeout(p1.dword, p2.Flags, EnableFlag);
|
||||
Hit = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Hit || DeviceID != ID_VG) {
|
||||
DeviceID = 0x0000;
|
||||
return;
|
||||
}
|
||||
// Monitor external video card activity
|
||||
p1.IO_Base = 0x03C0;
|
||||
p2.Range = 32;
|
||||
}
|
||||
|
||||
// Check for illegal combination of flags
|
||||
if ((p2.Flags & ALL_GLIUS) == ALL_GLIUS) {
|
||||
// ERROR: Illegal combination of EVENT_IO_TIMEOUT flags
|
||||
Report_VSM_Error(ERR_BAD_PARAMETER, EVENT_IO_TIMEOUT, p2.Flags);
|
||||
return;
|
||||
}
|
||||
|
||||
if (EnableFlag) {
|
||||
Set_MBus_IO_Timeout(p1.IO_Base, p1.Timeout, p2.Range, p2.Attributes, DeviceID);
|
||||
} else {
|
||||
Clr_MBus_IO_Timeout(p1.dword, p2.Flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
183
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/timer.c
vendored
Executable file
183
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/timer.c
vendored
Executable file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//*****************************************************************************
|
||||
//* Routines related to timer management.
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
#include "VSA2.H"
|
||||
#include "CHIPSET.H"
|
||||
#include "SYSMGR.H"
|
||||
#include "PROTOS.H"
|
||||
#include "TIMER.H"
|
||||
|
||||
typedef unsigned char (* TIMER_ON)(ULONG, UCHAR);
|
||||
typedef void (* TIMER_OFF)(unsigned short);
|
||||
|
||||
|
||||
// External prototypes:
|
||||
extern UCHAR EnableMsTimer_5536(ULONG, UCHAR);
|
||||
extern USHORT DisableMsTimer_5536(USHORT);
|
||||
extern void pascal MarkTimerAvailable(USHORT);
|
||||
|
||||
|
||||
// External variables:
|
||||
extern ULONG MsgPacket[];
|
||||
extern EVENT_ENTRY Events[];
|
||||
extern ULONG ClocksPerMs;
|
||||
extern Hardware HardwareInfo;
|
||||
extern TIMERS TimerInfo[];
|
||||
|
||||
|
||||
// Local variables:
|
||||
TIMER_ON EnableTimer;
|
||||
TIMER_OFF DisableTimer;
|
||||
USHORT ActiveTimer;
|
||||
ULONG ActiveInterval;
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Performs initialization related to timers
|
||||
//***********************************************************************
|
||||
void InitTimers(void)
|
||||
{
|
||||
|
||||
switch (HardwareInfo.Chipset_ID) {
|
||||
|
||||
case DEVICE_ID_5536:
|
||||
EnableTimer = EnableMsTimer_5536;
|
||||
DisableTimer = DisableMsTimer_5536;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// This routine handles timer ticks.
|
||||
//***********************************************************************
|
||||
USHORT FilterTimer(EVENT_ENTRY * EventPtr, EVENT EventIndex)
|
||||
{ USHORT ReturnValue=0;
|
||||
ULONG Vsm;
|
||||
static EVENT NextToExpire;
|
||||
|
||||
Vsm = EventPtr->Vsm;
|
||||
|
||||
|
||||
// If 1st registered timer, initialize 'next interval' variables
|
||||
if (EventIndex == EVENT_TIMER) {
|
||||
NextToExpire = 0;
|
||||
}
|
||||
|
||||
// Only decrement timers associated with the expired h/w timer
|
||||
if (EventPtr->Timer == ActiveTimer) {
|
||||
|
||||
// Has this timer expired ?
|
||||
if (ActiveInterval >= EventPtr->RemainingInterval) {
|
||||
|
||||
// Yes, reset the VSM's remaining interval
|
||||
EventPtr->RemainingInterval = EventPtr->Interval;
|
||||
|
||||
// Fill message packet
|
||||
MsgPacket[1] = EventPtr->Interval;
|
||||
MsgPacket[2] = EventPtr->Handle;
|
||||
|
||||
// Was timer due to a SYS_YIELD ?
|
||||
if (EventPtr->Param2 & SYS_YIELD) {
|
||||
// Yes, schedule the slumbering VSM
|
||||
Schedule_VSM(Vsm);
|
||||
}
|
||||
|
||||
// Return its Events[] index
|
||||
ReturnValue = EventIndex;
|
||||
} else {
|
||||
// Decrement RemainingInterval by the expired timer interval
|
||||
EventPtr->RemainingInterval -= ActiveInterval;
|
||||
}
|
||||
|
||||
// Find the next interval on the current h/w timer to expire
|
||||
if (EventPtr->RemainingInterval < Events[NextToExpire].RemainingInterval) {
|
||||
// Ignore one-shots that just expired
|
||||
if (ReturnValue != EventIndex || !(EventPtr->Param2 & ONE_SHOT)) {
|
||||
NextToExpire = EventIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If no more timers, then set timer h/w to next interval
|
||||
if (!EventPtr->Link) {
|
||||
// Set the timer h/w to the next interval to expire
|
||||
if (Events[NextToExpire].Vsm) {
|
||||
Enable_Event(EVENT_TIMER, NextToExpire, 2);
|
||||
}
|
||||
}
|
||||
|
||||
return ReturnValue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// This routine decrements all software timers. If a software timer has
|
||||
// expired, it sends an event message to the VSM. The time to the next
|
||||
// scheduled event and invokes Enable_Event() to restart the timer.
|
||||
//
|
||||
//***********************************************************************
|
||||
void pascal Timer_Handler(USHORT TimerNumber)
|
||||
{
|
||||
// Record the active timer
|
||||
ActiveTimer = TimerNumber;
|
||||
ActiveInterval = TimerInfo[ActiveTimer].Interval;
|
||||
|
||||
// Mark this timer as available
|
||||
MarkTimerAvailable(TimerNumber);
|
||||
|
||||
// Send the timer event
|
||||
Send_Event(EVENT_TIMER, 0x00000000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Enables a millisecond timer to the specified interval
|
||||
//
|
||||
// EnableFlag
|
||||
// 0 = disable
|
||||
// 1 = new registration
|
||||
// 2 = reprogram timer to new interval
|
||||
//*****************************************************************************
|
||||
void MillisecondTimer(UCHAR EnableFlag, EVENT_ENTRY * EventPtr)
|
||||
{
|
||||
if (EnableFlag == 0) {
|
||||
|
||||
// Disable the h/w timer
|
||||
DisableTimer(EventPtr->Timer);
|
||||
|
||||
} else {
|
||||
|
||||
// Program a hardware timer
|
||||
EventPtr->Timer = (UCHAR)EnableTimer(EventPtr->RemainingInterval, EventPtr->Attr);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
51
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/timer.h
vendored
Executable file
51
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/timer.h
vendored
Executable file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
typedef struct {
|
||||
UCHAR Timer; // Timer number
|
||||
UCHAR Mapper; // Unrestricted Z field
|
||||
USHORT Setup; // Scale factor & clock select
|
||||
USHORT Period; // microseconds/count
|
||||
ULONG Interval; // Current interval in milliseconds
|
||||
USHORT Mask; // Bit mask
|
||||
USHORT TimerBase; // I/O base
|
||||
} TIMERS;
|
||||
|
||||
|
||||
#define MFGPT_ENABLE 0x8000
|
||||
#define MFGPT_COMPARE2 0x4000
|
||||
#define MFGPT_COMPARE1 0x2000
|
||||
#define MFGPT_INITED 0x1000
|
||||
#define MFGPT_STOP_EN 0x0800
|
||||
#define MFGPT_EXT_EN 0x0400
|
||||
#define MFGPT_CMP2MODE 0x0300
|
||||
#define MFGPT_CMP2GE 0x0200
|
||||
#define MFGPT_CMP1MODE 0x00C0
|
||||
#define MFGPT_CMP1GE 0x0080
|
||||
#define MFGPT_REV_EN 0x0020
|
||||
#define MFGPT_CLK_SEL 0x0010
|
||||
#define MFGPT_SCALE_32 0x0005
|
||||
#define MFGPT_SCALE_1K 0x000A
|
||||
#define MFGPT_SCALE_2K 0x000B
|
||||
#define MFGPT_SCALE_4K 0x000C
|
||||
#define MFGPT_SCALE_8K 0x000D
|
||||
#define MFGPT_SCALE_16K 0x000E
|
||||
#define MFGPT_SCALE_32K 0x000F
|
||||
|
||||
348
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/topology.c
vendored
Executable file
348
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/topology.c
vendored
Executable file
@@ -0,0 +1,348 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//*****************************************************************************
|
||||
//* Implements tables that determine the virtualized PCI topology
|
||||
//* and register definitions.
|
||||
//*****************************************************************************
|
||||
|
||||
#include "VSA2.H"
|
||||
#include "VPCI.H"
|
||||
#include "PCI.H"
|
||||
#include "CHIPSET.H"
|
||||
#include "CS5536.H"
|
||||
#include "SYSMGR.H"
|
||||
#include "MDD.H"
|
||||
#include "MAPPER.H"
|
||||
|
||||
//***********************************************************************
|
||||
// Notes on Virtualized PCI Header Tables
|
||||
//
|
||||
// 1) The PCI_HEADER_ENTRY structure must contain at a minimum:
|
||||
// - Vendor & Device IDs
|
||||
// - Command/Status
|
||||
// - RevisionID/ClassCode
|
||||
// - CacheLine/LatencyTimer/HeaderType/BIST
|
||||
// 2) The Flag field of the last (and only last) entry must have EOL set.
|
||||
// 3) The Mask field contains a 1 in each bit position that is R/W,
|
||||
// except for bits 11-15 of the Status register. In this case, a set
|
||||
// bit means that this feature is reportable.
|
||||
// 4) Memory BARs require a minimum of 4 KB alignment.
|
||||
// 5) Registers up to and including BAR0 must be present and in ascending order
|
||||
//***********************************************************************
|
||||
|
||||
// Write-to-Clear Status bits
|
||||
#define WC_STATUS_BITS ((ULONG)(SIGNALED_TARGET_ABORT | RECEIVED_TARGET_ABORT | RECEIVED_MASTER_ABORT | \
|
||||
SIGNALED_SYSTEM_ERROR | DETECTED_PARITY_ERROR ))
|
||||
|
||||
|
||||
#define DEVSEL_TIMING (DEVSEL_MEDIUM)
|
||||
// Defaults
|
||||
#define DEF_STATUS (PCI_66MHZ_CAPABLE | DEVSEL_TIMING | BACK2BACK_CAPABLE)
|
||||
#define DEF_MASK (FAST_BACK_TO_BACK | PARITY_RESPONSE)
|
||||
|
||||
// Northbridge
|
||||
#define NB_STATUS (DEF_STATUS | BUS_MASTER) & ~(BACK2BACK_CAPABLE)
|
||||
#define NB_MASK (DEF_MASK | BUS_MASTER | IO_SPACE) & \
|
||||
~(SERR_ENABLE | PARITY_RESPONSE | SIGNALED_SYSTEM_ERROR | FAST_BACK_TO_BACK)
|
||||
|
||||
// Southbridge
|
||||
#define SB_MASK (DEF_MASK | SPECIAL_CYCLES)
|
||||
#define SB_STATUS (DEF_STATUS)
|
||||
|
||||
// Graphics
|
||||
#define GFX_STATUS (DEF_STATUS) & ~(BACK2BACK_CAPABLE)
|
||||
#define GFX_MASK (DEF_MASK | BUS_MASTER) & \
|
||||
~(SERR_ENABLE | PARITY_RESPONSE | SIGNALED_SYSTEM_ERROR | FAST_BACK_TO_BACK)
|
||||
|
||||
// AES
|
||||
#define AES_STATUS (DEF_STATUS)
|
||||
#define AES_MASK (GFX_MASK)
|
||||
|
||||
// Bus Masters
|
||||
#define BM_STATUS (DEF_STATUS)
|
||||
#define BM_MASK (DEF_MASK | BUS_MASTER)
|
||||
|
||||
// OHCI Controllers
|
||||
#define OHCI_MASK (BM_MASK | IO_SPACE | PARITY_RESPONSE)
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Virtualized Northbridge PCI Device
|
||||
//***********************************************************************
|
||||
PCI_HEADER_ENTRY HostBridge_Hdr[] = {
|
||||
// Reg Flag Value Mask
|
||||
{ 0x00, 0x00, 0x20801022, 0x00000000},
|
||||
{ COMMAND, 0x00, NB_STATUS, NB_MASK,0,0,WC_STATUS_BITS},
|
||||
{ 0x08, 0x00, 0x06000000, 0x00000000}, // Bridge: Host
|
||||
{ 0x0C, 0x00, 0x00800008, 0x0000F808},
|
||||
{ BAR0, 0x00, 0x00000000, 0x00000000}, // Virtual registers
|
||||
{ BAR1, 0x00, 0x00000000, 0x00000000}, // CPU PM functionality
|
||||
{ 0x58, EOL, 0x00000000, 0xFFFFFFFF}, // Regression testing
|
||||
};
|
||||
|
||||
|
||||
PCI_HEADER_ENTRY Graphics_Hdr[] = {
|
||||
// Reg Flag Value Mask
|
||||
{ 0x00, 0x00, 0x20811022, 0x00000000},
|
||||
{ COMMAND, 0x00, GFX_STATUS, GFX_MASK,0,0,WC_STATUS_BITS},
|
||||
{ 0x08, 0x00, 0x03000000, 0x00000000}, // Display: VGA-compatible
|
||||
{ 0x0C, 0x00, 0x00000008, 0x00000008},
|
||||
{ BAR0, 0x00, 0x00000000, 0x00000000}, // Graphics memory
|
||||
{ BAR1, 0x00, 0x00000000, 0x00000000}, // GP
|
||||
{ BAR2, 0x00, 0x00000000, 0x00000000}, // VG
|
||||
{ BAR3, 0x00, 0x00000000, 0x00000000}, // DF
|
||||
{ BAR4, 0x00, 0x00000000, 0x00000000}, // VIP (LX only)
|
||||
{ 0x3C, 0x00, 0x00000000, 0x00000000}, // LX only
|
||||
{ OEM_BAR0, 0x00, 0x00000000, 0x00000000}, // VG
|
||||
{ OEM_BAR1, 0x00, 0x00000000, 0x00000000}, // VG
|
||||
{ OEM_BAR2, 0x00, 0x00000000, 0x00000000}, // A0000-AFFFF or A0000-BFFFF if no MONO
|
||||
{ OEM_BAR3, EOL, 0x00000000, 0x00000000}, // B8000-BFFFF only if MONO present
|
||||
};
|
||||
|
||||
PCI_HEADER_ENTRY AES_Hdr[] = {
|
||||
// Reg Flag Value Mask
|
||||
{ 0x00, 0x00, 0x20821022, 0x00000000},
|
||||
{ COMMAND, 0x00, AES_STATUS, AES_MASK,0,0,WC_STATUS_BITS},
|
||||
{ 0x08, 0x00, 0x10100000, 0x00000000}, // Encryption: entertainment
|
||||
{ 0x0C, 0x00, 0x00000008, 0x00000008},
|
||||
{ BAR0, 0x00, 0x00000000, 0x00000000}, //
|
||||
{ 0x3C, EOL, 0x00000100, 0x000000FF}, // INTA
|
||||
};
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Virtualized Southbridge PCI Device
|
||||
//***********************************************************************
|
||||
|
||||
PCI_HEADER_ENTRY ISA_Hdr[] = {
|
||||
// Reg Flag Value Mask
|
||||
{ 0x00, 0x00, 0x20901022, 0x00000000},
|
||||
{ COMMAND, 0x00, SB_STATUS, SB_MASK,0,0,WC_STATUS_BITS},
|
||||
{ 0x08, 0x00, 0x06010000, 0x00000000}, // Bridge: ISA
|
||||
{ 0x0C, 0x00, 0x00800008, 0x0000F808},
|
||||
{ BAR0, 0x00, 0x00000000, 0x00000008, MSR_LBAR_SMB }, // 8 byte I/O BAR (SMB)
|
||||
{ BAR1, 0x00, 0x00000000, 0x00000100, MSR_LBAR_GPIO }, // 256 byte I/O BAR (GPIO)
|
||||
{ BAR2, 0x00, 0x00000000, 0x00000040, MSR_LBAR_MFGPT}, // 64 byte I/O BAR (MFGPT)
|
||||
{ BAR3, 0x00, 0x00000000, 0x00000020, MSR_LBAR_IRQ }, // 32 byte I/O BAR (IRQ)
|
||||
{ BAR4, 0x00, 0x00000000, 0x00000080, MSR_LBAR_PMS }, // 128 byte I/O BAR (PMS)
|
||||
{ BAR5, 0x00, 0x00000000, 0x00000040, MSR_LBAR_ACPI }, // 64 byte I/O BAR (ACPI)
|
||||
{ 0xD0, EOL, 0x00000000, 0x0000FFFF}, // Software SMI
|
||||
};
|
||||
|
||||
PCI_HEADER_ENTRY Flash_Hdr[] = {
|
||||
// Reg Flag Value Mask
|
||||
{ 0x00, 0x00, 0x20911022, 0x00000000},
|
||||
{ COMMAND, 0x00, DEF_STATUS, DEF_MASK,0,0,WC_STATUS_BITS},
|
||||
{ 0x08, 0x00, 0x05010000, 0x00000000}, // Memory controller: Flash
|
||||
{ 0x0C, 0x00, 0x00000008, 0x00000008},
|
||||
{ BAR0, 0x00, 0x00000000, 0x00000000, MSR_LBAR_FLSH0}, // Flash0
|
||||
{ BAR1, 0x00, 0x00000000, 0x00000000, MSR_LBAR_FLSH1}, // Flash1
|
||||
{ BAR2, 0x00, 0x00000000, 0x00000000, MSR_LBAR_FLSH2}, // Flash2
|
||||
{ BAR3, 0x00, 0x00000000, 0x00000000, MSR_LBAR_FLSH3}, // Flash3
|
||||
{ 0x3C, 0x00, 0x00000100 | Y_IRQ_FLASH, 0x000000FF}, // INTA
|
||||
{ 0x40, EOL, 0x00000000, 0xFFFFFFFF}, // IDE-Flash switch
|
||||
};
|
||||
|
||||
|
||||
|
||||
PCI_HEADER_ENTRY Audio_Hdr[] = {
|
||||
// Reg Flag Value Mask
|
||||
{ 0x00, 0x00, 0x20931022, 0x00000000},
|
||||
{ COMMAND, 0x00, BM_STATUS, BM_MASK,0,0,WC_STATUS_BITS},
|
||||
{ 0x08, 0x00, 0x04010000, 0x00000000}, // Multimedia: Audio
|
||||
{ 0x0C, 0x00, 0x00000008, 0x00000008},
|
||||
{ BAR0, 0x00, 0x00000000, 0x00000000}, // 128 byte I/O BAR
|
||||
{ 0x3C, EOL, 0x00000200 | Y_IRQ_AUDIO, 0x000000FF} // INTB
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#define USB20_INT (0x00000400 | Y_IRQ_USB2) // INTD
|
||||
#if SUPPORT_CAPABILITIES
|
||||
#define USB20_CMD (DEVSEL_TIMING | PCI_66MHZ_CAPABLE | CAPABILITIES_LIST)
|
||||
#else
|
||||
#define USB20_CMD (DEVSEL_TIMING | PCI_66MHZ_CAPABLE)
|
||||
#endif
|
||||
#define USB20_MASK (BM_MASK & ~(SERR_ENABLE | PARITY_RESPONSE | SIGNALED_SYSTEM_ERROR | FAST_BACK_TO_BACK | BACK2BACK_CAPABLE))
|
||||
|
||||
#define OTG_CMD USB20_CMD
|
||||
#define OTG_MASK (USB20_MASK & ~BUS_MASTER)
|
||||
|
||||
|
||||
|
||||
PCI_HEADER_ENTRY OHC_Hdr[] = {
|
||||
// Reg Flag Value Mask
|
||||
{ 0x00, 0x00, 0x20941022, 0x00000000},
|
||||
{ COMMAND, 0x00, USB20_CMD, USB20_MASK,0,0,WC_STATUS_BITS},
|
||||
{ 0x08, 0x00, 0x0C031000, 0x00000000}, // Serial Bus: USB : OHCI
|
||||
{ 0x0C, 0x00, 0x00000008, 0x00000008},
|
||||
{ BAR0, USE_BMK, 0x00000000, 0x00001000, USBMSROHCB},
|
||||
#if SUPPORT_CAPABILITIES
|
||||
{ 0x34, 0x00, PCI_PM_REG, 0x00000000}, // Capabilities pointer
|
||||
{ PCI_PM_REG, 0x00, 0xC8020001, 0x00000000}, // PCI Power Management
|
||||
{ PCI_PM_REG+4,PCI_PM, 0x00000000, 0x00008103},
|
||||
#endif
|
||||
{ 0x3C, EOL, USB20_INT, 0x000000FF},
|
||||
};
|
||||
|
||||
|
||||
PCI_HEADER_ENTRY EHC_Hdr[] = {
|
||||
// Reg Flag Value Mask
|
||||
{ 0x00, 0x00, 0x20951022, 0x00000000},
|
||||
{ COMMAND,PCI_EHCI, USB20_CMD, USB20_MASK,0,0,WC_STATUS_BITS},
|
||||
{ 0x08, 0x00, 0x0C032000, 0x00000000}, // Serial Bus: USB : EHCI
|
||||
{ 0x0C, 0x00, 0x00000008, 0x00000008},
|
||||
{ BAR0, PCI_EHCI, 0x00000000, 0x00001000, USBMSREHCB},
|
||||
#if SUPPORT_CAPABILITIES
|
||||
{ 0x34, 0x00, PCI_PM_REG, 0x00000000}, // Capabilities pointer
|
||||
{PCI_PM_REG, 0x00, 0xC8020001, 0x00000000}, // PCI Power Management
|
||||
{PCI_PM_REG+4,PCI_PM, 0x00000000, 0x00008103},
|
||||
#endif
|
||||
{ EECP, PCI_EHCI, 0x00000001, 0x01010000}, // USBLEGSUP section 2.1.7 of EHCI spec
|
||||
{ EECP+4, PCI_EHCI, 0x00000000, 0x0000E03F,0,0,0xE0000000}, // USBLEGCTLSTS section 2.1.8 of EHCI spec
|
||||
{ SRBN_REG,PCI_EHCI, 0x00000020, 0x00003F00}, // FLADJ/SBRN
|
||||
{ 0x3C, EOL, USB20_INT, 0x000000FF},
|
||||
};
|
||||
|
||||
|
||||
PCI_HEADER_ENTRY UDC_Hdr[] = {
|
||||
// Reg Flag Value Mask
|
||||
{ 0x00, 0x00, 0x20961022, 0x00000000},
|
||||
{ COMMAND, 0x00, USB20_CMD, USB20_MASK,0,0,WC_STATUS_BITS},
|
||||
{ 0x08, 0x00, 0x0C03FE00, 0x00000000}, // Serial Bus: USB : device
|
||||
{ 0x0C, 0x00, 0x00000008, 0x00000008},
|
||||
{ BAR0, 0x00, 0x00000000, 0x00002000, USBMSRUDCB},
|
||||
#if SUPPORT_CAPABILITIES
|
||||
{ 0x34, 0x00, PCI_PM_REG, 0x00000000}, // Capabilities pointer
|
||||
{PCI_PM_REG, 0x00, 0xC8020001, 0x00000000}, // PCI Power Management
|
||||
{PCI_PM_REG+4,PCI_PM, 0x00000000, 0x00008103},
|
||||
#endif
|
||||
{ 0x3C, EOL, USB20_INT, 0x000000FF},
|
||||
};
|
||||
|
||||
|
||||
PCI_HEADER_ENTRY OTG_Hdr[] = {
|
||||
// Reg Flag Value Mask
|
||||
{ 0x00, 0x00, 0x20971022, 0x00000000},
|
||||
{ COMMAND, 0x00, OTG_CMD, OTG_MASK,0,0,WC_STATUS_BITS},
|
||||
{ 0x08, 0x00, 0x0C038000, 0x00000000}, // Serial Bus: USB : No specific interface
|
||||
{ 0x0C, 0x00, 0x00000008, 0x00000008},
|
||||
{ BAR0, 0x00, 0x00000000, 0x00001000, USBMSRUOCB},
|
||||
#if SUPPORT_CAPABILITIES
|
||||
{ 0x34, 0x00, PCI_PM_REG, 0x00000000}, // Capabilities pointer
|
||||
{PCI_PM_REG, 0x00, 0xC8020001, 0x00000000}, // PCI Power Management
|
||||
{PCI_PM_REG+4,PCI_PM, 0x00000000, 0x00008103},
|
||||
#endif
|
||||
{ 0x3C, EOL, USB20_INT, 0x000000FF},
|
||||
};
|
||||
|
||||
|
||||
#define THOR_MASK (BM_MASK | IO_SPACE)
|
||||
PCI_HEADER_ENTRY Thor_Hdr[] = {
|
||||
// Reg Flag Value Mask
|
||||
{ 0x00, 0x00, 0x209A1022, 0x00000000},
|
||||
{ COMMAND, 0x00, BM_STATUS, THOR_MASK,0,0,WC_STATUS_BITS},
|
||||
{ 0x08, 0x00, 0x01018000, 0x00000000}, // Mass Storage: IDE
|
||||
{ 0x0C, 0x00, 0x0000F808, 0x00000008},
|
||||
{ BAR4, 0x00, 0x00000000, 0x00000000, MSR_LBAR_ATA}, // 16 byte I/O BAR
|
||||
// The following 4 registers must be contiguous:
|
||||
{ IDE_CFG, 0x00, 0x00000000, 0x0003FFFF, 0x10},
|
||||
{ IDE_DTC, 0x00, 0xA8A80000, 0xFFFF0000, 0x12},
|
||||
{ IDE_CAST, 0x00, 0xFF0000F0, 0xFF0000F0, 0x13},
|
||||
{ IDE_ETC, 0x00, 0x03030000, 0xC7C70000, 0x14},
|
||||
{ IDE_PM, EOL, 0x00000000, 0x00000003, 0x15},
|
||||
};
|
||||
|
||||
|
||||
PCI_HEADER_ENTRY * Virtual_5536[] = {
|
||||
ISA_Hdr, // F0 ISA bridge
|
||||
Flash_Hdr, // F1 Flash
|
||||
Thor_Hdr, // F2 ATA
|
||||
Audio_Hdr, // F3 AC97
|
||||
OHC_Hdr, // F4 OHCI
|
||||
EHC_Hdr, // F5 EHCI
|
||||
UDC_Hdr, // F6 UDC
|
||||
OTG_Hdr, // F7 OTG
|
||||
};
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// The following tables determine the virtualized PCI topology
|
||||
//***********************************************************************
|
||||
PCI_HEADER_ENTRY * NorthBridge[] = {
|
||||
HostBridge_Hdr, // F0 Host bridge
|
||||
0, // F1 Graphics (enabled via softvg)
|
||||
AES_Hdr, // F2 Encryption
|
||||
0, // F3
|
||||
0, // F4
|
||||
0, // F5
|
||||
0, // F6
|
||||
0 // F7
|
||||
};
|
||||
|
||||
|
||||
// Pointer to the virtualized Southbridge table
|
||||
VIRTUAL_DEVICE * SouthBridge;
|
||||
|
||||
|
||||
|
||||
// NOTE: SouthBridge will be inserted into the following table
|
||||
// at the same DEVSEL as the hardware header.
|
||||
VIRTUAL_DEVICE * Virtual_Devices[32] = {
|
||||
// IDSEL Dev# Address Description
|
||||
// ----- ----- ---------- ---------------------
|
||||
0, // N/A 0
|
||||
NorthBridge, // 11 1 0x80000800 HostBridge + Graphics
|
||||
0, // 12 2
|
||||
0, // 13 3
|
||||
0, // 14 4
|
||||
0, // 15 5
|
||||
0, // 16 6
|
||||
0, // 17 7
|
||||
0, // 18 8
|
||||
0, // 19 9
|
||||
0, // 20 10
|
||||
0, // 21 11
|
||||
0, // 22 12
|
||||
0, // 23 13
|
||||
0, // 24 14
|
||||
0, // 25 15 0x80007800 CS5535 & CS5536
|
||||
0, // 26 16
|
||||
0, // 27 17
|
||||
0, // 28 18 0x80009000 CS5530
|
||||
0, // 29 19 0x80009800 CS5530 OHCI
|
||||
0, // 30 20
|
||||
0, // 31 21
|
||||
0, // N/A 22
|
||||
0, // N/A 23
|
||||
0, // N/A 24
|
||||
0, // N/A 25
|
||||
0, // N/A 26
|
||||
0, // N/A 27
|
||||
0, // N/A 28
|
||||
0, // N/A 29
|
||||
0, // N/A 30
|
||||
0, // N/A 31
|
||||
};
|
||||
|
||||
|
||||
338
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/unregstr.c
vendored
Executable file
338
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/unregstr.c
vendored
Executable file
@@ -0,0 +1,338 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//******************************************************************************
|
||||
//* This file contains the code that unregisters events
|
||||
//******************************************************************************
|
||||
|
||||
|
||||
|
||||
#include "VSA2.H"
|
||||
#include "SYSMGR.H"
|
||||
#include "PROTOS.H"
|
||||
|
||||
|
||||
|
||||
// Externals:
|
||||
extern void pascal Clr_MBus_IO_Trap(ULONG Address, USHORT Range);
|
||||
extern UCHAR * VsmNames[];
|
||||
extern UCHAR * EventNames[];
|
||||
extern UCHAR FreeEvent;
|
||||
extern EVENT_ENTRY Events[MAX_REGISTRATIONS];
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Copies an Events[] entry
|
||||
//*****************************************************************************
|
||||
extern void pascal Copy_Event(USHORT From, USHORT To);
|
||||
|
||||
//*****************************************************************************
|
||||
// Retires an Events[] entry to the free list
|
||||
//*****************************************************************************
|
||||
void pascal Retire_Events_Entry(EVENT Event, USHORT match, USHORT previous)
|
||||
{ USHORT i;
|
||||
|
||||
// Remove Events[match] from the linked list.
|
||||
i = Events[match].Link;
|
||||
if (previous) {
|
||||
Events[previous].Link = (UCHAR)i;
|
||||
i = match;
|
||||
} else {
|
||||
// The first entry in the linked list is being removed.
|
||||
Copy_Event(i, Event);
|
||||
}
|
||||
|
||||
// Mark the entry as available.
|
||||
Events[i].Vsm = 0x00000000;
|
||||
if (i) {
|
||||
// Put Events[] entry on free list
|
||||
Events[i].Link = FreeEvent;
|
||||
FreeEvent = (UCHAR)i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Unregisters a PCI trap
|
||||
//*****************************************************************************
|
||||
USHORT pascal Unregister_PCI_Trap(VSM Vsm, USHORT PCI_Addr, USHORT PCI_Mask)
|
||||
{ USHORT EventIndex, IDSEL_Count=0, previous=0, match=0;
|
||||
register EVENT_ENTRY * EventPtr;
|
||||
|
||||
|
||||
// The entire event chain must be traversed to find out how
|
||||
// many registrations are trapping this IDSEL. If only this
|
||||
// one, then the IDSEL in the MPCI_PBUS MSR will be cleared.
|
||||
EventIndex = EVENT_PCI_TRAP;
|
||||
while (Events[EventIndex].Vsm) {
|
||||
EventPtr = &Events[EventIndex];
|
||||
|
||||
// Check if IDSEL matches
|
||||
if ((EventPtr->PCI_Addr & 0xF800) == (PCI_Addr & 0xF800)) {
|
||||
|
||||
IDSEL_Count++;
|
||||
|
||||
// If it is the requested VSM...
|
||||
if (EventPtr->Vsm == Vsm) {
|
||||
// and the PCI Address/Mask match...
|
||||
if (EventPtr->PCI_Addr == PCI_Addr && EventPtr->PCI_Mask == PCI_Mask) {
|
||||
// Record the EventIndex to be removed
|
||||
match = EventIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Record index immediately before the matching Events[] entry
|
||||
if (!match) {
|
||||
previous = EventIndex;
|
||||
}
|
||||
|
||||
// Get the next entry in the linked list
|
||||
EventIndex = EventPtr->Link;
|
||||
|
||||
} // end while
|
||||
|
||||
|
||||
// If this is the only registration for this IDSEL...
|
||||
if (IDSEL_Count == 1) {
|
||||
// disable trapping this IDSEL
|
||||
Disable_Event(EVENT_PCI_TRAP, match);
|
||||
}
|
||||
|
||||
// Retire the Events[] entry
|
||||
Retire_Events_Entry(EVENT_PCI_TRAP, match, previous);
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Disassociates an event from a VSM. This may occur as a result of a
|
||||
// VSM performing the UNREGISTER_EVENT() macro, or if a VSM is being
|
||||
// removed or replaced.
|
||||
//*****************************************************************************
|
||||
// RESOURCE_COUNT:
|
||||
// 1) Must be power of 2 since the Mod (%) operator is used
|
||||
// 2) A minimum of 32 (# GPIOs)
|
||||
// 3) A maximum of 256
|
||||
#define RESOURCE_COUNT 128
|
||||
USHORT pascal Unregister_Event(EVENT Event, VSM Vsm, ULONG Param1, ULONG Param2)
|
||||
{ USHORT EventIndex, i, j=4, k=0, previous=0, match=0;
|
||||
static UCHAR HW_Resource[RESOURCE_COUNT];
|
||||
UCHAR IO_Base, IO_Range;
|
||||
ULONG Mask1=0x00000000, Mask2=0x00000000;
|
||||
register EVENT_ENTRY * EventPtr;
|
||||
|
||||
|
||||
|
||||
// Determine which parameters must match
|
||||
switch (Event) {
|
||||
|
||||
case EVENT_TIMER:
|
||||
// Only require Handle to match
|
||||
Mask2 = 0x0000FFFF;
|
||||
j = 8; // # h/w timers
|
||||
break;
|
||||
|
||||
case EVENT_PWM:
|
||||
case EVENT_PME:
|
||||
case EVENT_GPIO:
|
||||
// Only require pin to match
|
||||
Mask1 = 0x0000FFFF;
|
||||
j = 32; // max # GPIO pins
|
||||
break;
|
||||
|
||||
case EVENT_IO_TRAP:
|
||||
j = RESOURCE_COUNT;
|
||||
// Only require I/O addresses within range to match
|
||||
Mask1 = 0x00010000 - RESOURCE_COUNT;
|
||||
break;
|
||||
|
||||
case EVENT_PCI_TRAP:
|
||||
match = Unregister_PCI_Trap(Vsm, (USHORT)Param1, (USHORT)Param2);
|
||||
return match;
|
||||
|
||||
case EVENT_IO_TIMEOUT:
|
||||
// Require Param1 to match
|
||||
Mask1 = 0xFFFFFFFF;
|
||||
break;
|
||||
}
|
||||
|
||||
// Zero the h/w resource usage counters
|
||||
for (i=0; i<j; i++) {
|
||||
HW_Resource[i] = 0;
|
||||
}
|
||||
j = 0;
|
||||
|
||||
// The entire event chain must be traversed to find out how
|
||||
// many registrations are using the resource. If more than
|
||||
// one, then the hardware will not be disabled.
|
||||
EventIndex = Event;
|
||||
while (Events[EventIndex].Vsm) {
|
||||
EventPtr = &Events[EventIndex];
|
||||
switch (Event) {
|
||||
case EVENT_TIMER:
|
||||
j = (USHORT)EventPtr->Timer;
|
||||
break;
|
||||
|
||||
case EVENT_PWM:
|
||||
case EVENT_PME:
|
||||
case EVENT_GPIO:
|
||||
j = (USHORT)EventPtr->Pin;
|
||||
break;
|
||||
}
|
||||
|
||||
// Check if parameters match
|
||||
if ((EventPtr->Param1 & Mask1) == (Param1 & Mask1) &&
|
||||
(EventPtr->Param2 & Mask2) == (Param2 & Mask2)) {
|
||||
|
||||
if (Event == EVENT_IO_TRAP) {
|
||||
// Accumulate usage count for each I/O location in range
|
||||
IO_Base = (UCHAR)EventPtr->IO_Base;
|
||||
IO_Range = (UCHAR)EventPtr->IO_Range;
|
||||
for (i = 0; i < IO_Range; i++) {
|
||||
k = (UCHAR)(i + IO_Base) % RESOURCE_COUNT;
|
||||
HW_Resource[k]++;
|
||||
}
|
||||
}
|
||||
|
||||
// If it is the requested VSM...
|
||||
if (EventPtr->Vsm == Vsm) {
|
||||
|
||||
// Record which h/w resource is being disabled
|
||||
switch (Event) {
|
||||
case EVENT_IO_TRAP:
|
||||
if (match) {
|
||||
// There are overlapping I/O ranges in the same VSM
|
||||
if ((EventPtr->IO_Base != (USHORT)Param1) ||
|
||||
(EventPtr->IO_Range != (USHORT)Param2)) {
|
||||
// This is not the one being removed
|
||||
break;
|
||||
}
|
||||
}
|
||||
case EVENT_PWM:
|
||||
case EVENT_PME:
|
||||
case EVENT_GPIO:
|
||||
case EVENT_TIMER:
|
||||
k = j;
|
||||
default:
|
||||
// Record the EventIndex to be removed
|
||||
if (!match) {
|
||||
match = EventIndex;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Record entry previous to 'match'
|
||||
if (!match) {
|
||||
previous = EventIndex;
|
||||
}
|
||||
|
||||
// Increment resource usage count
|
||||
if (Event != EVENT_IO_TRAP) {
|
||||
HW_Resource[j]++;
|
||||
}
|
||||
|
||||
// Link to the next entry in the list.
|
||||
EventIndex = EventPtr->Link;
|
||||
|
||||
} // end while
|
||||
|
||||
|
||||
if (match) {
|
||||
|
||||
switch (Event) {
|
||||
USHORT Range;
|
||||
|
||||
case EVENT_IO_TRAP:
|
||||
Range=0x0000;
|
||||
EventPtr = &Events[match];
|
||||
Param1 |= Param2 & 0xFFFF0000;
|
||||
for (j = 0; j < (UCHAR)Param2; j++) {
|
||||
k = (UCHAR)((j + EventPtr->Param1) % RESOURCE_COUNT);
|
||||
if (HW_Resource[k] > 1) {
|
||||
if (Range) {
|
||||
// Found end of a range used exclusively by this VSM
|
||||
Clr_MBus_IO_Trap(Param1, Range);
|
||||
Param1 += Range;
|
||||
Range = 0;
|
||||
} else {
|
||||
(USHORT)Param1++;
|
||||
}
|
||||
} else {
|
||||
Range++;
|
||||
}
|
||||
}
|
||||
if (Range) {
|
||||
Clr_MBus_IO_Trap(Param1, Range);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// If only one registration is using the h/w resource, disable it
|
||||
if (HW_Resource[k] == 1) {
|
||||
case EVENT_IO_TIMEOUT: // Statistic counter logic keeps track of usage
|
||||
Disable_Event(Event, match);
|
||||
}
|
||||
case EVENT_SOFTWARE_SMI:
|
||||
break;
|
||||
}
|
||||
|
||||
// Retire the Events[] entry
|
||||
Retire_Events_Entry(Event, match, previous);
|
||||
|
||||
} else {
|
||||
|
||||
// A VSM attempted to unregister a event that it is not registered for
|
||||
Log_Error("Attempt to unregister EVENT_%s[0x%08X;0x%08X] by the %s VSM", EventNames[Event], Param1, Param2, VsmNames[Get_VSM_Type(Vsm)]);
|
||||
}
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Removes all events registered to a VSM.
|
||||
//*****************************************************************************
|
||||
void pascal Unregister_VSM_Events(VSM Vsm)
|
||||
{ register EVENT Event;
|
||||
register EVENT_ENTRY * EventPtr;
|
||||
|
||||
// Unregister all events registered to this VSM
|
||||
for (Event=1; Event <= MAX_EVENT; Event++) {
|
||||
EventPtr = &Events[Event];
|
||||
while (EventPtr->Vsm) {
|
||||
|
||||
if (EventPtr->Vsm == Vsm) {
|
||||
if (Unregister_Event(Event, Vsm, EventPtr->Param1, EventPtr->Param2)) {
|
||||
// Start over on this event since there might be others for this VSM.
|
||||
Event--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
EventPtr = &Events[EventPtr->Link];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
642
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/utils.asm
vendored
Executable file
642
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/utils.asm
vendored
Executable file
@@ -0,0 +1,642 @@
|
||||
;
|
||||
; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
;
|
||||
; This library is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU Lesser General Public License as
|
||||
; published by the Free Software Foundation; either version 2.1 of the
|
||||
; License, or (at your option) any later version.
|
||||
;
|
||||
; This code is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
; Lesser General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU Lesser General
|
||||
; Public License along with this library; if not, write to the
|
||||
; Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
; Boston, MA 02111-1307 USA
|
||||
;
|
||||
;*******************************************************************************
|
||||
;* Miscellaneous utility routines
|
||||
;*******************************************************************************
|
||||
|
||||
|
||||
include SYSMGR.INC
|
||||
include VSA2.INC
|
||||
include PCI.INC
|
||||
include GX2.INC
|
||||
|
||||
.model tiny,c
|
||||
.586p
|
||||
.CODE
|
||||
|
||||
externdef SchedulerStack: word
|
||||
externdef SysMgr_VSM: dword
|
||||
externdef Saved_PCI: dword
|
||||
externdef Nested_PCI: dword
|
||||
externdef MsgPacket: dword
|
||||
externdef ClocksPerMs: dword
|
||||
externdef StartSaveArea: dword
|
||||
externdef Header_Addr: dword
|
||||
externdef Nested_Flag: dword
|
||||
externdef VSM_Ptrs: dword
|
||||
externdef Events: EVENT_ENTRY
|
||||
|
||||
|
||||
|
||||
|
||||
;************************************************************************
|
||||
;
|
||||
; 8 bit I/O routines
|
||||
;
|
||||
;************************************************************************
|
||||
|
||||
in_8 proc pascal \
|
||||
io_port: word
|
||||
|
||||
mov dx, [io_port]
|
||||
in al, dx
|
||||
ret
|
||||
|
||||
in_8 endp
|
||||
|
||||
|
||||
out_8 proc pascal \
|
||||
io_port: word, \
|
||||
io_data: byte
|
||||
|
||||
mov dx, [io_port]
|
||||
mov al, [io_data]
|
||||
out dx, al
|
||||
ret
|
||||
|
||||
out_8 endp
|
||||
|
||||
;************************************************************************
|
||||
;
|
||||
; 16 bit I/O routines
|
||||
;
|
||||
;************************************************************************
|
||||
|
||||
in_16 proc pascal \
|
||||
io_port: word
|
||||
|
||||
mov dx, [io_port]
|
||||
in ax, dx
|
||||
ret
|
||||
|
||||
in_16 endp
|
||||
|
||||
|
||||
out_16 proc pascal \
|
||||
io_port: word, \
|
||||
io_data: word
|
||||
|
||||
mov dx, [io_port]
|
||||
mov ax, [io_data]
|
||||
out dx, ax
|
||||
ret
|
||||
|
||||
out_16 endp
|
||||
|
||||
|
||||
;************************************************************************
|
||||
;
|
||||
; 32 bit I/O routines
|
||||
;
|
||||
;************************************************************************
|
||||
|
||||
in_32 proc pascal \
|
||||
io_port: word
|
||||
|
||||
mov dx, [io_port]
|
||||
in eax, dx
|
||||
mov edx, eax
|
||||
shr edx, 16
|
||||
ret
|
||||
|
||||
in_32 endp
|
||||
|
||||
|
||||
out_32 proc pascal \
|
||||
io_port: word, \
|
||||
io_data: dword
|
||||
|
||||
mov dx, [io_port]
|
||||
mov eax, [io_data]
|
||||
out dx, eax
|
||||
ret
|
||||
|
||||
out_32 endp
|
||||
|
||||
|
||||
|
||||
|
||||
;************************************************************************
|
||||
;
|
||||
; Input:
|
||||
; Ptr to a VSM header
|
||||
;
|
||||
; Output:
|
||||
; Ptr to the next VSM in the chain
|
||||
;
|
||||
;************************************************************************
|
||||
GetFlink proc pascal, \
|
||||
VSM_Ptr: dword
|
||||
|
||||
mov ebx, [VSM_Ptr]
|
||||
mov eax, (VSM_Header PTR fs:[ebx]).SysStuff.Flink
|
||||
mov edx, eax
|
||||
shr edx, 16
|
||||
ret
|
||||
|
||||
GetFlink endp
|
||||
|
||||
|
||||
|
||||
|
||||
;************************************************************************
|
||||
; Writes a BYTE, WORD, DWORD to a 32-bit address
|
||||
;************************************************************************
|
||||
write_flat_size proc pascal \
|
||||
Address: dword, \
|
||||
Data: dword, \
|
||||
Len: byte
|
||||
|
||||
mov ebx, [Address]
|
||||
mov eax, [Data]
|
||||
mov cl, [Len]
|
||||
cld
|
||||
cmp cl, BYTE_IO
|
||||
jne short CheckWord
|
||||
mov fs:[ebx], al
|
||||
jmp short Exit
|
||||
|
||||
CheckWord:
|
||||
cmp cl, WORD_IO
|
||||
je short WriteWord
|
||||
WriteDword:
|
||||
db 66H
|
||||
WriteWord:
|
||||
mov fs:[ebx], ax
|
||||
Exit: ret
|
||||
|
||||
write_flat_size endp
|
||||
|
||||
;************************************************************************
|
||||
; Writes a DWORD to a 32-bit address
|
||||
;************************************************************************
|
||||
write_flat proc pascal \
|
||||
Address: dword, \
|
||||
Data: dword
|
||||
|
||||
mov ebx, [Address]
|
||||
mov eax, [Data]
|
||||
mov fs:[ebx], eax
|
||||
ret
|
||||
|
||||
write_flat endp
|
||||
|
||||
;************************************************************************
|
||||
; Reads a DWORD from a 32-bit address
|
||||
;************************************************************************
|
||||
read_flat proc pascal \
|
||||
Address: dword
|
||||
|
||||
mov ebx, [Address]
|
||||
mov eax, fs:[ebx]
|
||||
mov edx, eax
|
||||
shr edx, 16
|
||||
ret
|
||||
|
||||
read_flat endp
|
||||
|
||||
|
||||
|
||||
;************************************************************************
|
||||
;
|
||||
; Copies the parameters for a synchronous event from the appropriate SMI
|
||||
; header to the MsgPacket array.
|
||||
; NOTE: This routine should only be called from a Synchronous SMI handler.
|
||||
;
|
||||
; On exit:
|
||||
; MsgPacket[1]: 15:0 - Flags field from SMM header
|
||||
; MsgPacket[2]: 15:0 - I/O address (or PCI address) from SMM header
|
||||
; 31:16 - Data Size field from SMM header
|
||||
; MsgPacket[3]: Data (if I/O write)
|
||||
;
|
||||
; Returns ptr to appropriate SMM header.
|
||||
;
|
||||
;************************************************************************
|
||||
Get_Header_Params proc pascal \
|
||||
SMI_Event: dword
|
||||
|
||||
mov bx, OFFSET VSM_Header.SysStuff.State
|
||||
|
||||
ASSUME BX: PTR SmiHeader
|
||||
|
||||
mov eax, [SMI_Event] ; Is it a nested event ?
|
||||
test [Nested_Flag], eax
|
||||
je Copy_Params
|
||||
|
||||
not eax ; Yes, clear the event
|
||||
and [Nested_Flag], eax
|
||||
|
||||
push si ; Copy VSM's header to local buffer
|
||||
mov si, bx
|
||||
|
||||
lea bx, [Nested_Header]
|
||||
push bx
|
||||
mov cx, sizeof(SmiHeader)/4
|
||||
cld
|
||||
CopyHdr:
|
||||
lodsd gs:[si]
|
||||
mov dword ptr [bx], eax
|
||||
add bx, 4
|
||||
loop CopyHdr
|
||||
|
||||
pop bx
|
||||
pop si
|
||||
|
||||
|
||||
|
||||
; Copy parameters from SMM header to MsgPacket[]
|
||||
Copy_Params:
|
||||
|
||||
movzx eax, [bx].SMI_Flags
|
||||
mov [MsgPacket+4*1], eax ; MsgPacket[1]
|
||||
|
||||
|
||||
; Is it a PCI trap ?
|
||||
mov eax, dword ptr [bx].IO_addr
|
||||
mov dx, ax
|
||||
and dl, NOT 3
|
||||
cmp dx, PCI_CONFIG_DATA
|
||||
jne short StoreAddr
|
||||
|
||||
; Yes, get PCI address from appropriate context
|
||||
mov cl, al ; Get 2 LSBs of PCI address
|
||||
and cl, 3
|
||||
mov ax, word ptr [Nested_PCI]
|
||||
cmp bx, OFFSET [Nested_Header]
|
||||
je short Get_PCI
|
||||
|
||||
mov ax, word ptr [Saved_PCI]
|
||||
Get_PCI:
|
||||
or al, cl
|
||||
StoreAddr:
|
||||
mov [MsgPacket+4*2], eax ; MsgPacket[2]
|
||||
|
||||
|
||||
; Get write data
|
||||
mov ecx, [bx].write_data
|
||||
shr eax, 16 ; Put I/O size into AL
|
||||
cmp al, DWORD_IO ; Dword I/O ?
|
||||
je short StoreData
|
||||
movzx ecx, cx
|
||||
cmp al, WORD_IO ; Word I/O ?
|
||||
je short StoreData
|
||||
xor ch, ch ; Byte I/O
|
||||
|
||||
StoreData:
|
||||
mov [MsgPacket+4*3], ecx ; MsgPacket[3]
|
||||
|
||||
mov ax, bx ; Return ptr to header
|
||||
ret
|
||||
|
||||
Nested_Header SmiHeader {}
|
||||
|
||||
|
||||
Get_Header_Params endp
|
||||
|
||||
ASSUME BX: NOTHING
|
||||
|
||||
|
||||
;************************************************************************
|
||||
; Returns the # milliseconds elapsed on a timer.
|
||||
;************************************************************************
|
||||
ElapsedSoFar proc StartTime: PTR
|
||||
|
||||
rdtsc ; Get current timestamp
|
||||
|
||||
mov bx, [StartTime] ; Subtract timer's start time
|
||||
sub eax, [bx+0]
|
||||
sbb edx, [bx+4]
|
||||
|
||||
idiv [ClocksPerMs] ; Convert delta to milliseconds
|
||||
mov edx, eax
|
||||
shr edx, 16
|
||||
ret
|
||||
|
||||
ElapsedSoFar endp
|
||||
|
||||
|
||||
|
||||
;************************************************************************
|
||||
; Returns the timestamp counter in the passed buffer
|
||||
;************************************************************************
|
||||
Store_Timestamp proc pascal \
|
||||
TimeStamp: PTR
|
||||
|
||||
rdtsc
|
||||
mov bx, [TimeStamp]
|
||||
mov [bx+0], eax
|
||||
mov [bx+4], edx
|
||||
ret
|
||||
|
||||
Store_Timestamp endp
|
||||
|
||||
|
||||
|
||||
;************************************************************************
|
||||
; Returns the type of the VSM pointed to by the Vsm parameter
|
||||
;************************************************************************
|
||||
Get_VSM_Type proc pascal \
|
||||
Vsm:dword
|
||||
|
||||
mov ebx, [Vsm]
|
||||
mov al, fs:(VSM_Header PTR [ebx]).VSM_Type
|
||||
ret
|
||||
|
||||
Get_VSM_Type endp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;************************************************************************
|
||||
; Translates a logical address to a physical address via the page tables
|
||||
; NOTES:
|
||||
; - This routine should only be called if paging is enabled.
|
||||
; - All page & segment protection has already occurred.
|
||||
;************************************************************************
|
||||
|
||||
PAGE_ATTR equ 0FFFh
|
||||
CR4_PSE_BIT equ 0010h
|
||||
PDIR_PS_BIT equ 0080h
|
||||
OFFSET_4M equ 0003FFFFFh
|
||||
PAGEBASE_4M equ 0FFC00000h
|
||||
|
||||
Convert_To_Physical_Addr proc pascal \
|
||||
Logical: dword
|
||||
|
||||
; Start by checking for 4MB page possibility
|
||||
mov eax, CR4
|
||||
test ax, CR4_PSE_BIT
|
||||
jz short page4K
|
||||
|
||||
mov ebx, CR3 ; Get ptr to page directory base
|
||||
and ebx, 0FFFFFC00h ; Mask attribute bits
|
||||
|
||||
mov edx, [Logical] ; Get address to translate
|
||||
shr edx, 22 ; Get page directory index
|
||||
|
||||
; See if this directory entry points to a 4MB page
|
||||
mov ebx, fs:[ebx+edx*4]
|
||||
|
||||
test bx, PDIR_PS_BIT
|
||||
jz short page4K
|
||||
|
||||
and ebx, PAGEBASE_4M ; Get the page base offset
|
||||
|
||||
mov eax, [Logical] ; Get address to translate
|
||||
and eax, OFFSET_4M ; Peel off the directory index
|
||||
|
||||
or eax, ebx ; Combine the base and offset
|
||||
|
||||
jmp short Exit
|
||||
|
||||
|
||||
page4K:
|
||||
mov ebx, CR3 ; Get ptr to page directory base
|
||||
and ebx, 0FFFFFC00h ; Mask attribute bits
|
||||
|
||||
mov eax, [Logical] ; Get address to translate
|
||||
|
||||
movzx ecx, ax ; Extract page offset
|
||||
and cx, PAGE_ATTR ; (contains offset into 4K page)
|
||||
|
||||
shr eax, 12 ; Remove page offset
|
||||
mov edx, eax
|
||||
|
||||
shr edx, 10 ; Get page directory offset
|
||||
|
||||
mov ebx, fs:[ebx+edx*4]
|
||||
and bx, NOT PAGE_ATTR ; Remove page directory attributes
|
||||
|
||||
and eax, 03FFh ; Extract page table offset
|
||||
mov eax, fs:[ebx+eax*4]
|
||||
and ax, NOT PAGE_ATTR ; Remove page attributes
|
||||
|
||||
add eax, ecx ; Add page offset
|
||||
|
||||
Exit: mov edx, eax ; Return translated addr in DX:AX
|
||||
shr edx, 16
|
||||
ret
|
||||
|
||||
Convert_To_Physical_Addr endp
|
||||
|
||||
|
||||
;************************************************************************
|
||||
; Marks a 'Blocked' VSM to 'Ready'
|
||||
;************************************************************************
|
||||
Unblock_VSM proc pascal Vsm: dword
|
||||
|
||||
mov ebx, [Vsm]
|
||||
mov fs:(VSM_Header PTR [ebx]).SysStuff.RunFlag, RUN_FLAG_READY
|
||||
ret
|
||||
|
||||
Unblock_VSM endp
|
||||
|
||||
;MEJ
|
||||
;************************************************************************
|
||||
; This routine determines if an event should wake the system.
|
||||
; If so, the PMCore VSM's RunFlag is changed from 'Sleeping' to 'Ready'.
|
||||
; There currently are two cases:
|
||||
; 1) A timer for either the APM or PMCore VSM
|
||||
; 2) A press of the sleep button while in Legacy PM mode
|
||||
;
|
||||
; Returns TRUE if the event is a wake event.
|
||||
;************************************************************************
|
||||
;IsWakeEvent proc pascal \
|
||||
; Vsm: DWORD
|
||||
;
|
||||
; mov ebx, [Vsm]
|
||||
;
|
||||
; ; Is event for a PM-related VSM ?
|
||||
; cmp fs:(VSM_Header PTR [ebx]).VSM_Type, VSM_PM
|
||||
; je short PossibleWakeEvent
|
||||
; cmp fs:(VSM_Header PTR [ebx]).VSM_Type, VSM_APM
|
||||
; jne short NotWakeEvent
|
||||
;
|
||||
; ; Yes, mark PM VSM 'Ready' if it is 'Sleeping'
|
||||
;PossibleWakeEvent:
|
||||
; mov ebx, [VSM_Ptrs+4*VSM_PM]
|
||||
; mov al, fs:(VSM_Header PTR [ebx]).SysStuff.RunFlag
|
||||
; cmp al, RUN_FLAG_SLEEPING
|
||||
; jne short NotWakeEvent
|
||||
; mov fs:(VSM_Header PTR [ebx]).SysStuff.RunFlag, RUN_FLAG_READY
|
||||
; jmp Exit
|
||||
;
|
||||
;
|
||||
;NotWakeEvent:
|
||||
; xor al, al
|
||||
;
|
||||
;Exit: ret
|
||||
;
|
||||
;IsWakeEvent endp
|
||||
|
||||
|
||||
|
||||
;************************************************************************
|
||||
; Returns the flat address to the VSM performing a system call
|
||||
; Used for reporting errors in a system call.
|
||||
;************************************************************************
|
||||
Get_SysCall_Address proc pascal \
|
||||
Vsm: dword, \
|
||||
Depth: byte
|
||||
|
||||
mov eax, [Vsm]
|
||||
|
||||
cmp eax, [SysMgr_VSM]
|
||||
jne short Get_VSM_Addr
|
||||
|
||||
if CHECKED_BUILD
|
||||
|
||||
mov dx, sp ; Save BP & SP
|
||||
shl edx, 16
|
||||
mov dx, bp
|
||||
|
||||
mov cl, [Depth]
|
||||
add cl, 2 ; Include stack frames for this routine's & Error_Report()
|
||||
PopStackFrame:
|
||||
mov bx, sp
|
||||
leave ; Pop a stack frame
|
||||
cmp sp, OFFSET StartSaveArea
|
||||
jae short Bail
|
||||
cmp sp, [SchedulerStack]
|
||||
jb short Bail
|
||||
|
||||
|
||||
dec cl
|
||||
jnz PopStackFrame
|
||||
jmp short GetFault
|
||||
|
||||
|
||||
Bail: mov sp, bx
|
||||
GetFault:
|
||||
mov bx, sp ; Get return address to faulting CALL
|
||||
movzx ebx, word ptr [bx]
|
||||
sub bx, 3 ; Account for CALL sys_xxxxx
|
||||
|
||||
mov bp, dx ; Restore BP & SP
|
||||
shr edx, 16
|
||||
mov sp, dx
|
||||
else
|
||||
xor ebx, ebx ; Don't attempt to determine address
|
||||
endif
|
||||
jmp short Result
|
||||
|
||||
Get_VSM_Addr:
|
||||
|
||||
ASSUME BX: PTR word
|
||||
|
||||
; There are 3 cases:
|
||||
; 1) A system call.
|
||||
; 2) In-line assembly (e.g. direct I/O virtual register)
|
||||
; 3) A subroutine call to offending I/O
|
||||
mov bx, word ptr gs:(VSM_Header).SysStuff.State.Next_EIP
|
||||
cmp gs:[bx-2], 380Fh ; Was it from a SMINT (system call)
|
||||
je short Sys_Call
|
||||
|
||||
mov dx, gs:[bx] ; Get next two bytes of VSM's code
|
||||
|
||||
dec bx ; In case it is in-line assembly
|
||||
; If the next two instructions are LEAVE & RET, then it is a
|
||||
; subroutine. Report the caller's address.
|
||||
cmp dl, 0C9h ; Is the next instruction a LEAVE ?
|
||||
jne short Result ; No, must be in-line assembly
|
||||
and dh, NOT 1 ; Yes, is the next one a struction a RET ?
|
||||
cmp dh, 0C2h
|
||||
jne short Result ; No, must be in-line assembly
|
||||
Sys_Call:
|
||||
mov bx, word ptr gs:(VSM_Header).SysStuff.SavedESP
|
||||
mov bx, gs:[bx+3*4] ; Get caller's BP
|
||||
movzx ebx, gs:[bx+2] ; Get SP at time of CALL sys_xxxx
|
||||
sub bx, 3 ; Account for CALL sys_xxxxx
|
||||
Result:
|
||||
add eax, ebx
|
||||
|
||||
mov edx, eax
|
||||
shr edx, 16
|
||||
|
||||
ret
|
||||
|
||||
Get_SysCall_Address endp
|
||||
|
||||
|
||||
|
||||
;************************************************************************
|
||||
; Returns the 8 MSBs of the DEVID field of the Device Capabilities MSR
|
||||
;************************************************************************
|
||||
GetPortID proc MBD_Addr: dword
|
||||
|
||||
mov ecx, [MBD_Addr]
|
||||
mov cx, MBD_MSR_CAP
|
||||
rdmsr
|
||||
shr eax, ID_SHIFT
|
||||
xor ah, ah
|
||||
ret
|
||||
|
||||
GetPortID endp
|
||||
|
||||
|
||||
;************************************************************************
|
||||
; Clears pending h/w emulation events in an GeodeLink device
|
||||
;************************************************************************
|
||||
ClearMbiu proc pascal Mbiu: dword
|
||||
|
||||
mov ecx, [Mbiu]
|
||||
or ecx, ecx
|
||||
jz short Exit
|
||||
mov cx, MBD_MSR_SMI
|
||||
rdmsr
|
||||
mov dl, 1
|
||||
wrmsr
|
||||
mov cx, MBD_MSR_ERROR
|
||||
rdmsr
|
||||
wrmsr
|
||||
|
||||
Exit: ret
|
||||
|
||||
ClearMbiu endp
|
||||
|
||||
|
||||
|
||||
;************************************************************************
|
||||
; Trims a P2D_R descriptor by Range
|
||||
;************************************************************************
|
||||
Trim_P2D_R proc pascal uses esi \
|
||||
MsrAddr: dword, \
|
||||
Range: dword, \
|
||||
MsrData: PTR
|
||||
|
||||
mov ecx, [MsrAddr] ; Get current MSR value
|
||||
rdmsr
|
||||
|
||||
mov ebx, [Range] ; Adjust by Range bytes
|
||||
mov esi, ebx
|
||||
shr esi, (12+12)
|
||||
shl ebx, (20-12)
|
||||
sub eax, ebx
|
||||
sbb edx, esi
|
||||
wrmsr
|
||||
|
||||
mov bx, [MsrData] ; Return modified MSR
|
||||
mov dword ptr [bx+0], eax
|
||||
mov dword ptr [bx+4], edx
|
||||
ret
|
||||
|
||||
Trim_P2D_R endp
|
||||
|
||||
end
|
||||
885
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/virt_pci.c
vendored
Executable file
885
firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/virt_pci.c
vendored
Executable file
@@ -0,0 +1,885 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//******************************************************************************
|
||||
//* Utility routines related to virtualized PCI config headers
|
||||
//******************************************************************************
|
||||
|
||||
|
||||
|
||||
#include "VSA2.H"
|
||||
#include "PCI.H"
|
||||
#include "GX2.H"
|
||||
#include "VPCI.H"
|
||||
#include "SYSMGR.H"
|
||||
#include "CHIPSET.H"
|
||||
#include "PROTOS.H"
|
||||
#include "DESCR.H"
|
||||
#include "MDD.H"
|
||||
|
||||
|
||||
// External function declarations:
|
||||
extern void pascal Parse_Descriptor(UCHAR, ULONG *, ULONG *);
|
||||
extern void pascal Trim_P2D_R(ULONG, ULONG, ULONG *);
|
||||
|
||||
|
||||
// External variable declarations:
|
||||
extern UCHAR DynamicVSALoad;
|
||||
extern UCHAR MC_Port, VG_Port;
|
||||
extern UCHAR MBIU1_SelfReference;
|
||||
extern UCHAR End_of_POST;
|
||||
extern ULONG MDD_Base;
|
||||
extern ULONG Mbiu0, Mbiu1, Mbiu2;
|
||||
extern ULONG MPCI_NB, MPCI_SB;
|
||||
extern DESCRIPTOR MSRs[];
|
||||
extern ULONG ExtendedMemoryDescr0, ExtendedMemoryDescr1;
|
||||
extern Hardware HardwareInfo;
|
||||
extern VIRTUAL_DEVICE * Virtual_Devices[];
|
||||
extern VIRTUAL_DEVICE * SouthBridge;
|
||||
extern PCI_HEADER_ENTRY * NorthBridge[];
|
||||
extern PCI_HEADER_ENTRY * Virtual_5536[];
|
||||
extern PCI_HEADER_ENTRY Graphics_Hdr[];
|
||||
extern PCI_HEADER_ENTRY HostBridge_Hdr[];
|
||||
extern PCI_HEADER_ENTRY AES_Hdr[];
|
||||
extern PCI_HEADER_ENTRY ISA_Hdr[];
|
||||
extern PCI_HEADER_ENTRY Thor_Hdr[];
|
||||
extern PCI_HEADER_ENTRY Audio_Hdr[];
|
||||
extern PCI_HEADER_ENTRY Flash_Hdr[];
|
||||
|
||||
|
||||
// Local variable declarations:
|
||||
PCI_HEADER_ENTRY * CommandPtr, * HdrPtr;
|
||||
PCI_HEADER_ENTRY Dummy_Hdr[] = {
|
||||
{0x00, 0x00, 0xFFFFFFFF, 0x00000000},
|
||||
{0x00, 0x00, 0xFFFFFFFF, 0x00000000},
|
||||
{0x00, 0x00, 0xFFFFFFFF, 0x00000000},
|
||||
{0x00, EOL, 0xFFFFFFFF, 0x00000000},
|
||||
};
|
||||
VIRTUAL_DEVICE * IDSELs;
|
||||
VIRTUAL_PTR * VirtDevPtr;
|
||||
USHORT DeviceID;
|
||||
USHORT Class;
|
||||
UCHAR BaseClass;
|
||||
UCHAR Shift, AlignedReg, Function;
|
||||
ULONG Virtualized_PCI_Devices=0;
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Given a ptr to a virtual PCI header, finds Register
|
||||
//***********************************************************************
|
||||
PCI_HEADER_ENTRY * pascal Find_Register(PCI_HEADER_ENTRY * Pci, UCHAR Register)
|
||||
{
|
||||
// Keep a ptr to the Vendor ID register
|
||||
HdrPtr = Pci;
|
||||
DeviceID = HdrPtr->Device_ID;
|
||||
|
||||
// Keep a ptr to the Command register
|
||||
CommandPtr = Pci + COMMAND/4;
|
||||
|
||||
// Record the device Class
|
||||
BaseClass = (HdrPtr+REVISION_ID/4)->BaseClass;
|
||||
Class = (HdrPtr+REVISION_ID/4)->Class;
|
||||
|
||||
// Scan the table for the specified register entry
|
||||
do {
|
||||
if (Pci->Reg == Register) {
|
||||
return Pci;
|
||||
}
|
||||
} while (!((Pci++)->Flag & EOL));
|
||||
|
||||
|
||||
// If CommandPtr is used, avoid generating an exception
|
||||
CommandPtr = Dummy_Hdr;
|
||||
|
||||
// Register is not in the table
|
||||
return (PCI_HEADER_ENTRY *) UNIMPLEMENTED_REGISTER;
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
// Parses PCI_Address & returns a pointer to the corresponding entry in a
|
||||
// virtual header table.
|
||||
// Computes global variables:
|
||||
// AlignedReg, Function, Shift, HdrPtr, CommandPtr, & DeviceID
|
||||
//***********************************************************************
|
||||
PCI_HEADER_ENTRY * pascal Get_Structure(USHORT PCI_Address)
|
||||
{ register PCI_HEADER_ENTRY * Pci;
|
||||
UCHAR Reg;
|
||||
|
||||
// Compute Function #
|
||||
Function = (UCHAR)(PCI_Address >> 8) & 0x07;
|
||||
|
||||
// Get register offset
|
||||
Reg = (UCHAR) PCI_Address;
|
||||
|
||||
// Compute DWORD aligned register offset
|
||||
AlignedReg = Reg & ~3;
|
||||
|
||||
// Compute shift count
|
||||
Shift = (Reg & 3) << 3;
|
||||
|
||||
// Subsystem Vendor ID & Subsystem ID are same as Vendor ID & Device ID
|
||||
if (AlignedReg == SUBSYSTEM_VENDOR_ID) {
|
||||
AlignedReg = VENDOR_ID;
|
||||
}
|
||||
|
||||
|
||||
// Return value if function not implemented
|
||||
Pci = (PCI_HEADER_ENTRY *) UNIMPLEMENTED_FUNCTION;
|
||||
|
||||
// Is this IDSEL virtualized ?
|
||||
if (IDSELs = *(VirtDevPtr+(PCI_Address >> 11))) {
|
||||
|
||||
// Get ptr to this function (0000 if not implemented)
|
||||
if (Pci = IDSELs[Function]) {
|
||||
Pci = Find_Register(Pci, AlignedReg);
|
||||
}
|
||||
}
|
||||
|
||||
return Pci;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Trims the MSRs that map extended memory by RangeRequest bytes
|
||||
//***********************************************************************
|
||||
ULONG Trim_Extended_Memory(ULONG RangeRequest)
|
||||
{ ULONG Fields[3], Ext_Mem[2], Msr;
|
||||
|
||||
// Trim the MPCI Region 1 configuration
|
||||
Msr = MPCI_NB + MPCI_R1;
|
||||
Read_MSR(Msr, Ext_Mem);
|
||||
if (DynamicVSALoad) {
|
||||
RangeRequest = 0;
|
||||
}
|
||||
Ext_Mem[1] -= RangeRequest;
|
||||
Write_MSR(Msr, Ext_Mem);
|
||||
|
||||
// Adjust RCONF_DEFAULT[SYSTOP]
|
||||
Read_MSR(MSR_RCONF_DEFAULT, Ext_Mem);
|
||||
Ext_Mem[0] -= RangeRequest >> 4;
|
||||
Write_MSR(MSR_RCONF_DEFAULT, Ext_Mem);
|
||||
|
||||
|
||||
// Trim extended memory in GLIUs 0 & 1
|
||||
Trim_P2D_R(ExtendedMemoryDescr0, RangeRequest, Ext_Mem);
|
||||
Trim_P2D_R(ExtendedMemoryDescr1, RangeRequest, Ext_Mem);
|
||||
|
||||
// Copy Start/End to new descriptor
|
||||
Parse_Descriptor(P2D_R, Ext_Mem, Fields);
|
||||
return (Fields[1] + 1);
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
UCHAR StartType;
|
||||
UCHAR EndType;
|
||||
UCHAR Port;
|
||||
ULONG Msr;
|
||||
} ROUTING_INFO;
|
||||
#define MAX_ROUTE 5
|
||||
ROUTING_INFO Routing[MAX_ROUTE];
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Allocates a Region Configuration Register
|
||||
//***********************************************************************
|
||||
ROUTING_INFO * pascal Allocate_RCONF(ULONG DevAddress, ROUTING_INFO * RoutingPtr)
|
||||
{
|
||||
|
||||
// Allocate a region configuration register
|
||||
// If in Southbridge...
|
||||
if ((DevAddress & MPCI_SB) == MPCI_SB) {
|
||||
// then use SB MPCI R0-R15
|
||||
RoutingPtr->StartType = MPCI_RCONF;
|
||||
RoutingPtr->Msr = MPCI_SB;
|
||||
} else {
|
||||
// else use GX2 RCONF0-RCONF7
|
||||
RoutingPtr->StartType = GX2_RCONF;
|
||||
}
|
||||
RoutingPtr++;
|
||||
return RoutingPtr;
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
// This routines creates an association between the virtualized PCI BAR
|
||||
// (specified by BaseAddr and Device_ID) and an MBus device (specified by
|
||||
// Geode_ID). The Resource parameter specifies the type of BAR (Memory,
|
||||
// Memory-mapped I/O, or I/O) and the size of the region by RangeRequest.
|
||||
//***********************************************************************
|
||||
USHORT pascal Allocate_BAR(UCHAR Resource, USHORT BaseAddr, ULONG RangeRequest, \
|
||||
USHORT Geode_ID, USHORT Device_ID)
|
||||
{ ULONG DevAddress, Mbiu, Physical=0;
|
||||
UCHAR LSB, MSB;
|
||||
UCHAR Instance=1;
|
||||
UCHAR Index, StartType, EndType;
|
||||
UCHAR * LinkPtr;
|
||||
USHORT DevNum, Function, PCI_Address;
|
||||
register ROUTING_INFO * RoutingPtr;
|
||||
register PCI_HEADER_ENTRY * Pci;
|
||||
register VIRTUAL_DEVICE * VirtDev;
|
||||
register DESCRIPTOR * Descr;
|
||||
int i;
|
||||
|
||||
// Validate parameters
|
||||
switch (Resource) {
|
||||
case RESOURCE_MEMORY:
|
||||
case RESOURCE_MMIO:
|
||||
case RESOURCE_SCIO:
|
||||
case RESOURCE_IO:
|
||||
break;
|
||||
default:
|
||||
Log_Error("Invalid value for parameter Resource: 0x%02X", Resource);
|
||||
return 0x0000;
|
||||
}
|
||||
|
||||
// Ensure RangeRequest meets PCI & MBus requirements
|
||||
LSB = BitScanForward(RangeRequest);
|
||||
MSB = BitScanReverse(RangeRequest);
|
||||
|
||||
if (Resource == RESOURCE_MEMORY || Resource == RESOURCE_MMIO) {
|
||||
// Memory BARs must be at least 4 KB because of granularity of descriptors
|
||||
if (RangeRequest < 4096) {
|
||||
MSB = LSB = 12;
|
||||
}
|
||||
}
|
||||
// If RangeRequest is not a power of 2...
|
||||
if (LSB != MSB) {
|
||||
// Round size of BAR to next higher power of 2
|
||||
MSB++;
|
||||
}
|
||||
|
||||
|
||||
// Do some massaging based on Device ID
|
||||
switch (Device_ID) {
|
||||
|
||||
// Graphics header is invisible until SoftVG is enabled.
|
||||
case DEVICE_ID_GFX2:
|
||||
case DEVICE_ID_GFX3:
|
||||
NorthBridge[1] = Graphics_Hdr;
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Determine the PCI Address by scanning the PCI tables for Device_ID
|
||||
//
|
||||
for (DevNum = 1; DevNum <= 21; DevNum++) {
|
||||
if (VirtDev = *(VirtDevPtr+DevNum)) {
|
||||
// For each defined function...
|
||||
for (Function = 0; Function <= 7; Function++) {
|
||||
if (Pci = *VirtDev++) {
|
||||
// Do the Device IDs match ?
|
||||
if (Pci->Device_ID == Device_ID) {
|
||||
// Handle the 2nd instance of 5536's OHCI
|
||||
if ((Geode_ID == ID_OHCI) && ((Pci+BAR0/4)->Flag & (IO_BAR | MEM_BAR | MMIO_BAR))) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// If Device ID match is found...
|
||||
if (Function < 8) {
|
||||
// Compute the PCI address
|
||||
PCI_Address = (DevNum << 11) + (Function << 8) + (UCHAR)BaseAddr;
|
||||
|
||||
Pci = Find_Register(Pci, (UCHAR)BaseAddr);
|
||||
|
||||
// Check for errors
|
||||
if ((USHORT)Pci > UNIMPLEMENTED_REGISTER) {
|
||||
// Has this BAR already been allocated ?
|
||||
if (Pci->Flag & (IO_BAR | MEM_BAR | MMIO_BAR)) {
|
||||
// Yes, log an error
|
||||
Log_Error("Resource has already been allocated for PCI address 0x%X", PCI_Address);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Device_ID was not found in virtual PCI tables
|
||||
if (DevNum > 21) {
|
||||
Log_Error("DeviceID 0x%04X was not found", Device_ID);
|
||||
return 0x0000;
|
||||
}
|
||||
|
||||
// Record Mask for BAR
|
||||
Pci->Mask = ~((1L << MSB)-1);
|
||||
|
||||
|
||||
// Initialize routing structure
|
||||
RoutingPtr = &Routing[0];
|
||||
for (i=0; i<MAX_ROUTE; i++) {
|
||||
RoutingPtr->StartType = 0x00;
|
||||
RoutingPtr->EndType = 0x00;
|
||||
RoutingPtr->Port = 0x00;
|
||||
RoutingPtr->Msr = 0x00000000;
|
||||
RoutingPtr++;
|
||||
}
|
||||
RoutingPtr = &Routing[0];
|
||||
|
||||
|
||||
// Handle special cases
|
||||
switch (Geode_ID) {
|
||||
|
||||
// SMI generation on access (no physical device, e.g. virtual registers)
|
||||
case 0x0000:
|
||||
DevAddress = 0x00000000;
|
||||
break;
|
||||
|
||||
// Routing address of some devices has already been determined
|
||||
case ID_MDD:
|
||||
DevAddress = MDD_Base;
|
||||
break;
|
||||
|
||||
// Handle the 2nd instance of 5536's OHCI
|
||||
case ID_OHCI:
|
||||
if (Function == 4) {
|
||||
Instance = 2;
|
||||
}
|
||||
|
||||
default:
|
||||
// Search for the requested Geode_ID
|
||||
DevAddress = Find_MBus_ID(Geode_ID, Instance);
|
||||
if (!DevAddress) {
|
||||
Log_Error("Geode ID 0x%04X was not found for Device ID 0x%04X", Geode_ID, Device_ID);
|
||||
return 0x0000;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
// If an LBAR is required, allocate it
|
||||
if (Pci->LBar) {
|
||||
RoutingPtr->StartType = MDD_LBAR;
|
||||
RoutingPtr->Msr = MDD_Base;
|
||||
switch (Geode_ID) {
|
||||
case ID_USB_20:
|
||||
// OHCI needs an LBAR in the MDD
|
||||
if ((HdrPtr+REVISION_ID/4)->Interface == 0x10) {
|
||||
(UCHAR)RoutingPtr->Msr = MSR_LBAR_KEL1;
|
||||
RoutingPtr++;
|
||||
}
|
||||
RoutingPtr->StartType = USB_LBAR;
|
||||
|
||||
case ID_ATA:
|
||||
RoutingPtr->Msr = DevAddress;
|
||||
break;
|
||||
}
|
||||
(UCHAR)RoutingPtr->Msr = Pci->LBar;
|
||||
RoutingPtr++;
|
||||
}
|
||||
|
||||
// Get an available descriptor appropriate to the type of BAR
|
||||
switch (Resource) {
|
||||
|
||||
// Physical Memory
|
||||
case RESOURCE_MEMORY:
|
||||
|
||||
// Mark it as a memory BAR
|
||||
Pci->Flag |= MEM_BAR;
|
||||
|
||||
RoutingPtr->StartType = P2D_BMO;
|
||||
RoutingPtr->EndType = P2D_RO;
|
||||
RoutingPtr->Msr = Mbiu0;
|
||||
|
||||
// Legacy VGA frame buffers don't require physical memory
|
||||
if ((UCHAR)BaseAddr > BAR5) {
|
||||
ULONG RegionEnables, RegionProperties[2];
|
||||
|
||||
#define OFF_PROPS (REGION_WS) // Frame buffer properties to be disabled
|
||||
#define OFF_PROPERTIES ((OFF_PROPS<<24) | (OFF_PROPS<<16) | (OFF_PROPS<<8) | (OFF_PROPS))
|
||||
#define ON_PROPS (0) // Frame buffer properties to be enabled
|
||||
#define ON_PROPERTIES (( ON_PROPS<<24) | ( ON_PROPS<<16) | ( ON_PROPS<<8) | ( ON_PROPS))
|
||||
|
||||
// Set MPCI Fixed Region Enables and disable write-serialize
|
||||
Read_MSR(MSR_RCONF_A0_BF, RegionProperties);
|
||||
|
||||
Physical = 0xA0000;
|
||||
RegionEnables = 0x00;
|
||||
|
||||
switch (RangeRequest) {
|
||||
|
||||
case 128L*1024:
|
||||
RegionEnables = 0xFF; // A0000-BFFFF
|
||||
RegionProperties[1] &= ~OFF_PROPERTIES;
|
||||
RegionProperties[1] |= ON_PROPERTIES;
|
||||
|
||||
case 64L*1024:
|
||||
RegionEnables |= 0x0F; // A0000-AFFFF
|
||||
RegionProperties[0] &= ~OFF_PROPERTIES;
|
||||
RegionProperties[0] |= ON_PROPERTIES;
|
||||
break;
|
||||
|
||||
case 32L*1024:
|
||||
RegionEnables = 0xC0; // B8000-BFFFF
|
||||
RegionProperties[1] &= ~(OFF_PROPERTIES & 0xFFFF0000);
|
||||
RegionProperties[1] |= (ON_PROPERTIES & 0xFFFF0000);
|
||||
Physical = 0xB8000;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
// Set Vail Region Properties (0x180B)
|
||||
Write_MSR(MSR_RCONF_A0_BF, RegionProperties);
|
||||
|
||||
// Set MPCI Fixed Region Enables (0x2014)
|
||||
Write_MSR_LO(MPCI_NB + MPCI_REN, Read_MSR_LO(MPCI_NB + MPCI_REN) | RegionEnables);
|
||||
|
||||
// Allocate P2D_BM
|
||||
switch (Device_ID) {
|
||||
case DEVICE_ID_GFX2:
|
||||
case DEVICE_ID_GFX3:
|
||||
RoutingPtr->StartType = P2D_BM;
|
||||
break;
|
||||
}
|
||||
RoutingPtr++;
|
||||
|
||||
} else {
|
||||
|
||||
// Trim required memory from the end of extended memory
|
||||
Physical = Trim_Extended_Memory(RangeRequest);
|
||||
DevAddress = Find_MBus_ID(ID_MC, 1);
|
||||
|
||||
// Allocate a Region Configuration Register
|
||||
RoutingPtr++;
|
||||
RoutingPtr = Allocate_RCONF(DevAddress, RoutingPtr);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
// Memory-mapped I/O
|
||||
case RESOURCE_MMIO:
|
||||
// Mark it as a memory-mapped BAR
|
||||
Pci->Flag |= MMIO_BAR;
|
||||
|
||||
switch (Geode_ID) {
|
||||
|
||||
// Subtractive ports; no MBIU descriptor is necessary
|
||||
case ID_MPCI:
|
||||
case ID_MDD:
|
||||
break;
|
||||
|
||||
case ID_USB_20:
|
||||
case ID_OHCI:
|
||||
// Allocate a P2D_BMK descriptor in MBIU2
|
||||
RoutingPtr->StartType = P2D_BMK;
|
||||
if (!(Pci->Flag & USE_BMK)) {
|
||||
RoutingPtr->EndType = P2D_BM;
|
||||
}
|
||||
RoutingPtr->Msr = Mbiu2;
|
||||
RoutingPtr->Port = (UCHAR)DevAddress;
|
||||
RoutingPtr++;
|
||||
|
||||
if (Pci->Flag & EPCI_RW) {
|
||||
// Allocate the appropriate mailbox address
|
||||
RoutingPtr->StartType = EPCI;
|
||||
RoutingPtr->Msr = DevAddress & ROUTING;
|
||||
RoutingPtr++;
|
||||
}
|
||||
break;
|
||||
|
||||
case ID_VG:
|
||||
RoutingPtr->StartType = P2D_RO;
|
||||
RoutingPtr++;
|
||||
// Fix for VG alias bug: POFFSET field should be set to -PBASE
|
||||
// See Compute_Msr_Value()
|
||||
Physical = 1;
|
||||
break;
|
||||
|
||||
case ID_AES:
|
||||
RoutingPtr->StartType = P2D_R;
|
||||
RoutingPtr++;
|
||||
break;
|
||||
|
||||
default:
|
||||
RoutingPtr->StartType = P2D_BM;
|
||||
RoutingPtr->EndType = P2D_RO;
|
||||
RoutingPtr++;
|
||||
break;
|
||||
}
|
||||
|
||||
// Allocate a Region Configuration Register
|
||||
RoutingPtr = Allocate_RCONF(DevAddress, RoutingPtr);
|
||||
break;
|
||||
|
||||
|
||||
// I/O Space
|
||||
case RESOURCE_SCIO:
|
||||
RoutingPtr->StartType = IOD_SC;
|
||||
RoutingPtr++;
|
||||
|
||||
case RESOURCE_IO:
|
||||
// Mark it as an I/O BAR
|
||||
Pci->Flag |= IO_BAR;
|
||||
|
||||
switch (Geode_ID) {
|
||||
// Subtractive ports; no MBIU descriptor is necessary
|
||||
case ID_MPCI:
|
||||
case ID_MDD:
|
||||
break;
|
||||
|
||||
default:
|
||||
if (Resource != RESOURCE_SCIO) {
|
||||
RoutingPtr->StartType = IOD_BM;
|
||||
RoutingPtr->EndType = IOD_SC;
|
||||
RoutingPtr++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// If device is in the Southbridge...
|
||||
if ((DevAddress & MPCI_SB) == MPCI_SB) {
|
||||
// allocate a Region Configuration Register
|
||||
RoutingPtr = Allocate_RCONF(DevAddress, RoutingPtr);
|
||||
}
|
||||
|
||||
// PCI Spec requires I/O BAR a minimum of 4 bytes
|
||||
Pci->Mask &= 0xFFFFFFFC;
|
||||
break;
|
||||
|
||||
default:
|
||||
Log_Error("Unknown resource requested: 0x%X", Resource);
|
||||
return 0x0000;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Get device's PCI Revision ID
|
||||
//
|
||||
switch (Device_ID) {
|
||||
|
||||
// Revision of some devices is already determined
|
||||
case DEVICE_ID_OHCI:
|
||||
case DEVICE_ID_5536:
|
||||
case DEVICE_ID_GX2:
|
||||
case DEVICE_ID_LX:
|
||||
break;
|
||||
|
||||
// Graphic's Revision ID comes from GP, not VG or DF
|
||||
case DEVICE_ID_GFX2:
|
||||
case DEVICE_ID_GFX3:
|
||||
if (Geode_ID != ID_GP) {
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
// Read MBD_MSR_CAP
|
||||
Mbiu = DevAddress;
|
||||
(USHORT)Mbiu = MBD_MSR_CAP;
|
||||
|
||||
// Insert Revision ID into header
|
||||
(HdrPtr+REVISION_ID/4)->Revision_ID = (UCHAR)Read_MSR_LO(Mbiu);
|
||||
break;
|
||||
}
|
||||
|
||||
// Compute number of MSRs needed to support this BAR
|
||||
i = (UCHAR)(RoutingPtr - &Routing[0]);
|
||||
|
||||
if (i >= MAX_ROUTE) {
|
||||
Log_Error("Allocate_BAR- routing failed on PCI address 0x%X", PCI_Address);
|
||||
}
|
||||
|
||||
//
|
||||
// Allocate the required MSRs
|
||||
//
|
||||
RoutingPtr = &Routing[0];
|
||||
LinkPtr = &Pci->Link;
|
||||
|
||||
while (i) {
|
||||
|
||||
// Force use of P2D_RO to prevent ROVER from complaining about overlapped
|
||||
// physical addresses when the frame buffer length is not a power of 2.
|
||||
if (Pci == &Graphics_Hdr[BAR0/4]) {
|
||||
if(RoutingPtr->Msr == Mbiu0) {
|
||||
RoutingPtr->StartType = P2D_RO;
|
||||
}
|
||||
}
|
||||
StartType = RoutingPtr->StartType;
|
||||
EndType = RoutingPtr->EndType;
|
||||
|
||||
// If 2nd choice is not specified, force it to 1st choice
|
||||
if (EndType == 0x00) {
|
||||
EndType = StartType;
|
||||
}
|
||||
// Has the correct MBIU been determined ?
|
||||
if (RoutingPtr->Msr == 0x00000000) {
|
||||
// Determine the MBIU as follows:
|
||||
// - If the 2nd routing field == 0, then it's MBIU0
|
||||
// - If the 1st three routing fields match MBIU2, then it's MBIU2
|
||||
// - Otherwise it's MBIU1
|
||||
if ((DevAddress & (7L << 26)) == 0) {
|
||||
Mbiu = Mbiu0;
|
||||
} else {
|
||||
if ((DevAddress & 0xFF800000) == (Mbiu2 & 0xFF800000)) {
|
||||
Mbiu = Mbiu2;
|
||||
} else {
|
||||
Mbiu = Mbiu1;
|
||||
}
|
||||
}
|
||||
RoutingPtr->Msr = Mbiu;
|
||||
}
|
||||
|
||||
|
||||
if (StartType) {
|
||||
|
||||
Index = Allocate_Descriptor(StartType, EndType, RoutingPtr->Msr);
|
||||
|
||||
if (Index == DESCRIPTOR_NOT_FOUND) {
|
||||
|
||||
// If SMI generation, then any MBIU may be used
|
||||
if (!Geode_ID) {
|
||||
// Try MBIU1
|
||||
Mbiu = Mbiu1;
|
||||
Index = Allocate_Descriptor(StartType, EndType, Mbiu);
|
||||
if (Index == DESCRIPTOR_NOT_FOUND) {
|
||||
if (Mbiu = Mbiu2) {
|
||||
Index = Allocate_Descriptor(StartType, EndType, Mbiu);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Index == DESCRIPTOR_NOT_FOUND) {
|
||||
UCHAR Mbiu=9;
|
||||
|
||||
if (RoutingPtr->Msr == Mbiu0) Mbiu = 0;
|
||||
else if (RoutingPtr->Msr == Mbiu1) Mbiu = 1;
|
||||
else if (RoutingPtr->Msr == Mbiu2) Mbiu = 2;
|
||||
Log_Error("MSR allocation failed for GeodeID=%02X/DeviceID=%04X/BAR%x/MBIU%1x", \
|
||||
(UCHAR)Geode_ID, Device_ID, (USHORT)((BaseAddr-BAR0)/4), Mbiu);
|
||||
goto NextMSR;
|
||||
}
|
||||
|
||||
// Record info about the descriptor
|
||||
Descr = &MSRs[Index];
|
||||
Descr->Owner = PCI_Address;
|
||||
Descr->Range = RangeRequest;
|
||||
Descr->Physical = Physical;
|
||||
|
||||
|
||||
if (RoutingPtr->Port == 0) {
|
||||
RoutingPtr->Port = (UCHAR)DevAddress;
|
||||
}
|
||||
Descr->Port = RoutingPtr->Port;
|
||||
|
||||
// If embedded PCI device, record PCI mailbox MSR to Command register
|
||||
if (StartType == EPCI) {
|
||||
CommandPtr->Link = Index;
|
||||
}
|
||||
|
||||
// Link to previous MSRs[] (or Pci->Link)
|
||||
* LinkPtr = Index;
|
||||
|
||||
// Update link pointer
|
||||
LinkPtr = &Descr->Link;
|
||||
|
||||
|
||||
// Is an additional swiss-cheese descriptor necessary ?
|
||||
if (Descr->Type == IOD_SC && RangeRequest > 8) {
|
||||
RangeRequest -= 8;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the device is on GLIU0, then allocate a descriptor on GLIU1
|
||||
// to route FS2 transactions to GLIU0.
|
||||
if (RoutingPtr->Msr == Mbiu0 && RoutingPtr->StartType < GX2_RCONF ) {
|
||||
// Don't allocate MBUI1 descriptor for virtual register BAR
|
||||
if (Geode_ID) {
|
||||
switch (RoutingPtr->StartType) {
|
||||
|
||||
case IOD_SC:
|
||||
RoutingPtr->StartType = IOD_BM;
|
||||
RoutingPtr->EndType = IOD_SC;
|
||||
RangeRequest = 1L << MSB;
|
||||
break;
|
||||
|
||||
case P2D_RO:
|
||||
if (Pci == &Graphics_Hdr[BAR0/4]) {
|
||||
RoutingPtr->StartType = P2D_R;
|
||||
break;
|
||||
} else {
|
||||
RoutingPtr->StartType = P2D_BM;
|
||||
}
|
||||
|
||||
default:
|
||||
RangeRequest = 1L << MSB;
|
||||
break;
|
||||
}
|
||||
|
||||
// Use only 1 descriptor for northbound VG transactions
|
||||
if (RangeRequest == 16 && Geode_ID == ID_VG) {
|
||||
static UCHAR VG_FS2_Flag=0;
|
||||
|
||||
if (VG_FS2_Flag) {
|
||||
break;
|
||||
} else {
|
||||
VG_FS2_Flag = 1;
|
||||
RangeRequest = 32;
|
||||
}
|
||||
}
|
||||
|
||||
RoutingPtr->Msr = Mbiu1;
|
||||
RoutingPtr->Port = MBIU1_SelfReference;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Advance ptr to next MSR
|
||||
NextMSR:
|
||||
RoutingPtr++;
|
||||
i--;
|
||||
} // end while
|
||||
|
||||
|
||||
|
||||
// Make appropriate Command register bit R/W
|
||||
if (Pci->Flag & IO_BAR) {
|
||||
CommandPtr->Mask |= IO_SPACE;
|
||||
} else {
|
||||
CommandPtr->Mask |= MEM_SPACE;
|
||||
}
|
||||
|
||||
return PCI_Address;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
//
|
||||
// Perform early POST initialization of virtualized PCI config space
|
||||
//
|
||||
//***********************************************************************
|
||||
void VirtualPCI_EarlyInit(void)
|
||||
{ USHORT i;
|
||||
ULONG PCI_Address;
|
||||
ULONG MsrAddr;
|
||||
VIRTUAL_PTR DevicePtr;
|
||||
PCI_HEADER_ENTRY * Pci;
|
||||
|
||||
|
||||
// Initialize ptr to virtualized PCI topology
|
||||
VirtDevPtr = &Virtual_Devices[0];
|
||||
|
||||
|
||||
// Virtualize CS5536's configuration space, if present,
|
||||
// at the same device number as the h/w header.
|
||||
i = (UCHAR)((USHORT)HardwareInfo.Chipset_Base >> 11);
|
||||
switch (HardwareInfo.Chipset_ID) {
|
||||
|
||||
case DEVICE_ID_5536:
|
||||
Virtual_Devices[i] = Virtual_5536;
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
SouthBridge = Virtual_Devices[i];
|
||||
|
||||
// Compute mask of IDSELs that are to be virtualized
|
||||
for (i = 1; i <= 21; i++) {
|
||||
// If IDSEL is virtualized, set enable mask
|
||||
DevicePtr = * (VirtDevPtr+i);
|
||||
if (DevicePtr) {
|
||||
|
||||
// Record IDSEL to trap
|
||||
Virtualized_PCI_Devices |= (1L << i);
|
||||
|
||||
// Register System Manager for this IDSEL
|
||||
PCI_Address = ((ULONG)i << 11);
|
||||
Register_Event(EVENT_PCI_TRAP, MAX_PRIORITY, SysMgr_VSM, PCI_Address, 0x07FF);
|
||||
}
|
||||
}
|
||||
|
||||
// Enable virtual PCI headers
|
||||
MsrAddr = MPCI_NB + MBD_MSR_SMI;
|
||||
Write_MSR_LO(MsrAddr, Read_MSR_LO(MsrAddr) & ~VPHM);
|
||||
|
||||
|
||||
// Store CPU's Device & Revision IDs in Host Bridge's PCI header
|
||||
HostBridge_Hdr[0].Device_ID = HardwareInfo.CPU_ID;
|
||||
HostBridge_Hdr[2].Revision_ID = (UCHAR)HardwareInfo.CPU_Revision;
|
||||
|
||||
|
||||
// AES header (F2) BAR
|
||||
Allocate_BAR(RESOURCE_MMIO, BAR0, 16*1024, ID_AES, AES_Hdr[0].Device_ID);
|
||||
|
||||
// Implement Interrupt Pin/Line registers in LX graphic header
|
||||
if (Pci = Find_Register(Graphics_Hdr, INTERRUPT_LINE)) {
|
||||
// Make Interrupt Line read-write
|
||||
(UCHAR)Pci->Mask = 0xFF;
|
||||
// Set Interrupt Pin to INTA#
|
||||
Pci->Interrupt_Pin = 0x01;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************
|
||||
// Routine to support INFO getting PCI<->MSR linkages
|
||||
//***********************************************************************
|
||||
ULONG pascal Get_MSR_Linkage(USHORT PCI_Address)
|
||||
{ PCI_HEADER_ENTRY * Pci;
|
||||
ULONG MsrAddr;
|
||||
static UCHAR Link=0x00;
|
||||
static DESCRIPTOR * Descr;
|
||||
static USHORT LastPCI = 0x0000;
|
||||
|
||||
if (PCI_Address != LastPCI) {
|
||||
LastPCI = PCI_Address;
|
||||
Pci = Get_Structure(PCI_Address);
|
||||
|
||||
switch ((USHORT)Pci) {
|
||||
|
||||
case UNIMPLEMENTED_FUNCTION:
|
||||
case UNIMPLEMENTED_REGISTER:
|
||||
Link = 0x00;
|
||||
break;
|
||||
|
||||
default:
|
||||
Link = Pci->Link;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Descr = &MSRs[Link];
|
||||
|
||||
// Get link to next descriptor
|
||||
Link = Descr->Link;
|
||||
|
||||
if (!(MsrAddr = Descr->MsrAddr)) {
|
||||
LastPCI = 0x0000;
|
||||
}
|
||||
|
||||
return MsrAddr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user