[coreboot] [VSA] r1 - / trunk trunk/gplvsa2 trunk/gplvsa2/build trunk/gplvsa2/inc trunk/gplvsa2/legacy trunk/gplvsa2/lxvg trunk/gplvsa2/sysmgr trunk/gplvsa2/vsm_lib

svn at coreboot.org svn at coreboot.org
Fri Mar 20 19:32:39 CET 2009


Author: stepan
Date: 2009-03-20 19:32:39 +0100 (Fri, 20 Mar 2009)
New Revision: 1

Added:
   branches/
   tags/
   trunk/
   trunk/gplvsa2/
   trunk/gplvsa2/README.txt
   trunk/gplvsa2/amd_vsa_lx.bin
   trunk/gplvsa2/build/
   trunk/gplvsa2/build/legacy.mak
   trunk/gplvsa2/build/lxvg.mak
   trunk/gplvsa2/build/makefile
   trunk/gplvsa2/build/rules.mak
   trunk/gplvsa2/build/setvars.mak
   trunk/gplvsa2/build/sysmgr.mak
   trunk/gplvsa2/build/vsainit.mak
   trunk/gplvsa2/inc/
   trunk/gplvsa2/inc/acpi.h
   trunk/gplvsa2/inc/chipset.h
   trunk/gplvsa2/inc/cs5536.h
   trunk/gplvsa2/inc/gx2.h
   trunk/gplvsa2/inc/hce.h
   trunk/gplvsa2/inc/isa.h
   trunk/gplvsa2/inc/pci.h
   trunk/gplvsa2/inc/vr.h
   trunk/gplvsa2/inc/vsa2.h
   trunk/gplvsa2/legacy/
   trunk/gplvsa2/legacy/blockio.c
   trunk/gplvsa2/legacy/cs5536.c
   trunk/gplvsa2/legacy/events.c
   trunk/gplvsa2/legacy/flash.bak
   trunk/gplvsa2/legacy/flash.c
   trunk/gplvsa2/legacy/header.asm
   trunk/gplvsa2/legacy/ide.c
   trunk/gplvsa2/legacy/init.c
   trunk/gplvsa2/legacy/legacy.c
   trunk/gplvsa2/legacy/legacy.h
   trunk/gplvsa2/legacy/makefile
   trunk/gplvsa2/legacy/msr.asm
   trunk/gplvsa2/legacy/swapsif.c
   trunk/gplvsa2/legacy/sysinfo.c
   trunk/gplvsa2/legacy/uarts.c
   trunk/gplvsa2/legacy/virtregs.c
   trunk/gplvsa2/lxvg/
   trunk/gplvsa2/lxvg/decode.c
   trunk/gplvsa2/lxvg/init.c
   trunk/gplvsa2/lxvg/lxhwctl.c
   trunk/gplvsa2/lxvg/lxvg.h
   trunk/gplvsa2/lxvg/main.asm
   trunk/gplvsa2/lxvg/makefile
   trunk/gplvsa2/lxvg/msr.c
   trunk/gplvsa2/lxvg/utils.asm
   trunk/gplvsa2/lxvg/vgdata.c
   trunk/gplvsa2/lxvg/vgdata.h
   trunk/gplvsa2/lxvg/vsa2.c
   trunk/gplvsa2/sysmgr/
   trunk/gplvsa2/sysmgr/bugs.asm
   trunk/gplvsa2/sysmgr/chip.asm
   trunk/gplvsa2/sysmgr/chipset.c
   trunk/gplvsa2/sysmgr/cpu.asm
   trunk/gplvsa2/sysmgr/cpu_init.asm
   trunk/gplvsa2/sysmgr/cs5536.c
   trunk/gplvsa2/sysmgr/debug.asm
   trunk/gplvsa2/sysmgr/descr.c
   trunk/gplvsa2/sysmgr/descr.h
   trunk/gplvsa2/sysmgr/errors.c
   trunk/gplvsa2/sysmgr/events.c
   trunk/gplvsa2/sysmgr/gpio.c
   trunk/gplvsa2/sysmgr/gpio5536.c
   trunk/gplvsa2/sysmgr/handlers.c
   trunk/gplvsa2/sysmgr/history.c
   trunk/gplvsa2/sysmgr/idt.asm
   trunk/gplvsa2/sysmgr/image.asm
   trunk/gplvsa2/sysmgr/init.asm
   trunk/gplvsa2/sysmgr/init.h
   trunk/gplvsa2/sysmgr/io.c
   trunk/gplvsa2/sysmgr/io_trap.c
   trunk/gplvsa2/sysmgr/makefile
   trunk/gplvsa2/sysmgr/mapper.c
   trunk/gplvsa2/sysmgr/mapper.h
   trunk/gplvsa2/sysmgr/mbiu.c
   trunk/gplvsa2/sysmgr/mbus.c
   trunk/gplvsa2/sysmgr/mdd.c
   trunk/gplvsa2/sysmgr/mdd.h
   trunk/gplvsa2/sysmgr/message.asm
   trunk/gplvsa2/sysmgr/mfgpt.c
   trunk/gplvsa2/sysmgr/msr.asm
   trunk/gplvsa2/sysmgr/ohci.c
   trunk/gplvsa2/sysmgr/pci_pm.c
   trunk/gplvsa2/sysmgr/pci_rd.c
   trunk/gplvsa2/sysmgr/pci_wr.c
   trunk/gplvsa2/sysmgr/port92.asm
   trunk/gplvsa2/sysmgr/protos.h
   trunk/gplvsa2/sysmgr/smimac.mac
   trunk/gplvsa2/sysmgr/smis.asm
   trunk/gplvsa2/sysmgr/sw_int.asm
   trunk/gplvsa2/sysmgr/swapsif.c
   trunk/gplvsa2/sysmgr/syscalls.asm
   trunk/gplvsa2/sysmgr/sysmgr.asm
   trunk/gplvsa2/sysmgr/sysmgr.h
   trunk/gplvsa2/sysmgr/timeout.c
   trunk/gplvsa2/sysmgr/timer.c
   trunk/gplvsa2/sysmgr/timer.h
   trunk/gplvsa2/sysmgr/topology.c
   trunk/gplvsa2/sysmgr/unregstr.c
   trunk/gplvsa2/sysmgr/utils.asm
   trunk/gplvsa2/sysmgr/virt_pci.c
   trunk/gplvsa2/sysmgr/vpci.h
   trunk/gplvsa2/sysmgr/vr.c
   trunk/gplvsa2/sysmgr/vr_misc.asm
   trunk/gplvsa2/sysmgr/vsa_init.c
   trunk/gplvsa2/vsabuild.txt
   trunk/gplvsa2/vsm_lib/
   trunk/gplvsa2/vsm_lib/critical.asm
   trunk/gplvsa2/vsm_lib/descr.asm
   trunk/gplvsa2/vsm_lib/hex.asm
   trunk/gplvsa2/vsm_lib/irq.asm
   trunk/gplvsa2/vsm_lib/makefile
   trunk/gplvsa2/vsm_lib/message.asm
   trunk/gplvsa2/vsm_lib/misc.asm
   trunk/gplvsa2/vsm_lib/msrs.asm
   trunk/gplvsa2/vsm_lib/pci.asm
   trunk/gplvsa2/vsm_lib/present.asm
   trunk/gplvsa2/vsm_lib/regs.asm
   trunk/gplvsa2/vsm_lib/resource.asm
   trunk/gplvsa2/vsm_lib/sw_int.asm
   trunk/gplvsa2/vsm_lib/sysinfo.asm
   trunk/gplvsa2/vsm_lib/utils.asm
   trunk/gplvsa2/vsm_lib/virtual.asm
   trunk/gplvsa2/vsm_lib/vsa2util.asm
   trunk/gplvsa2/vsm_lib/yield.asm
Log:
Initial import of AMD's GPL version of VSA2


Added: trunk/gplvsa2/README.txt
===================================================================
--- trunk/gplvsa2/README.txt	                        (rev 0)
+++ trunk/gplvsa2/README.txt	2009-03-20 18:32:39 UTC (rev 1)
@@ -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


Property changes on: trunk/gplvsa2/README.txt
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/amd_vsa_lx.bin
===================================================================
(Binary files differ)


Property changes on: trunk/gplvsa2/amd_vsa_lx.bin
___________________________________________________________________
Added: svn:executable
   + *
Added: svn:mime-type
   + application/octet-stream

Added: trunk/gplvsa2/build/legacy.mak
===================================================================
--- trunk/gplvsa2/build/legacy.mak	                        (rev 0)
+++ trunk/gplvsa2/build/legacy.mak	2009-03-20 18:32:39 UTC (rev 1)
@@ -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)
\ No newline at end of file


Property changes on: trunk/gplvsa2/build/legacy.mak
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/build/lxvg.mak
===================================================================
--- trunk/gplvsa2/build/lxvg.mak	                        (rev 0)
+++ trunk/gplvsa2/build/lxvg.mak	2009-03-20 18:32:39 UTC (rev 1)
@@ -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)


Property changes on: trunk/gplvsa2/build/lxvg.mak
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/build/makefile
===================================================================
--- trunk/gplvsa2/build/makefile	                        (rev 0)
+++ trunk/gplvsa2/build/makefile	2009-03-20 18:32:39 UTC (rev 1)
@@ -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):
+	- at md $(OBJECT)
+
+
+############################################
+# Tools.lib
+############################################
+tools_clean:
+	- at cd $(VSA2ROOT)\vsm_lib
+	-@$(MAKE) /nologo cleanall
+	- at 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
+


Property changes on: trunk/gplvsa2/build/makefile
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/build/rules.mak
===================================================================
--- trunk/gplvsa2/build/rules.mak	                        (rev 0)
+++ trunk/gplvsa2/build/rules.mak	2009-03-20 18:32:39 UTC (rev 1)
@@ -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: 
+	- at IF EXIST $(OBJECT)\*.def $(DEL) $(OBJECT)\*.def
+	- at IF EXIST $(OBJECT)\*.lnk $(DEL) $(OBJECT)\*.lnk
+	- at IF EXIST $(OBJECT)\*.map $(DEL) $(OBJECT)\*.map
+	- at IF EXIST $(OBJECT)\*.obj $(DEL) $(OBJECT)\*.obj
+	- at IF EXIST $(OBJECT)\*.exe $(DEL) $(OBJECT)\*.exe
+	- at IF EXIST $(OBJECT)\*.rom $(DEL) $(OBJECT)\*.rom
+	- at IF EXIST $(OBJECT)\*.cpu $(DEL) $(OBJECT)\*.cpu
+	- at IF EXIST $(OBJECT)\*.scc $(DEL) $(OBJECT)\*.scc
+	- at IF EXIST $(OBJECT)\*.inc $(DEL) $(OBJECT)\*.inc
+	- at IF EXIST $(OBJECT)\*.h $(DEL) $(OBJECT)\*.h
+	- at IF EXIST $(OBJECT)\*.lst $(DEL) $(OBJECT)\*.lst
+	- at IF EXIST $(OBJECT)\*.bak $(DEL) $(OBJECT)\*.bak
+	- at IF EXIST $(OBJECT)\*.mac $(DEL) $(OBJECT)\*.mac
+	- at IF EXIST $(OBJECT)\*.asm $(DEL) $(OBJECT)\*.asm
+	- at IF EXIST $(OBJECT)\*.cod $(DEL) $(OBJECT)\*.cod
+	- at IF EXIST $(MAKEDIR)\*.map $(DEL) $(MAKEDIR)\*.map
+	- at IF EXIST $(MAKEDIR)\arccode.h $(DEL) $(MAKEDIR)\arccode.h
+
+cleanall: clean 
+	- at IF EXIST $(MAKEDIR)\*.vsm $(DEL) $(MAKEDIR)\*.vsm
+	- at IF EXIST $(OBJECT)\*.vsm $(DEL) $(OBJECT)\*.vsm
+	- at IF EXIST $(OBJECT)\*.bin $(DEL) $(OBJECT)\*.bin
+	- at IF EXIST $(OBJECT)\*.lib $(DEL) $(OBJECT)\*.lib
+	- at 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) $< $@
+


Property changes on: trunk/gplvsa2/build/rules.mak
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/build/setvars.mak
===================================================================
--- trunk/gplvsa2/build/setvars.mak	                        (rev 0)
+++ trunk/gplvsa2/build/setvars.mak	2009-03-20 18:32:39 UTC (rev 1)
@@ -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
+
+


Property changes on: trunk/gplvsa2/build/setvars.mak
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/build/sysmgr.mak
===================================================================
--- trunk/gplvsa2/build/sysmgr.mak	                        (rev 0)
+++ trunk/gplvsa2/build/sysmgr.mak	2009-03-20 18:32:39 UTC (rev 1)
@@ -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)
\ No newline at end of file


Property changes on: trunk/gplvsa2/build/sysmgr.mak
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/build/vsainit.mak
===================================================================
--- trunk/gplvsa2/build/vsainit.mak	                        (rev 0)
+++ trunk/gplvsa2/build/vsainit.mak	2009-03-20 18:32:39 UTC (rev 1)
@@ -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)
\ No newline at end of file


Property changes on: trunk/gplvsa2/build/vsainit.mak
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/inc/acpi.h
===================================================================
--- trunk/gplvsa2/inc/acpi.h	                        (rev 0)
+++ trunk/gplvsa2/inc/acpi.h	2009-03-20 18:32:39 UTC (rev 1)
@@ -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


Property changes on: trunk/gplvsa2/inc/acpi.h
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/inc/chipset.h
===================================================================
--- trunk/gplvsa2/inc/chipset.h	                        (rev 0)
+++ trunk/gplvsa2/inc/chipset.h	2009-03-20 18:32:39 UTC (rev 1)
@@ -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)
+
+
+


Property changes on: trunk/gplvsa2/inc/chipset.h
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/inc/cs5536.h
===================================================================
--- trunk/gplvsa2/inc/cs5536.h	                        (rev 0)
+++ trunk/gplvsa2/inc/cs5536.h	2009-03-20 18:32:39 UTC (rev 1)
@@ -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)


Property changes on: trunk/gplvsa2/inc/cs5536.h
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/inc/gx2.h
===================================================================
--- trunk/gplvsa2/inc/gx2.h	                        (rev 0)
+++ trunk/gplvsa2/inc/gx2.h	2009-03-20 18:32:39 UTC (rev 1)
@@ -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)
+
+
+
+
+


Property changes on: trunk/gplvsa2/inc/gx2.h
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/inc/hce.h
===================================================================
--- trunk/gplvsa2/inc/hce.h	                        (rev 0)
+++ trunk/gplvsa2/inc/hce.h	2009-03-20 18:32:39 UTC (rev 1)
@@ -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
+


Property changes on: trunk/gplvsa2/inc/hce.h
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/inc/isa.h
===================================================================
--- trunk/gplvsa2/inc/isa.h	                        (rev 0)
+++ trunk/gplvsa2/inc/isa.h	2009-03-20 18:32:39 UTC (rev 1)
@@ -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
+
+
+
+


Property changes on: trunk/gplvsa2/inc/isa.h
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/inc/pci.h
===================================================================
--- trunk/gplvsa2/inc/pci.h	                        (rev 0)
+++ trunk/gplvsa2/inc/pci.h	2009-03-20 18:32:39 UTC (rev 1)
@@ -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
+


Property changes on: trunk/gplvsa2/inc/pci.h
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/inc/vr.h
===================================================================
--- trunk/gplvsa2/inc/vr.h	                        (rev 0)
+++ trunk/gplvsa2/inc/vr.h	2009-03-20 18:32:39 UTC (rev 1)
@@ -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


Property changes on: trunk/gplvsa2/inc/vr.h
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/inc/vsa2.h
===================================================================
--- trunk/gplvsa2/inc/vsa2.h	                        (rev 0)
+++ trunk/gplvsa2/inc/vsa2.h	2009-03-20 18:32:39 UTC (rev 1)
@@ -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;
+
+
+
+


Property changes on: trunk/gplvsa2/inc/vsa2.h
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/legacy/blockio.c
===================================================================
--- trunk/gplvsa2/legacy/blockio.c	                        (rev 0)
+++ trunk/gplvsa2/legacy/blockio.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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);
+
+}


Property changes on: trunk/gplvsa2/legacy/blockio.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/legacy/cs5536.c
===================================================================
--- trunk/gplvsa2/legacy/cs5536.c	                        (rev 0)
+++ trunk/gplvsa2/legacy/cs5536.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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);
+}
+


Property changes on: trunk/gplvsa2/legacy/cs5536.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/legacy/events.c
===================================================================
--- trunk/gplvsa2/legacy/events.c	                        (rev 0)
+++ trunk/gplvsa2/legacy/events.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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;
+  }
+}


Property changes on: trunk/gplvsa2/legacy/events.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/legacy/flash.bak
===================================================================
--- trunk/gplvsa2/legacy/flash.bak	                        (rev 0)
+++ trunk/gplvsa2/legacy/flash.bak	2009-03-20 18:32:39 UTC (rev 1)
@@ -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);
+    }
+  }
+}


Property changes on: trunk/gplvsa2/legacy/flash.bak
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/legacy/flash.c
===================================================================
--- trunk/gplvsa2/legacy/flash.c	                        (rev 0)
+++ trunk/gplvsa2/legacy/flash.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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);
+    }
+  }
+}


Property changes on: trunk/gplvsa2/legacy/flash.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/legacy/header.asm
===================================================================
--- trunk/gplvsa2/legacy/header.asm	                        (rev 0)
+++ trunk/gplvsa2/legacy/header.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -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
+


Property changes on: trunk/gplvsa2/legacy/header.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/legacy/ide.c
===================================================================
--- trunk/gplvsa2/legacy/ide.c	                        (rev 0)
+++ trunk/gplvsa2/legacy/ide.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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;
+}


Property changes on: trunk/gplvsa2/legacy/ide.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/legacy/init.c
===================================================================
--- trunk/gplvsa2/legacy/init.c	                        (rev 0)
+++ trunk/gplvsa2/legacy/init.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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);
+            
+}


Property changes on: trunk/gplvsa2/legacy/init.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/legacy/legacy.c
===================================================================
--- trunk/gplvsa2/legacy/legacy.c	                        (rev 0)
+++ trunk/gplvsa2/legacy/legacy.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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);
+}
\ No newline at end of file


Property changes on: trunk/gplvsa2/legacy/legacy.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/legacy/legacy.h
===================================================================
--- trunk/gplvsa2/legacy/legacy.h	                        (rev 0)
+++ trunk/gplvsa2/legacy/legacy.h	2009-03-20 18:32:39 UTC (rev 1)
@@ -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
+
+
+


Property changes on: trunk/gplvsa2/legacy/legacy.h
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/legacy/makefile
===================================================================
--- trunk/gplvsa2/legacy/makefile	                        (rev 0)
+++ trunk/gplvsa2/legacy/makefile	2009-03-20 18:32:39 UTC (rev 1)
@@ -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):
+	- at 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 $<


Property changes on: trunk/gplvsa2/legacy/makefile
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/legacy/msr.asm
===================================================================
--- trunk/gplvsa2/legacy/msr.asm	                        (rev 0)
+++ trunk/gplvsa2/legacy/msr.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -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
+
+
+


Property changes on: trunk/gplvsa2/legacy/msr.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/legacy/swapsif.c
===================================================================
--- trunk/gplvsa2/legacy/swapsif.c	                        (rev 0)
+++ trunk/gplvsa2/legacy/swapsif.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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;
+  }
+}
\ No newline at end of file


Property changes on: trunk/gplvsa2/legacy/swapsif.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/legacy/sysinfo.c
===================================================================
--- trunk/gplvsa2/legacy/sysinfo.c	                        (rev 0)
+++ trunk/gplvsa2/legacy/sysinfo.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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);
+}


Property changes on: trunk/gplvsa2/legacy/sysinfo.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/legacy/uarts.c
===================================================================
--- trunk/gplvsa2/legacy/uarts.c	                        (rev 0)
+++ trunk/gplvsa2/legacy/uarts.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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);
+		}
+	}
+	
+}
+
+
+


Property changes on: trunk/gplvsa2/legacy/uarts.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/legacy/virtregs.c
===================================================================
--- trunk/gplvsa2/legacy/virtregs.c	                        (rev 0)
+++ trunk/gplvsa2/legacy/virtregs.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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;
+  }
+}
+
+
+
+
+
+


Property changes on: trunk/gplvsa2/legacy/virtregs.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/lxvg/decode.c
===================================================================
--- trunk/gplvsa2/lxvg/decode.c	                        (rev 0)
+++ trunk/gplvsa2/lxvg/decode.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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


Property changes on: trunk/gplvsa2/lxvg/decode.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/lxvg/init.c
===================================================================
--- trunk/gplvsa2/lxvg/init.c	                        (rev 0)
+++ trunk/gplvsa2/lxvg/init.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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


Property changes on: trunk/gplvsa2/lxvg/init.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/lxvg/lxhwctl.c
===================================================================
--- trunk/gplvsa2/lxvg/lxhwctl.c	                        (rev 0)
+++ trunk/gplvsa2/lxvg/lxhwctl.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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;
+}
+


Property changes on: trunk/gplvsa2/lxvg/lxhwctl.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/lxvg/lxvg.h
===================================================================
--- trunk/gplvsa2/lxvg/lxvg.h	                        (rev 0)
+++ trunk/gplvsa2/lxvg/lxvg.h	2009-03-20 18:32:39 UTC (rev 1)
@@ -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);
+


Property changes on: trunk/gplvsa2/lxvg/lxvg.h
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/lxvg/main.asm
===================================================================
--- trunk/gplvsa2/lxvg/main.asm	                        (rev 0)
+++ trunk/gplvsa2/lxvg/main.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -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
+
+
+
+


Property changes on: trunk/gplvsa2/lxvg/main.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/lxvg/makefile
===================================================================
--- trunk/gplvsa2/lxvg/makefile	                        (rev 0)
+++ trunk/gplvsa2/lxvg/makefile	2009-03-20 18:32:39 UTC (rev 1)
@@ -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):
+	- at 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$@ $<


Property changes on: trunk/gplvsa2/lxvg/makefile
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/lxvg/msr.c
===================================================================
--- trunk/gplvsa2/lxvg/msr.c	                        (rev 0)
+++ trunk/gplvsa2/lxvg/msr.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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;
+
+}
+


Property changes on: trunk/gplvsa2/lxvg/msr.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/lxvg/utils.asm
===================================================================
--- trunk/gplvsa2/lxvg/utils.asm	                        (rev 0)
+++ trunk/gplvsa2/lxvg/utils.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -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


Property changes on: trunk/gplvsa2/lxvg/utils.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/lxvg/vgdata.c
===================================================================
--- trunk/gplvsa2/lxvg/vgdata.c	                        (rev 0)
+++ trunk/gplvsa2/lxvg/vgdata.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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


Property changes on: trunk/gplvsa2/lxvg/vgdata.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/lxvg/vgdata.h
===================================================================
--- trunk/gplvsa2/lxvg/vgdata.h	                        (rev 0)
+++ trunk/gplvsa2/lxvg/vgdata.h	2009-03-20 18:32:39 UTC (rev 1)
@@ -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


Property changes on: trunk/gplvsa2/lxvg/vgdata.h
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/lxvg/vsa2.c
===================================================================
--- trunk/gplvsa2/lxvg/vsa2.c	                        (rev 0)
+++ trunk/gplvsa2/lxvg/vsa2.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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;
+	}
+}
\ No newline at end of file


Property changes on: trunk/gplvsa2/lxvg/vsa2.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/bugs.asm
===================================================================
--- trunk/gplvsa2/sysmgr/bugs.asm	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/bugs.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -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
+


Property changes on: trunk/gplvsa2/sysmgr/bugs.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/chip.asm
===================================================================
--- trunk/gplvsa2/sysmgr/chip.asm	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/chip.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -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
+	
\ No newline at end of file


Property changes on: trunk/gplvsa2/sysmgr/chip.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/chipset.c
===================================================================
--- trunk/gplvsa2/sysmgr/chipset.c	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/chipset.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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;
+  }
+}
+
+
+


Property changes on: trunk/gplvsa2/sysmgr/chipset.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/cpu.asm
===================================================================
--- trunk/gplvsa2/sysmgr/cpu.asm	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/cpu.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -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


Property changes on: trunk/gplvsa2/sysmgr/cpu.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/cpu_init.asm
===================================================================
--- trunk/gplvsa2/sysmgr/cpu_init.asm	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/cpu_init.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -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
+	
\ No newline at end of file


Property changes on: trunk/gplvsa2/sysmgr/cpu_init.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/cs5536.c
===================================================================
--- trunk/gplvsa2/sysmgr/cs5536.c	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/cs5536.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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);
+          }
+        }
+      }
+    }
+  }
+}


Property changes on: trunk/gplvsa2/sysmgr/cs5536.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/debug.asm
===================================================================
--- trunk/gplvsa2/sysmgr/debug.asm	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/debug.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -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
+


Property changes on: trunk/gplvsa2/sysmgr/debug.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/descr.c
===================================================================
--- trunk/gplvsa2/sysmgr/descr.c	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/descr.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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;
+}
+
+
+
+
+


Property changes on: trunk/gplvsa2/sysmgr/descr.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/descr.h
===================================================================
--- trunk/gplvsa2/sysmgr/descr.h	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/descr.h	2009-03-20 18:32:39 UTC (rev 1)
@@ -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


Property changes on: trunk/gplvsa2/sysmgr/descr.h
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/errors.c
===================================================================
--- trunk/gplvsa2/sysmgr/errors.c	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/errors.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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);
+  }
+}
+
+


Property changes on: trunk/gplvsa2/sysmgr/errors.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/events.c
===================================================================
--- trunk/gplvsa2/sysmgr/events.c	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/events.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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);
+
+}
\ No newline at end of file


Property changes on: trunk/gplvsa2/sysmgr/events.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/gpio.c
===================================================================
--- trunk/gplvsa2/sysmgr/gpio.c	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/gpio.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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);
+
+}
+
+
+
+
+
+
+
+


Property changes on: trunk/gplvsa2/sysmgr/gpio.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/gpio5536.c
===================================================================
--- trunk/gplvsa2/sysmgr/gpio5536.c	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/gpio5536.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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);
+
+}


Property changes on: trunk/gplvsa2/sysmgr/gpio5536.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/handlers.c
===================================================================
--- trunk/gplvsa2/sysmgr/handlers.c	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/handlers.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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,
+};
+
+
+
+
+						   
\ No newline at end of file


Property changes on: trunk/gplvsa2/sysmgr/handlers.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/history.c
===================================================================
--- trunk/gplvsa2/sysmgr/history.c	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/history.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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


Property changes on: trunk/gplvsa2/sysmgr/history.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/idt.asm
===================================================================
--- trunk/gplvsa2/sysmgr/idt.asm	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/idt.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -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
+


Property changes on: trunk/gplvsa2/sysmgr/idt.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/image.asm
===================================================================
--- trunk/gplvsa2/sysmgr/image.asm	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/image.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -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
+	
\ No newline at end of file


Property changes on: trunk/gplvsa2/sysmgr/image.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/init.asm
===================================================================
--- trunk/gplvsa2/sysmgr/init.asm	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/init.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -0,0 +1,1017 @@
+; 
+; 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 installation code for VSA II.
+;*
+;*   BIOS Usage:
+;*     CALL far ptr [VSA_Entry]
+;*         where VSA_Entry:   dw 0020h, <segment>
+;*
+;*******************************************************************************
+
+
+include vsa2.inc
+include sysmgr.inc
+include init.inc
+include smimac.mac
+include chipset.inc
+;include vpci.inc
+DESCRIPTOR struc
+DescrType  BYTE  ?      ; Type of MSR
+Flag       BYTE  ?      ; See definitions below
+Link       BYTE  ?      ; Link to next MSR
+Split      BYTE  ?      ; Index of descriptor that was split
+
+Owner      WORD  ?      ; PCI Address this descriptor belongs to
+Mbiu       BYTE  ?      ; MBUI on which this descriptor is located
+Port       BYTE  ?      ; Port this descriptor routes to
+
+MsrAddr    DWORD ?      ; Routing address of MSR (descriptor/LBAR/RCONF)
+MsrData0   DWORD ?      ; MSR data low
+MsrData1   DWORD ?      ; MSR data high
+Physical   DWORD ?      ; Physical memory assigned  (00000000 if none)
+Range      DWORD ?      ; Actual I/O range for IOD_SC
+Address    WORD  ?      ; Address of I/O Trap or Timeout
+DESCRIPTOR ENDS
+
+
+.model small,c
+.586
+.CODE
+
+VERIFY_VSM_COPY equ	1		; 0=skip verify
+
+
+SW_SMI		equ	0D0h
+
+
+; VSA loader debug codes:
+VSA_ENTERED  	equ     10h		; VSA installation has been entered
+VSA_INIT1    	equ     11h		; Returned from Setup
+VSA_SYSMGR	equ     12h		; Image of SysMgr was found
+VSA_VSM_FOUND	equ     13h		; A VSM has been found (followed by VSM type)
+VSA_COPY_START	equ     14h		; Start of module copy
+VSA_COPY_END	equ     15h		; End of module copy
+VSA_VRFY_START equ     1Ch		; Start of verifying module copy
+VSA_VRFY_END   equ     1Dh		; End of verifying module copy
+VSA_FILL_START equ     1Eh		; Start of filling BSS
+VSA_FILL_END   equ     1Fh		; End of filling BSS
+VSA_INIT2    	equ     16h		; Returned from copying VSA image
+VSA_INIT3    	equ     17h		; Performing VSA initialization SMI
+VSA_INIT4    	equ     18h		; Returned from s/w SMI
+VSA_INIT5    	equ     19h		; Returned from initializing statistics
+VSA_INIT6    	equ     1Ah		; Returning to BIOS
+VSA_ERROR	equ     0EEh		; Installation error. EBX contains error mask
+
+
+
+; NOTES:
+;  1) A VSM's CS segment must be writeable since the message queue is
+;     stored there and the VSM must be able to update the pointers.
+;  2) The nested flag must be set so when the System Manager RSMs
+;     to a VSM, the processor remains in SMM.
+VSM_FLAGS	equ 	SMI_FLAGS_CS_WRITABLE + SMI_FLAGS_NESTED + SMI_FLAGS_CS_READABLE
+
+
+
+
+
+POST	macro	Code
+
+    	mov	al, Code
+    	out	80h, al
+
+    	endm
+
+public	Device_ID
+public	Chipset_Base
+public	Errors
+public	BIOS_ECX
+public	BIOS_EDX
+
+
+externdef Software_SMI:	proc
+externdef Get_Sbridge_Info:	proc
+externdef Get_IRQ_Base:	proc
+externdef Get_SMI_Base:	proc
+externdef Get_CPU_Info:	proc
+externdef Clear_SMIs:		proc
+externdef Get_SMM_Region:	proc
+externdef Init_SMM_Region:	proc
+externdef Enable_SMIs:		proc
+externdef Enable_SMM_Instr:	proc
+externdef Disable_A20:		proc
+externdef Get_Memory_Size:	proc
+externdef Set_CPU_Fields:	proc
+externdef VSA_Image: 		byte
+
+
+
+
+	ORG	0000h
+;***********************************************************************
+; Entry Point for DOS installer
+;***********************************************************************
+VSA_Installation:
+
+	mov	dx, offset Msg_Not_DOS_BUILD
+	push	cs			; DS <= CS
+	pop	ds
+	mov	ah, 9			; Call DOS PrintString
+	int	21h
+
+
+ReturnToDOS:
+	sti
+	mov	ah, 4Ch			; Return to DOS
+	int	21h
+
+
+	org	001Eh			; Used by INFO to skip over init code
+	dw	offset VSA_Image
+
+
+;***********************************************************************
+; Entry point for BIOS installer
+;***********************************************************************
+	org	0020h
+
+VSA_Install proc far
+
+	POST	VSA_ENTERED
+
+	pushf
+	push	cs			; DS <- CS
+	pop	ds
+	ASSUME	DS:_TEXT
+	mov	[BIOS_ECX], ecx		; MSR address of SMM memory descriptor (P2D_BMO)
+	mov	[BIOS_EDX], edx		; MSR address of system memory descriptor (P2D_R)
+
+
+;
+; Make sure VSM's SmiHeader is DWORD aligned
+;
+	mov	si, VSM_Header.SysStuff.State
+	test	si, 3
+	jz	AlignmentOK
+	mov	bx, [Errors]
+	or	bx, ERR_INTERNAL
+	jmp	DisplayErrors
+
+AlignmentOK:
+
+
+	; Set up for SMM
+	call	Setup
+	jc	DisplayErrors	
+
+	; Load System Manager and VSMs into memory
+	POST	VSA_INIT1
+	call	ProcessModules
+	POST	VSA_INIT2
+
+	push	cs
+	pop	ds
+	
+	mov	bx, [Errors]		; Any errors detected ?
+	test	bx, bx
+	jz	Init_VSA
+DisplayErrors:
+	POST	VSA_ERROR
+
+	jmp	Exit
+
+
+Init_VSA:
+	cli
+
+	; Set SMM MSRs
+	mov	ebx, [SysMgrEntry]
+	call	Init_SMM_Region
+
+
+	; Generate s/w SMI to initialize VSA
+	POST	VSA_INIT3		; POST 17h
+
+
+	call	Enable_SMIs		; Enable SMIs
+	movzx	eax, [SysCall_Code]
+	mov	ebx, [InitParam1]
+	mov	ecx, [InitParam2]
+	call	Software_SMI
+
+	POST	VSA_INIT4		; POST 18h
+
+
+	call	InitStatistics		; Initialize VSA statistics
+
+	POST	VSA_INIT5		; POST 19h
+
+
+Exit:
+	POST	VSA_INIT6		; POST 1Ah
+	popf
+	ret
+
+VSA_Install endp
+
+	ASSUME	DS:NOTHING
+	
+
+;***********************************************************************
+;***********************************************************************
+;***********************************************************************
+;***********************************************************************
+
+
+
+
+
+;***********************************************************************
+;
+; Some of the time in SMM cannot be recorded by VSA.
+; This unaccounted time consists of:
+;  1) the cycles used to write the SMM header.
+;  2) the cycles for the SMM entry code before RDTSC is executed.
+;  3) the cycles between the exit RDTSC through the RSM instruction.
+;
+; The following code calculates how many clocks this time consists
+; of and stores it in a VSA structure.  It is used as an adjustment
+; to the statistics calculations.
+;
+;***********************************************************************
+InitStatistics proc
+
+	in	al, 92h			; Save A20 mask
+	push	ax
+
+	mov	si, 0			; Don't toggle A20 (no SMI)
+	call	DeltaSMI
+	mov	edi, eax		; EDI = overhead of DeltaSMI()
+
+	mov	ebx, [SysMgrEntry]	; Get ptr to SysMgr's header
+	add	ebx, VSM_Header.SysStuff
+	mov	es:(System PTR [ebx]).Clocks, 0
+	mov	si, 2			; Generate an SMI by toggling A20
+	call	DeltaSMI
+
+	mov	ecx, es:(System PTR [ebx]).Clocks
+	sub	eax, ecx		; Subtract clocks VSA determined
+	sub	eax, edi		; Subtract DeltaSMI() overhead
+	mov	es:(System PTR [ebx]).Adjustment, eax
+
+	pop	ax			; Restore A20 mask
+	out	92h, al 
+
+	; Initialize statistics structure
+	RDTSC				; Record VSA start time
+	mov	es:(System PTR [ebx+0]).StartClocks, eax
+	mov	es:(System PTR [ebx+4]).StartClocks, edx
+	xor	eax, eax
+	mov	es:(System PTR [ebx+0]).Clocks, eax
+	mov	es:(System PTR [ebx+4]).Clocks, eax
+	mov	es:(System PTR [ebx+0]).NumSMIs, eax
+	mov	es:(System PTR [ebx+4]).NumSMIs, eax
+	ret
+
+InitStatistics endp
+
+;***********************************************************************
+; Helper routine for InitStatistics()
+; Input: SI = XOR mask for port 92h
+;***********************************************************************
+DeltaSMI proc
+
+	RDTSC				; Record VSA start time
+	mov	ecx, eax
+
+	in	al, 92h			; Generate an SMI by toggling A20 mask
+	xor	ax, si
+	out	92h, al
+
+	RDTSC				; Compute actual delta clocks
+	sub	eax, ecx
+	jnc	Exit
+	neg	eax			; TSC rolled over
+Exit:	ret
+
+DeltaSMI endp
+
+
+
+
+;***********************************************************************
+; Setup for VSA installation:
+; - Gets information about the system: CPU, Southbridge, memory, PCI
+; - Sets ES to be 4 GB descriptor
+; - Clears pending SMIs
+;***********************************************************************
+Setup proc near
+
+	ASSUME	DS:_TEXT
+
+	cli
+
+	call	Get_CPU_Info		; Get information about the CPU
+	mov	[Cpu_Revision], ax
+	mov	[Cpu_ID], si
+	mov	[PCI_MHz], bx
+	mov	[CPU_MHz], cx
+	mov	[DRAM_MHz], dx
+
+	call	Get_Sbridge_Info	; Get information about the Southbridge
+	jc	short SetupExit
+	mov	[Chipset_Base], ebx
+	mov	[Device_ID], dx
+	mov	[Chipset_Rev], cl
+
+	call	Get_SMM_Region		; Get SMM entry point
+	mov	[ModuleBase], eax
+	mov	[SysMgr_Location], eax
+	mov	[VSA_Size], bx
+	movzx	ebx, bx			; Get end of VSA memory
+	shl	ebx, 10
+	add	eax, ebx
+	mov	[VSA_End], eax
+
+	call	Enable_SMM_Instr	; Enable SMM instructions
+
+
+	rsdc	es, [Flat_Descriptor]	; Setup ES as a 4 GB flat descriptor
+
+
+	call	Disable_A20		; Turn off A20 masking
+
+	
+	call	Get_Memory_Size		; Get physical memory size
+	mov	[TotalMemory], eax
+
+
+	call	Clear_SMIs		; Clear all pending SMIs
+
+SetupExit:
+	mov	[SetupComplete], 0FFh
+	clc
+	ret
+
+
+	ASSUME	DS: NOTHING
+
+Setup endp
+
+
+
+
+
+
+
+
+
+
+
+;*****************************************************************************
+;
+; Loads the VSA II image into memory
+; NOTE: The System Manager must be the first module of the VSA image. 
+;
+;*****************************************************************************
+ProcessModules proc
+
+	; Point DS:ESI to loaded VSA image
+	lea	bx, [VSA_Image]			; Point DS to start of file image
+	movzx	esi, bx
+	and	si, 000Fh
+	shr	bx, 4
+	mov	ax, cs
+	add	ax, bx
+	mov	ds, ax
+
+	; Point EDI to where System Manager will be loaded
+	mov	edi, cs:[ModuleBase]		; Get last ptr value
+	call	AlignVSM
+	mov	cs:[SysMgrEntry], edi		; Record entry point of System Manager
+
+
+	; Ensure the System Manager is the first module unless loading from DOS
+	mov	ax, ERR_NO_SYS_MGR
+ 	cmp	(VSM_Header PTR [si]).Signature, VSM_SIGNATURE	
+	jne	ErrExit
+ 	cmp	(VSM_Header PTR [si]).VSM_Type, VSM_SYS_MGR
+	je	LoadSysMgr
+
+
+LoadSysMgr:
+	POST	VSA_SYSMGR
+	call	PatchSysMgr			; Apply patches to the System Manager
+
+	;   EDI = flat ptr of System Manager base
+	; DS:SI = near ptr to System Manager image
+	call	CopyModule			; Install System Manager
+	jc	ErrExit
+
+
+
+	; Sequence through each VSM and install it.
+VSM_Loop:
+	mov	eax, VSM_SIGNATURE		; Check for a VSM signature
+ 	cmp	eax, (VSM_Header PTR [si]).Signature
+	jne	short Return
+	call	Load_VSM			; Load the VSM
+	jnc	VSM_Loop
+
+
+ErrExit:or	cs:[Errors], ax
+Return:	ret
+
+ProcessModules endp
+
+
+
+
+
+
+;*****************************************************************************
+; Copies INT vector table to VSA. If installing VSA from DOS, copies the
+; INT_Vector[] from current System Manager to the VSA image being installed.
+;*****************************************************************************
+SnagInterruptVectors proc
+
+Exit:	ret
+
+SnagInterruptVectors endp
+
+
+
+
+
+
+;*******************************************************************
+;
+; Aligns a VSM ptr according to requirements flag
+; Input:
+;   EDI = ptr to be aligned
+; Output:
+;   EDI = aligned ptr
+;
+;*******************************************************************
+AlignVSM proc uses eax
+
+	mov	cx, cs:[Requirments]		; Compute alignment
+	and	cl, MASK Alignment@@tag_i0	; Compute mask from 2^(n+4)
+	add	cl, 4
+	xor	eax, eax
+	mov	al, 1
+	shl	eax, cl
+	dec	eax
+
+	add	edi, eax			; Align the next VSM load address
+	not	eax				; to requested boundary
+	and	edi, eax
+	ret
+
+AlignVSM endp
+
+
+
+
+;*******************************************************************
+; Patches various fields within System Manager
+; INPUT:
+;   SI = ptr to System Manager
+;  EDI = ptr to where System Manager will reside
+;*******************************************************************
+PatchSysMgr proc
+
+	pushad
+
+	;
+	; Patch "jmp <EntryPoint>" over System Manager's VSM signature
+	;
+	mov	ax, (VSM_Header PTR [si]).EntryPoint
+	sub	ax, 3
+	shl	eax, 8
+	mov	al, 0E9h			; JMP opcode
+	mov	(VSM_Header PTR [si]).Signature, eax
+
+	;
+	; Patch SysMgr's Hardware structure
+	;
+	lea     bx, [si+SPECIAL_LOC]
+	mov     bx, (InfoStuff PTR [bx]).HardwareInfo
+	ASSUME  BX: PTR Hardware
+
+	mov	ax, cs:[Device_ID]
+	mov	[bx].Chipset_ID, ax
+	
+	mov	ax, cs:[PCI_MHz]
+	mov	[bx].PCI_MHz, ax
+	
+	movzx	ax, cs:[Chipset_Rev]
+	mov	[bx].Chipset_Rev, ax
+
+	mov	eax, cs:[Chipset_Base]
+	mov	[bx].Chipset_Base, eax
+
+	mov	ax, cs:[Cpu_ID]
+ 	mov	[bx].CPU_ID, ax
+
+	mov	ax, cs:[Cpu_Revision]
+	mov	[bx].CPU_Revision, ax
+
+	mov	ax, cs:[CPU_MHz]
+	mov	[bx].CPU_MHz, ax
+
+	mov	ax, cs:[DRAM_MHz]
+	mov	[bx].DRAM_MHz, ax
+
+	mov	eax, cs:[TotalMemory]
+	mov	[bx].SystemMemory, eax
+
+	mov	eax, cs:[SysMgr_Location]
+	mov	[bx].VSA_Location, eax
+	mov	[si].SysStuff.SysMgr_Ptr, eax
+
+	mov	ax, cs:[VSA_Size]
+	mov	[bx].VSA_Size, ax
+	ASSUME	BX:NOTHING
+
+	;
+	; Patch SysMgr's descriptors
+	;
+	mov	eax, (VSM_Header PTR [si]).DS_Limit 
+	mov	[SysMgrSize], ax
+	lea	bx, (VSM_Header PTR [si])._DS
+	call	Init_Descr
+
+	mov	eax, SYSMGRS_STACK + VSM_STACK_FRAME	
+	lea	bx, (VSM_Header PTR [si])._SS
+	call	Init_Descr
+	
+	;
+	; Initialize the SysMgr's message queue
+	;
+	call	Init_Msg_Q
+
+	;
+	; Patch variables in SysMgr
+	;
+	mov	eax, cs:[Chipset_Base]
+	mov	[si].SysStuff.Southbridge, eax
+
+	mov	bx, si
+	add	si, SPECIAL_LOC
+	ASSUME	SI: PTR InfoStuff
+	
+	movzx	eax, [si].SysMgr_Stack
+	mov	(VSM_Header PTR [bx]).SysStuff.SavedESP, eax
+
+	mov	[si].SysMgr_VSM, edi
+
+	lea	eax, (VSM_Header PTR [edi]).SysStuff.State + sizeof(SmiHeader)
+	add	bx, [si].Header_Addr
+	mov	[bx], eax
+
+	call	Get_SMI_Base
+	mov	[si].SMI_Base, eax
+	
+	call	Get_IRQ_Base
+	mov	[si].IRQ_Base, eax
+
+	
+Exit:
+
+	call	SnagInterruptVectors		; Snapshot INT vectors from current VSA
+
+	popad
+	ret
+
+
+PatchSysMgr endp
+
+
+
+
+;*******************************************************************
+;
+; Loads a VSM into memory
+; Input: 
+;   DS:SI = ptr to VSM to load
+;
+;*******************************************************************
+Load_VSM proc
+
+	POST	VSA_VSM_FOUND
+
+
+	; Initialize the VSM's Header
+	ASSUME	si:PTR VSM_Header
+
+	mov	ax, [si].Flag
+	mov	cs:[Requirments], ax
+	test	ax, MASK SkipMe@@tag_i0
+	jz	LoadIt
+
+Skip_VSM:	
+	add	esi, [si].VSM_Length		; Point to end of this VSM
+	call	Flat_ESI
+	jmp	Next_VSM
+LoadIt:
+
+	; Initialize CPU dependent fields in the VSM's SMM header
+	call	Set_CPU_Fields
+
+
+	; Initialize EIP to VSM's entry point 
+	movzx	ecx, [si].EntryPoint
+	mov	[si].SysStuff.State.Next_EIP, ecx
+
+	or	[si].SysStuff.State.SMI_Flags, VSM_FLAGS
+
+
+	; Store ptrs to certain System Manager structures for fast access
+	mov	eax, cs:[SysMgrEntry]
+	add	eax, SPECIAL_LOC
+	mov	[si].SysStuff.SysMgr_Ptr, eax
+
+	mov	eax, cs:[Chipset_Base]
+	mov	al, SW_SMI
+	mov	[si].SysStuff.Southbridge, eax
+
+
+
+	; Initialize the VSM's resume header
+	; Get size of DS segment
+	mov	eax, [si].DS_Limit		; _DS.limit_15_0
+
+	
+	inc	eax				; Round to WORD boundary
+	and	al, NOT 1
+	mov	ecx, eax
+
+	; Initialize the CS descriptor fields
+	; NOTE: CS descriptor fields in SMM header are in "linear" format.
+	mov	[si].SysStuff.State._CS.limit, ecx
+	mov	[si].SysStuff.State._CS.attr, CODE_ATTR
+
+	mov	[si].SysStuff.State.EFLAGS, VSM_EFLAGS
+	mov	ecx, CR0			; Preserve the CD & NW bit
+	and	ecx, 60000000h
+	or	ecx, VSM_CR0
+	mov	[si].SysStuff.State.r_CR0,  ecx
+	mov	[si].SysStuff.State.r_DR7,  VSM_DR7   
+
+
+	; Determine size of VSM's stack
+	movzx	ecx, [si]._SS.limit_15_0	; Get SS limit
+	or	cx, cx				; Did VSM specify a stack size ?
+	jnz	CheckMemSize
+	mov	cx, VSM_STACK_SIZE	 	; No, use default stack size
+
+;*******************************************************************
+;  SI = ptr to VSM image to be loaded
+; EAX = DS limit
+; ECX = stack size
+;*******************************************************************
+CheckMemSize:
+	add	eax, ecx			; Compute descriptor limits
+	add	ax, 15				; Round up to next paragraph
+	and	al, NOT 15
+	mov	[si].DS_Limit,eax		; Update for use by BIOS scan
+
+	lea	ebx, [edi+eax]			; If not enough memory, skip this VSM
+	cmp	ebx, [VSA_End]
+	jae	Skip_VSM
+	call	AlignVSM
+	mov	cs:[ModuleBase], edi		; Save the VSM module pointer in EDI
+
+
+;*******************************************************************
+;
+; Initialize VSM's descriptors
+;
+;  SI = ptr to VSM image to be loaded
+; EAX = DS limit
+; EDI = Runtime address for this VSM
+;
+;*******************************************************************
+
+
+	; Set VSM's CS selector to <load address> & 0xFFFFF
+	mov	ecx, edi
+	and	ecx, 000FFFFFh
+	shr	ecx, 4
+	mov	[si].SysStuff.State._CS.selector, cx
+
+	mov	[si].SysStuff.State._CS.base, edi
+
+
+	; Initialize the VSM's stack ptr
+	mov	ebx, eax
+	and	bl, 0FCh			; Round DOWN to nearest DWORD
+	sub	bx, VSM_STACK_FRAME
+	mov	[si].SysStuff.SavedESP, ebx
+
+	lea	bx, [si]._DS			; Init DS
+	call	Init_Descr
+
+	lea	bx, [si]._ES			; Init ES
+	call	Init_Descr
+
+	lea	bx, [si]._SS			; Init SS
+	call	Init_Descr
+
+
+	; Initialize the VSM's message queue
+	call	Init_Msg_Q
+	
+ 
+	; Update the doubly linked list of VSMs
+	mov	ebx, edi
+	xchg	ebx, cs:[Blink]
+	or	ebx, ebx			; 1st VSM other than System Manager ?
+	jnz	SetFlink
+
+       	; Store ptr to 1st VSM in the System Manager
+	mov	eax, cs:[SysMgrEntry]
+	mov	es:(VSM_Header PTR [eax]).SysStuff.Flink, edi
+
+	jmp	Setlinks
+
+	; EBX points to previous VSM
+SetFlink:
+	mov	(VSM_Header PTR es:[ebx]).SysStuff.Flink, edi
+Setlinks:
+	mov	[si].SysStuff.Blink, ebx
+
+	mov	eax, cs:[Flink]
+	mov	[si].SysStuff.Flink, eax
+
+	call	CopyModule
+	ret
+
+
+Load_VSM endp
+
+
+END_MSG_QUEUE   equ  (MAX_MSG_CNT)*sizeof(Message)
+
+
+Init_Msg_Q proc
+	
+	mov	bx, offset VSM_Header.SysStuff.MsgQueue
+	mov	[si].SysStuff.Qhead, bx 	; Store queue head ptr
+	mov	[si].SysStuff.Qtail, bx 	; Store queue tail ptr
+	add	bx, END_MSG_QUEUE		; End of queue
+	mov	[si].SysStuff.EndMsgQ, bx
+	ret
+	
+Init_Msg_Q endp	
+
+
+
+
+
+
+
+;*******************************************************************
+;
+; Initializes a descriptor
+; On entry:
+;   BX = ptr to descriptor
+;  EAX = limit
+;  EDI = base
+;
+;*******************************************************************
+Init_Descr proc
+	ASSUME	bx: PTR Descriptor
+
+	push	eax
+	push	edi
+	mov	[bx].limit_15_0, ax		; limit
+	shr	eax, 16	
+	mov	[bx].limit_19_16, al
+ 	mov	[bx].base_15_0, di		; base[15:00]
+	shr	edi, 16
+	mov	ax, di
+	mov	[bx].base_23_16, al		; base[31:16]
+	mov	[bx].base_31_24, ah
+	mov	[bx].attr, DATA_ATTR		; attribute
+	pop	edi
+	pop	eax
+	ret
+
+	ASSUME	bx: NOTHING
+
+Init_Descr endp
+
+
+;*******************************************************************
+;
+; Copies a module to its runtime location.
+; On Entry:
+;    DS:SI - ptr to source
+;   ES:EDI - ptr to destination
+; On Exit:
+;       CF - set if error. AX = error code
+;*******************************************************************
+CopyModule proc
+
+
+
+	; Get length of segment & compute size of BSS
+	mov	ecx, [si].VSM_Length
+	movzx	edx, [si]._DS.limit_15_0
+	sub	edx, ecx
+ 
+
+	call	Flat_ESI
+
+
+	;
+	; Copy the VSM image to its runtime location
+	;
+
+if VERIFY_VSM_COPY
+	push	ecx			; Save byte count & ptrs
+	push	esi
+	push	edi
+endif
+	
+	POST	VSA_COPY_START		; 14h
+
+	mov	ah, cl
+	shr	ecx, 2			; Convert BYTE count to DWORD count
+	cld
+	rep	movsd [edi], es:[esi]
+
+	and	ah, 3 			; Copy remaining bytes
+	mov	cl, ah
+	rep	movsb [edi], es:[esi]
+
+	POST	VSA_COPY_END		; 15h
+
+if VERIFY_VSM_COPY
+
+	pop	edi			; Restore original ptrs and byte count 
+	pop	esi
+	pop	ecx
+
+	;
+	; Verify the VSM image copy
+	;
+	mov	ebx, edi		; Save ptr to start of VSM
+	shr	ecx, 2			; Convert byte count to dword count
+
+	POST	VSA_VRFY_START           ; 1Ch
+
+	repe    cmpsd es:[esi], [edi]
+	jne	VerifyError
+
+	mov	cl, ah			; Compare leftover byte(s)
+	repe    cmpsb es:[esi], [edi]
+	je	Verify_Passed
+
+VerifyError:
+
+	mov	ax, ERR_VERIFY
+	stc
+	jmp	Exit
+	
+Verify_Passed:
+	POST	VSA_VRFY_END		; 1Dh
+
+endif  ; VERIFY_VSM_COPY
+
+
+
+
+	POST	VSA_FILL_START
+
+	;
+	; Clear the uninitialized data space
+	;
+	mov	ecx, edx		; Fill BSS with zeros
+	shr	ecx, 2
+	xor	eax, eax
+	rep	stosd [edi]
+	mov	cl, dl
+	and	cl, 3
+	je	BSS_Cleared
+	rep	stosb [edi]
+BSS_Cleared:
+
+
+	POST	VSA_FILL_END
+	
+
+
+
+	; Search the image for the next VSM.
+	; Some VSMs lie about their size.  Search a byte at a time
+	; for 'VSM ', first backward, then forward.
+Next_VSM::
+	mov	edx, -1			; Start search backwards
+MAX_SEARCH  equ 16
+Search:
+	mov	cx, MAX_SEARCH		; Range in bytes to scan for VSM
+
+SearchNext:
+	cmp	dword ptr es:[esi], VSM_SIGNATURE
+	je	NextVSMfound
+	add	esi, edx 
+	loop	SearchNext
+
+	add	esi, MAX_SEARCH
+	neg	edx			; Look the other direction
+ 	cmp	dl, 1			; Have we already looked in that direction ?
+	je	Search
+	jmp	OK_Exit			; No more VSMs found
+
+
+NextVSMfound:
+
+	; Convert ESI into DS:SI format
+	mov	edx, esi
+	shr	edx, 4
+	mov	ds, dx
+	and	esi, 0000000Fh
+OK_Exit:
+	clc
+Exit:	ret
+
+
+
+CopyModule endp
+
+
+;*******************************************************************
+; Converts DS:SI to a flat ptr in ESI.
+;*******************************************************************
+Flat_ESI proc
+
+	push	eax
+	mov	ax, ds			; Convert DS:SI to a flat ptr
+	movzx	eax, ax
+	shl	eax, 4
+	movzx	esi, si
+	add	esi, eax
+	pop	eax
+	ret
+
+Flat_ESI endp
+
+
+BIOS_ECX	dd	0
+BIOS_EDX	dd	0
+TotalMemory	dd	0
+SysMgr_Location dd	0
+VSA_End	dd	0
+Chipset_Base	dd	0
+SysMgrEntry	dd	00000000h
+ModuleBase	dd	00000000h
+Blink		dd	00000000h
+Flink		dd	00000000h
+InitParam1	dd	0
+InitParam2	dd	0
+
+SysMgrSize	dw	0
+VSA_Size	dw	0
+Errors	 	dw	0
+Device_ID	dw	0
+Cpu_ID		dw	0
+Cpu_Revision	dw	0
+SysCall_Code	dw	SYS_BIOS_INIT
+Requirments	dw	0
+CPU_MHz	dw	0
+PCI_MHz	dw	0
+DRAM_MHz	dw	0
+Chipset_Rev	db	0
+SetupComplete	db	0
+LoadFlag	db	0
+
+Flat_Descriptor	Descriptor {0FFFFh, 0000h, 00h, DATA_ATTR, 8Fh, 00h, 0}
+
+Msg_CompareError	db	"...compare error at 0x$"
+Msg_Not_DOS_BUILD	db	CR,LF, "This version of INIT doesn't support DOS install.$"
+
+
+	END VSA_Installation
+
+
+


Property changes on: trunk/gplvsa2/sysmgr/init.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/init.h
===================================================================
--- trunk/gplvsa2/sysmgr/init.h	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/init.h	2009-03-20 18:32:39 UTC (rev 1)
@@ -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)
+


Property changes on: trunk/gplvsa2/sysmgr/init.h
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/io.c
===================================================================
--- trunk/gplvsa2/sysmgr/io.c	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/io.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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);
+  }
+}


Property changes on: trunk/gplvsa2/sysmgr/io.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/io_trap.c
===================================================================
--- trunk/gplvsa2/sysmgr/io_trap.c	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/io_trap.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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);
+  }
+}


Property changes on: trunk/gplvsa2/sysmgr/io_trap.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/makefile
===================================================================
--- trunk/gplvsa2/sysmgr/makefile	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/makefile	2009-03-20 18:32:39 UTC (rev 1)
@@ -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):
+	- at 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
+


Property changes on: trunk/gplvsa2/sysmgr/makefile
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/mapper.c
===================================================================
--- trunk/gplvsa2/sysmgr/mapper.c	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/mapper.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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++;
+  }
+}
+


Property changes on: trunk/gplvsa2/sysmgr/mapper.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/mapper.h
===================================================================
--- trunk/gplvsa2/sysmgr/mapper.h	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/mapper.h	2009-03-20 18:32:39 UTC (rev 1)
@@ -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
+
+


Property changes on: trunk/gplvsa2/sysmgr/mapper.h
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/mbiu.c
===================================================================
--- trunk/gplvsa2/sysmgr/mbiu.c	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/mbiu.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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++;
+}
+
+
+
+
+
+
+


Property changes on: trunk/gplvsa2/sysmgr/mbiu.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/mbus.c
===================================================================
--- trunk/gplvsa2/sysmgr/mbus.c	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/mbus.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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;
+}


Property changes on: trunk/gplvsa2/sysmgr/mbus.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/mdd.c
===================================================================
--- trunk/gplvsa2/sysmgr/mdd.c	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/mdd.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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);
+    }
+  }
+}


Property changes on: trunk/gplvsa2/sysmgr/mdd.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/mdd.h
===================================================================
--- trunk/gplvsa2/sysmgr/mdd.h	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/mdd.h	2009-03-20 18:32:39 UTC (rev 1)
@@ -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)
+


Property changes on: trunk/gplvsa2/sysmgr/mdd.h
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/message.asm
===================================================================
--- trunk/gplvsa2/sysmgr/message.asm	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/message.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -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
+
+
+


Property changes on: trunk/gplvsa2/sysmgr/message.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/mfgpt.c
===================================================================
--- trunk/gplvsa2/sysmgr/mfgpt.c	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/mfgpt.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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);
+}
+


Property changes on: trunk/gplvsa2/sysmgr/mfgpt.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/msr.asm
===================================================================
--- trunk/gplvsa2/sysmgr/msr.asm	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/msr.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -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


Property changes on: trunk/gplvsa2/sysmgr/msr.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/ohci.c
===================================================================
--- trunk/gplvsa2/sysmgr/ohci.c	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/ohci.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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;
+}


Property changes on: trunk/gplvsa2/sysmgr/ohci.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/pci_pm.c
===================================================================
--- trunk/gplvsa2/sysmgr/pci_pm.c	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/pci_pm.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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


Property changes on: trunk/gplvsa2/sysmgr/pci_pm.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/pci_rd.c
===================================================================
--- trunk/gplvsa2/sysmgr/pci_rd.c	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/pci_rd.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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;
+}   
+
+
+


Property changes on: trunk/gplvsa2/sysmgr/pci_rd.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/pci_wr.c
===================================================================
--- trunk/gplvsa2/sysmgr/pci_wr.c	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/pci_wr.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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;
+}
+
+
+


Property changes on: trunk/gplvsa2/sysmgr/pci_wr.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/port92.asm
===================================================================
--- trunk/gplvsa2/sysmgr/port92.asm	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/port92.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -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


Property changes on: trunk/gplvsa2/sysmgr/port92.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/protos.h
===================================================================
--- trunk/gplvsa2/sysmgr/protos.h	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/protos.h	2009-03-20 18:32:39 UTC (rev 1)
@@ -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);
+
+
+


Property changes on: trunk/gplvsa2/sysmgr/protos.h
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/smimac.mac
===================================================================
--- trunk/gplvsa2/sysmgr/smimac.mac	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/smimac.mac	2009-03-20 18:32:39 UTC (rev 1)
@@ -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
+
+


Property changes on: trunk/gplvsa2/sysmgr/smimac.mac
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/smis.asm
===================================================================
--- trunk/gplvsa2/sysmgr/smis.asm	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/smis.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -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
+


Property changes on: trunk/gplvsa2/sysmgr/smis.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/sw_int.asm
===================================================================
--- trunk/gplvsa2/sysmgr/sw_int.asm	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/sw_int.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -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


Property changes on: trunk/gplvsa2/sysmgr/sw_int.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/swapsif.c
===================================================================
--- trunk/gplvsa2/sysmgr/swapsif.c	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/swapsif.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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);
+  }
+}
\ No newline at end of file


Property changes on: trunk/gplvsa2/sysmgr/swapsif.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/syscalls.asm
===================================================================
--- trunk/gplvsa2/sysmgr/syscalls.asm	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/syscalls.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -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
+
+
+


Property changes on: trunk/gplvsa2/sysmgr/syscalls.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/sysmgr.asm
===================================================================
--- trunk/gplvsa2/sysmgr/sysmgr.asm	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/sysmgr.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -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
+


Property changes on: trunk/gplvsa2/sysmgr/sysmgr.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/sysmgr.h
===================================================================
--- trunk/gplvsa2/sysmgr/sysmgr.h	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/sysmgr.h	2009-03-20 18:32:39 UTC (rev 1)
@@ -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;


Property changes on: trunk/gplvsa2/sysmgr/sysmgr.h
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/timeout.c
===================================================================
--- trunk/gplvsa2/sysmgr/timeout.c	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/timeout.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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);
+  }
+}
+
+


Property changes on: trunk/gplvsa2/sysmgr/timeout.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/timer.c
===================================================================
--- trunk/gplvsa2/sysmgr/timer.c	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/timer.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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);
+    
+  }
+}
+
+


Property changes on: trunk/gplvsa2/sysmgr/timer.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/timer.h
===================================================================
--- trunk/gplvsa2/sysmgr/timer.h	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/timer.h	2009-03-20 18:32:39 UTC (rev 1)
@@ -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
+


Property changes on: trunk/gplvsa2/sysmgr/timer.h
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/topology.c
===================================================================
--- trunk/gplvsa2/sysmgr/topology.c	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/topology.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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
+};
+
+


Property changes on: trunk/gplvsa2/sysmgr/topology.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/unregstr.c
===================================================================
--- trunk/gplvsa2/sysmgr/unregstr.c	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/unregstr.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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];
+    }
+  }
+}
+


Property changes on: trunk/gplvsa2/sysmgr/unregstr.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/utils.asm
===================================================================
--- trunk/gplvsa2/sysmgr/utils.asm	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/utils.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -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


Property changes on: trunk/gplvsa2/sysmgr/utils.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/virt_pci.c
===================================================================
--- trunk/gplvsa2/sysmgr/virt_pci.c	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/virt_pci.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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;
+}
+
+
+
+


Property changes on: trunk/gplvsa2/sysmgr/virt_pci.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/vpci.h
===================================================================
--- trunk/gplvsa2/sysmgr/vpci.h	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/vpci.h	2009-03-20 18:32:39 UTC (rev 1)
@@ -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 
+*/
+
+
+#define UNIMPLEMENTED_FUNCTION  0
+#define UNIMPLEMENTED_REGISTER  1
+
+
+struct vpci_header {
+  unsigned char Reg;				   // Register offset (DWORD aligned)
+  unsigned char Flag;				   // See flag fields below
+  union {
+    unsigned long Value;			   // Current value of register
+    struct {
+      unsigned short Value_LO;
+      unsigned short Value_HI;
+    };
+	struct {
+      unsigned short Vendor_ID;		   // Register 0x00
+      unsigned short Device_ID;
+    };
+	struct {						   // Register 0x08
+      unsigned char Revision_ID;
+      unsigned char Interface;
+	  union {
+        struct {
+          unsigned char SubClass;
+          unsigned char BaseClass;
+        };
+        unsigned short Class;     
+      };
+    };
+	struct {						   // Register 0x0C
+      unsigned char CacheLineSize;
+      unsigned char LatencyTimer;
+      unsigned char HeaderType;
+      unsigned char Bist;
+    };
+	struct {						   // BARs
+	  union {
+        unsigned short IO_Base;
+        unsigned long  Memory_Base;
+      };       
+    };
+	struct {						   // Register 0x3C
+      unsigned char Interrupt_Line;
+      unsigned char Interrupt_Pin;
+      unsigned char Min_Gnt;
+      unsigned char Max_Gnt;
+    };
+	struct {						   // EHCI register 0x54
+      unsigned char EHCI_SMI_Enables;
+      unsigned char reserved1;
+      unsigned char EHCI_Errors;
+      unsigned char reserved2;
+    };
+	struct {						   // EHCI register 0x60
+      unsigned char SRBN;
+      unsigned char FLADJ;
+      unsigned short PORTWAKECAP;
+    };
+  };
+  unsigned long Mask;				   // 0 = R/O   1 = R/W
+  unsigned char LBar;				   // MSR offset of LBAR, if required
+  unsigned char Link;				   // Index of 1st MSR in chain
+  unsigned long WriteToClear;		   // 0 = N/A   1 = W/C
+
+};
+
+typedef struct vpci_header PCI_HEADER_ENTRY ;
+
+
+//   Device                     MSRs used to implement a BAR
+// ------------	   --------------------------------------------------------------
+// Northbridge     MBIUx descriptor
+// Graphics        MBIU0 descriptor    MBIU1 (for FS2)         RCONF
+// Southbridge     LBAR
+// IDE             MBIU2 descriptor	   Region config      
+// OHCI            MBIU2 to OHCI       MBIU2 to KEL (P2D_BMK)  MDD LBAR
+
+// PCI_HEADER_ENTRY.Flag definitions:
+#define EOL         (1 << 7)   // End of list
+#define PCI_EHCI    (1 << 6)   // EHCI (NOTE: leverages same bit as PCI_PM)
+#define PCI_PM      (1 << 6)   // PCI Power Management
+#define USE_BMK     (1 << 5)   // P2D_BMK needs Bizarro bit set
+#define IO_BAR      (1 << 4)   // BAR is I/O
+#define MEM_BAR     (1 << 3)   // BAR is memory
+#define MMIO_BAR    (1 << 2)   // BAR is memory-mapped I/O
+#define EPCI_W      (1 << 1)   // Embedded PCI: write to h/w
+#define EPCI_R      (1 << 0)   // Embedded PCI: read from h/w
+#define EPCI_RW     (EPCI_R | EPCI_W)
+
+typedef PCI_HEADER_ENTRY * VIRTUAL_DEVICE;
+typedef VIRTUAL_DEVICE *   VIRTUAL_PTR;
+
+#define MAX_DESCR   110        // Max. # for all descriptor types in all MBIUs
+#define DESCRIPTOR_NOT_FOUND 0
+
+
+
+// NOTE: A copy of this structure exists in INIT.ASM
+typedef struct {
+  unsigned char Type;          // Type of MSR
+  unsigned char Flag;          // See definitions below
+  unsigned char Link;          // Link to next MSR
+  unsigned char Split;         // Index of descriptor that was split
+
+  unsigned short Owner;        // PCI Address this descriptor belongs to
+  unsigned char Mbiu;          // MBUI on which this descriptor is located
+  unsigned char Port;          // Port this descriptor routes to
+
+  unsigned long MsrAddr;       // Routing address of MSR (descriptor/LBAR/RCONF)
+  unsigned long Physical;      // Physical memory assigned  (00000000 if none)
+  unsigned long Range;         // Actual I/O range for IOD_SC
+  unsigned long MsrData[2];
+  unsigned short Address;      // Address of I/O Trap or Timeout
+} DESCRIPTOR;
+
+
+// DESCRIPTOR.Flag definitions
+#define IO_TIMEOUT  (1 << 2)   // Descriptor is used for I/O timeout
+#define IO_TRAP     (1 << 1)   // Descriptor is used for I/O trap
+#define AVAILABLE   (1 << 0)   // Descriptor is available
+
+
+
+
+
+typedef struct {
+  unsigned char NP2D_BM;
+  unsigned char NP2D_BMO;
+  unsigned char NP2D_R;
+  unsigned char NP2D_RO;
+  unsigned char NP2D_SC;
+  unsigned char NP2D_SCO;
+  unsigned char NP2D_BMK;
+  unsigned char NIOD_BM;
+  unsigned char NIOD_SC;
+  unsigned char NPORTS;
+  unsigned char NSTATS;
+} CAPABILITIES;
+
+
+
+
+
+
+// External function prototypes:
+void pascal Read_MSR(unsigned long, unsigned long *);
+void pascal Write_MSR(unsigned long, unsigned long *);
+void pascal Write_MSR_LO(unsigned long, unsigned long);
+void pascal MergeFields(unsigned long *, unsigned long, unsigned long, unsigned long);
+void pascal Parse_Capabilities(unsigned long *, CAPABILITIES *);
+void pascal Free_Descriptor(unsigned char Index);
+void pascal Update_BAR(PCI_HEADER_ENTRY *, unsigned char);
+unsigned char pascal Allocate_Descriptor(unsigned char, unsigned char, unsigned long);
+unsigned long pascal Read_MSR_LO(unsigned long);
+unsigned long pascal Find_MBus_ID(unsigned short, unsigned char);


Property changes on: trunk/gplvsa2/sysmgr/vpci.h
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/vr.c
===================================================================
--- trunk/gplvsa2/sysmgr/vr.c	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/vr.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -0,0 +1,356 @@
+/*
+* 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 virtual register handler 
+//******************************************************************************
+
+#include "VSA2.H"
+#include "PROTOS.H" 
+#include "SYSMGR.H"
+#include "VR.H"
+#include "PCI.H" 
+#include "CHIPSET.H"
+
+// External variables
+extern ULONG Saved_EAX;
+extern USHORT Saved_AX;
+extern SmiHeader SMM_Header;
+extern ULONG IRQ_Mask;
+extern ULONG Audio_IRQ;
+extern ULONG NativeAudioStatus;
+extern ULONG MsgPacket[];
+extern ULONG VSM_Ptrs[];
+extern Hardware	HardwareInfo;
+
+
+// External function prototypes
+extern void pascal Send_Synchronous_Event(EVENT, SmiHeader *);
+extern void pascal VR_Miscellaneous_Write(UCHAR);
+extern void pascal Return_Virtual_Value(SmiHeader *, ULONG);
+extern ULONG pascal VR_Miscellaneous_Read(UCHAR);
+
+
+
+
+//***********************************************************************
+// Initialize virtual register trapping
+//***********************************************************************
+void Init_Virtual_Regs(void) 
+{ USHORT PCI_Addr;
+  ULONG Enable;
+
+
+  // Allocate a 4-byte I/O BAR0 associated with Northbridge header
+  PCI_Addr = Allocate_BAR(RESOURCE_SCIO, BAR0, 4, 0x0000, HardwareInfo.CPU_ID);
+
+  // Set the base address  
+  Virtual_PCI_Write_Handler(PCI_Addr, DWORD_IO, VRC_INDEX);
+
+  // Enable the I/O space
+  PCI_Addr = (PCI_Addr & 0xFF00) + COMMAND;
+  Enable = Virtual_PCI_Read_Handler(PCI_Addr);   
+  Enable |= IO_SPACE;
+  Virtual_PCI_Write_Handler(PCI_Addr, DWORD_IO, Enable);
+
+
+}
+
+//***********************************************************************
+// Handles audio virtual registers when there is no audio VSM.
+//***********************************************************************
+void Handle_Audio_VRC(UCHAR Index, ULONG Trapped_Data, USHORT Trapped_Flags, UCHAR Size)
+{ static USHORT AudioVRs[MAX_AUDIO+1] = {
+    0x201,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xAC97,0xFFFF,0xFFFF,0xFFFF,0x04F0
+  };
+
+
+
+  // If illegal register, ignore it
+  if (Index > MAX_AUDIO) {
+    return;
+  }
+
+  if (Trapped_Flags & SMI_FLAGS_OUTPUT) {
+
+    switch (Index) {
+
+      // Read-only registers
+      case CODEC_TYPE:
+      case AUDIO_VERSION:
+        return;
+
+      // Native audio IRQ                
+      case AUDIO_IRQ:
+
+        // Set previous audio IRQ to external
+        IRQ_Mask |= Audio_IRQ << 16;
+
+        Audio_IRQ = 0;
+        if ((UCHAR)Trapped_Data) {
+          Audio_IRQ = 0x00000001L << (UCHAR)Trapped_Data;
+        }
+        break;
+
+      // Native audio status pointer
+      case STATUS_PTR:
+        switch (SMM_Header.data_size) {
+
+          case WORD_IO:
+            (USHORT)NativeAudioStatus = (USHORT)Trapped_Data;
+            break;
+
+          case DWORD_IO:
+            NativeAudioStatus = Trapped_Data;
+            break;
+        }
+        break;
+    }
+
+    AudioVRs[Index] = (USHORT)Trapped_Data; 
+
+  } else {
+    // Return virtual register value
+    Saved_AX = AudioVRs[Index];
+    // STATUS_PTR may be read as a DWORD
+    if (Index == STATUS_PTR && DWORD_IO == Size) {
+      Saved_EAX = NativeAudioStatus;
+    }
+  }
+}
+
+
+typedef struct {
+  union {
+    USHORT ClassIndex;
+    struct {
+      UCHAR Index;
+      UCHAR Class;
+    };
+  };
+} CLASS_INDEX;
+
+
+typedef struct {
+  union {
+    ULONG Dword;
+    struct {
+      USHORT Word0;
+      USHORT Word1;
+    };
+    struct {
+      UCHAR Byte0;
+      UCHAR Byte1;
+      UCHAR Byte2;
+      UCHAR Byte3;
+    };
+  };
+} DWORD;
+
+#define VR_LOCKED   0
+#define VR_UNLOCKED 1
+#define VR_INDEXED  2
+
+//***********************************************************************
+// Handles accesses to Virtual Registers
+//***********************************************************************
+void VR_Handler(SmiHeader * SmiHdr)
+{ USHORT Trapped_Addr;
+  ULONG Data, SegOffset;
+  UCHAR Trapped_Flags, IO_Write, Addr_2LSBs, Size;
+  DWORD Trapped_Data;
+  static UCHAR VR_LockState = 0;
+  static CLASS_INDEX VirtReg;
+
+  // Get info from SMM header
+  Trapped_Addr  = (USHORT)SmiHdr->IO_addr;
+  Trapped_Flags = (UCHAR)SmiHdr->SMI_Flags_Ushort;
+  IO_Write      = (UCHAR)Trapped_Flags & SMI_FLAGS_OUTPUT ? 1 : 0;
+  Size          = (UCHAR)SmiHdr->data_size;
+  Addr_2LSBs    = (UCHAR)Trapped_Addr & 3;
+  Trapped_Data.Dword  = SmiHdr->write_data;
+
+  SegOffset  = (ULONG) SmiHdr->_CS.selector << 16;
+  SegOffset += (USHORT)SmiHdr->Current_EIP;
+
+
+  // Validate the I/O as a valid virtual register access
+  switch (Size) {
+
+    case DWORD_IO:
+      // Allow unlock & index to occur in a single SMI
+      if (VR_LockState == VR_LOCKED) {
+        if (IO_Write && (VR_UNLOCK == Trapped_Data.Word1)) {
+          VirtReg.ClassIndex = Trapped_Data.Word0;
+          VR_LockState = VR_INDEXED;
+          return;
+        }
+      }
+
+    case BYTE_IO:
+      // Byte I/O is illegal for virtual registers.  Start over.
+      VR_LockState = VR_LOCKED;
+      return;
+
+  } // end switch(Size)
+
+
+  switch(Addr_2LSBs) {
+
+    // Virtual register INDEX
+    case 0:
+
+      switch (VR_LockState) {
+
+        // Virtual registers have been unlocked & Class:Index has been written,
+        // but VR class::index is being re-written.
+        case VR_INDEXED:
+          if (!IO_Write) {
+            goto ReturnClassIndex;
+          }
+          VR_LockState = VR_LOCKED;
+
+        // Virtual registers have not been unlocked yet
+        case VR_LOCKED:
+          if (IO_Write) {
+            if (VR_UNLOCK == Trapped_Data.Word0) {
+              // Virtual registers have been unlocked.
+              // Advance to the next VR_LockState.
+              VR_LockState = VR_UNLOCKED;
+            }
+          }
+          return;
+ 
+        // Virtual registers have been unlocked.
+        // Next VR write should be Class::Index
+        case VR_UNLOCKED:
+          if (IO_Write) {
+
+            // Record the VR index & advance to the next VR_LockState
+            VirtReg.ClassIndex = Trapped_Data.Word0;
+
+
+            // Report error if illegal VR class
+            if (VirtReg.Class > MAX_VR_CLASS && VirtReg.Class < 0x80) {
+              Log_Error("Invalid virtual register class 0x%02X", VirtReg.Class);
+              goto VR_Error;
+            }
+
+            VR_LockState = VR_INDEXED;
+
+          } else {
+ReturnClassIndex:
+            // Reading back Class::Index
+            Return_Virtual_Value(SmiHdr, (ULONG)VirtReg.ClassIndex);
+          }
+          return;
+
+
+      } // end switch (VR_LockState)
+
+      Log_Error("Incorrect virtual register sequence");
+      goto VR_Error;
+
+
+    // Virtual register DATA
+    case 2:
+      if (VR_INDEXED == VR_LockState) {
+        switch (VirtReg.Class) {
+
+          case VRC_MISCELLANEOUS:
+
+            if (IO_Write) {
+
+              VR_Miscellaneous_Write(VirtReg.Index);
+
+            } else {
+
+              Data = VR_Miscellaneous_Read(VirtReg.Index);
+
+              switch (VirtReg.Index) {
+                case SIGNATURE:
+                case HIGH_MEM_ACCESS:
+                  (UCHAR)SmiHdr->data_size = DWORD_IO;
+
+                case VSA_VERSION_NUM:
+                case VSM_VERSION:
+                  // Return virtualized PCI device value to the right environment                     
+                  Return_Virtual_Value(SmiHdr, Data);
+                  break;
+              }
+            }
+            // If access was to an invalid MSR, ignore the SSMI_FLAG
+            if (VirtReg.Index == MSR_ACCESS) {
+              SmiHdr->SMI_Flags.IO_Trap = 0;
+              SmiHdr->SMI_Flags.Ext_IO_Trap = 0;
+            }
+            break;
+
+
+          default:
+
+            // Prepare message packet
+            MsgPacket[1] = (ULONG)VirtReg.ClassIndex;
+            MsgPacket[2] = 0;        		// Assume I/O read
+            MsgPacket[3] = 0;
+            if (IO_Write) {
+              (UCHAR) MsgPacket[2] = 1;		// I/O write
+              (USHORT)MsgPacket[3] = Trapped_Data.Word0;
+            }
+            // Send EVENT_VIRTUAL_REGISTER to registered VSM(s)
+            Send_Synchronous_Event(EVENT_VIRTUAL_REGISTER, SmiHdr);
+            break;
+
+        } // switch (Class)
+
+      } else {
+        static UCHAR * RdWr[] = {"Read", "Write"};
+
+        Log_Error("%s of locked VR %02X:%02X at %04X:%08X ", RdWr[IO_Write], VirtReg.Class, VirtReg.Index, SmiHdr->_CS.selector, SmiHdr->Current_EIP);
+VR_Error:
+
+
+        // Ignore writes. Return 0's for reads.
+        if (!IO_Write) {
+          // NOTE: We know it is a WORD_IO from above validation.
+          Saved_AX = 0;
+        }
+      }
+      break;
+
+    default:
+      // Report mis-aligned access to virtual register
+      Log_Error("Mis-aligned access to virtual register 0x04X", Trapped_Addr);
+      break;
+  }	// end switch(Addr_2LSBs)
+
+  // Reset the VR state machine
+  VR_LockState = VR_LOCKED;
+
+}
+
+
+
+
+
+
+
+
+
+						   
\ No newline at end of file


Property changes on: trunk/gplvsa2/sysmgr/vr.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/vr_misc.asm
===================================================================
--- trunk/gplvsa2/sysmgr/vr_misc.asm	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/vr_misc.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -0,0 +1,1161 @@
+; 
+; 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 virtual register VR_MISCELLANEOUS.
+;******************************************************************************
+
+
+.model tiny,c
+.586
+.CODE
+
+include VSA2.INC
+include SYSMGR.INC
+include VR.INC
+include CHIPSET.INC
+include GX2.INC
+
+externdef	MsgPacket:	          byte
+externdef	HistoryStart:             word
+externdef	HistoryEnd:               word
+externdef	HistoryWrap:              word
+externdef	SysMgr_VSM:	          dword
+externdef	VSM_Ptrs:	          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_DS:	          dword
+externdef	Saved_ES:	          dword
+externdef	Saved_FS:	          dword
+externdef	Saved_GS:	          dword
+externdef	Saved_SS:	          dword
+externdef	IDT_Selector:		  dword
+externdef	IDT_Base:		  dword
+externdef	IDT_Limit:		  dword
+externdef	VSM_ListHead:             dword
+
+externdef	pascal Get_MSR_Linkage:   proc
+externdef	pascal Broadcast_Message: proc 
+externdef	pascal Register_Event:    proc
+externdef	Get_Errors:               proc
+externdef	VirtualRegisterEvent:     proc
+externdef	HardwareInfo:	          Hardware
+externdef	History:	          EVENT_HISTORY
+externdef	Events:		          EVENT_ENTRY
+externdef	SMM_Header:	          SmiHeader
+
+; Required for OHCI h/w bugs
+externdef	OHCI1_Hdr:                dword
+externdef	OHCI2_Hdr:                dword
+externdef	OHCI1_Smi:                dword
+externdef	OHCI2_Smi:                dword
+
+;******************************************************************************
+	align	2
+
+public VSM_Filter
+VSM_Filter	db	VSM_ANY
+		db	0		; Pad for alignment
+Next_VSM   	dd	0
+
+
+
+ReadMiscTable:
+	dw	OFFSET Get_VSA_Version   ; 0
+	dw	OFFSET Read_High_Memory  ; 1
+	dw	OFFSET Get_VSM_Info      ; 2
+	dw	OFFSET Signature         ; 3
+	dw	OFFSET Get_HW_Info       ; 4
+	dw	OFFSET Get_VSM_Version   ; 5
+	dw	OFFSET JustReturn        ; 6
+	dw	OFFSET MSR_Read          ; 7
+	dw	OFFSET JustReturn	 ; 8
+MAX_READ  equ ($-ReadMiscTable)/2
+
+WriteMiscTable:
+	dw	OFFSET JustReturn        ; 0
+	dw	OFFSET Write_High_Memory ; 1	
+	dw	OFFSET JustReturn        ; 2
+	dw	OFFSET JustReturn        ; 3
+	dw	OFFSET Select_HW_Info    ; 4
+	dw	OFFSET JustReturn        ; 5
+	dw	OFFSET Warm_Boot         ; 6
+	dw	OFFSET MSR_Write         ; 7
+	dw	OFFSET Do_WBINVD	 ; 8
+MAX_WRITE  equ ($-WriteMiscTable)/2
+
+
+VSM_Info_Table:
+	dw	OFFSET Get_VSM_Basics
+	dw	OFFSET Get_VSM_Events
+	dw	OFFSET Get_VSM_Statistics
+	dw	OFFSET Get_VSM_History
+	dw	OFFSET Get_VSM_Hardware
+	dw	OFFSET Get_Errors
+	dw	OFFSET Set_VSM_Type
+	dw	OFFSET Get_Linkage
+MAX_INFO equ  ($-VSM_Info_Table)/2
+
+
+
+;***************************************************************************
+; Handler for reads from a VRC_MISCELLANEOUS register
+; Returns ULONG with value read
+;***************************************************************************
+VR_Miscellaneous_Read proc pascal uses si di \
+	Index: BYTE
+
+	mov	al, [Index]
+	cmp	al, MAX_READ
+	mov	di, 0			; Read
+	jae	short VRC_Common
+
+	lea	bx, [ReadMiscTable]
+	call	Dispatch
+	ret
+
+VR_Miscellaneous_Read endp
+
+
+;***************************************************************************
+; Handler for writes to a VRC_MISCELLANEOUS register
+;***************************************************************************
+VR_Miscellaneous_Write proc pascal uses si di \
+	Index: BYTE
+
+	mov	al, [Index]
+	cmp	al, MAX_WRITE
+	jb	short UseTable
+	mov	di, 1			; Write
+VRC_Common::	
+	mov	bh, VRC_MISCELLANEOUS
+	mov	bl, al
+	mov	edx, [SysMgr_VSM]	; From_VSM
+	mov	cx, word ptr [Saved_EAX]
+	call	VirtualRegisterEvent
+	jmp	short Exit
+		
+UseTable:
+	lea	bx, [WriteMiscTable]
+	call	Dispatch
+Exit:	ret
+
+VR_Miscellaneous_Write endp
+
+;***************************************************************************
+; Dispatches to routine defined by table at BX[AL]
+;***************************************************************************
+Dispatch proc
+
+	xor	ah, ah
+	add	ax, ax
+	add	bx, ax
+	call	word ptr [bx]
+JustReturn::
+	ret
+Dispatch endp
+
+
+
+
+;***************************************************************************
+; Dispatches to sub-function of GET_VSM_INFO (determined by caller's BL)
+;***************************************************************************
+Get_VSM_Info proc
+
+	mov	al, byte ptr [Saved_EBX]
+	cmp	al, MAX_INFO
+	jae	short Exit
+	lea	bx, [VSM_Info_Table]
+	call	Dispatch
+Exit:	ret
+
+Get_VSM_Info endp
+
+
+;***************************************************************************
+; SI = PCI address
+;***************************************************************************
+Get_Linkage proc
+
+
+	push	word ptr [Saved_ESI]
+	call	Get_MSR_Linkage
+
+	mov	word ptr [Saved_ECX], ax	; Return MSR address in caller's ECX
+	mov	word ptr [Saved_ECX+2], dx
+	
+	ret	
+
+Get_Linkage endp
+
+
+;***************************************************************************
+; Returns in EAX the location by EBX.
+; CF is toggled
+;***************************************************************************
+Read_High_Memory proc
+
+	mov	ebx, [Saved_EBX]
+	mov	eax, fs:[ebx]
+	mov	[Saved_EAX], eax
+	mov	edx, eax
+	shr	edx, 16
+
+	; Toggle the caller's carry flag
+	xor	byte ptr ([SMM_Header]).EFLAGS, EFLAGS_CF
+	ret
+
+Read_High_Memory endp
+
+;***************************************************************************
+; Modifies a memory location according to:
+;   *EBX = *EBX & ESI | EDI;
+;   CF is toggled
+;***************************************************************************
+Write_High_Memory proc
+
+	mov	ebx, [Saved_EBX]	; Address
+	mov	edx, [Saved_ESI]	; AND mask
+	mov	eax, [Saved_EDI]	; OR mask
+	or	edx, edx
+	jz	short WriteBack
+
+	mov	ecx, fs:[ebx]
+	and	ecx, edx
+	or	eax, ecx
+WriteBack:
+	mov	fs:[ebx], eax
+	; Toggle the caller's carry flag
+	xor	byte ptr ([SMM_Header]).EFLAGS, EFLAGS_CF
+	ret
+
+Write_High_Memory endp
+
+
+
+
+;***************************************************************************
+; Modifies an MSR
+; On entry:
+;       ECX = MSR address
+;   ESI:EDI = AND mask
+;   EBX:EAX = OR mask
+; On exit:
+;   CF is toggled
+;***************************************************************************
+MSR_Write proc
+
+	mov	ecx, [Saved_ECX]	; Get MSR address
+	call	Read_MSR
+
+	and	edx, [Saved_ESI]	; Apply AND mask
+	and	eax, [Saved_EDI]
+	or	edx, [Saved_EBX]	; Apply OR mask
+	or	eax, [Saved_EAX]
+
+	test	ecx, 0E0000000h
+	jnz	Not_CPU_MSR
+	stc				; Indicate this is a WRMSR
+	call	MSR_Handler		; Update the MSR
+	jmp	short Exit
+
+Not_CPU_MSR:
+	wrmsr
+	; Toggle the caller's carry flag
+Exit:	xor	byte ptr ([SMM_Header]).EFLAGS, EFLAGS_CF
+	ret
+
+MSR_Write endp
+
+
+
+
+
+
+;***************************************************************************
+; Reads an MSR
+; On entry:
+;     ECX = MSR address
+; On exit:
+;     EDX:EAX = MSR data
+;     CF is toggled
+;***************************************************************************
+MSR_Read  proc
+
+	mov	ecx, [Saved_ECX]	; Get MSR address
+
+	call	Read_MSR		; Handle special MSRs
+
+	mov	[Saved_EAX], eax	; Return results
+	mov	[Saved_EDX], edx
+
+	; Toggle the caller's carry flag
+	xor	byte ptr ([SMM_Header]).EFLAGS, EFLAGS_CF
+	ret
+
+MSR_Read endp
+
+
+;***************************************************************************
+; Input:
+;      ECX = MSR address
+; Output:
+;      EBX = OHCI BAR for multiplexer workaround (0 if not applicable)
+;  EDX:EAX = MSR contents
+;***************************************************************************
+Read_MSR proc
+
+	test	ecx, 0E0000000h		; Is the MSR in the CPU ?
+	jnz	Not_CPU_MSR
+	xor	edx, edx		; Yes, then possibly requires special handling
+	clc				; Indicate this is a RDMSR
+	call	MSR_Handler		; Read the MSR
+	ret
+
+Not_CPU_MSR:
+	rdmsr
+	ret
+
+Read_MSR endp
+
+
+
+
+
+
+
+;***************************************************************************
+; Reads/writes MSRs that require special handling
+;  a) those modified by SysMgr
+;  b) those located in the SMM header
+;  c) those that are SMM-related are not allowed to be written
+; On entry:
+;  CF = 0 for MSR read
+;       1 for MSR write	
+;***************************************************************************
+
+MSR_Handler proc
+	ASSUME	BX: PTR SpecialMSR
+	lea	bx, [Special_MSRs]
+	mov	di, [SpecialMSR.RdHandler]
+	jnc	MSR_Loop
+	mov	di, [SpecialMSR.WrHandler]
+MSR_Loop:
+	cmp	cx, [bx].MSR_Addr	; Does MSR match ?
+	je	Match
+	add	bx, sizeof(SpecialMSR)	; Advance table ptr
+	cmp	[bx].MSR_Addr, 0000h	; End of table ?
+	jne	MSR_Loop
+NotSpecial:
+	cmp	di, [SpecialMSR.WrHandler] ; Read or Write ?
+	je	short WriteMSR
+	rdmsr
+	jmp	short Exit
+
+WriteMSR:
+	wrmsr
+	jmp	short Exit
+	
+
+Match:	mov	si, [bx].DataOffset
+	call	word ptr [bx+di]	; Jump to MSR handler
+Exit:	ret
+	
+	ASSUME	BX: NOTHING
+
+SpecialMSR struc
+  MSR_Addr	dw	?
+  RdHandler	dw	?
+  WrHandler	dw	?
+  DataOffset	dw	?
+SpecialMSR ends 
+	
+
+Special_MSRs:
+	; 		MSR_Addr	Rd_Handler    Wr_Handler	DataOffset
+	SpecialMSR	{MSR_EFLAGS,	Get_Header,   Set_Header,	(SMM_Header[0]).EFLAGS}
+	SpecialMSR	{MSR_CR0,	Get_Header,   Set_CR0,		(SMM_Header[0]).r_CR0}
+	SpecialMSR	{MSR_DR7,	Get_DR7,      Set_DR7,		(SMM_Header[0]).r_DR7}
+	SpecialMSR	{1321h,		Get_CS_Sel,   Set_CS_Sel,	(SMM_Header[0])}
+	SpecialMSR	{1331h,		Get_CS_Base,  Set_CS_Base,	(SMM_Header[0])}
+
+	SpecialMSR	{1320h,		Get_Selector, Set_Selector,	Saved_ES}
+	SpecialMSR	{1322h,		Get_Selector, Set_Selector,	Saved_SS}
+	SpecialMSR	{1323h,		Get_Selector, Set_Selector,	Saved_DS}
+	SpecialMSR	{1324h,		Get_Selector, Set_Selector,	Saved_FS}
+	SpecialMSR	{1325h,		Get_Selector, Set_Selector,	Saved_GS}
+
+	SpecialMSR	{1330h,		Get_Base,     Set_Base,		Saved_ES}
+	SpecialMSR	{1332h,		Get_Base,     Set_Base,		Saved_SS}
+	SpecialMSR	{1333h,		Get_Base,     Set_Base,		Saved_DS}
+	SpecialMSR	{1334h,		Get_Base,     Set_Base,		Saved_FS}
+	SpecialMSR	{1335h,		Get_Base,     Set_Base,		Saved_GS}
+
+	SpecialMSR	{1329h,		Get_IDT_Sel,  Set_IDT_Sel,	IDT_Selector}
+	SpecialMSR	{1339h,		Get_IDT_Base, Set_IDT_Base,	IDT_Base}
+	
+ 	; SMM related MSRs: don't allow these to be written
+	SpecialMSR	{MSR_SMM_CTRL,	NotSpecial,   Exit}
+	SpecialMSR	{MSR_SMM_HDR,	NotSpecial,   Exit}
+	SpecialMSR	{MSR_SMM_LOC,	NotSpecial,   Exit}
+	SpecialMSR	{MSR_RCONF_SMM,	NotSpecial,   Exit}
+		
+	dw	0  ; End of table
+
+;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	; Get MSR value from SMM Header
+Get_Header proc
+	mov	eax, [si]
+	ret
+Get_Header endp
+
+
+	; Store MSR value into SMM Header
+Set_Header proc
+	mov	[si], eax
+	ret
+Set_Header endp
+
+;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	; Segment selector & attributes	
+	ASSUME	SI: PTR Descriptor
+Get_Selector proc
+	mov	ax, word ptr [si].attr
+	and	ah, 0F0h			; Mask Limit 19:16
+	shl	eax, 16
+	mov	ax, [si].selector
+	ret
+Get_Selector endp
+		
+Set_Selector proc
+	mov	[si].selector, ax
+	shr	eax, 16
+	and	ah, 0F0h			; Mask Limit 19:16
+	and	word ptr [si].attr, 0F00h	; Preserve Limit 19:16
+	or	word ptr [si].attr, ax
+	ret
+Set_Selector endp		
+
+
+
+;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	; Segment base & limit
+Get_Base proc
+	mov	ah, [si].base_31_24		; Get base
+	mov	al, [si].base_23_16
+	shl	eax, 16
+	mov	ax, [si].base_15_0
+	
+	movzx	dx, [si].limit_19_16		; Get limit
+	mov	bh, dl
+	and	dl, 0Fh				; Preserve only limit
+	shl	edx, 16
+	mov	dx, [si].limit_15_0	
+	test	bh, G_BIT			; Handle page granular bit
+	jz	short Exit
+	shl	edx, 12
+	or	dx, 0FFFh	
+Exit:	ret
+Get_Base endp
+
+
+Set_Base proc
+	mov	[si].base_15_0, ax		; Set base in [Saved_?S]
+	ror	eax, 16
+	mov	[si].base_31_24, ah
+	mov	[si].base_23_16, al
+	rol	eax, 16				; Restore base
+	and	[si].limit_19_16, NOT G_BIT	; Clear Granularity bit
+	
+	test	edx, 0FFF00000h			; 32-bit limit ?
+	jz	short Limit16
+
+	or	[si].limit_19_16, G_BIT		; Set Granularity bit
+	shr	edx, 12
+Limit16:
+	mov	[si].limit_15_0, dx
+	shr	edx, 16
+	and	[si].limit_19_16, 0F0h
+	and	dl, 0Fh
+	or	[si].limit_19_16, dl
+	ret
+Set_Base endp
+
+	ASSUME	SI: PTR SmiHeader
+;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	; CS selector & attributes
+Get_CS_Sel proc
+	mov	eax, dword ptr [si]._CS.selector
+	ret
+Get_CS_Sel endp
+
+Set_CS_Sel proc
+	mov	dword ptr [si]._CS.selector, eax
+	ret
+Set_CS_Sel endp
+
+;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	; CS base & limit
+Get_CS_Base proc
+	mov	eax, [si]._CS.base
+	mov	edx, [si]._CS.limit
+	ret
+Get_CS_Base endp
+
+Set_CS_Base proc
+	mov	[si]._CS.base, eax
+	mov	[si]._CS.limit, edx
+	ret
+Set_CS_Base endp
+
+
+
+	ASSUME	SI: NOTHING
+
+;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+; CR0
+;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Set_CR0 proc
+
+CD	equ	40000000h
+NW	equ	20000000h
+	mov	ebx, (CD+NW)
+	mov	edi, ebx
+	not	edi
+	and	ebx, eax		; Extract CD and NW
+	cmp	ebx, NW			; Don't allow CD=0 & NW=1
+	je	Exit
+	mov	[si], eax		; Write new CR0 to the SMM header
+		
+	; 1) Update VSA's CR0
+	; 2) Update SMM RCONF cache bits
+	; 3) Update all VSM's CR0[CD] and CR0[NW]
+	; 4) Flush the cache
+	wbinvd
+	mov	esi, CR0
+	and	esi, edi 
+	or	esi, ebx
+	mov	CR0, esi
+
+	push	bx
+	mov	ecx, MSR_RCONF_DEFAULT	; Re-synch MSR_RCONF_SMM with MSR_RCONF_DEFAULT
+	rdmsr
+	mov	bl, al
+	mov	ecx, MSR_RCONF_SMM	; Update MSR_RCONF_SMM	
+	rdmsr
+	mov	al, REGION_WP		; Write-protect SMM region in non-SMM
+	mov	dl, bl
+	wrmsr
+	wbinvd
+	pop	bx
+
+	; Update all VSM's CR0
+	mov	ecx, [VSM_ListHead]
+VSM_Loop:
+	jecxz	Exit
+	and	fs:(VSM_Header PTR [ecx]).SysStuff.State.r_CR0, edi
+	or	fs:(VSM_Header PTR [ecx]).SysStuff.State.r_CR0, ebx
+	mov     ecx, fs:(VSM_Header PTR [ecx]).SysStuff.Flink
+	jmp	VSM_Loop
+
+Exit:	ret
+Set_CR0	endp
+
+;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	; DR7
+Get_DR7 proc
+	mov	edx, [si]		; Get DR7 in SMM header
+	mov	eax, DR6
+Exit:	ret
+Get_DR7 endp
+
+Set_DR7 proc
+	xchg	[si], edx		; Set DR7 field in SMM header
+	mov	eax, DR6		; EAX = current DR7
+	wrmsr				; Update DR6
+	ret
+Set_DR7 endp
+	
+;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	; IDT selector & attributes
+Get_IDT_Sel proc
+	mov	eax, [si]
+	ret
+Get_IDT_Sel endp
+
+Set_IDT_Sel proc
+	mov	[si], eax
+	ret
+Set_IDT_Sel endp
+
+;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	; IDT base & limit
+Set_IDT_Base proc
+	mov	[si], eax
+	mov	[IDT_Limit], edx
+	ret
+Set_IDT_Base endp
+
+Get_IDT_Base proc
+	mov	eax, [si]
+	mov	edx, [IDT_Limit]
+	ret
+Get_IDT_Base endp
+
+MSR_Handler endp
+
+
+
+
+
+;***************************************************************************
+; Sets the VSM type for filtering events kept in the History buffer.
+;***************************************************************************
+Set_VSM_Type proc
+
+	mov	al, byte ptr [Saved_EBX+1]
+	mov	[VSM_Filter], al
+	ret
+
+Set_VSM_Type endp
+
+;***************************************************************************
+;   SYS_BROADCAST_MSG(MSG_WARM_BOOT, &Param, VSM_ANY);
+;***************************************************************************
+Warm_Boot proc
+
+	xor	eax, eax
+	lea	bx, [MsgPacket]
+	mov	[bx+0], eax
+	mov	[bx+4], eax
+	mov	[bx+8], eax
+	
+	push	word ptr MSG_WARM_BOOT	; Message code
+	push	word ptr VSM_ANY	; To VSMs
+	push	eax			; From_VSM
+	call    Broadcast_Message
+	ret
+
+Warm_Boot endp
+
+
+
+
+;***************************************************************************
+; Returns VSA II signature in caller's EAX
+;***************************************************************************
+Signature proc
+
+	mov	ax, VSA2_SIGNATURE AND 0FFFFh
+	mov	dx, VSA2_SIGNATURE SHR 16
+	ret
+
+Signature endp
+
+
+;***************************************************************************
+; Returns version of VSA II in caller's AX
+;***************************************************************************
+Get_VSA_Version proc
+
+	mov	ax, VSA_VERSION
+	ret
+
+Get_VSA_Version endp
+
+
+
+
+;***************************************************************************
+; Returns the version # of the specified VSM type
+;***************************************************************************
+Get_VSM_Version proc
+
+	; Get caller's BL
+	mov	dl, byte ptr [Saved_EBX]
+Find_VSM::
+	mov	ecx, [SysMgr_VSM]
+	mov	ax, 0FFFFh		; Not found
+VSM_Loop:
+	jecxz	Exit
+	cmp	dl, fs:(VSM_Header PTR [ecx]).VSM_Type
+	je	Found
+	mov	ecx, fs:(VSM_Header PTR [ecx]).SysStuff.Flink
+	jmp	VSM_Loop
+
+Found:	mov	ax, fs:(VSM_Header PTR [ecx]).VSM_Version
+Exit:	mov	word ptr [Saved_EAX], ax
+	ret
+
+
+Get_VSM_Version endp
+
+
+
+
+
+
+
+;***************************************************************************
+; Helper routine
+; On Entry:
+;   Caller's BH - VSM type to process
+; On Exit:
+;   ECX - ptr to the next VSM to be processed
+;***************************************************************************
+Common_Entry proc
+
+	mov	ecx, [Next_VSM]
+	mov	dl, byte ptr [Saved_EBX+1]	; Caller's BH
+	cmp	dl, 0FFh			; Next VSM ?
+	je	Exit
+
+	call	Find_VSM
+	cmp	ax, 0FFFFh
+	stc
+	jz	Return
+
+Exit:	clc
+Return:ret
+
+Common_Entry	endp
+
+;***************************************************************************
+; Updates Next_VSM with the Flink field of the current VSM
+;***************************************************************************
+Common_Exit proc
+
+	; Get ptr to next VSM	
+	mov	ecx, fs:(VSM_Header PTR [ecx]).SysStuff.Flink
+	mov	[Next_VSM], ecx
+	ret
+
+Common_Exit endp
+
+
+
+
+
+;***************************************************************************
+; Return's to caller's registers:
+;   EAX - VSM_Version::VSM_Type  (0xFFFF if no more)
+;   EBX - Base of VSM
+;   ECX - IP::SP
+;    DX - VSM_Length
+;***************************************************************************
+Get_VSM_Basics proc
+
+	call	Common_Entry
+	jc	short Exit
+
+	; Put info into caller's registers
+	mov	[Saved_EBX], ecx
+
+	mov	ax, fs:(VSM_Header PTR [ecx]).VSM_Version
+	shl	eax, 16
+	movzx	ax, fs:(VSM_Header PTR [ecx]).VSM_Type
+	mov	[Saved_EAX], eax
+
+	mov	ax, word ptr fs:(VSM_Header PTR [ecx]).SysStuff.State.Next_EIP
+	shl	eax, 16
+	mov	ax, word ptr fs:(VSM_Header PTR [ecx]).SysStuff.SavedESP
+	mov	[Saved_ECX], eax
+
+	mov	ax, word ptr fs:(VSM_Header PTR [ecx]).DS_Limit
+	mov	word ptr [Saved_EDX], ax
+
+	call	Common_Exit
+
+Exit:	ret
+
+Get_VSM_Basics endp
+
+
+;***************************************************************************
+; Entry:
+;        CL - History entry # (0-based)
+;        CH - 1 to clear history buffer
+; Exit:
+;        AL - VSM type
+;        AH - Event
+;       EBX - Count
+;       ECX - Param1
+;       EDX - Param2
+;   EDI:ESI - TimeStamp
+;***************************************************************************
+Get_VSM_History proc
+
+if HISTORY
+
+	; Get starting index
+	mov	ax, [HistoryStart]
+	mov	cx, [HistoryEnd]
+	cmp	ax, cx
+	je	NoHistory
+
+	movzx	dx, byte ptr [Saved_ECX]
+ 	add	ax, dx
+	mov	dl, HISTORY		; Index = (HistoryStart+CX) % HISTORY
+	div	dl
+	movzx	ax, ah
+
+	cmp	ax, cx			; if (Index < HistoryEnd)
+	jb	short GetItem		;    goto GetItem
+	mov	dx, ax
+	cmp	dx, cx
+	jne	short GetItem
+
+	cmp	byte ptr [Saved_ECX+1], 1
+	jne	NoHistory
+	xor	ax, ax
+	mov	[HistoryStart], ax
+	mov	[HistoryEnd], ax
+	mov	[HistoryWrap], ax
+	jmp	NoHistory
+
+GetItem:
+
+
+	; Get ptr to History[] entry
+	lea	bx, History
+	ASSUME	BX: PTR EVENT_HISTORY
+	mov	dl, sizeof(EVENT_HISTORY)
+	mul	dl
+	add	bx, ax
+
+	; Get info about the event
+	mov	ah, byte ptr [bx].Event
+	mov	ecx, [bx].Vsm
+	mov	al, fs:(VSM_Header PTR [ecx]).VSM_Type
+	mov	word ptr [Saved_EAX], ax
+
+	mov	eax, [bx].Count
+	mov	[Saved_EBX], eax
+
+	mov	eax, [bx].Param1
+	mov	[Saved_ECX], eax
+
+	mov	eax, [bx].Param2
+	mov	[Saved_EDX], eax
+
+	mov	eax, [bx].TimeStamp
+	mov	[Saved_ESI], eax
+	mov	eax, [bx].TimeStamp+4
+	mov	[Saved_EDI], eax
+	ret
+
+endif
+
+
+NoHistory:
+	xor	eax, eax
+	mov	[Saved_EAX], eax
+	ret
+
+
+Get_VSM_History endp
+
+
+;***************************************************************************
+; Returns:
+;  AX = Chipset ID
+;  BX = CPU ID
+;  CX = CPU MHz
+; EDX = PCI address of Southbridge 
+;***************************************************************************
+Get_VSM_Hardware proc
+
+	; Get ptr to Hardware structure
+	lea	bx, [HardwareInfo]
+	ASSUME	BX: PTR Hardware
+
+	mov	ax, [bx].Chipset_ID
+	mov	word ptr [Saved_EAX], ax
+
+	mov	ax, [bx].CPU_ID
+	mov	word ptr [Saved_EBX], ax
+
+	mov	ax, [bx].CPU_MHz
+	mov	word ptr [Saved_ECX], ax
+
+	mov	eax, [bx].Chipset_Base	
+	mov	[Saved_EDX], eax
+
+	ret
+
+	ASSUME	BX: NOTHING
+
+Get_VSM_Hardware endp
+
+
+;***************************************************************************
+; Returns:
+;  AX = Chipset ID
+;***************************************************************************
+Get_HW_Info proc
+
+	mov	ax, 0FFFFh		; Value for illegal index
+	movzx	bx, [HW_Index]
+	cmp	bl, MAX_HW_INFO
+	ja	short Exit
+
+	add	bx, bx
+	mov	bx, [HW_Offsets+bx]
+	mov	ax, [bx]
+Exit:
+	mov	word ptr [Saved_EAX], ax
+	ret
+
+Get_HW_Info endp
+
+HW_Index	db	0
+
+HW_Offsets:
+	dw	OFFSET HardwareInfo.Chipset_ID
+	dw	OFFSET HardwareInfo.Chipset_Rev
+	dw	OFFSET HardwareInfo.Chipset_Base
+	dw	OFFSET HardwareInfo.CPU_ID
+	dw	OFFSET HardwareInfo.CPU_Revision
+	dw	OFFSET HardwareInfo.CPU_MHz
+	dw	OFFSET HardwareInfo.PCI_MHz
+MAX_HW_INFO equ ($-HW_Offsets)/2-1
+
+
+
+;***************************************************************************
+; Entry:
+;   AL - Hardware item to be returned by Select_HW_Info
+;        0 = Southbridge ID
+;        1 = Southbridge Revision
+;        2 = Southbridge PCI address
+;        3 = CPU ID
+;        4 = CPU Revision
+;        5 = CPU MHz
+;        6 = PCI MHz
+;***************************************************************************
+Select_HW_Info proc
+
+	mov	al, byte ptr [Saved_EAX]
+	mov	[HW_Index], al
+	ret
+
+Select_HW_Info endp
+
+;***************************************************************************
+; Entry:
+;   ESI - VSM of interest
+; Exit:
+;   EAX - Priority::Event
+;   ECX - Param1
+;   EDX - Param2
+;***************************************************************************
+Get_VSM_Events proc
+
+	mov	esi, [Saved_ESI]	; Get the VSM of interest
+	mov	cx, word ptr [CurrentIndex]
+EventIndex:
+	mov	al, sizeof(EVENT_ENTRY)
+	mul	cl
+	lea	bx, [Events]
+	add	bx, ax
+	ASSUME	BX: PTR EVENT_ENTRY
+	cmp	esi, [bx].Vsm		; Is it the VSM of interest ?
+	je	FoundEvent
+
+	mov	cl, [bx].Link		; Get link to next event
+	or	cl, cl
+	jnz	EventIndex
+
+	; Increment Event
+	inc	ch			; Increment event index
+	mov	cl, ch
+	cmp	ch, MAX_EVENT		; Last event ?
+	jbe	EventIndex
+	xor	cx, cx			; Yes, reset variables
+
+	; Set the caller's carry flag
+	or	byte ptr ([SMM_Header]).EFLAGS, EFLAGS_CF
+	jmp	short Exit
+
+
+FoundEvent:
+	mov	eax, [bx].Param1	; Return Param1 in ECX
+	mov	[Saved_ECX], eax
+	mov	eax, [bx].Param2	; Return Param2 in EDX
+	mov	[Saved_EDX], eax
+
+	mov	ax, [bx].Priority	; Return Priority::Event in EAX
+	shl	eax, 16
+	movzx	ax, ch
+	mov	[Saved_EAX], eax
+	
+	mov	cl, [bx].Link		; Get link to next event
+
+Exit:	mov	word ptr [CurrentIndex], cx
+	ret
+
+	ASSUME	BX:NOTHING
+
+
+CurrentIndex	db	0
+CurrentEvent	db	0
+
+Get_VSM_Events endp
+
+
+
+;***************************************************************************
+; Entry:
+;   Caller's BH - VSM to report (0FFh for next)
+;   Caller's CL - clear statistics flag (1=clear)
+; Exit:
+;    EDX:EAX - # SMIs
+;    EBX:ECX - # clocks
+;         BP - VSM Type
+;    If SysMgr:
+;     EDI:ESI - start time
+;  16 MSBs BP - clock adjustment 
+;   Carry Flag set if no more VSMs
+; 
+;***************************************************************************
+Get_VSM_Statistics proc
+
+	call	Common_Entry
+	jc	Exit
+	or	ecx, ecx
+	jz	NoMoreVSMs
+
+
+	mov	dl, byte ptr [Saved_ECX]	; Get /S flag
+	cld
+
+
+	; If SysMgr, freeze statistics & return extra information
+	cmp	fs:(VSM_Header PTR [ecx]).VSM_Type, VSM_SYS_MGR
+	jne	ReturnInfo
+
+	mov	bx, OFFSET VSM_Header.SysStuff
+	ASSUME	BX: PTR System
+
+	;     EDI:ESI - start time
+	; 16 MSBs EBP - adjustment (clocks/SMI)
+	mov	ax, word ptr [bx].Adjustment
+	mov	word ptr [Saved_EBP+2], ax
+
+	mov	eax, [bx+0].StartClocks
+	mov	[Saved_ESI], eax
+	mov	eax, [bx+4].StartClocks
+	mov	[Saved_EDI], eax
+
+	; Clear statistics ?
+	cmp	dl, 1
+	jne	short FreezeStats
+
+	; Yes, record a new start time
+	push	dx
+	rdtsc
+	mov	[bx+0].StartClocks, eax
+	mov	[bx+4].StartClocks, edx
+	pop	dx
+
+	ASSUME	BX:NOTHING
+
+
+
+	; Freeze statistics of all VSMs
+FreezeStats:
+	push	ecx
+	mov	ebx, ecx
+	xor	eax, eax
+VSM_Loop:
+	lea	esi, (VSM_Header PTR [ebx]).SysStuff.Clocks
+	lea	edi, (VSM_Header PTR [ebx]).SysStuff.FrozenClocks
+	mov	ecx, 4
+	rep	movsd [edi], es:[esi]
+
+	; Clear statistics ?
+	cmp	dl, 1
+	jne	short NextVSM
+	lea	edi, (VSM_Header PTR [ebx]).SysStuff.Clocks
+	mov	cl, 4
+	rep	stosd [edi]
+
+NextVSM:
+	mov	ebx, es:(VSM_Header PTR [ebx]).SysStuff.Flink
+	or	ebx, ebx
+	jnz	VSM_Loop
+
+	pop	ecx
+
+
+	; Put info into caller's registers
+ReturnInfo:
+	movzx	ax, es:(VSM_Header PTR [ecx]).VSM_Type
+	mov	word ptr [Saved_EBP], ax
+
+	lea	esi, (VSM_Header PTR [ecx]).SysStuff.FrozenClocks
+	lodsd	es:[esi]
+	mov	[Saved_EAX], eax
+	lodsd	es:[esi]
+	mov	[Saved_EDX], eax
+	lodsd	es:[esi]
+	mov	[Saved_ECX], eax
+	lodsd	es:[esi]
+	mov	[Saved_EBX], eax
+
+	call	Common_Exit
+	ret
+
+NoMoreVSMs:
+	; Set caller's CF
+	or	byte ptr ([SMM_Header]).EFLAGS, EFLAGS_CF
+Exit:	ret
+
+Get_VSM_Statistics endp
+
+
+;***************************************************************************
+; Invalidates the cache(s)
+;***************************************************************************
+Do_WBINVD proc
+
+	wbinvd
+	ret
+
+Do_WBINVD endp
+
+
+;***************************************************************************
+; Updates the CR0 field of each VSM with the current non-VSA CR0
+;***************************************************************************
+Update_VSMs_CR0 proc
+
+	mov	si, OFFSET [SMM_Header[0].r_CR0]
+	mov	eax, [si]		; Get current CR0
+	call	Set_CR0
+	ret
+
+Update_VSMs_CR0 endp
+
+	END


Property changes on: trunk/gplvsa2/sysmgr/vr_misc.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/sysmgr/vsa_init.c
===================================================================
--- trunk/gplvsa2/sysmgr/vsa_init.c	                        (rev 0)
+++ trunk/gplvsa2/sysmgr/vsa_init.c	2009-03-20 18:32:39 UTC (rev 1)
@@ -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 
+*/
+
+//*	 Function:                                                          *
+//*     Implements the initialization code for System Manager 
+
+#include "VSA2.H"
+#include "SYSMGR.H"
+#include "PROTOS.H"
+#include "VR.H"
+#include "CHIPSET.H"
+
+
+
+// External function prototypes
+extern void Initialize_Events(void);
+extern void Install_SMI_Routines(void);
+extern void Initialize_History(void);
+extern void InitChipset(void);
+extern void Init_MBus(void);
+extern void VirtualPCI_EarlyInit(void);
+extern void Init_Virtual_Regs(void);
+extern void Record_VSM_Locations(void);
+extern void Broadcast_SysMgr_Msg (MSG, UCHAR);
+extern Hardware HardwareInfo;
+
+//***********************************************************************
+// Gets called from early VSA init, but after VSMs have initialized.
+//***********************************************************************
+void Post_VSM_InitInit(void) 
+{
+
+}
+
+
+
+//*****************************************************************************
+//
+// Initialize the System Manager
+//
+//*****************************************************************************
+void Init_SysMgr(void)
+{
+
+  // Initialize the array of registered events
+  Initialize_Events();
+
+  // Initialize the history buffers
+  Initialize_History();
+
+
+  // Install SMI routines appropriate to chipset
+  Install_SMI_Routines();
+
+
+  // Initialize MBus related structures & MSRs
+  Init_MBus();
+
+
+  // Initialize virtual PCI headers and MBUS
+  VirtualPCI_EarlyInit();
+
+  // Initialize chipset-specific registers
+  InitChipset();
+
+
+  // Initialize virtual register trapping
+  Init_Virtual_Regs();
+
+
+  // Register System Manager as handler for A20
+  Register_Event(EVENT_A20, MAX_PRIORITY, SysMgr_VSM, 0, 0);
+
+
+
+  // Register System Manager as handler of VRC_MISCELLANEOUS
+  Register_Event(EVENT_VIRTUAL_REGISTER, MAX_PRIORITY, SysMgr_VSM, VRC_MISCELLANEOUS, GET_DESCR_INFO);
+
+
+  // Record locations of VSMs requiring special handling
+  Record_VSM_Locations();
+
+
+  // Schedule control after VSMs have performed initialization
+  Schedule_VSM((USHORT)Post_VSM_InitInit);
+
+
+
+  //
+  // Send a phase 0 initialization message to each VSM
+  //
+  Broadcast_SysMgr_Msg(MSG_INITIALIZE, EARLY_INIT);
+
+
+}


Property changes on: trunk/gplvsa2/sysmgr/vsa_init.c
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/vsabuild.txt
===================================================================
--- trunk/gplvsa2/vsabuild.txt	                        (rev 0)
+++ trunk/gplvsa2/vsabuild.txt	2009-03-20 18:32:39 UTC (rev 1)
@@ -0,0 +1,52 @@
+TOOLS:
+• MASM 6.11c or greater: This is available through an MSDN subscription.
+- Upgrade to 6.14: ftp://ftp.microsoft.com/softlib/mslfiles/ml614.exe
+• NMAKE.EXE Version 1.40 or greater (1.20 is included with MASM 6.11 – the
+  upgrade is needed to build)
+- Update to 1.50: ftp://ftp.microsoft.com/softlib/mslfiles/nmake15.exe
+- Unzip into the masm611\bin directory
+• MSVC Version 1.52: This is available through an MSDN subscription.
+• exe2bin.exe: This is supplied with Microsoft operating systems from DOS
+  to Windows XP.
+
+These are the minimum tools & files you need to build VSA:
+333,312  c13216.exe  
+493,056  c23216.exe  
+244,224  c33216.exe  
+  1,756  cl.err      
+ 91,648  cl.exe      
+  4,279  cl.msg      
+ 21,879  h2inc.err   
+249,344  h2inc.exe   
+ 59,089  lib.exe     
+364,544  link.exe    
+  9,687  ml.err      
+372,736  ml.exe      
+  5,056  nmake.err   
+ 65,536  nmake.exe   
+  5,647  oldnames.lib
+391,207  slibc7.lib  
+404,519  slibce.lib  
+
+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+SETTING THE BUILD ENVIRONMENT:
+The path should include the bin directories from MASM and MSVC, as well as the
+normal path for DOS or Windows.
+Following is a sample batch file to set up the environment:
+
+ at echo off
+if "%varset%" == "xpath" goto done
+set path=c:\tools;c:\tools\masm\bin;c:\tools\msvc\bin;%path%
+set lib=c:\tools\msvc\lib
+set varset=xpath
+:done
+
+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+BUILDING THE ROM:
+Change directories to vsa_ii\build and type NMAKE. This will create the
+VSA .bin file.
+
+Build Targets in the Makefiles:
+• NMAKE all - builds the VSA binary
+• NMAKE clean - cleans up last compile, but leaves the VSM files.
+• NMAKE cleanall - cleans up last compile completely


Property changes on: trunk/gplvsa2/vsabuild.txt
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/vsm_lib/critical.asm
===================================================================
--- trunk/gplvsa2/vsm_lib/critical.asm	                        (rev 0)
+++ trunk/gplvsa2/vsm_lib/critical.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -0,0 +1,67 @@
+; 
+; 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 the critical section macros. 
+
+
+include gx2.inc
+
+.model tiny,c
+.586p
+.CODE
+
+
+
+
+
+;***********************************************************************
+; Disables SMI nesting
+;***********************************************************************
+EnterCriticalSection proc
+
+	mov	ecx, MSR_SMM_CTRL
+	rdmsr
+	and	eax, NOT NEST_SMI_EN
+	wrmsr	
+	ret
+
+EnterCriticalSection endp
+
+
+
+;***********************************************************************
+; Enables SMI nesting
+;***********************************************************************
+ExitCriticalSection proc
+
+	mov	ecx, MSR_SMM_CTRL
+	rdmsr
+	or	eax, NEST_SMI_EN
+	wrmsr	
+	ret
+
+ExitCriticalSection endp
+
+
+
+
+
+
+	END 
+


Property changes on: trunk/gplvsa2/vsm_lib/critical.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/vsm_lib/descr.asm
===================================================================
--- trunk/gplvsa2/vsm_lib/descr.asm	                        (rev 0)
+++ trunk/gplvsa2/vsm_lib/descr.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -0,0 +1,182 @@
+; 
+; 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 library functions for accessing descriptors  
+
+include SYSMGR.INC
+include VSA2.INC
+include SMIMAC.MAC
+
+.model tiny,c
+.586p
+.CODE
+
+
+
+
+externdef Function:  byte
+externdef ValidateMacro:proc
+externdef ParamError:proc
+
+
+
+;***********************************************************************
+; void sys_get_descriptor(USHORT, void *)
+;***********************************************************************
+sys_get_descriptor proc pascal uses si\
+        seg_reg: WORD, \
+	buffer:	 PTR
+
+
+	mov	[Function], GET_DESCR	; In case of error
+	movzx	eax, [seg_reg]		; Get which register
+	call	ValidateMacro		; Get ptr to registers
+	jc	Exit
+
+	mov	si, [buffer]		; Destination ptr
+	cmp	ax, R_CS
+	je	Get_CS
+
+
+	cmp	ax, R_GS		; Validate offset
+	ja	Error
+	
+	; Get descriptor from SysMgr's state save area
+	xor	ah, ah			; Extract offset
+	lea	ebx, [eax-8]		; Offset points to .selector
+	mov	ax,  fs:[eax]		; Copy 10 bytes of descriptor info
+	mov	[si+8], ax
+	mov	eax, fs:[ebx]
+	mov	[si], eax
+	mov	eax, fs:[ebx+4]
+	mov	[si+4], eax
+	jmp	Exit
+
+
+	; Get CS from SMM header.
+	; Convert from linear format to descriptor format
+Get_CS:
+	ASSUME	SI: PTR Descriptor
+	; CS base
+	mov	eax, fs:(SmiHeader PTR [ecx])._CS.base
+	mov	[si].base_15_0, ax
+	shr	eax, 16
+	mov	[si].base_23_16, al
+	mov	[si].base_31_24, ah
+
+	; CS limit
+	mov	eax, fs:(SmiHeader PTR [ecx])._CS.limit
+	test	fs:(SmiHeader PTR [ecx])._CS.attr, 8000h
+	jz	short SetLimit
+	shr	eax, 12
+	or	eax, 800000h		; Set G bit
+SetLimit:
+	mov	[si].limit_15_0, ax
+	shr	eax, 16
+	mov	[si].limit_19_16, al
+
+	; CS selector
+	mov	ax, word ptr fs:(SmiHeader PTR [ecx])._CS.selector
+	mov	[si].selector, ax
+
+	; CS attributes
+	mov	ax, fs:(SmiHeader PTR [ecx])._CS.attr
+	mov	[si].attr, al
+	jmp	short Exit
+
+Error:	call	ParamError
+Exit:	ret
+
+
+sys_get_descriptor endp
+
+
+
+
+;***********************************************************************
+; void sys_set_descriptor(USHORT, void *)
+;***********************************************************************
+sys_set_descriptor proc pascal \
+        seg_reg: word, \
+	buffer:	PTR
+
+	movzx	eax, [seg_reg]		; Get which register
+	mov	[Function], SET_DESCR	; In case of error
+	call	ValidateMacro		; Get ptr to registers
+	jc	Exit
+
+
+	mov	si, [buffer]		; Destination ptr
+	ASSUME	SI: PTR Descriptor
+
+	cmp	al, R_CS AND 0FFh
+	je	Set_CS
+
+	xor	ah, ah			; Extract offset
+	lea	ecx, [eax-8]		; Offset points to .selector
+
+
+	; Set a non-SMM descriptor
+	cld
+	lodsd				; Copy 10 bytes of descriptor info
+	mov	fs:[ecx+0], eax
+	lodsd
+	mov	fs:[ecx+4], eax
+	lodsw
+	mov	fs:[ecx+8], ax
+	jmp	short Exit
+
+
+
+	; Convert descriptor format to linear format
+Set_CS:			       
+	; Set limit
+	mov	al, [si].limit_19_16
+	mov	cl, al
+	and	ax, 000Fh
+	shl	eax, 16
+	mov	ax, [si].limit_15_0
+	mov	fs:(SmiHeader PTR [ecx])._CS.limit, eax
+
+	; Set base
+	mov	ah, [si].base_31_24
+	mov	al, [si].base_23_16
+	shl	eax, 16
+	mov	ax, [si].base_15_0
+	mov	fs:(SmiHeader PTR [ecx])._CS.base, eax
+
+	; Set attribute
+	mov	al, [si].attr
+	mov	ah, cl			; Contains G bit
+	mov	fs:(SmiHeader PTR [ecx])._CS.attr, ax
+	jmp	short Exit
+
+
+Error:	call	ParamError
+Exit:	ret
+
+sys_set_descriptor endp
+
+
+
+
+
+
+	END 
+


Property changes on: trunk/gplvsa2/vsm_lib/descr.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/vsm_lib/hex.asm
===================================================================
--- trunk/gplvsa2/vsm_lib/hex.asm	                        (rev 0)
+++ trunk/gplvsa2/vsm_lib/hex.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -0,0 +1,95 @@
+; 
+; 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 hex debug routines   
+
+
+.model tiny,c
+.586p
+.CODE
+
+
+
+
+
+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	Char
+	add	al, 7			; 'A'-'F'
+Char:	mov	dx, 84h
+	out	dx, al
+	in	al, 80h
+	ret
+
+Space:	mov	al, ' '
+	jmp	Char
+
+
+
+
+	END 
+


Property changes on: trunk/gplvsa2/vsm_lib/hex.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/vsm_lib/irq.asm
===================================================================
--- trunk/gplvsa2/vsm_lib/irq.asm	                        (rev 0)
+++ trunk/gplvsa2/vsm_lib/irq.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -0,0 +1,82 @@
+; 
+; 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 the SYS_GENERATE_IRQ & SYS_MAP_IRQ macros. 
+
+
+include vsa2.inc
+include sysmgr.inc
+
+.model tiny,c
+.586p
+.CODE
+
+externdef sys_system_call:proc
+
+;***********************************************************************
+;***********************************************************************
+sys_map_irq proc pascal \
+	Y_Source: byte, \
+	IRQ:	byte
+	
+	mov	bl, [Y_Source]
+	mov	cl, [IRQ]
+	mov	ax, SYS_CODE_IRQ_MAPPER
+	call	sys_system_call
+	ret
+
+sys_map_irq endp
+
+
+;***********************************************************************
+; void sys_generate_IRQ(USHORT Irq);
+;
+; Generates an IRQ upon exit from SMM
+; NOTE:  If 8 MSBs of Irq are non-zero, then IRQ is set to external
+;***********************************************************************
+sys_generate_IRQ proc pascal  \
+	Irq: word
+
+	xor	bx, bx				; Get ptr to SysMgr's IRQ_Mask
+	mov	ebx, (VSM_Header PTR [bx]).SysStuff.SysMgr_Ptr
+
+	mov	cx, [Irq]			; Get IRQ number
+	mov	eax, 00010001h			; Generate bit mask
+	shl	eax, cl
+	or	ch, ch				; Disable internal IRQ external ?
+	jz	short AssertIRQ
+
+	not	ax				; Yes
+	mov	ebx, fs:(InfoStuff PTR [ebx]).IRQ_Base
+	and	fs:[ebx], ax			; Mark IRQ as external
+	jmp	short Exit
+
+
+AssertIRQ:
+	lea	ebx, (InfoStuff PTR [ebx]).IRQ_Mask
+	or	fs:[ebx], eax			; Record IRQ to be generated
+
+Exit:	ret
+
+sys_generate_IRQ endp
+
+
+
+	END 
+


Property changes on: trunk/gplvsa2/vsm_lib/irq.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/vsm_lib/makefile
===================================================================
--- trunk/gplvsa2/vsm_lib/makefile	                        (rev 0)
+++ trunk/gplvsa2/vsm_lib/makefile	2009-03-20 18:32:39 UTC (rev 1)
@@ -0,0 +1,134 @@
+#
+# 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 .h .inc .obj .mac
+
+INCLUDE		= $(OBJECT);$(INCLUDE)
+
+VSMNAME	= vsm_lib
+
+
+######################################################################
+#
+#				Build Macros
+#
+######################################################################
+
+VSMUTILS_ASM_OBJS	= \
+	$(OBJECT)\vsa2util.obj \
+	$(OBJECT)\pci.obj \
+	$(OBJECT)\descr.obj \
+	$(OBJECT)\utils.obj \
+	$(OBJECT)\misc.obj \
+	$(OBJECT)\message.obj \
+	$(OBJECT)\virtual.obj \
+	$(OBJECT)\irq.obj \
+	$(OBJECT)\regs.obj \
+	$(OBJECT)\sysinfo.obj \
+	$(OBJECT)\sw_int.obj \
+	$(OBJECT)\resource.obj \
+	$(OBJECT)\critical.obj \
+	$(OBJECT)\yield.obj \
+	$(OBJECT)\hex.obj \
+	$(OBJECT)\present.obj \
+	$(OBJECT)\msrs.obj \
+
+#######################################################################
+#
+#				Targets
+#
+#######################################################################
+
+all: $(OBJECT) setenv tools.lib
+!if !exist ($(BUILD_DIR)\obj)	
+	md $(BUILD_DIR)\obj
+!endif
+	$(COPY) $(OBJECT)\tools.lib $(BUILD_DIR)\obj
+
+tools.lib: $(VSMUTILS_ASM_OBJS)
+
+#This and only this clean target must exist as it is called by cleanall
+#cleanall and cleanlocal are defined in rules.mak
+
+clean: cleanlocal
+	- at IF EXIST $(BUILD_DIR)\obj\tools.lib $(DEL) $(BUILD_DIR)\obj\tools.lib
+	- at IF NOT EXIST $(BUILD_DIR)\obj\*.* rd $(BUILD_DIR)\obj
+
+$(OBJECT):
+	- at md $(OBJECT)
+
+#######################################################################
+#
+#				Dependencies
+#
+#######################################################################
+
+$(VSMUTILS_ASM_OBJS): $(MAKEDIR)\makefile\
+		$(OBJECT)\sysmgr.inc \
+		$(OBJECT)\smimac.mac \
+		$(OBJECT)\vsa2.inc\
+		$(OBJECT)\isa.inc \
+		$(OBJECT)\gx2.inc \
+		$(OBJECT)\pci.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 $<
+
+{$(MAKEDIR)}.asm{$(OBJECT)}.obj:
+	$(AS) /nologo $(AS_OPTS) /Fo$@ $< 
+	$(LB) $(OBJECT)\tools.lib -+$@;
+
+{$(MAKEDIR)\$(CPU)}.asm{$(OBJECT)}.obj:
+	$(AS) /nologo $(AS_OPTS) /Fo$@ $< 
+	$(LB) $(OBJECT)\tools.lib -+$@;


Property changes on: trunk/gplvsa2/vsm_lib/makefile
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/vsm_lib/message.asm
===================================================================
--- trunk/gplvsa2/vsm_lib/message.asm	                        (rev 0)
+++ trunk/gplvsa2/vsm_lib/message.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -0,0 +1,61 @@
+; 
+; 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 the SYS_BROADCAST_MSG system call
+
+include sysmgr.inc
+include vsa2.inc
+
+.model tiny,c
+.586p
+.CODE
+
+
+
+
+externdef sys_system_call:proc
+externdef Async_VSM:  dword
+externdef EventIndex: byte
+
+;***********************************************************************
+; void sys_broadcast_msg(MSG Code, ULONG * Params, UCHAR VSM_Type)
+;***********************************************************************
+sys_broadcast_msg proc pascal uses esi edi \
+	MsgCode:     MSG,	\
+	Params:      PTR,	\
+	VSM_Type:    WORD
+
+
+	mov	bx,  [MsgCode]		; Get MSG to broadcast
+	shl	ebx, 16			; Put into 16 MSBs
+	mov	di,  [Params]		; Get parameters
+	mov	ecx, [di+0]		; Param1
+	mov	esi, [di+4]		; Param2
+	mov	edi, [di+8]		; Param3
+	mov	bx,  [VSM_Type]		; Get VSM(s) to send message to
+	
+	mov	ax, SYS_CODE_BROADCAST
+	call	sys_system_call
+ 	ret
+
+sys_broadcast_msg endp
+
+
+	END 
+


Property changes on: trunk/gplvsa2/vsm_lib/message.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/vsm_lib/misc.asm
===================================================================
--- trunk/gplvsa2/vsm_lib/misc.asm	                        (rev 0)
+++ trunk/gplvsa2/vsm_lib/misc.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -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 
+; 
+;*******************************************************************************
+;*     This file contains miscellaneous VSM library functions.   
+;*******************************************************************************
+
+
+include sysmgr.inc
+.model tiny,c
+.586p
+.CODE
+
+
+
+externdef sys_system_call:proc
+
+
+
+sys_unload_vsm proc
+
+	mov	ax, SYS_CODE_UNLOAD
+	call	sys_system_call
+	ret
+
+; Does not return. VSM is removed.
+
+sys_unload_vsm endp
+		
+
+
+sys_duplicate_vsm proc pascal  \
+	MemoryModel:word 
+
+	mov	bx, [MemoryModel]
+	mov	ax, SYS_CODE_DUPLICATE
+	call	sys_system_call
+	ret
+
+sys_duplicate_vsm endp
+		
+
+
+
+
+	END 
+


Property changes on: trunk/gplvsa2/vsm_lib/misc.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/vsm_lib/msrs.asm
===================================================================
--- trunk/gplvsa2/vsm_lib/msrs.asm	                        (rev 0)
+++ trunk/gplvsa2/vsm_lib/msrs.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -0,0 +1,98 @@
+; 
+; 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 routines to access MSRs. 
+
+
+
+.model tiny,c
+.586p
+.CODE
+
+
+
+
+
+;************************************************************************
+; Returns the low dword of the specified MSR
+;************************************************************************
+Read_MSR_LO proc pascal  \
+	MSR_Addr: dword
+	
+	mov	ecx, [MSR_Addr]
+	rdmsr
+	mov	edx, eax
+	shr	edx, 16
+	ret
+
+Read_MSR_LO endp
+
+;************************************************************************
+; Writes the low dword of the specified MSR
+;************************************************************************
+Write_MSR_LO proc pascal  \
+	MSR_Addr: dword, \
+	MSR_Data: dword
+	
+	mov	ecx, [MSR_Addr]
+	rdmsr
+	mov	eax, [MSR_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_Addr:DWORD, \
+	pMSR_Data:PTR DWORD
+	
+	mov	ecx, [MSR_Addr]
+	rdmsr
+	mov	bx, [pMSR_Data]
+	mov	dword ptr [bx+0], eax
+	mov	dword ptr [bx+4], edx
+	ret
+
+Read_MSR endp
+
+
+;***********************************************************************
+; Writes an MSR.
+; Usage: Write_MSR(ULONG Msr, ULONG * Buffer);
+;***********************************************************************
+Write_MSR proc pascal \
+	MSR_Addr:DWORD, \
+	pMSR_Data:PTR DWORD
+	
+	mov	ecx, [MSR_Addr]
+	mov	bx, [pMSR_Data]
+	mov	eax, dword ptr [bx+0]
+	mov	edx, dword ptr [bx+4]
+	wrmsr
+	ret
+
+Write_MSR endp
+
+	END 


Property changes on: trunk/gplvsa2/vsm_lib/msrs.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/vsm_lib/pci.asm
===================================================================
--- trunk/gplvsa2/vsm_lib/pci.asm	                        (rev 0)
+++ trunk/gplvsa2/vsm_lib/pci.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -0,0 +1,296 @@
+; 
+; 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 PCI related library functions.   
+;*******************************************************************************
+
+
+include sysmgr.inc
+include pci.inc
+include vsa2.inc
+include gx2.inc
+
+.model tiny,c
+.586p
+.CODE
+
+
+
+
+externdef sys_system_call:proc
+
+
+
+
+
+;**********************************************************************
+; Writes the PCI Config Address
+; Input:
+;   EAX = config address
+; Output:
+;    DX = points to 0xCFC-0xCFF
+;**********************************************************************
+PCI_Common  proc
+
+	mov	dx, PCI_CONFIG_ADDRESS
+	ror	eax, 16			; Set 16 MSBs to 8000h
+	mov	ax, 8000h
+	ror	eax, 16
+	out	dx, eax
+	add	dl, 4			; PCI_CONFIG_DATA + 2 LSBs
+	and	al, 3
+	add	dl, al
+	ret
+
+PCI_Common endp
+
+
+
+;**********************************************************************
+; Reads a byte PCI register
+;**********************************************************************
+read_PCI_byte proc pascal PCI_Config_Addr:DWORD
+
+	mov	eax, [PCI_Config_Addr]
+	call	PCI_Common
+	in	al, dx
+	ret
+
+read_PCI_byte endp
+
+
+;**********************************************************************
+; Reads a word PCI register
+;**********************************************************************
+read_PCI_word proc pascal \
+	PCI_Config_Addr:DWORD
+
+	mov	eax, [PCI_Config_Addr]
+	call	PCI_Common
+	in	ax, dx
+	ret
+
+read_PCI_word endp
+
+
+;**********************************************************************
+; Reads a dword PCI register
+;**********************************************************************
+read_PCI_dword proc pascal \
+	PCI_Config_Addr:DWORD
+
+	mov	eax, [PCI_Config_Addr]
+	call	PCI_Common
+	in	eax, dx
+	mov	edx, eax
+	shr	edx, 16
+	ret
+
+read_PCI_dword endp
+
+
+;**********************************************************************
+; Writes a byte PCI register
+;**********************************************************************
+write_PCI_byte proc pascal \
+	PCI_Config_Addr: DWORD, \
+	Data: BYTE
+
+	mov	eax, [PCI_Config_Addr]
+	call	PCI_Common
+	mov	al, [Data]
+	out	dx, al
+	ret
+
+write_PCI_byte endp
+
+
+;**********************************************************************
+; Writes a word PCI register
+;**********************************************************************
+write_PCI_word proc pascal \
+	PCI_Config_Addr:DWORD, \
+	Data:WORD
+
+	mov	eax, [PCI_Config_Addr]
+	call	PCI_Common
+	mov	ax, [Data]
+	out	dx, ax
+	ret
+
+write_PCI_word endp
+
+
+;**********************************************************************
+; Writes a dword PCI register
+;**********************************************************************
+write_PCI_dword proc pascal \
+	PCI_Config_Addr: DWORD, \
+	Data:            DWORD
+
+	mov	eax, [PCI_Config_Addr]
+	call	PCI_Common
+	mov	eax, [Data]
+	out	dx, eax
+	ret
+
+write_PCI_dword endp
+
+
+
+
+;**********************************************************************
+; Disables PCI trapping (except virtualized PCI devices)
+;**********************************************************************
+Disable_PCI_Traps proc
+
+	; Has MPCI NB MSR been determined yet ?
+	mov	ecx, [PBus_Addr]
+	or	ecx, ecx
+	jnz	GotPbus
+
+	; No, get routing address for MPCI NB
+	push	bx
+	push	ID_MPCI		; MBus ID
+	push	1		; Instance
+	call	sys_lookup_device
+	pop	bx
+
+	mov	cx, dx
+	shl	ecx, 16
+	mov	cx, MPCI_PBUS
+	mov	[PBus_Addr], ecx
+
+	; Compute mask for virtual Southbridge
+	mov     ax, word ptr (VSM_Header PTR ds:[0]).SysStuff.Southbridge
+	shr	ah, 3
+	mov	cl, ah
+	mov	eax, 1
+	shl	eax, cl
+	or	al, 2			; Assume Northbridge is at 0x80000800
+	mov	[PBus_Mask], eax
+GotPbus:
+	rdmsr
+	mov	[PBus_Hi], edx		; Save original value for Restore_PCI_Traps
+	mov	[PBus_Lo], eax
+	and	eax, [PBus_Mask]	; Disable all except virtual NB & SB
+	wrmsr
+	ret
+
+Disable_PCI_Traps endp
+
+;**********************************************************************
+; Restores PCI trapping
+;**********************************************************************
+Restore_PCI_Traps proc uses eax edx
+       
+	mov	edx, [PBus_Hi]
+	mov	eax, [PBus_Lo]
+	wrmsr
+	ret
+
+Restore_PCI_Traps endp
+
+
+PBus_Addr    dd	0
+PBus_Hi      dd	0
+PBus_Lo      dd	0
+PBus_Mask    dd	0
+
+;**********************************************************************
+; Performs a PCI configuration write cycle sans any PCI trapping except
+; for virtualized PCI devices.
+;**********************************************************************
+write_PCI_no_trap proc pascal uses si \
+ 	PCI_Config_Addr:DWORD, \
+ 	Data:           DWORD, \
+ 	DataSize:       WORD
+
+	mov	ebx, [PCI_Config_Addr]
+	mov	si, [DataSize]
+
+	; Disable PCI trapping on all but virtualized PCI devices
+	call	Disable_PCI_Traps
+	
+	mov	eax, ebx
+	call	PCI_Common
+	mov	eax, [Data]
+	cmp	si, BYTE_IO
+	jne	short NotByte
+	out	dx, al
+	jmp	short RestoreTraps
+
+NotByte:
+	cmp	si, WORD_IO
+	je	short WordWrite
+	db	66h			; Make the following instruction an OUT DX,EAX
+WordWrite:
+	out	dx, ax
+RestoreTraps:
+	call	Restore_PCI_Traps	; Restore PCI trapping
+Exit:	ret
+
+write_PCI_no_trap endp
+
+
+;**********************************************************************
+; Performs a PCI configuration read cycle sans any PCI trapping except
+; for virtualized PCI devices.
+;**********************************************************************
+read_PCI_no_trap proc pascal uses si\
+	PCI_Config_Addr: DWORD, \
+	DataSize:        WORD
+
+	mov	ebx, [PCI_Config_Addr]
+	mov	si, [DataSize]
+
+
+	; Disable PCI trapping on all but virtualized PCI devices
+	call	Disable_PCI_Traps
+	
+	mov	eax, ebx		; Output PCI address
+	call	PCI_Common
+
+	cmp	si, BYTE_IO
+	jne	short NotByte
+	in	al, dx
+	jmp	short RestoreTraps
+
+NotByte:
+	cmp	si, WORD_IO
+	je	short WordRead
+	db	66h			; Makes the following instruction an IN EAX,DX
+WordRead:
+	in	ax, dx
+
+RestoreTraps:
+	push	eax
+	call	Restore_PCI_Traps	; Restore PCI trapping
+	pop	eax
+
+	mov	edx, eax
+	shr	edx, 16
+Exit:	ret
+
+read_PCI_no_trap endp
+
+
+
+	END 
+


Property changes on: trunk/gplvsa2/vsm_lib/pci.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/vsm_lib/present.asm
===================================================================
--- trunk/gplvsa2/vsm_lib/present.asm	                        (rev 0)
+++ trunk/gplvsa2/vsm_lib/present.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -0,0 +1,54 @@
+; 
+; 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 SYS_VSM_PRESENT 
+
+
+include sysmgr.inc
+include vsa2.inc
+
+.model tiny,c
+.586p
+.CODE
+
+
+;***********************************************************************
+; Returns TRUE if a VSM of the specified type is present
+;***********************************************************************
+sys_vsm_present PROC pascal \
+	VSM_Type: byte
+
+	mov	ecx, (VSM_Header PTR ds:[0]).SysStuff.SysMgr_Ptr
+	sub	ecx, SPECIAL_LOC
+	mov	ah, [VSM_Type]	
+	xor	al, al			; Assume VSM is not present
+VSM_Search:
+	mov	ecx, fs:(VSM_Header PTR [ecx]).SysStuff.Flink
+	jecxz	short Exit
+	cmp	ah, fs:(VSM_Header PTR [ecx]).VSM_Type
+	jne	VSM_Search
+
+	inc	al			; VSM is present
+Exit:	ret
+
+sys_vsm_present endp
+
+
+	END 
+


Property changes on: trunk/gplvsa2/vsm_lib/present.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/vsm_lib/regs.asm
===================================================================
--- trunk/gplvsa2/vsm_lib/regs.asm	                        (rev 0)
+++ trunk/gplvsa2/vsm_lib/regs.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -0,0 +1,368 @@
+; 
+; 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 library functions for accessing registers & headers
+
+include SYSMGR.INC
+include VSA2.INC
+include SMIMAC.MAC
+
+
+
+.model tiny,c
+.586p
+.CODE
+
+
+
+public Function
+
+externdef Async_VSM: dword
+externdef sys_system_call:proc
+
+Function	db	0, 0, 0, 0
+
+;***********************************************************************
+; Reports a parameter error
+; 
+; EAX = parameter
+;***********************************************************************
+ParamError proc
+	; SYS_REPORT_ERROR(ERR_BAD_PARAMETER, macro, param);
+	push	word ptr ERR_BAD_PARAMETER
+	mov	bh, [Function]
+	mov	bl, 1			; Parameter #1
+	push	ebx			; Info1
+	push	eax			; Info2
+	call	sys_report_error
+	ret
+
+ParamError endp
+
+
+;***********************************************************************
+; Validates if a macro is valid for the current message.
+; Output:  if "invalid macro usage"
+;            sys_report_error(ERR_ILLEGAL_MACRO);
+;            set CF
+;          else
+;            clear CF
+;            EBX = ptr to relevant VSM's stack
+;            ECX = ptr to relevant VSM's state
+; NOTE: Must preserve AX
+;***********************************************************************
+ValidateMacro proc
+	mov	ebx, [Async_VSM]
+	test	ebx, ebx
+	jz	short NotSynchronous
+
+	; Mark blocked VSM as 'Ready'
+	mov	fs:(VSM_Header PTR [ebx]).SysStuff.RunFlag, RUN_FLAG_READY
+	jmp	short Macro_OK
+	
+
+
+NotSynchronous:
+	; Always allow GET_REGISTER, GET_DESCRIPTOR & GET_HEADER
+	test	byte ptr [Function], 1
+	jnz	Async_Error
+
+	; Get ptr to System Manager's VSM header
+	mov	ebx, (VSM_Header PTR [bx]).SysStuff.SysMgr_Ptr
+	sub	ebx, SPECIAL_LOC
+
+Macro_OK:
+	mov	ecx, ebx
+	add	ebx, fs:(VSM_Header PTR [ecx]).SysStuff.SavedESP
+	add	ebx, EXTRA_SAVE
+
+	lea	ecx, (VSM_Header PTR [ecx]).SysStuff.State
+	clc
+	ret
+
+Async_Error:
+
+	; SYS_REPORT_ERROR(ERR_ILLEGAL_MACRO, macro, argument);
+	push	word ptr ERR_ILLEGAL_MACRO
+	push	dword ptr [Function]
+	movzx	eax, ax
+	push	eax
+	call	sys_report_error
+
+	mov	ax, 0FFFFh		; Return FFFFs
+	mov	dx, ax
+	stc
+	ret
+
+ValidateMacro endp
+
+
+
+
+
+;***********************************************************************
+; Helper routine for SYS_SET_REGISTER and SYS_SET_HEADER_DATA macros.
+; Input:
+;    AL = offset
+;   EBX = base
+;   ECX = data
+;    DL = max field offset
+;************************************************************ ***********
+SetHeader:
+	mov	dx, R_DR7		; Max valid field
+SetField proc
+
+	cmp	al, dl			; Valid field name ?
+	ja	short Error		; No
+
+	mov	dx, ax			; Save field size
+	xor	ah, ah			; Extract offset
+	movzx	eax, ax
+	mov	fs:[ebx+eax], cl	; Store data as BYTE
+	test	dx, (DWORD_SIZE OR WORD_SIZE) 
+	jz	Exit
+	test	dx, DWORD_SIZE		; WORD or DWORD ?
+	jz	Set_Word
+Set_Dword:
+	db	66h			; DWORD 
+Set_Word:
+	mov	fs:[ebx+eax], cx	; WORD
+	clc
+Exit:	ret
+
+Error:	call	ParamError
+	ret
+
+SetField endp
+
+
+
+;***********************************************************************
+; Helper routine for SYS_GET_REGISTER and SYS_GET_HEADER_DATA macros.
+; Input:
+;   EBX = base of structure
+;    AX = offset
+;    DX = maximum valid offset
+; Output:
+;   DX:AX = data
+;***********************************************************************
+GetField proc
+
+	cmp	al, dl			; Valid field name ?
+	ja	short Error		; No, return FFFFs
+
+	mov	cx, ax			; Save field size
+	xor	ah, ah			; Extract offset
+	movzx	eax, ax
+	mov	eax, fs:[ebx+eax] 	; Get requested value
+	test	cx, DWORD_SIZE		; DWORD field ?
+	jz	NotDword
+	mov	edx, eax		; Put 16 MSBs into DX
+	shr	edx, 16
+	ret
+
+NotDword:
+	xor	dx, dx			; Zero 16 MSBs
+	test	cx, WORD_SIZE		; WORD field ?
+	jnz	Exit
+	xor	ah, ah			; BYTE field
+Exit:	ret
+
+Error:	call	ParamError
+	mov	ax, 0FFFFh		; Return FFFFs
+	mov	dx, ax
+	ret
+
+GetField endp
+
+
+
+
+
+;***********************************************************************
+; ULONG sys_get_register(USHORT register)
+;***********************************************************************
+sys_get_register proc pascal \
+	Register:WORD
+
+	mov	ax, [Register]		; Get which register
+	mov	[Function], GET_REG	; In case of error
+	call	ValidateMacro		; Get ptr to registers
+	jc	Exit
+	
+	test	ax, FROM_HEADER		; Is register in SMM header ?
+	jnz	Get_Header
+	
+	mov	dx, R_GS
+	call	GetField		; Get register from saved state buffer
+	
+Exit:	ret
+
+sys_get_register endp
+
+
+
+
+
+;***********************************************************************
+; void sys_set_register(USHORT register, ULONG Data)
+;***********************************************************************
+sys_set_register proc pascal \
+	Register: WORD, \
+	Data:     DWORD
+
+	mov	ax, [Register]		; Get register
+	mov	[Function], SET_REG	; In case of error
+	call	ValidateMacro		; Get ptr to registers
+	jc	Exit
+
+	test	ax, FROM_HEADER		; Is register in SMM header ?
+	jnz	Set_Header
+		
+	mov	ecx, [Data]
+
+	mov	dx, R_ESP		; Max valid register field
+	call	SetField
+
+Exit:	ret
+
+sys_set_register endp
+
+
+
+
+;***********************************************************************
+; Gets a field from the top-level SMM header
+; ULONG sys_get_header_data(USHORT SMM_Field)
+;***********************************************************************
+sys_get_header_data proc pascal \
+	SMM_Field: WORD
+
+	mov	ax, [SMM_Field]		; Get SMM header field
+	mov	[Function], GET_HDR	; In case of error
+	call	ValidateMacro
+	jc	short Exit
+
+	mov	ax, [SMM_Field]		; Get SMM header field
+	test	ax, FROM_HEADER		; Validate field
+	jnz	short Get_Header
+	call	ParamError
+	jmp	short Exit
+
+Get_Header::
+	mov	ebx, ecx
+	mov	dx, R_DR7		; Max valid field
+	call	GetField
+Exit:	ret
+
+sys_get_header_data endp
+
+
+
+;***********************************************************************
+; void sys_set_header_data(USHORT SMM_Field, ULONG Data)
+;***********************************************************************
+sys_set_header_data proc pascal \
+	SMM_Field: WORD, \
+	Data:      DWORD
+
+	mov	ax, [SMM_Field]		; Get SMM header field
+	mov	[Function], SET_HDR	; In case of error
+	call	ValidateMacro
+	jc	short Exit
+
+	test	ax, FROM_HEADER		; Validate field
+	jnz	short Set_Header
+	call	ParamError
+	jmp	short Exit
+	
+Set_Header::	
+	mov	ebx, ecx
+	mov	ecx, [Data]
+	call	SetHeader
+Exit:	ret
+
+sys_set_header_data endp
+
+
+
+;***********************************************************************
+; Reports an error
+;***********************************************************************
+sys_report_error proc pascal uses di \
+	Error_Code: WORD,  \
+	Info1:      DWORD, \
+	Info2:      DWORD
+
+	mov	di,  [Error_Code]
+	mov	ebx, [Info1]
+	mov	ecx, [Info2]
+
+	mov	ax, SYS_CODE_ERROR
+	call	sys_system_call
+	ret
+
+sys_report_error endp
+
+
+;***********************************************************************
+; void sys_return_result(ULONG Result);
+;
+; Implements the SYS_RETURN_RESULT macro
+; Returns a byte/word/dword result to the appropriate environment
+;
+;***********************************************************************
+sys_return_result proc pascal \
+	Result:  DWORD
+
+
+	mov	ebx, [Result]
+
+	; Return to another VSM's environment ?	
+	mov	ecx, [Async_VSM]
+	mov	eax, (VSM_Header PTR ds:[0]).SysStuff.SysMgr_Ptr
+	xor	ax, ax
+	cmp	ecx, eax
+	je	RetToTopLevel
+
+	; Yes, get the data size
+	mov	dl, byte ptr fs:(VSM_Header PTR [ecx]).SysStuff.State.data_size
+	mov	ax, R_AL
+	cmp	dl, BYTE_IO
+	je	SetReg
+	mov	ax, R_AX
+	cmp	dl, WORD_IO
+	je	SetReg
+	mov	ax, R_EAX
+SetReg:
+	push	ax			; Register AL/AX/EAX
+	push	ebx			; Data
+	call	sys_set_register
+	jmp	Exit
+
+RetToTopLevel:
+	mov	ax, SYS_CODE_RESULT	; Let SysMgr return the result
+	call	sys_system_call
+Exit:	ret
+	
+sys_return_result endp
+
+
+	END 
+


Property changes on: trunk/gplvsa2/vsm_lib/regs.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/vsm_lib/resource.asm
===================================================================
--- trunk/gplvsa2/vsm_lib/resource.asm	                        (rev 0)
+++ trunk/gplvsa2/vsm_lib/resource.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -0,0 +1,146 @@
+; 
+; 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 implements the resource-related macros:
+;*          SYS_MBUS_DESCRIPTOR
+;*          SYS_IO_DESCRIPTOR
+;*          SYS_ALLOCATE_RESOURCE
+;*          SYS_SET_DECODE    
+;*******************************************************************************
+
+
+include sysmgr.inc
+.model tiny,c
+.586p
+.CODE
+
+
+
+externdef sys_system_call:proc
+
+
+
+;***********************************************************************
+; ULONG sys_mbus_descriptor(USHORT Address, ULONG * Buffer, UCHAR IO_Flag);
+;
+; Returns the MSR address & contents of the descriptor assigned to a
+; virtualized PCI address or an I/O address.
+;
+;***********************************************************************
+sys_mbus_descriptor proc pascal   \
+	Address: WORD, \
+ 	Buffer: PTR,   \
+	IO_Flag: WORD
+	
+	mov	bx, [Address]
+	mov	cx, [IO_Flag]
+	mov	ax, SYS_CODE_DESCRIPTOR
+	call	sys_system_call	
+	; Returns:
+	;   ECX = MSR address
+	;   EDX:EAX = original MSR value
+
+	mov	bx, [Buffer]		; Store MSR value into caller's buffer
+	mov	[bx+0], eax
+	mov	[bx+4], edx
+
+	push	ecx			; Return MSR address
+	pop	ax
+	pop	dx
+	ret
+
+sys_mbus_descriptor endp
+
+
+
+
+;***********************************************************************
+; ULONG sys_resource(USHORT Resource, ULONG Param1, ULONG Param2);
+;
+; Records a VSM's use of a non-shareable resource (e.g. GPIO, IRQ, etc.)
+; If the resources is a memory or I/O PCI BAR, it returns the assigned
+; PCI address.
+;
+;***********************************************************************
+sys_resource proc pascal  uses edi si \
+	Resource:   BYTE,  \
+	BAR:        WORD,  \
+	BaseRange:  DWORD, \
+	Pci_ID:     WORD,  \
+	MBus_ID:    WORD
+
+	mov	bl, [Resource]
+	mov	si, [BAR]
+	mov	ecx, [BaseRange]
+	mov	di, [MBus_ID]
+	shl	edi, 16
+	mov	di, [Pci_ID]
+	mov	ax, SYS_CODE_RESOURCE
+	call	sys_system_call
+
+	; If xxxx != 0x0000, then return 0x8000xxxx, where xxxx is return value
+	xor	dx, dx	
+	or	ax, ax
+	jz	Exit
+	or	dh, 80h
+Exit:	ret
+
+sys_resource endp
+
+
+
+
+;***********************************************************************
+; ULONG __pascal sys_lookup_device(USHORT DeviceID, USHORT Instance);
+; Returns the routing bits for the specified Device ID.
+;***********************************************************************
+sys_lookup_device proc pascal \
+	Device_ID: word, \
+	Instance:  word
+
+	mov	bx, [Device_ID]
+	mov	cx, [Instance]
+	mov	ax, SYS_CODE_LOOKUP
+	call	sys_system_call
+	ret
+
+sys_lookup_device endp
+
+
+
+
+;***********************************************************************
+;void Set_Address_Decode(USHORT Address, USHORT Decode) 
+;***********************************************************************
+sys_address_decode proc pascal \
+	Address:   WORD, \
+	Decode: WORD
+
+	mov	bx, [Address]
+	mov	cx, [Decode]
+	mov	ax, SYS_CODE_DECODE
+	call	sys_system_call
+	ret
+
+sys_address_decode endp
+
+
+
+	END 
+


Property changes on: trunk/gplvsa2/vsm_lib/resource.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/vsm_lib/sw_int.asm
===================================================================
--- trunk/gplvsa2/vsm_lib/sw_int.asm	                        (rev 0)
+++ trunk/gplvsa2/vsm_lib/sw_int.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -0,0 +1,87 @@
+; 
+; 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 the SYS_SW_INTERRUPT macro.  
+
+include sysmgr.inc
+.model tiny,c
+.586p
+.CODE
+
+
+
+externdef sys_system_call:proc
+
+
+
+;***********************************************************************
+; void sys_software_interrupt(USHORT Interrupt, Regs * RegsBuffer);
+;
+; This routine performs the equivalent of a software INT.            
+;
+; Input:
+;   Interrupt = interrupt to execute
+;   RegBuffer = ptr to buffer containing general-purpose registers (16 bit)
+;
+;***********************************************************************
+
+sys_software_interrupt proc pascal \
+	Interrupt:	WORD,	\
+	RegsBuffer:	PTR Regs
+
+	movzx   ecx, [RegsBuffer]		; Get ptr to Regs[]
+	movzx   ebx, [Interrupt]		; Get 4 * INT#
+	shl	bx, 2
+	mov     ax, SYS_CODE_SW_INT
+	call    sys_system_call
+	ret
+
+sys_software_interrupt endp
+
+
+
+;***********************************************************************
+; void sys_state(USHORT Flag, UCHAR * Buffer);
+;
+; This routine saves/restores the non-SMM state. 
+; It's intended purpose is to facilitate SaveToRAM and SaveToDisk VSMs.
+;
+; Input:
+;   Flag:      0 = Save   1 = Restore
+;   RegBuffer: Ptr to state buffer.  Must be STATE_SIZE bytes
+;
+;***********************************************************************
+sys_state proc pascal uses di \
+	Flag:	WORD,	\
+	Buffer:	PTR byte
+
+	movzx   edi, [Buffer]
+	mov     cx, [Flag]
+
+	mov     ax, SYS_CODE_STATE
+	call    sys_system_call
+
+	ret
+
+sys_state endp
+
+
+
+	END 
+


Property changes on: trunk/gplvsa2/vsm_lib/sw_int.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/vsm_lib/sysinfo.asm
===================================================================
--- trunk/gplvsa2/vsm_lib/sysinfo.asm	                        (rev 0)
+++ trunk/gplvsa2/vsm_lib/sysinfo.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -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 
+; 
+;*   Function:                                                         *
+;*     Implementation of the macros:                                   *
+;*        SYS_GET_SYSTEM_INFO                                          *
+;*        SYS_LOGICAL_TO_PHYSICAL   
+
+include sysmgr.inc
+include vsa2.inc
+
+.model tiny,c
+.586p
+.CODE
+
+
+
+;***********************************************************************
+; Gets hardware information
+;***********************************************************************
+sys_get_system_info proc pascal uses si \
+	buffer:	PTR
+
+	; Get a ptr to the System Manager's hardware information structure
+	xor	bx, bx
+	mov	esi, (VSM_Header PTR [bx]).SysStuff.SysMgr_Ptr
+	movzx	eax, fs:(InfoStuff PTR [esi]).HardwareInfo
+	add	esi, eax
+	sub	esi, SPECIAL_LOC
+
+
+	mov	bx, [buffer]
+
+	; Fetch the data
+	mov	cx, sizeof(Hardware)/2
+	cld
+Copy:	lodsw	fs:[esi]
+	mov	[bx], ax
+	add	bx, 2
+	loop	Copy
+
+	ret
+
+sys_get_system_info endp
+
+
+
+;***********************************************************************
+; Converts a logical offset to a physical address
+;***********************************************************************
+sys_logical_to_physical proc pascal \
+	Address: PTR
+
+	movzx	eax, [Address]
+	xor	bx, bx
+	add	eax, (VSM_Header PTR [bx]).SysStuff.State._CS.base
+	mov	edx, eax
+	shr	edx, 16
+	ret
+
+sys_logical_to_physical endp 
+
+
+
+
+
+	END 
+


Property changes on: trunk/gplvsa2/vsm_lib/sysinfo.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/vsm_lib/utils.asm
===================================================================
--- trunk/gplvsa2/vsm_lib/utils.asm	                        (rev 0)
+++ trunk/gplvsa2/vsm_lib/utils.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -0,0 +1,203 @@
+; 
+; 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 generic VSM library functions.
+
+.model tiny,c
+.586p
+.CODE
+
+
+
+
+
+
+;***********************************************************************
+; UCHAR in_8(USHORT io_port)
+;***********************************************************************
+in_8 proc  pascal io_port:word
+
+	mov	dx, io_port
+	in	al, dx
+	ret
+   
+in_8 endp
+
+
+;***********************************************************************
+; void out_8(USHORT io_port, UCHAR io_data)
+;***********************************************************************
+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
+
+;***********************************************************************
+; USHORT in_16(USHORT io_port)
+;***********************************************************************
+in_16 proc  pascal, io_port:WORD
+
+	mov	dx, io_port
+	in	ax, dx
+	ret
+   
+in_16 endp
+
+
+;***********************************************************************
+; void out_16(USHORT io_port, USHORT io_data)
+;***********************************************************************
+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
+
+
+
+;***********************************************************************
+; ULONG in_32(USHORT io_port)
+;***********************************************************************
+in_32	proc   pascal	io_port: WORD
+
+	mov	dx, io_port
+	in	eax, dx
+	mov	edx, eax
+	shr	edx, 16
+	ret
+
+in_32	endp
+
+
+;***********************************************************************
+;
+; void out_32(USHORT io_port, ULONG io_data)
+;***********************************************************************
+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
+
+
+
+
+
+
+
+write_flat proc pascal \
+	Address: DWORD,\
+	Data:    DWORD
+
+	mov	ebx, [Address]
+	mov	eax, [Data]
+	mov	fs:[ebx], eax
+	ret
+
+write_flat endp
+
+
+read_flat proc pascal \
+	Address: DWORD
+
+	mov	ebx, [Address]
+	mov	eax, fs:[ebx]
+	mov	edx, eax
+	shr	edx, 16
+	ret
+
+read_flat endp
+
+
+write_flat_word proc pascal \
+	Address: DWORD,\
+	Data:    WORD
+
+	mov	ebx, [Address]
+	mov	ax, [Data]
+	mov	fs:[ebx], ax
+	ret
+
+write_flat_word endp
+
+
+read_flat_word proc pascal \
+	Address: DWORD
+
+	mov	ebx, [Address]
+	mov	ax, fs:[ebx]
+	ret
+
+read_flat_word endp
+
+
+
+write_flat_byte proc pascal \
+	Address: DWORD,\
+	Data:    BYTE
+
+	mov	ebx, [Address]
+	mov	al, [Data]
+	mov	fs:[ebx], al
+	ret
+
+write_flat_byte endp
+
+
+read_flat_byte proc pascal \
+	Address: DWORD
+
+	mov	ebx, [Address]
+	mov	al, fs:[ebx]
+	ret
+
+read_flat_byte endp
+
+
+
+
+read_timestamp proc
+
+	RDTSC
+	mov	edx, eax
+	shr	edx, 16
+	ret
+
+read_timestamp endp
+
+
+
+	END 
+


Property changes on: trunk/gplvsa2/vsm_lib/utils.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/vsm_lib/virtual.asm
===================================================================
--- trunk/gplvsa2/vsm_lib/virtual.asm	                        (rev 0)
+++ trunk/gplvsa2/vsm_lib/virtual.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -0,0 +1,94 @@
+; 
+; 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 virtual register library functions.
+
+include sysmgr.inc
+include vsa2.inc
+
+.model tiny,c
+.586p
+.CODE
+
+
+
+
+externdef sys_system_call:proc
+
+
+
+
+;***********************************************************************
+; IMPLEMENTATION NOTE:
+;
+; Using a system call for virtual register access by a VSM has
+; advantages over performing I/O:
+;
+; 1) There is no dependency on VIRTUAL_BASE. It can be changed
+;    without requiring recompilation of the VSM.
+;
+; 2) Better performance.  There is only one SMI for a system call
+;    versus two for I/O (index & data).
+;
+; 3) It solves the problem of atomic accesses to index/data pairs.      
+;
+;***********************************************************************
+
+
+;***********************************************************************
+; void sys_set_virtual_register(USHORT Index, USHORT Data)
+;***********************************************************************
+
+sys_set_virtual_register proc pascal \
+	VR_Index:WORD, \
+	VR_Data: WORD
+
+	mov	bx, VR_Index
+	mov	cx, VR_Data
+	mov	ax, SYS_CODE_SET_VIRTUAL
+	call	sys_system_call
+
+	ret
+
+sys_set_virtual_register endp
+
+
+
+
+;***********************************************************************
+; USHORT sys_get_virtual_register(USHORT Index)
+;***********************************************************************
+sys_get_virtual_register proc pascal  \
+	VR_Index:word
+
+	mov	bx, VR_Index
+	mov	ax, SYS_CODE_GET_VIRTUAL
+	call	sys_system_call
+
+	ret
+
+sys_get_virtual_register endp
+
+
+
+
+
+
+	END 
+


Property changes on: trunk/gplvsa2/vsm_lib/virtual.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/vsm_lib/vsa2util.asm
===================================================================
--- trunk/gplvsa2/vsm_lib/vsa2util.asm	                        (rev 0)
+++ trunk/gplvsa2/vsm_lib/vsa2util.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -0,0 +1,204 @@
+; 
+; 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 the SYS_GET_NEXT_MSG & SYS_REGISTER_EVENT  *
+;*     macros as well as the code to perform a system call.  
+
+include sysmgr.inc
+include smimac.mac
+include vsa2.inc
+
+.model tiny,c
+.586p
+.CODE
+
+
+
+
+public Async_VSM
+
+Async_VSM	dd	0
+
+
+;***********************************************************************
+; USHORT sys_get_next_msg(ULONG *)
+;
+; This routine retrieves a message packet from a VSM's message queue.
+;
+; Input:
+;   MsgPacket = ptr to message packet (relative to DS)
+; Returns:
+;   Message code
+;***********************************************************************
+
+sys_get_next_msg proc uses si di \
+	MsgPacket:  PTR
+
+CheckMsgQ:
+	xor	di, di
+	ASSUME	di: PTR VSM_Header
+
+	mov	si, [di].SysStuff.Qtail	; Is the message queue empty ?
+	cmp	si, [di].SysStuff.Qhead
+	jne	MessageIsWaiting
+
+	mov	ax, SYS_CODE_EXIT	; Return to the System Manager
+	smint
+
+	; Returns here when there are message(s) pending for this VSM.
+	jmp	short CheckMsgQ
+
+
+MessageIsWaiting:
+	ASSUME	si: PTR Message
+	lea	di, [si+sizeof(Message)]
+	mov	dx, [si].Msg		; Get the message code
+
+	mov	eax, [si].From_VSM	; Get VSM message is from
+	mov	[Async_VSM], eax
+
+
+	; Copy message packet into caller's buffer
+	cld
+	lea	si, [si].Param
+	mov	cx, MAX_MSG_PARAM
+	mov	bx, [MsgPacket]		; Get ptr to message buffer
+CopyMsg:
+	lodsd
+	mov	[bx], eax
+	add	bx, 4
+	loop	CopyMsg
+
+	;
+	; Advance the message queue ptr
+	;
+	mov	si, OFFSET VSM_Header.SysStuff
+	ASSUME	si: PTR System
+	cmp	di, [si].EndMsgQ	; Is Qtail at end ?
+	jb	UpdateQtail
+	lea	di, [si].MsgQueue	; Yes, wrap ptr to start of queue
+UpdateQtail:
+	mov	[si].Qtail, di
+
+
+	; Return value of function is the message code
+	mov	ax, dx
+Exit:	ret
+
+
+
+	ASSUME	si:NOTHING
+
+sys_get_next_msg endp
+
+
+;***********************************************************************
+; USHORT sys_query_msg_queue(ULONG *)
+;
+; This routine queries the VSM's message queue
+;
+; Input:
+;   If a message is present:
+;       MsgPacket = ptr to message packet (relative to DS)
+; Returns:
+;   If a message is present:
+;       Message code
+;   Else
+;       0xFFFF
+;***********************************************************************
+
+sys_query_msg_queue proc uses si  \
+	MsgPacket:  PTR
+
+	xor	bx, bx
+	ASSUME  bx: PTR VSM_Header
+
+	mov	si, [bx].SysStuff.Qtail	; Is the message queue empty ?
+	cmp	si, [bx].SysStuff.Qhead
+	mov	ax, 0FFFFh		; Return value if queue is empty
+	je 	short Exit
+
+
+	ASSUME	si: PTR Message
+	mov	dx, [si].Msg		; Get the message code
+
+
+	; Copy message packet into caller's buffer
+	cld
+	lea	si, [si].Param
+	mov	cx, MAX_MSG_PARAM
+	mov	bx, [MsgPacket]		; Get ptr to message buffer
+CopyMsg:
+	lodsd
+	mov	dword ptr [bx], eax
+	add	bx, 4
+	loop	CopyMsg
+
+	; NOTE:  Qtail is not advanced !!
+
+	; Return value of function is the message code
+	mov	ax, dx
+Exit:	ret
+
+sys_query_msg_queue endp
+
+
+
+
+
+
+;***********************************************************************
+; Registers this VSM as a handler for an event
+;***********************************************************************
+sys_register_event proc pascal uses edi \
+	Event: EVENT,	\
+	Param1: DWORD,	\
+	Param2: DWORD,	\
+	Priority: WORD
+
+	mov	bx, [Event]		; Get event to register
+	shl	ebx, 16
+	mov	bx,  [Priority]		; Get event priority
+	mov	ecx, [Param1]		; Get parameters
+	mov	edi, [Param2]
+
+	mov	ax, SYS_CODE_EVENT
+	call	sys_system_call
+	ret
+
+sys_register_event endp
+
+
+
+
+
+ ;***********************************************************************
+; Performs a system call
+;***********************************************************************
+sys_system_call proc
+
+	smint
+	ret
+
+sys_system_call endp
+
+
+
+	END 
+


Property changes on: trunk/gplvsa2/vsm_lib/vsa2util.asm
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gplvsa2/vsm_lib/yield.asm
===================================================================
--- trunk/gplvsa2/vsm_lib/yield.asm	                        (rev 0)
+++ trunk/gplvsa2/vsm_lib/yield.asm	2009-03-20 18:32:39 UTC (rev 1)
@@ -0,0 +1,49 @@
+; 
+; 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 the SYS_YIELD_CONTROL macro. 
+
+include vsa2.inc
+include sysmgr.inc
+.model tiny,c
+.586p
+.CODE
+
+
+
+externdef sys_system_call:proc
+
+
+
+sys_yield_control proc pascal \
+	Milliseconds: DWORD
+
+	mov	ecx, [Milliseconds]
+	jecxz	Exit
+
+	mov	ax, SYS_CODE_YIELD		; Yield control to the System Manager
+	call	sys_system_call
+
+Exit:	ret
+
+sys_yield_control endp
+
+
+	END 
+


Property changes on: trunk/gplvsa2/vsm_lib/yield.asm
___________________________________________________________________
Added: svn:executable
   + *





More information about the coreboot mailing list