mirror of
				https://github.com/Telecominfraproject/OpenCellular.git
				synced 2025-10-31 18:38:06 +00:00 
			
		
		
		
	firmware/coreboot: Subtree merged blobs
This commit is contained in:
		
							
								
								
									
										1
									
								
								firmware/coreboot/3rdparty/blobs
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								firmware/coreboot/3rdparty/blobs
									
									
									
									
										vendored
									
									
								
							 Submodule firmware/coreboot/3rdparty/blobs deleted from 78a02a7f9d
									
								
							
							
								
								
									
										
											BIN
										
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/family_10h-family_14h/microcode_amd.bin
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/family_10h-family_14h/microcode_amd.bin
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/family_15h/microcode_amd_fam15h.bin
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/family_15h/microcode_amd_fam15h.bin
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										9
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/README
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/README
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| This VSA is taken from | ||||
| http://marcjonesconsulting.com/gplvsa/gpl_vsa_lx_102.bin.gz | ||||
|  | ||||
| and decompressed for simplicity. The original SHA1 was: | ||||
| 96a6097331278d644230eac4fc39bcfebc3c9a16  gpl_vsa_lx_102.bin.gz | ||||
|  | ||||
| While we have the source code (see gplvsa_ii), it requires a rather | ||||
| esoteric build system. Should this be fixed, we could consider adding | ||||
| VSA to the coreboot tree. Until then, source and binary can reside here. | ||||
							
								
								
									
										
											BIN
										
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gpl_vsa_lx_102.bin
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gpl_vsa_lx_102.bin
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										27
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/README.txt
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										27
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/README.txt
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| This is the VSA (Virtual Systems Architecture) code used on the AMD | ||||
| Geode series of processors. The Geode, rather than carrying lots of | ||||
| legacy hardware interfaces that are presumed to exist on x86 systems | ||||
| that might be painful to implement on a highly integrated, low power | ||||
| processor, the Geode often emulates such interfaces by use of software that is | ||||
| invoked by special traps that take place when the processor accesses | ||||
| these devices. | ||||
|  | ||||
| Note that the code here is not currently buildable on open source | ||||
| systems, being only buildable using very obsolete and no longer | ||||
| commercially availble Windows based commercial toolchains.  On the | ||||
| OLPC system, these "blobs" of binary code are concatenated together | ||||
| with LinuxBIOS and the bootloader, and set up to be executed by | ||||
| LinuxBIOS early in the Geode's initialization sequence (no linking is | ||||
| involved). | ||||
|  | ||||
| If you are interested for some reason in making this code buildable on | ||||
| free systems, please let us know of your progress.  It is under the  | ||||
| GNU LGPL.  | ||||
|  | ||||
| Also note that VESA emulation is *not* included in this (nor does what | ||||
| we use on the OLPC machine use VESA at this date; we use frame | ||||
| buffer code for our console); that code was not owned by AMD and | ||||
| therefore not theirs to make available.  Our thanks to AMD to making | ||||
| the VSA code available. | ||||
|  | ||||
| 		     Jim Gettys, OLPC, September 27, 2006 | ||||
							
								
								
									
										42
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/build/legacy.mak
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										42
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/build/legacy.mak
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| # | ||||
| # Copyright (c) 2006 Advanced Micro Devices,Inc. ("AMD"). | ||||
| # | ||||
| # This library is free software; you can redistribute it and/or modify | ||||
| # it under the terms of the GNU Lesser General Public License as | ||||
| # published by the Free Software Foundation; either version 2.1 of the | ||||
| # License, or (at your option) any later version. | ||||
| # | ||||
| # This code is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| # Lesser General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU Lesser General | ||||
| # Public License along with this library; if not, write to the | ||||
| # Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| # Boston, MA 02111-1307 USA  | ||||
| # | ||||
|  | ||||
| VSMNAME	= legacy | ||||
| VSMDIR	= $(VSA2ROOT)\$(VSMNAME) | ||||
|  | ||||
|  | ||||
| all: | ||||
| 	cd $(VSMDIR) | ||||
| 	$(MAKE) /nologo all "VSA2ROOT=$(VSA2ROOT)" "USER=$(USER)" "BUILDOBJ=$(OBJECT)" "CPU=$(CPU)" | ||||
| 	cd $(MAKEDIR) | ||||
|  | ||||
| clean: | ||||
| 	cd $(VSMDIR) | ||||
| 	$(MAKE) /nologo clean | ||||
| 	cd $(MAKEDIR) | ||||
|  | ||||
| cleanlocal: | ||||
| 	cd $(VSMDIR) | ||||
| 	$(MAKE) /nologo cleanlocal | ||||
| 	cd $(MAKEDIR) | ||||
|  | ||||
| cleanall: | ||||
| 	cd $(VSMDIR) | ||||
| 	$(MAKE) /nologo cleanall | ||||
| 	cd $(MAKEDIR) | ||||
							
								
								
									
										40
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/build/lxvg.mak
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										40
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/build/lxvg.mak
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| # Copyright (c) 2007-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| # | ||||
| # This library is free software; you can redistribute it and/or modify | ||||
| # it under the terms of the GNU Lesser General Public License as | ||||
| # published by the Free Software Foundation; either version 2.1 of the | ||||
| # License, or (at your option) any later version. | ||||
| # | ||||
| # This code is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| # Lesser General Public License for more details. | ||||
|  | ||||
| # You should have received a copy of the GNU Lesser General | ||||
| # Public License along with this library; if not, write to the | ||||
| # Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| # Boston, MA 02111-1307 USA | ||||
|  | ||||
| VSMNAME	= lxvg | ||||
| VSMDIR	= $(VSA2ROOT)\$(VSMNAME) | ||||
|  | ||||
| all: | ||||
| 	cd $(VSMDIR) | ||||
| 	$(MAKE) /nologo all "VSA2ROOT=$(VSA2ROOT)" "USER=$(USER)" "BUILDOBJ=$(OBJECT)" "CPU=$(CPU)" | ||||
| 	cd $(MAKEDIR) | ||||
|  | ||||
|  | ||||
| clean: | ||||
| 	cd $(VSMDIR) | ||||
| 	$(MAKE) /nologo clean | ||||
| 	cd $(MAKEDIR) | ||||
|  | ||||
| cleanlocal: | ||||
| 	cd $(VSMDIR) | ||||
| 	$(MAKE) /nologo cleanlocal | ||||
| 	cd $(MAKEDIR) | ||||
|  | ||||
| cleanall: | ||||
| 	cd $(VSMDIR) | ||||
| 	$(MAKE) /nologo cleanall | ||||
| 	cd $(MAKEDIR) | ||||
							
								
								
									
										99
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/build/makefile
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										99
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/build/makefile
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,99 @@ | ||||
| # | ||||
| # Copyright (c) 2006 Advanced Micro Devices,Inc. ("AMD"). | ||||
| # | ||||
| # This library is free software; you can redistribute it and/or modify | ||||
| # it under the terms of the GNU Lesser General Public License as | ||||
| # published by the Free Software Foundation; either version 2.1 of the | ||||
| # License, or (at your option) any later version. | ||||
| # | ||||
| # This code is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| # Lesser General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU Lesser General | ||||
| # Public License along with this library; if not, write to the | ||||
| # Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| # Boston, MA 02111-1307 USA | ||||
| # | ||||
| #	makefile  for VSA2 | ||||
|  | ||||
|  | ||||
|  | ||||
| !ifndef VSA2ROOT | ||||
| VSA2ROOT	= $(MAKEDIR)\.. | ||||
| !endif | ||||
|  | ||||
| USER		= $(VSA2ROOT) | ||||
|  | ||||
| OBJECT		= $(MAKEDIR)\obj | ||||
|  | ||||
| .SUFFIXES: | ||||
| .SUFFIXES : .exe .vsm .lib .bin .mak .cln | ||||
|  | ||||
| !include setvars.mak | ||||
|  | ||||
| VSMS = \ | ||||
| 	$(OBJECT)\sysmgr.vsm \ | ||||
| 	$(OBJECT)\vsainit.bin \ | ||||
| 	$(OBJECT)\legacy.vsm \ | ||||
| 	$(OBJECT)\lxvg.vsm | ||||
|  | ||||
| VSM_CLN0		= $(VSMS:.vsm=.cln) | ||||
| VSM_CLN			= $(VSM_CLN0:.bin=.cln) | ||||
|  | ||||
|  | ||||
| ####################################################################### | ||||
| # | ||||
| #				Targets | ||||
| # | ||||
| ####################################################################### | ||||
| all: $(OBJECT) $(VSMS) basic | ||||
|  | ||||
| basic: setenv | ||||
| 	@$(ECHO) Make LX VSA Image | ||||
| 	$(MAKE) /nologo vsa_lx.bin | ||||
|  | ||||
| $(VSMS): setenv | ||||
|  | ||||
| vsa_lx.bin $(OBJECT)\amd_vsa_lx.bin: $(OBJECT)\vsainit.bin $(OBJECT)\vsa2.bin | ||||
| 	@$(ECHO) Concatenate for LX Image ... | ||||
| 	-$(BINCOPY) $(OBJECT)\vsainit.bin+$(OBJECT)\vsa2.bin+$(OBJECT)\lxvg.vsm $(OBJECT)\amd_vsa_lx.bin | ||||
|  | ||||
| vsa2.bin $(OBJECT)\vsa2.bin: $(OBJECT)\sysmgr.vsm $(OBJECT)\legacy.vsm | ||||
| 	@$(ECHO) Concatenate for VSA2.BIN Image ... | ||||
| 	-$(BINCOPY) $(OBJECT)\sysmgr.vsm+$(OBJECT)\legacy.vsm $(OBJECT)\vsa2.bin | ||||
|  | ||||
| #This and only this clean target must exist as it is called by cleanall | ||||
| #cleanall and cleanlocal are defined in rules.mak | ||||
|  | ||||
| clean: cleanlocal cleanlib $(VSM_CLN) tools_clean | ||||
|  | ||||
| $(OBJECT): | ||||
| 	-@md $(OBJECT) | ||||
|  | ||||
|  | ||||
| ############################################ | ||||
| # Tools.lib | ||||
| ############################################ | ||||
| tools_clean: | ||||
| 	-@cd $(VSA2ROOT)\vsm_lib | ||||
| 	-@$(MAKE) /nologo cleanall | ||||
| 	-@cd $(MAKEDIR) | ||||
|  | ||||
|  | ||||
| ########################################################################### | ||||
| #						   All VSMs | ||||
| ########################################################################### | ||||
| {$(MAKEDIR)}.mak{$(OBJECT)}.vsm: | ||||
| 	$(MAKE) /nologo -f $(MAKEDIR)\%|fF.mak "VSA2ROOT=$(VSA2ROOT)" "USER=$(VSA2ROOT)" "OBJECT=$(OBJECT)" "CPU=$(CPU)" | ||||
|  | ||||
| {$(MAKEDIR)}.mak{$(OBJECT)}.bin: | ||||
| 	$(MAKE) /nologo -f $(MAKEDIR)\%|fF.mak "VSA2ROOT=$(VSA2ROOT)" "USER=$(VSA2ROOT)" "OBJECT=$(OBJECT)" "CPU=$(CPU)" | ||||
|  | ||||
| {$(MAKEDIR)}.mak{$(OBJECT)}.cln: | ||||
| 	-@$(MAKE) /nologo -f $(MAKEDIR)\%|fF.mak cleanall "VSA2ROOT=$(VSA2ROOT)" "USER=$(VSA2ROOT)" | ||||
|  | ||||
|  | ||||
| !include rules.mak | ||||
|  | ||||
							
								
								
									
										138
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/build/rules.mak
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										138
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/build/rules.mak
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,138 @@ | ||||
| # | ||||
| # Copyright (c) 2006 Advanced Micro Devices,Inc. ("AMD"). | ||||
| # | ||||
| # This library is free software; you can redistribute it and/or modify | ||||
| # it under the terms of the GNU Lesser General Public License as | ||||
| # published by the Free Software Foundation; either version 2.1 of the | ||||
| # License, or (at your option) any later version. | ||||
| # | ||||
| # This code is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| # Lesser General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU Lesser General | ||||
| # Public License along with this library; if not, write to the | ||||
| # Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| # Boston, MA 02111-1307 USA  | ||||
| # | ||||
|  | ||||
| ############################################################################## | ||||
| # | ||||
| #	Common targets | ||||
| # | ||||
| ############################################################################## | ||||
|  | ||||
|  | ||||
|  | ||||
| setenv: | ||||
| !if "$(VARS_SET)" != "VSA_II" | ||||
| 	@$(SETENV) PATH=.\;$(VSA2ROOT)\uti;$(PATH); | ||||
| 	@$(SETENV) Lib=.\;$(VSA2ROOT)\lib;$(VSA2ROOT)\build;$(LIB); | ||||
| 	@$(SETENV) VARS_SET=VSA_II | ||||
| !endif | ||||
| 	@echo INCLUDE=$(INCLUDE) | ||||
|  | ||||
| $(BUILD_DIR)\obj\$(TOOL_LIB):  | ||||
| 	cd $(VSA2ROOT)\vsm_lib | ||||
| 	$(MAKE) /nologo all "BUILDOBJ=$(OBJECT)" "CPU=$(CPU)" | ||||
| 	cd $(MAKEDIR) | ||||
|  | ||||
| cleanlib: | ||||
| 	cd $(VSA2ROOT)\vsm_lib | ||||
| 	$(MAKE) /nologo cleanall | ||||
| 	cd $(MAKEDIR)	 | ||||
|  | ||||
| cleanlocal:  | ||||
| 	-@IF EXIST $(OBJECT)\*.def $(DEL) $(OBJECT)\*.def | ||||
| 	-@IF EXIST $(OBJECT)\*.lnk $(DEL) $(OBJECT)\*.lnk | ||||
| 	-@IF EXIST $(OBJECT)\*.map $(DEL) $(OBJECT)\*.map | ||||
| 	-@IF EXIST $(OBJECT)\*.obj $(DEL) $(OBJECT)\*.obj | ||||
| 	-@IF EXIST $(OBJECT)\*.exe $(DEL) $(OBJECT)\*.exe | ||||
| 	-@IF EXIST $(OBJECT)\*.rom $(DEL) $(OBJECT)\*.rom | ||||
| 	-@IF EXIST $(OBJECT)\*.cpu $(DEL) $(OBJECT)\*.cpu | ||||
| 	-@IF EXIST $(OBJECT)\*.scc $(DEL) $(OBJECT)\*.scc | ||||
| 	-@IF EXIST $(OBJECT)\*.inc $(DEL) $(OBJECT)\*.inc | ||||
| 	-@IF EXIST $(OBJECT)\*.h $(DEL) $(OBJECT)\*.h | ||||
| 	-@IF EXIST $(OBJECT)\*.lst $(DEL) $(OBJECT)\*.lst | ||||
| 	-@IF EXIST $(OBJECT)\*.bak $(DEL) $(OBJECT)\*.bak | ||||
| 	-@IF EXIST $(OBJECT)\*.mac $(DEL) $(OBJECT)\*.mac | ||||
| 	-@IF EXIST $(OBJECT)\*.asm $(DEL) $(OBJECT)\*.asm | ||||
| 	-@IF EXIST $(OBJECT)\*.cod $(DEL) $(OBJECT)\*.cod | ||||
| 	-@IF EXIST $(MAKEDIR)\*.map $(DEL) $(MAKEDIR)\*.map | ||||
| 	-@IF EXIST $(MAKEDIR)\arccode.h $(DEL) $(MAKEDIR)\arccode.h | ||||
|  | ||||
| cleanall: clean  | ||||
| 	-@IF EXIST $(MAKEDIR)\*.vsm $(DEL) $(MAKEDIR)\*.vsm | ||||
| 	-@IF EXIST $(OBJECT)\*.vsm $(DEL) $(OBJECT)\*.vsm | ||||
| 	-@IF EXIST $(OBJECT)\*.bin $(DEL) $(OBJECT)\*.bin | ||||
| 	-@IF EXIST $(OBJECT)\*.lib $(DEL) $(OBJECT)\*.lib | ||||
| 	-@IF EXIST $(OBJECT) rd $(OBJECT) | ||||
|  | ||||
|  | ||||
| ############################################################################## | ||||
| # | ||||
| #	Common inference rules | ||||
| # | ||||
| ############################################################################## | ||||
|  | ||||
| {$(INC_DIR)}.h{$(OBJECT)}.inc: | ||||
| 	$(H2) /Fa$(OBJECT)\$(@F) /nologo /C $< | ||||
|  | ||||
| {$(INC_DIR)\$(CPU)}.h{$(OBJECT)}.inc: | ||||
| 	$(H2) /Fa$(OBJECT)\$(@F) /nologo /C $< | ||||
|  | ||||
| {$(SYSMGR_SRC)}.h{$(OBJECT)}.inc: | ||||
| 	$(H2) /Fa$(OBJECT)\$(@F) /nologo /C $< | ||||
|  | ||||
| {$(SYSMGR_SRC)\$(CPU)}.h{$(OBJECT)}.inc: | ||||
| 	$(H2) /Fa$(OBJECT)\$(@F) /nologo /C $< | ||||
|  | ||||
| {$(MAKEDIR)}.h{$(OBJECT)}.inc: | ||||
| 	$(H2) /Fa$(OBJECT)\$(@F) /nologo /C $< | ||||
|  | ||||
| {$(MAKEDIR)\$(CPU)}.h{$(OBJECT)}.inc: | ||||
| 	$(H2) /Fa$(OBJECT)\$(@F) /nologo /C $< | ||||
|  | ||||
| {$(INC_DIR)}.h{$(OBJECT)}.h: | ||||
| 	$(COPY) $< $@ | ||||
|  | ||||
| {$(INC_DIR)\$(CPU)}.h{$(OBJECT)}.h: | ||||
| 	$(COPY) $< $@ | ||||
|  | ||||
| {$(SYSMGR_SRC)}.h{$(OBJECT)}.h: | ||||
| 	$(COPY) $< $@ | ||||
|  | ||||
| {$(SYSMGR_SRC)\$(CPU)}.h{$(OBJECT)}.h: | ||||
| 	$(COPY) $< $@ | ||||
|  | ||||
| {$(MAKEDIR)}.h{$(OBJECT)}.h: | ||||
| 	$(COPY) $< $@ | ||||
|  | ||||
| {$(MAKEDIR)\$(CPU)}.h{$(OBJECT)}.h: | ||||
| 	$(COPY) $< $@ | ||||
|  | ||||
| {$(MAKEDIR)}.inc{$(OBJECT)}.inc: | ||||
| 	$(COPY) $< $@ | ||||
|  | ||||
| {$(MAKEDIR)\$(CPU)}.inc{$(OBJECT)}.inc: | ||||
| 	$(COPY) $< $@ | ||||
|  | ||||
| {$(MAKEDIR)}.c{$(OBJECT)}.obj: | ||||
| 	$(CC) /nologo $(CC_OPTS) /Fo$@ $<  | ||||
|  | ||||
| {$(MAKEDIR)\$(CPU)}.c{$(OBJECT)}.obj: | ||||
| 	$(CC) /nologo $(CC_OPTS) /Fo$@ $<  | ||||
|  | ||||
| {$(MAKEDIR)}.asm{$(OBJECT)}.obj: | ||||
| 	$(AS) /nologo $(AS_OPTS) /Fo$@ $<  | ||||
|  | ||||
| {$(MAKEDIR)\$(CPU)}.asm{$(OBJECT)}.obj: | ||||
| 	$(AS) /nologo $(AS_OPTS) /Fo$@ $<  | ||||
|  | ||||
| {$(SYSMGR_SRC)}.mac{$(OBJECT)}.mac: | ||||
| 	$(COPY) $< $@ | ||||
|  | ||||
| {$(SYSMGR_SRC)\$(CPU)}.mac{$(OBJECT)}.mac: | ||||
| 	$(COPY) $< $@ | ||||
|  | ||||
							
								
								
									
										65
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/build/setvars.mak
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										65
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/build/setvars.mak
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,65 @@ | ||||
| # | ||||
| # Copyright (c) 2006 Advanced Micro Devices,Inc. ("AMD"). | ||||
| # | ||||
| # This library is free software; you can redistribute it and/or modify | ||||
| # it under the terms of the GNU Lesser General Public License as | ||||
| # published by the Free Software Foundation; either version 2.1 of the | ||||
| # License, or (at your option) any later version. | ||||
| # | ||||
| # This code is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| # Lesser General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU Lesser General | ||||
| # Public License along with this library; if not, write to the | ||||
| # Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| # Boston, MA 02111-1307 USA  | ||||
| # | ||||
|  | ||||
| ############################################################################## | ||||
| # | ||||
| #	Directories | ||||
| # | ||||
| ############################################################################## | ||||
| BUILD_DIR		= $(VSA2ROOT)\build | ||||
| SYSMGR_SRC		= $(VSA2ROOT)\sysmgr | ||||
| VSMUTILS_SRC	= $(VSA2ROOT)\vsm_lib | ||||
| LEGACY_SRC		= $(VSA2ROOT)\legacy | ||||
| INC_DIR		= $(VSA2ROOT)\inc | ||||
| H_DIR			= $(VSA2ROOT)\sysmgr | ||||
|  | ||||
| SHELL			= | ||||
|  | ||||
| ############################################################################## | ||||
| # | ||||
| #	Tools / Options for tools | ||||
| # | ||||
| ############################################################################## | ||||
| ECHO		= echo | ||||
| COPY		= copy | ||||
| BINCOPY	= copy /b | ||||
| MOVE		= move | ||||
| DEL		= del | ||||
| REN		= ren | ||||
| SETENV	= set | ||||
| CD		= cd | ||||
| AS		= ml | ||||
| CC		= cl | ||||
| H2		= h2inc | ||||
| LN		= link | ||||
| LB		= lib | ||||
| X2ROM = exe2bin | ||||
|  | ||||
| AS_OPTS	= /c /Cx /Sa /W3 $(ALIST) /I$(OBJECT) | ||||
| CC_OPTS	= /c /AT /Gs /FPi87 /G3fsy /W3 /Fc$(OBJECT)\ /I$(OBJECT) $(COPTS_OPT) $(CLIST) | ||||
|  | ||||
| COPTS_OPT	= /Ow /W3  | ||||
| LOPTS_OPT	= /NONULLS /nologo /MAP | ||||
| LOPTS_SYS	= /MAP /TINY /nologo | ||||
| LOPTS_VSM	= /MAP /TINY /nologo | ||||
|  | ||||
| TOOL_LIB	= tools.lib | ||||
| HEAD_LIB	= header.lib | ||||
|  | ||||
|  | ||||
							
								
								
									
										42
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/build/sysmgr.mak
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										42
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/build/sysmgr.mak
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| # | ||||
| # Copyright (c) 2006 Advanced Micro Devices,Inc. ("AMD"). | ||||
| # | ||||
| # This library is free software; you can redistribute it and/or modify | ||||
| # it under the terms of the GNU Lesser General Public License as | ||||
| # published by the Free Software Foundation; either version 2.1 of the | ||||
| # License, or (at your option) any later version. | ||||
| # | ||||
| # This code is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| # Lesser General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU Lesser General | ||||
| # Public License along with this library; if not, write to the | ||||
| # Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| # Boston, MA 02111-1307 USA  | ||||
| # | ||||
|  | ||||
| VSMNAME	= sysmgr | ||||
| VSMDIR	= $(VSA2ROOT)\$(VSMNAME) | ||||
|  | ||||
| all: | ||||
| 	cd $(VSMDIR) | ||||
| 	$(MAKE) /nologo all "VSA2ROOT=$(VSA2ROOT)" "USER=$(USER)" "BUILDOBJ=$(OBJECT)" "CPU=$(CPU)" | ||||
| 	cd $(MAKEDIR) | ||||
|  | ||||
|  | ||||
| clean: | ||||
| 	cd $(VSMDIR) | ||||
| 	$(MAKE) /nologo clean | ||||
| 	cd $(MAKEDIR) | ||||
|  | ||||
| cleanlocal: | ||||
| 	cd $(VSMDIR) | ||||
| 	$(MAKE) /nologo cleanlocal | ||||
| 	cd $(MAKEDIR) | ||||
|  | ||||
| cleanall: | ||||
| 	cd $(VSMDIR) | ||||
| 	$(MAKE) /nologo cleanall | ||||
| 	cd $(MAKEDIR) | ||||
							
								
								
									
										42
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/build/vsainit.mak
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										42
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/build/vsainit.mak
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| # | ||||
| # Copyright (c) 2006 Advanced Micro Devices,Inc. ("AMD"). | ||||
| # | ||||
| # This library is free software; you can redistribute it and/or modify | ||||
| # it under the terms of the GNU Lesser General Public License as | ||||
| # published by the Free Software Foundation; either version 2.1 of the | ||||
| # License, or (at your option) any later version. | ||||
| # | ||||
| # This code is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| # Lesser General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU Lesser General | ||||
| # Public License along with this library; if not, write to the | ||||
| # Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| # Boston, MA 02111-1307 USA  | ||||
| # | ||||
|  | ||||
| VSMNAME	= vsainit | ||||
| VSMDIR	= $(VSA2ROOT)\sysmgr | ||||
|  | ||||
| all: | ||||
| 	cd $(VSMDIR) | ||||
| 	$(MAKE) /nologo all "VSA2ROOT=$(VSA2ROOT)" "USER=$(USER)" "BUILDOBJ=$(OBJECT)" "CPU=$(CPU)" | ||||
| 	cd $(MAKEDIR) | ||||
|  | ||||
|  | ||||
| clean: | ||||
| 	cd $(VSMDIR) | ||||
| 	$(MAKE) /nologo clean | ||||
| 	cd $(MAKEDIR) | ||||
|  | ||||
| cleanlocal: | ||||
| 	cd $(VSMDIR) | ||||
| 	$(MAKE) /nologo cleanlocal | ||||
| 	cd $(MAKEDIR) | ||||
|  | ||||
| cleanall: | ||||
| 	cd $(VSMDIR) | ||||
| 	$(MAKE) /nologo cleanall | ||||
| 	cd $(MAKEDIR) | ||||
							
								
								
									
										249
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/acpi.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										249
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/acpi.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,249 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
|  | ||||
|  | ||||
| //********************************************************* | ||||
| // Private messages used between ACPI VSM and PMCORE VSM ** | ||||
| //********************************************************* | ||||
| #define PMSG_GOTO_SLEEP         0x70 | ||||
| #define PMSG_BLINK_LED		    0x71 | ||||
|  | ||||
|  | ||||
| /* device power states */ | ||||
| #define D0_STATE	(0) | ||||
| #define D1_STATE	(1) | ||||
| #define D2_STATE	(2) | ||||
| #define D3_STATE	(3) | ||||
|  | ||||
| /************************************************************** | ||||
| * smi_cmd Definitions | ||||
| * These values must match the corresponding values in ACPI | ||||
| * FADT.  OS writes these values to SMI_CMD I/O location. | ||||
| ****************************************************************/ | ||||
| #define ACPI_ENABLE     (0xA1) | ||||
| #define ACPI_DISABLE    (0xA2) | ||||
| #define S4BIOS_REQ      (0xA3) | ||||
|  | ||||
|  | ||||
| // Bitmap of IRQ's PM VSM can map SCI to | ||||
| #define ALLOWED_SCI_IRQ	(0x0E20) // 11,10,9,5 | ||||
| #define DEFAULT_SCI_IRQ	(9) | ||||
|  | ||||
| /************************************************************** | ||||
| * PM1_STS bit definitions | ||||
| ****************************************************************/ | ||||
| #define WAKE_STS        (0x8000) | ||||
| #define RTC_STS         (0x0400) | ||||
| #define SLPBTN_STS      (0x0200) | ||||
| #define PWRBTN_STS      (0x0100) | ||||
| #define GBL_STS         (0x0020) | ||||
| #define BM_STATUS       (0x0010) | ||||
| #define TMR_STS         (0x0001) | ||||
| #define PM1_STS_CLR		(0x8731) | ||||
|  | ||||
| /************************************************************** | ||||
| * PM1_EN bit definitions | ||||
| ****************************************************************/ | ||||
| #define RTC_EN          (0x0400) | ||||
| #define SLPBTN_EN       (0x0200) | ||||
| #define PWRBTN_EN       (0x0100) | ||||
| #define GBL_EN          (0x0020) | ||||
| #define TMR_EN          (0x0001) | ||||
|  | ||||
| /************************************************************** | ||||
| * PM1_CNT bit definitions | ||||
| ****************************************************************/ | ||||
| #define SLP_EN          (0x2000) | ||||
| #define SLP_ENB			(0x20) | ||||
| #define SLP_TYPx_MASK   (0x1C00)            // mask for setting SLP_TYPx | ||||
| #define SLP_TYPx_MASKB	(0x1C) | ||||
| #define SLP_TYPx_SHFT	(10) | ||||
| #define SLP_TYPx_SHFTB	(2) | ||||
| #define GBL_RLS         (0x0004) | ||||
| #define BM_RLD          (0x0002) | ||||
| #define SCI_EN          (0x0001) | ||||
| #define ACPI_S0			(0) | ||||
| #define ACPI_S1			(1) | ||||
| #define ACPI_S1_CLKOFF	(0x81) | ||||
| #define ACPI_S2			(2) | ||||
| #define ACPI_S3			(3) | ||||
| #define ACPI_S4			(4) | ||||
| #define ACPI_S5			(5) | ||||
|  | ||||
| /************************************************************** | ||||
| * PM2_CNT bit definitions | ||||
| **************************************************************/ | ||||
| #define ARB_DIS			(0x0001) | ||||
|  | ||||
|  | ||||
| /************************************************************** | ||||
| * P_CNT bit definitions | ||||
| ****************************************************************/ | ||||
| #define CLK_VAL_MASK    (0x0000000F) | ||||
| #define CLK_VAL_OFFSET  (0) | ||||
| #define CLK_VAL_WIDTH   (4) | ||||
| #define THT_EN          (0x00000010) | ||||
|  | ||||
|  | ||||
| /******************************************************************** | ||||
| * FACS | ||||
| ********************************************************************/ | ||||
| #define FACS_SIG_OFS	(0x00) | ||||
| #define FACS_LEN_OFS	(0x04) | ||||
| #define FACS_HWSIG_OFS	(0x08) | ||||
| #define FACS_OSWV_OFS	(0x0C) | ||||
| #define FACS_GBLOCK_OFS	(0x10) | ||||
| 	#define FACS_GBL_OWNED		(0x02) | ||||
| 	#define FACS_GBL_PENDING	(0x01) | ||||
| #define FACS_FLAGS_OFS	(0x14) | ||||
|  | ||||
|  | ||||
| /******************************************************************** | ||||
| * CS5536 PM stuff | ||||
| ********************************************************************/ | ||||
| #define YIG_SCI			(5)			// Y Interrupt Group 5 is all SCI sources | ||||
| #define MSR_SYS_RESET	(0x0014)	// 5536 GLCP SYS_RESET MSR | ||||
|  | ||||
| // default location of PMC regs | ||||
| #define PMC5536_BASE		(0x9D00) | ||||
|  | ||||
| // default location of ACPI regs (32 bytes) | ||||
| #define ACPI5536_BASE	(0x9C00) | ||||
| #define PM1_STS_OFS		(0x00) | ||||
| #define PM1_EN_OFS		(0x02) | ||||
| #define PM1_CNT_OFS		(0x08) | ||||
| #define PM2_CNT_OFS		(0x0C) | ||||
| #define PM_TMR_OFS		(0x10) | ||||
| #define GPE0_STS_OFS	(0x18) | ||||
| #define GPE0_EN_OFS		(0x1C) | ||||
|  | ||||
| // Virtualized ACPI registers, these offsets were picked to provide | ||||
| // minimal overlap of misaligned accesses. | ||||
| // Note: PM1_STS/EN and GPE0_STS/EN must be back-to-back AND  | ||||
| // PM1_STS and PM1_EN must be 16-bit only. | ||||
| #define	VACPI_TRAP_BASE	0x9C20 | ||||
| #define VACPI_TRAP_LEN	(32) | ||||
| #define VPM1_STS_OFS	(0x00) | ||||
| #define VPM1_EN_OFS		(0x02) | ||||
| #define VPM1_CNT_OFS	(0x08) | ||||
| #define VGPE0_STS_OFS	(0x10) | ||||
| #define VGPE0_EN_OFS	(0x14) | ||||
| #define VACPI_ENABLE	(0x1C) | ||||
|  | ||||
| // 5536 GPIO13 AUX1_IN is dedicated to Sleep Button. It's controlled | ||||
| // by SLPB_STS in PM1_STS and SLPB_EN in PM1_EN. | ||||
| // Unfortunately, GPIO13 is in Working Power Domain so it is useless as | ||||
| // a wake event for anything other than S1. | ||||
| #define DFLT_5536_SLPB_GPIO	(13) | ||||
|  | ||||
| // Bit[9] of PM1_CNT, ignored bit in ACPI spec. On 5536 this bit indicates | ||||
| // software has written a 1 to GBL_RLS(bit[2]) of PM1_CNT. Bit[9] can be cleared | ||||
| // by writing a 1 to it. | ||||
| #define GBL_RLS_FLAG	(0x0200) | ||||
|  | ||||
| // Bit[11] of PM1_STS, ignored bit in ACPI spec. On 5536 writing this bit=1 causes | ||||
| // GBL_STS(bit[5]) to be set to 1.  Bit[11] always reads as 0. | ||||
| #define SET_GBL_STS		(0x0800) | ||||
|  | ||||
| // 5536 specific bits in ACPI GPE0_STS & GPE0_EN | ||||
| #define GPE0_PIC_INT	(0x00000001L) | ||||
| #define GPE0_PIC_ASMI	(0x00000002L) | ||||
| #define GPE0_SMB		(0x00000004L) | ||||
| #define GPE0_UART1		(0x00000008L) | ||||
| #define GPE0_UART2		(0x00000010L) | ||||
| #define GPE0_USB1		(0x00000020L) | ||||
| #define GPE0_USB2		(0x00000040L) | ||||
| #define GPE0_PME0		(0x00010000L) | ||||
| #define GPE0_PME1		(0x00020000L) | ||||
| #define GPE0_PME2		(0x00040000L) | ||||
| #define GPE0_PME3		(0x00080000L) | ||||
| #define GPE0_PME4		(0x00100000L) | ||||
| #define GPE0_PME5		(0x00200000L) | ||||
| #define GPE0_PME6		(0x40000000L) | ||||
| #define GPE0_PME7		(0x80000000L) | ||||
|  | ||||
|  | ||||
|  | ||||
| /*## | ||||
|  *## ACPI Indicator Designations | ||||
|  *## | ||||
|  */ | ||||
| #define LED_OFF				0x00		// LED turned off | ||||
| #define LED_SLOW			0x01		// 1/4Hz rate (4 second cycle time), 50% duty cycle | ||||
| #define LED_FAST			0x02		// 1Hz rate (1 second cycle time), 50% duty cycle | ||||
| #define LED_ON				0x03		// LED always on | ||||
|  | ||||
| #define	NO_LED				0x00		// No LEDs here | ||||
| //#define	MB_LED0				0x01		// The motherboard LED 0 bit mask | ||||
| //#define	MB_LED1				0x02		// The motherboard LED 1 bit mask | ||||
| //#define	MB_LED2				0x04		// The motherboard LED 2 bit mask | ||||
| //#define	MB_LED3				0x08		// The motherboard LED 3 bit mask | ||||
| #define	MB_LEDALL			0x0F		// The all motherboard LEDs bit mask | ||||
| //#define	SIO_LED0			0x10		// The SIO LED 0 bit mask | ||||
| //#define	SIO_LED1			0x20		// The SIO LED 1 bit mask | ||||
| //#define	SIO_LED2			0x40		// The SIO LED 2 bit mask | ||||
| //#define	SIO_LED3			0x80		// The SIO LED 3 bit mask | ||||
| #define SIO_LEDALL			0xF0		// The SIO LEDs are in the upper nibble | ||||
| //The LEDS used to indicate sleep/wake | ||||
| #define	INDICATOR_SLEEP		0x11 | ||||
|  | ||||
|  | ||||
| /* | ||||
| * table indexes for gx2/lx msrs | ||||
| *   (This may be moved *) | ||||
| */ | ||||
| // Northbridge | ||||
| #define IDX_GLIU0	(0) | ||||
| #define IDX_MC		(1) | ||||
| #define IDX_GLIU1	(2) | ||||
| #define IDX_VG		(3) | ||||
| #define IDX_GP		(4) | ||||
| #define IDX_DF		(5) | ||||
| #define IDX_GLCP	(6) | ||||
| #define IDX_GLPCI	(7) | ||||
| #define IDX_FG		(8) | ||||
| #define IDX_CPU		(9) | ||||
| #define IDX_VIP		(10) | ||||
| #define IDX_AES		(11) | ||||
|  | ||||
| // Southbridge | ||||
| #define IDX_SB_GLPCI (12) | ||||
| #define IDX_SB_GLIU	(13) | ||||
| #define IDX_SB_USB2	(14) | ||||
| #define IDX_SB_ATA	(15) | ||||
| #define IDX_SB_MDD	(16) | ||||
| #define IDX_SB_AC97	(17) | ||||
| #define IDX_SB_USB1	(18) | ||||
| #define IDX_SB_GLCP	(19) | ||||
|  | ||||
|  | ||||
| #define NUM_DEVS		(IDX_SB_GLCP+1) | ||||
|  | ||||
| // definitions for callbacks for PM functions | ||||
| #define PM_CALLBACK 0xBD50 | ||||
| #define  PM_CB_LED  0x00 | ||||
| #define  PM_CB_PME  0x01 | ||||
| #define     PM_CB_PME_DISARM    0x00 | ||||
| #define     PM_CB_PME_ARM       0x01 | ||||
| #define  PM_CB_SLEEP 0x02 | ||||
| #define     PM_CB_ENTER_S3    0x00 | ||||
| #define     PM_CB_ENTER_SLEEP 0x01 | ||||
| #define     PM_CB_LEAVE_SLEEP 0x02 | ||||
| #define     PM_CB_DONE_S3     0x03 | ||||
							
								
								
									
										374
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/chipset.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										374
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/chipset.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,374 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| #define VENDOR_ID_COMPAQ		0x0E11 | ||||
| #define VENDOR_ID_CYRIX		0x1078 | ||||
| #define VENDOR_ID_NATIONAL		0x100B | ||||
| #define VENDOR_ID_AMD			0x1022 | ||||
|  | ||||
| #define DEVICE_ID_MEDIAGX		0x0001 | ||||
| #define DEVICE_ID_5530			0x0100 | ||||
|  | ||||
| #define DEVICE_ID_GX2			0x0028 | ||||
| #define DEVICE_ID_GFX2			0x0030 | ||||
|  | ||||
| #define DEVICE_ID_5535			0x002B | ||||
| #define DEVICE_ID_FLASH		0x002C | ||||
| #define DEVICE_ID_ATA			0x002D | ||||
| #define DEVICE_ID_AUDIO		0x002E | ||||
| #define DEVICE_ID_OHCI			0x002F | ||||
|  | ||||
| #define DEVICE_ID_LX			0x2080 | ||||
| #define DEVICE_ID_GFX3			0x2081 | ||||
| #define DEVICE_ID_AES			0x2082 | ||||
|  | ||||
| #define DEVICE_ID_5536			0x2090 | ||||
| #define DEVICE_ID_AMD_FLASH		0x2091 | ||||
| #define DEVICE_ID_AMD_ATA		0x2092 | ||||
| #define DEVICE_ID_AMD_AUDIO		0x2093 | ||||
| #define DEVICE_ID_AMD_OHCI		0x2094 | ||||
| #define DEVICE_ID_AMD_EHCI		0x2095 | ||||
| #define DEVICE_ID_AMD_UDC		0x2096 | ||||
| #define DEVICE_ID_AMD_OTG		0x2097 | ||||
| #define DEVICE_ID_AMD_THOR		0x209A | ||||
|  | ||||
|  | ||||
| #define LEGACY_FUNCTION			0x0000 | ||||
| #define PM_FUNCTION				0x0100 | ||||
| #define IDE_FUNCTION			0x0200 | ||||
| #define AUDIO_FUNCTION			0x0300 | ||||
| #define VIDEO_FUNCTION			0x0400 | ||||
| #define XBUS_FUNCTION			0x0500 | ||||
|  | ||||
|  | ||||
|  | ||||
| // SMI sources relative to Function 1 BAR0 | ||||
| #define SMI_STATUS_RO          0x0000 | ||||
| #define SMI_STATUS				0x0002 | ||||
| #define SMI_SRC_PM		 				(1L << 0) | ||||
| #define SMI_SRC_AUDIO_INDEX			1 | ||||
| #define SMI_SRC_AUDIO					(1L << SMI_SRC_AUDIO_INDEX) | ||||
| #define SMI_SRC_ACPI					(1L << 2) | ||||
| #define SMI_SRC_VG						(1L << 3) | ||||
| #define SMI_SRC_INT_MEMORY				(1L << 4) | ||||
| #define SMI_SRC_RETRACE				(1L << 5) | ||||
| #define SMI_SRC_VGA_TIMER  			(1L << 6) | ||||
| #define SMI_SRC_A20_INDEX 				7 | ||||
| #define SMI_SRC_A20					(1L << SMI_SRC_A20_INDEX) | ||||
| #define SMI_SRC_SW_INDEX				8 | ||||
| #define SMI_SRC_SW	 	 				(1L << SMI_SRC_SW_INDEX) | ||||
| #define GTT_INDEX              		9 | ||||
| #define SMI_SRC_GTT					(1L << GTT_INDEX) | ||||
| #define SMI_SRC_DEBUG					(1L << 10) | ||||
| #define SMI_SRC_MFGPT					(1L << 11) | ||||
| #define SMI_SRC_NMI					(1L << 12) | ||||
| #define SMI_SRC_RESET		   			(1L << 13) | ||||
| #define SMI_SRC_USB1	   				(1L << 14) | ||||
| #define SMI_SRC_USB2	   				(1L << 15) | ||||
| #define SMI_IGNORE						0x7FFF | ||||
|  | ||||
|  | ||||
| #define GTT_STATUS				0x0006 | ||||
| // NOTE: The following source definitions are shifted left 16 bits because | ||||
| //       Get_SMI_Sources passes them that way in the SMI_Sources variable. | ||||
|   #define GTT_SRC_GT1		  			(1L << ( 0+16)) | ||||
|   #define GTT_SRC_GT2					(1L << ( 1+16)) | ||||
|   #define GTT_SRC_USR_DEF_TRAP1		(1L << ( 2+16)) | ||||
|   #define GTT_SRC_USR_DEF_TRAP2		(1L << ( 3+16)) | ||||
|   #define GTT_SRC_USR_DEF_TRAP3		(1L << ( 4+16)) | ||||
|   #define SMI_SRC_PCI_TRAP				(1L << ( 5+16)) | ||||
|   #define GTT_SRC_1MS_TMR				(1L << ( 6+16)) | ||||
|   #define GTT_SRC_1SEC_TMR				(1L << ( 7+16)) | ||||
|   #define SMI_SRC_MPCI					(1L << ( 8+16))	 // Virtualized PCI access | ||||
|   #define SMI_SRC_DESCR_HIT			(1L << ( 9+16))  // Hit on MBus descriptor | ||||
|   #define SMI_SRC_STAT	 				(1L << (10+16))  // Hit on MBus statistics counter | ||||
|   #define SMI_SRC_PIC					(1L << (11+16))  // PIC event | ||||
|   #define SMI_SRC_KEL					(1L << (12+16))  // KEL event | ||||
|   #define SMI_SRC_PME					(1L << (13+16))  // PME event | ||||
|   #define SMI_SRC_BLOCKIO				(1L << (14+16))  // BLOCKIO event | ||||
|  | ||||
| #define SMI_SPEEDUP_DISABLE	 	0x0008 | ||||
|  | ||||
| #define AUDIO_STATUS            	0x0010		// relative to F3 BAR0 | ||||
|  | ||||
|  | ||||
|  | ||||
| //############################################################################################ | ||||
|  | ||||
|  | ||||
| #define PCI_CFG_CONTROL			0x40 | ||||
|   #define   LEGACY_CFG_SMI				(1L <<  8) | ||||
|   #define   PM_CFG_SMI      			(1L << 11) | ||||
|   #define   IDE_CFG_SMI				(1L << 14) | ||||
|   #define   AUDIO_CFG_SMI 				(1L << 16) | ||||
|   #define   VIDEO_CFG_SMI 				(1L << 17) | ||||
|   #define   USB_PM_SMI	 				(1L << 22) | ||||
|   #define   USB_CFG_SMI 				(1L << 23) | ||||
|   #define   USB_ENABLE	 				(1L << 24) | ||||
|  | ||||
|   #define   PM_CFG_SMI_SCxxxx          (1L <<  9) | ||||
|   #define   IDE_CFG_SMI_SCxxxx         (1L << 10) | ||||
|   #define   AUDIO_CFG_SMI_SCxxxx       (1L << 11)  | ||||
|   #define   VIDEO_CFG_SMI_SCxxxx       (1L << 12) | ||||
|   #define   XBUS_CFG_SMI_SCxxxx        (1L << 13) | ||||
|  | ||||
| #define RESET_CONTROL				0x44 | ||||
|   #define   X_BUS_WARM_START			(1L << 0) | ||||
|   #define   PCI_RESET					(1L << 1) | ||||
|   #define   IDE_RESET					(1L << 2) | ||||
|   #define   IDE_CONTROLLER_RESET		(1L << 3) | ||||
|   #define   AC97_RESET					(1L << 7) | ||||
|  | ||||
|  | ||||
| #define ROM_AT_LOGIC				0x52 | ||||
|   #define   LOWER_ROM_ENABLE			(1 << 0) | ||||
|   #define   ROM_WRITE_ENABLE			(1 << 1) | ||||
|   #define   ROM_1MB_WRITE_ENABLE		(1 << 2) | ||||
|   #define   PORT_92_ENABLE				(1 << 3) | ||||
|   #define   A20M_DEASSERT				(1 << 4) | ||||
|   #define   GAMEPORT_CS_ON_READS		(1 << 5) | ||||
|   #define   GAMEPORT_CS_ON_WRITES		(1 << 6) | ||||
|   #define   FAST_KEYBOARD_DISABLE		(1 << 7) | ||||
|  | ||||
|  | ||||
| #define CPU_SUPPORT				0x53 | ||||
|   #define   A20M_ENABLE				(1 << 0) | ||||
|   #define   RTC_ENABLE					(1 << 2) | ||||
|   #define   GAMEPORT_ENABLE			(1 << 3) | ||||
|  | ||||
| #define DECODE_CONTROL				0x5A | ||||
|   #define   RTC_POSITIVE_DECODE		(1 << 0) | ||||
|   #define   KBD_POSITIVE_DECODE		(1 << 1) | ||||
|   #define   COM1_POSITIVE_DECODE		(1 << 2) | ||||
|   #define   COM2_POSITIVE_DECODE		(1 << 3) | ||||
|   #define   COM3_POSITIVE_DECODE		(1 << 4) | ||||
|   #define   COM4_POSITIVE_DECODE		(1 << 5) | ||||
|   #define   FLPY1_POSITIVE_DECODE		(1 << 6) | ||||
|   #define   FLPY2_POSITIVE_DECODE		(1 << 7) | ||||
|   #define   LPT1_POSITIVE_DECODE		(1 << 8) | ||||
|   #define   LPT2_POSITIVE_DECODE		(1 << 9) | ||||
|   #define   LPT3_POSITIVE_DECODE		(1 << 10) | ||||
|   #define   IDE1_POSITIVE_DECODE		(1 << 11) | ||||
|   #define   IDE2_POSITIVE_DECODE		(1 << 12) | ||||
|   #define   ROM_POSITIVE_DECODE		(1 << 13) | ||||
|   #define   KBD_6X_DECODE				(1 << 15) | ||||
|  | ||||
| #define PCI_STEERING				0x5C | ||||
|  | ||||
|  | ||||
| // Top-level SMI enables  (registers 0x80-0x83) | ||||
| #define ENABLE_TRAPS_TIMERS		0x80 | ||||
|   #define   ENABLE_PM					(1L << 0) | ||||
|   #define   ENABLE_TIMERS				(1L << 1) | ||||
|   #define   ENABLE_TRAPS		   		(1L << 2) | ||||
|   #define   ENABLE_IRQ_SPEEDUP			(1L << 3) | ||||
|   #define   ENABLE_VIDEO_SPEEDUP		(1L << 4) | ||||
|   #define   ENABLE_CODEC_SMI			(1L << 5) | ||||
|   #define   ENABLE_RESERVED1			(1L << 6) | ||||
|   #define   ENABLE_RESERVED2			(1L << 7) | ||||
|   #define   ENABLE_HDD0_TIMER			(1L << 8) | ||||
|   #define   ENABLE_FDD_TIMER			(1L << 9) | ||||
|   #define   ENABLE_PAR_SER_TIMER		(1L << 10) | ||||
|   #define   ENABLE_KYBD_MOUSE_TIMER	(1L << 11) | ||||
|   #define   ENABLE_USR_DEF_TIMER1		(1L << 12) | ||||
|   #define   ENABLE_USR_DEF_TIMER2		(1L << 13) | ||||
|   #define   ENABLE_USR_DEF_TIMER3		(1L << 14) | ||||
|   #define   ENABLE_VIDEO_TIMER			(1L << 15) | ||||
|   #define   ENABLE_HDD0_TRAP	   		(1L << 16)  | ||||
|   #define   ENABLE_FDD_TRAP			(1L << 17) | ||||
|   #define   ENABLE_PAR_SER_TRAP		(1L << 18) | ||||
|   #define   ENABLE_KYBD_MOUSE_TRAP 	(1L << 19) | ||||
|   #define   ENABLE_USR_DEF_TRAP1		(1L << 20) | ||||
|   #define   ENABLE_USR_DEF_TRAP2		(1L << 21) | ||||
|   #define   ENABLE_USR_DEF_TRAP3		(1L << 22) | ||||
|   #define   ENABLE_VIDEO_TRAP			(1L << 23) | ||||
|   #define   ENABLE_GT1					(1L << 24) | ||||
|   #define   ENABLE_GT2					(1L << 25) | ||||
|   #define   ENABLE_RETRACE				(1L << 26) | ||||
|   #define   ENABLE_VGA_TIMER	  		(1L << 27) | ||||
|   #define   ENABLE_THERMAL				(1L << 28)	// SCxxxx only | ||||
|   #define   ENABLE_ACPI_TIMER			(1L << 29) | ||||
|   #define   ENABLE_HDD1_TRAP			(1L << 30) | ||||
|   #define   ENABLE_HDD1_TIMER			(1L << 31) | ||||
|  | ||||
|  | ||||
| #define GT1_COUNT					0x88 | ||||
| #define GT1_CONTROL				0x89 | ||||
|   #define   GT1_RESET_HDD				(1 << 0) | ||||
|   #define   GT1_RESET_FDD				(1 << 1) | ||||
|   #define   GT1_RESET_PARALLEL_SERIAL	(1 << 2) | ||||
|   #define   GT1_RESET_KEYBD_MOUSE		(1 << 3) | ||||
|   #define   GT1_RESET_USR_DEF1			(1 << 4) | ||||
|   #define   GT1_RESET_USR_DEF2			(1 << 5) | ||||
|   #define   GT1_RESET_USR_DEF3			(1 << 6) | ||||
|   #define   GT1_TIMEBASE				(1 << 7) | ||||
|  | ||||
|  | ||||
| #define GT2_COUNT					0x8A | ||||
| #define GT2_CONTROL				0x8B | ||||
|   #define GT2_RESET_GPIO7				(1 << 2) | ||||
|   #define GT2_TIMEBASE					(1 << 3)			// 0=second  1=ms | ||||
|   #define GT1_SHIFT					(1 << 4)			// 0=8 bit   1=16 bit | ||||
|   #define GT2_SHIFT					(1 << 5)			// 0=8 bit   1=16 bit | ||||
|   #define VGA_TIMEBASE					(1 << 6)			// 0=ms      1=32 us | ||||
|   #define GT1_RESET_SEC_HDD			(1 << 7)			// 0=disable 1=enable | ||||
|  | ||||
| #define IRQ_SPEEDUP_COUNT          0x8C | ||||
| #define VIDEO_SPEEDUP_COUNT        0x8D | ||||
| #define VGA_TIMER_LOAD_COUNT       0x8E | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| #define GPIO_DIRECTION          	0x90 | ||||
| #define GPIO_DATA               	0x91 | ||||
| #define   GPIO_CONTROL				0x92 | ||||
|   #define   GPIO0_ENABLE				(1 << 0) | ||||
|   #define   GPIO1_ENABLE				(1 << 1) | ||||
|   #define   GPIO2_ENABLE				(1 << 2) | ||||
|   #define   GPIO0_EDGE					(1 << 3) | ||||
|   #define   GPIO1_EDGE					(1 << 4) | ||||
|   #define   GPIO2_EDGE					(1 << 5) | ||||
|   #define   GPIO6_ENABLE				(1 << 6) | ||||
|   #define   GPIO6_EDGE					(0 << 6) | ||||
|   #define   GPIO7_EDGE					(1 << 7) | ||||
|  | ||||
|  | ||||
|  | ||||
| #define MISCELLANEOUS				0x93 | ||||
|   #define   SERIAL_MOUSE_SELECT		(1 << 0) | ||||
|   #define   SERIAL_MOUSE				(1 << 1) | ||||
|   #define   HDD1_PARTIAL_DECODE		(1 << 4) | ||||
|   #define   HDD0_PARTIAL_DECODE		(1 << 5) | ||||
|   #define   HDD_SELECT					(1 << 6) | ||||
|   #define   FDD_SELECT					(1 << 7) | ||||
|  | ||||
| #define SUSPEND_MODULATION_OFF     0x94 | ||||
| #define SUSPEND_MODULATION_ON      0x95 | ||||
| #define SUSPEND_CONFIGURATION      0x96 | ||||
|   #define   SUSPEND_MOD_ENABLE         (1 << 0) | ||||
|   #define   SMI_SPEEDUP                (1 << 1) | ||||
|   #define   SUSPEND_MODE               (1 << 2) | ||||
|  | ||||
|  | ||||
| #define GPIO_CONTROL2				0x97 | ||||
|   #define   GPIO3_ENABLE				(1 << 0) | ||||
|   #define   GPIO4_ENABLE				(1 << 1) | ||||
|   #define   GPIO5_ENABLE				(1 << 2) | ||||
|   #define   GPIO7_ENABLE				(1 << 3) | ||||
|   #define   GPIO3_EDGE					(1 << 4) | ||||
|   #define   GPIO4_EDGE					(1 << 5) | ||||
|   #define   GPIO5_EDGE					(1 << 6) | ||||
|   #define   GPIO7_EDGE            		(1 << 7) | ||||
|  | ||||
|  | ||||
| #define HDD_IDLE_TIMEOUT           0x98 | ||||
| #define FDD_IDLE_TIMEOUT           0x9A | ||||
| #define PAR_SER_IDLE_TIMEOUT  		0x9C | ||||
| #define KYBD_MOUSE_IDLE_TIMEOUT	0x9E | ||||
| #define USR_DEF1_IDLE_TIMEOUT		0xA0 | ||||
| #define USR_DEF2_IDLE_TIMEOUT		0xA2 | ||||
| #define USR_DEF3_IDLE_TIMEOUT		0xA4 | ||||
| #define VIDEO_IDLE_TIMEOUT			0xA6 | ||||
|  | ||||
| #define SEC_HDD_TIMEOUT            0xAC | ||||
| #define CPU_SUSPEND_COMMAND        0xAE | ||||
| #define CPU_STOP_CLOCK_COMMAND     0xAF | ||||
| #define CPU_CACHE_MISS_ACTIVITY    0xB0 | ||||
| #define CPU_CACHE_MISS_INACTIVITY  0xB1 | ||||
| #define CPU_CACHE_MISS_THRESHOLD   0xB2 | ||||
|  | ||||
| #define FLOPPY_SHADOW				0xB4 | ||||
| #define FLOPPY_3F2					0xB4 | ||||
| #define FLOPPY_3F7					0xB5 | ||||
| #define FLOPPY_372					0xB6 | ||||
| #define FLOPPY_377					0xB7 | ||||
|  | ||||
| #define DMA_SHADOW					0xB8 | ||||
| #define DMA_SHADOW_CNT				10 | ||||
|  | ||||
| #define PIC_SHADOW					0xB9 | ||||
| #define PIC_SHADOW_CNT				12 | ||||
|  | ||||
| #define PIT_SHADOW					0xBA | ||||
| #define PIT_SHADOW_CNT				9 | ||||
|  | ||||
| #define RTC_SHADOW					0xBB | ||||
| #define RTC_SHADOW_CNT				1 | ||||
|  | ||||
| #define PIC_SHADOW					0xB9 | ||||
| #define PIT_SHADOW					0xBA | ||||
| #define RTC_SHADOW					0xBB | ||||
|  | ||||
| #define CLOCK_STOP_CONTROL         0xBC | ||||
|  | ||||
| #define USR_DEF_1_BASE				0xC0 | ||||
| #define USR_DEF_2_BASE				0xC4 | ||||
| #define USR_DEF_3_BASE				0xC8 | ||||
| #define USR_DEF_1_CONTROL			0xCC | ||||
| #define USR_DEF_2_CONTROL			0xCD | ||||
| #define USR_DEF_3_CONTROL			0xCE | ||||
|   #define USR_DEF_MEMORY             	(1 << 7)	// Bit 7 = 1 | ||||
|   #define USR_DEF_IO                 	(0 << 7)	// Bit 7 = 0 | ||||
|   #define USR_DEF_WRITE              	(1 << 6)	// Bit 6 = 1 (only for I/O) | ||||
|   #define USR_DEF_READ               	(1 << 5)	// Bit 5 = 1 (only for I/O) | ||||
|  | ||||
|  | ||||
| #define SW_SMI					0xD0 | ||||
|  | ||||
|  | ||||
|  | ||||
| // Relative to PCI Function 0 | ||||
| #define PM_STATUS					0xF4 | ||||
|   #define   PM_SRC_GPIO3	 			(1L <<  0) | ||||
|   #define   PM_SRC_GPIO4	 			(1L <<  1) | ||||
|   #define   PM_SRC_GPIO5	 			(1L <<  2) | ||||
|   #define   PM_SRC_GPIO7	 			(1L <<  3) | ||||
|   #define   PM_SRC_GAMEPORT	 		(1L <<  4) | ||||
|   #define   PM_SRC_HDD_IDLE	 		(1L <<  8)	// Primary | ||||
|   #define   PM_SRC_FDD_IDLE	 		(1L <<  9) | ||||
|   #define   PM_SRC_PARSER_IDLE 		(1L << 10) | ||||
|   #define   PM_SRC_KEYBMS_IDLE			(1L << 11) | ||||
|   #define   PM_SRC_USER_DEF1_IDLE		(1L << 12) | ||||
|   #define   PM_SRC_USER_DEF2_IDLE		(1L << 13) | ||||
|   #define   PM_SRC_USER_DEF3_IDLE		(1L << 14) | ||||
|   #define   PM_SRC_VIDEO_IDLE			(1L << 15) | ||||
|   #define   PM_SRC_HDD_TRAP	 		(1L << 16)	// Primary | ||||
|   #define   PM_SRC_FDD_TRAP	 		(1L << 17) | ||||
|   #define   PM_SRC_PAR_SER_TRAP		(1L << 18) | ||||
|   #define   PM_SRC_KYBD_MOUSE_TRAP		(1L << 19) | ||||
|   #define   PM_SRC_SECONDARY_IDLE		(1L << 20) | ||||
|   #define   PM_SRC_SECONDARY_TRAP 		(1L << 21) | ||||
|   #define   PM_SRC_reserved			(1L << 22) | ||||
|   #define   PM_SRC_VIDEO_TRAP			(1L << 23) | ||||
|   #define   PM_SRC_ACPI_TIMER 			(1L << 24) | ||||
|   #define   PM_SRC_RTC_ALARM 			(1L << 25) | ||||
|   #define   PM_SRC_AC97_CODEC 			(1L << 26) | ||||
|   #define   PM_SRC_LID_SWITCH 			(1L << 27) | ||||
|   #define   PM_SRC_LID_POSITION		(1L << 28)	// Not an SMI source | ||||
|   #define   PM_SRC_GPIO0	 			(1L << 29) | ||||
|   #define   PM_SRC_GPIO1	 			(1L << 30)  // CS55x0 only | ||||
|   #define   PM_SRC_THERMAL	 			(1L << 30)	// SCxxxx only | ||||
|   #define   PM_SRC_GPIO2	 			((ULONG)(1L << 31)) | ||||
|  | ||||
|  | ||||
| #define GPIO_PINS	(PM_SRC_GPIO0 | PM_SRC_GPIO1 | PM_SRC_GPIO2 | PM_SRC_GPIO3 | PM_SRC_GPIO4 | PM_SRC_GPIO5 | PM_SRC_LID_SWITCH | PM_SRC_GPIO7) | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										230
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/cs5536.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										230
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/cs5536.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,230 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //**************************  CS5536 related defines  *************************** | ||||
|  | ||||
|  | ||||
|  | ||||
| // Southbridge MPCI CTRL: | ||||
| #define ME	(1 << 0)	// Enable in-bound memory accesses | ||||
| #define IE	(1 << 1)	// Enable in-bound I/O accesses | ||||
| #define CIS_MASK  (3 << 3)	// CIS Mode  | ||||
|   #define CIS_A (1 << 3) | ||||
|   #define CIS_B (2 << 3) | ||||
|   #define CIS_C (3 << 3) | ||||
|  | ||||
|  | ||||
|  | ||||
| #define MPCI_SOUTH	0x51000000	 // 2.4.2.0 | ||||
|  | ||||
| #define MDD_PORT    4  // Port that MDD is at | ||||
|  | ||||
|  | ||||
|  | ||||
| #define REGION_R0   0x20 | ||||
| #define REGION_R15  (REGION_R0 + 15) | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| /****** 5536 GPIO definitions ******/ | ||||
|  | ||||
| // offsets from GPIO base | ||||
| #define GPIO5536_BASE			(0x6100) | ||||
|  | ||||
| #define NUM_5536_GPIO			(28) | ||||
|  | ||||
| #define GPIOH_OFFSET			(0x80) | ||||
|   | ||||
| #define GPIO_OUT_VAL 			(0x00) | ||||
| #define GPIO_OUT_EN 			(0x04) | ||||
| #define GPIO_OUT_OD_EN 			(0x08) | ||||
| #define GPIO_OUT_INV_EN 		(0x0C) | ||||
| #define GPIO_OUT_AUX1_SEL 		(0x10) | ||||
| #define GPIO_OUT_AUX2_SEL 		(0x14) | ||||
| #define GPIO_PU_EN 				(0x18) | ||||
| #define GPIO_PD_EN				(0x1C) | ||||
| #define GPIO_IN_EN				(0x20) | ||||
| #define GPIO_IN_INV_EN			(0x24) | ||||
| #define GPIO_IN_FIL_EN			(0x28) | ||||
| #define GPIO_IN_EVC_EN			(0x2C) | ||||
| #define GPIO_READBACK			(0x30) | ||||
| #define GPIO_IN_AUX_SEL			(0x34) | ||||
| #define GPIO_EVENT_EN			(0x38) | ||||
| #define GPIO_LOCK_EN			(0x3C) | ||||
| #define GPIO_IN_PEDG_EN			(0x40) | ||||
| #define GPIO_IN_NEDG_EN			(0x44) | ||||
| #define GPIO_IN_PEDG_STS		(0x48) | ||||
| #define GPIO_IN_NEDG_STS		(0x4C) | ||||
|  | ||||
| #define	GPIO00_FILA				(0x50) | ||||
| #define GPIO00_FILC				(0x52) | ||||
| #define GPIO00_EVCNT			(0x54) | ||||
| #define GPIO00_EVCMP			(0x56) | ||||
| #define	GPIO01_FILA				(0x58) | ||||
| #define GPIO01_FILC				(0x5A) | ||||
| #define GPIO01_EVCNT			(0x5C) | ||||
| #define GPIO01_EVCMP			(0x5E) | ||||
| #define	GPIO02_FILA				(0x60) | ||||
| #define GPIO02_FILC				(0x62) | ||||
| #define GPIO02_EVCNT			(0x64) | ||||
| #define GPIO02_EVCMP			(0x66) | ||||
| #define	GPIO03_FILA				(0x68) | ||||
| #define GPIO03_FILC				(0x6A) | ||||
| #define GPIO03_EVCNT			(0x6C) | ||||
| #define GPIO03_EVCMP			(0x6E) | ||||
| #define	GPIO04_FILA				(0x70) | ||||
| #define GPIO04_FILC				(0x72) | ||||
| #define GPIO04_EVCNT			(0x74) | ||||
| #define GPIO04_EVCMP			(0x76) | ||||
| #define	GPIO05_FILA				(0x78) | ||||
| #define GPIO05_FILC				(0x7A) | ||||
| #define GPIO05_EVCNT			(0x7C) | ||||
| #define GPIO05_EVCMP			(0x7E) | ||||
| #define	GPIO06_FILA				(0xD0) | ||||
| #define GPIO06_FILC				(0xD2) | ||||
| #define GPIO06_EVCNT			(0xD4) | ||||
| #define GPIO06_EVCMP			(0xD6) | ||||
| #define	GPIO07_FILA				(0xD8) | ||||
| #define GPIO07_FILC				(0xDA) | ||||
| #define GPIO07_EVCNT			(0xDC) | ||||
| #define GPIO07_EVCMP			(0xDE) | ||||
|    | ||||
| #define GPIO_MAPX				(0xE0) | ||||
| #define GPIO_MAPY				(0xE4) | ||||
| #define GPIO_MAPZ				(0xE8) | ||||
| #define GPIO_MAPW				(0xEC) | ||||
|  | ||||
| #define GPIO_FE0				(0xF0) | ||||
| #define GPIO_FE1				(0xF1) | ||||
| #define GPIO_FE2				(0xF2) | ||||
| #define GPIO_FE3				(0xF3) | ||||
| #define GPIO_FE4				(0xF4) | ||||
| #define GPIO_FE5				(0xF5) | ||||
| #define GPIO_FE6				(0xF6) | ||||
| #define GPIO_FE7				(0xF7) | ||||
|  | ||||
| #define GPIOL_IN_EVENT_DECR		(0xF8) | ||||
| #define GPIOH_IN_EVENT_DECR		(0xFC) | ||||
|  | ||||
| // GPIO atomic register values | ||||
| #define	GPIO00_SET		(0x00000001L) | ||||
| #define GPIO00_CLR		(0x00010000L) | ||||
| #define GPIO01_SET		(0x00000002L) | ||||
| #define GPIO01_CLR		(0x00020000L) | ||||
| #define	GPIO02_SET		(0x00000004L) | ||||
| #define GPIO02_CLR		(0x00040000L) | ||||
| #define GPIO03_SET		(0x00000008L) | ||||
| #define GPIO03_CLR		(0x00080000L) | ||||
| #define	GPIO04_SET		(0x00000010L) | ||||
| #define GPIO04_CLR		(0x00100000L) | ||||
| #define GPIO05_SET		(0x00000020L) | ||||
| #define GPIO05_CLR		(0x00200000L) | ||||
| #define	GPIO06_SET		(0x00000040L) | ||||
| #define GPIO06_CLR		(0x00400000L) | ||||
| #define GPIO07_SET		(0x00000080L) | ||||
| #define GPIO07_CLR		(0x00800000L) | ||||
| #define	GPIO08_SET		(0x00000100L) | ||||
| #define GPIO08_CLR		(0x01000000L) | ||||
| #define GPIO09_SET		(0x00000200L) | ||||
| #define GPIO09_CLR		(0x02000000L) | ||||
| #define	GPIO10_SET		(0x00000400L) | ||||
| #define GPIO10_CLR		(0x04000000L) | ||||
| #define GPIO11_SET		(0x00000800L) | ||||
| #define GPIO11_CLR		(0x08000000L) | ||||
| #define	GPIO12_SET		(0x00001000L) | ||||
| #define GPIO12_CLR		(0x10000000L) | ||||
| #define GPIO13_SET		(0x00002000L) | ||||
| #define GPIO13_CLR		(0x20000000L) | ||||
| #define	GPIO14_SET		(0x00004000L) | ||||
| #define GPIO14_CLR		(0x40000000L) | ||||
| #define GPIO15_SET		(0x00008000L) | ||||
| #define GPIO15_CLR		(0x80000000L) | ||||
|  | ||||
| #define	GPIO16_SET		(0x00000001L) | ||||
| #define GPIO16_CLR		(0x00010000L) | ||||
| #define GPIO17_SET		(0x00000002L) | ||||
| #define GPIO17_CLR		(0x00020000L) | ||||
| #define	GPIO18_SET		(0x00000004L) | ||||
| #define GPIO18_CLR		(0x00040000L) | ||||
| #define GPIO19_SET		(0x00000008L) | ||||
| #define GPIO19_CLR		(0x00080000L) | ||||
| #define	GPIO20_SET		(0x00000010L) | ||||
| #define GPIO20_CLR		(0x00100000L) | ||||
| #define GPIO21_SET		(0x00000020L) | ||||
| #define GPIO21_CLR		(0x00200000L) | ||||
| #define	GPIO22_SET		(0x00000040L) | ||||
| #define GPIO22_CLR		(0x00400000L) | ||||
| #define GPIO23_SET		(0x00000080L) | ||||
| #define GPIO23_CLR		(0x00800000L) | ||||
| #define	GPIO24_SET		(0x00000100L) | ||||
| #define GPIO24_CLR		(0x01000000L) | ||||
| #define GPIO25_SET		(0x00000200L) | ||||
| #define GPIO25_CLR		(0x02000000L) | ||||
| #define	GPIO26_SET		(0x00000400L) | ||||
| #define GPIO26_CLR		(0x04000000L) | ||||
| #define GPIO27_SET		(0x00000800L) | ||||
| #define GPIO27_CLR		(0x08000000L) | ||||
| #define	GPIO28_SET		(0x00001000L) | ||||
| #define GPIO28_CLR		(0x10000000L) | ||||
| #define GPIO29_SET		(0x00002000L) | ||||
| #define GPIO29_CLR		(0x20000000L) | ||||
| #define	GPIO30_SET		(0x00004000L) | ||||
| #define GPIO30_CLR		(0x40000000L) | ||||
| #define GPIO31_SET		(0x00008000L) | ||||
| #define GPIO31_CLR		(0x80000000L) | ||||
|  | ||||
| // Hawk platform has Sleep Button connected to GPIO25 | ||||
| #define DEFAULT_SLPB_GPIO	(25) | ||||
|  | ||||
| // GPIO13 AUX_IN is dedicated 5536 Sleep Button but it is only connected | ||||
| // to Working Power Domain and can't wake the system from Standby. | ||||
| // #define DEFAULT_SLPB_GPIO	(13) | ||||
|  | ||||
|  | ||||
| // 5536 Power Management Controller | ||||
|  | ||||
| // offsets from base PMC I/O address, all are 32-bit regs | ||||
| #define PM_SSD		(0x00)	// Sleep start delay | ||||
| #define PM_SCXA		(0x04)	// Sleep control X Assert Delay and Enable | ||||
| #define PM_SCYA		(0x08)	// Sleep control Y Assert Delay and Enable | ||||
| #define PM_SODA		(0x0C)	// Sleep Output Disable Assert Delay and Enable | ||||
| #define PM_SCLK		(0x10)	// Sleep Clock Delay and Enable | ||||
| #define PM_SED		(0x14)	// Sleep End Delay | ||||
| #define PM_SCXD		(0x18)	// Sleep Control X De-assert Delay and Enable | ||||
| #define PM_SCYD		(0x1C)	// Sleep Control Y De-assert Delay and Enable | ||||
| #define PM_SIDD		(0x20)	// Sleep Input Disable De-assert Delay and Enable | ||||
| #define PM_WKD		(0x30)	// Working De-assert Delay and Enable | ||||
| #define PM_WKXD		(0x34)	// Work_AUX De-assert Delay and Enable | ||||
| #define PM_RD		(0x38)	// De-assert Delay from Standby | ||||
| #define PM_WKXA		(0x3C)	// Work_AUX Assert Delay from Standby Wakeup | ||||
| #define PM_FSD		(0x40)	// Fail-Safe Delay and Enable | ||||
| #define PM_TSD		(0x44)	// Thermal-Safe Delay and Enable | ||||
| #define PM_PSD		(0x48)	// Power-Safe Delay and Enable | ||||
| #define PM_NWKD		(0x4C)	// Normal Work Delay and Enable | ||||
| #define PM_AWKD		(0x50)	// Abnormal Work Delay and Enable | ||||
| #define PM_SSC		(0x54)	// Standby Status and Control | ||||
|  | ||||
|  | ||||
|  | ||||
| #define USBMSROHCB			0x0008 | ||||
| #define USBMSREHCB			0x0009 | ||||
| #define USBMSRUDCB			0x000A | ||||
| #define USBMSRUOCB			0x000B | ||||
| #define PMEEN               (1L << 3) | ||||
							
								
								
									
										443
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/gx2.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										443
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/gx2.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,443 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
|  | ||||
| // Vail MSRs | ||||
| #define MSR_SMM_CTRL               0x1301 | ||||
|   #define SMM_NMI_EN     (1L << 0)	// Enables NMIs during SMM | ||||
|   #define SMM_SUSP_EN    (1L << 1)	// Enables SUSP# pin during SMM | ||||
|   #define NEST_SMI_EN    (1L << 2)	// Enables SSMIs during SMM | ||||
|   #define SMM_INST_EN    (1L << 3)	// Enables SMM instructions | ||||
|   #define INTL_SMI_EN    (1L << 4)	// Enables SSMIs | ||||
|   #define EXTL_SMI_EN    (1L << 5)	// Enables SMI# pin | ||||
|  | ||||
| #define MSR_SMM_HDR                0x132B | ||||
| #define MSR_SMM_LOC                0x133B | ||||
| #define MSR_EFLAGS                 0x1418 | ||||
| #define MSR_CR0                    0x1420 | ||||
| #define MSR_DR7                    0x1343 | ||||
|  | ||||
|  | ||||
| // | ||||
| // Region Control Registers (see page 10-188 of Vail spec) | ||||
| // | ||||
| #define REGION_CD        (1L << 0)	// Cache disabled | ||||
| #define REGION_WA        (1L << 1)	// Write-allocate | ||||
| #define REGION_WP        (1L << 2)	// Write-protect | ||||
| #define REGION_WT        (1L << 3)	// Write-through | ||||
| #define REGION_WC        (1L << 4)	// Write-combine | ||||
| #define REGION_WS        (1L << 5)	// Write-serialize | ||||
| #define REGION_EN        (1L << 8) // Region enable | ||||
|  | ||||
| #define MSR_RCONF_DEFAULT          0x1808 | ||||
| #define MSR_RCONF_BYPASS           0x180A | ||||
| #define MSR_RCONF_A0_BF            0x180B | ||||
| #define MSR_RCONF_C0_DF            0x180C | ||||
| #define MSR_RCONF_E0_FF            0x180D | ||||
| #define MSR_RCONF_SMM              0x180E | ||||
| #define MSR_RCONF_DMM              0x180F | ||||
|  | ||||
|  | ||||
| // Bit(s)           Field  | ||||
| // ------      ----------------------------------------------- | ||||
| //  7:0        Region Properties | ||||
| //   8         Enable | ||||
| //  11:9       reserved | ||||
| //  31:12      Start of region (4 KB granularity; inclusive) | ||||
| //  43:32      reserved | ||||
| //  63:44      Top of region (4 KB granularity; inclusive) | ||||
| #define MSR_RCONF0                 0x1810 | ||||
| #define MSR_RCONF1                 0x1811 | ||||
| #define MSR_RCONF2                 0x1812 | ||||
| #define MSR_RCONF3                 0x1813 | ||||
| #define MSR_RCONF4                 0x1814 | ||||
| #define MSR_RCONF5                 0x1815 | ||||
| #define MSR_RCONF6                 0x1816 | ||||
| #define MSR_RCONF7                 0x1817 | ||||
|  | ||||
|  | ||||
| //======================================================================================== | ||||
| #define BIZARRO          (1L << 28) | ||||
| #define ROUTING          0xFFFFC000	// Mask for routing field | ||||
|  | ||||
|  | ||||
|  | ||||
| // Ports under Redcloud MBIU0 | ||||
| #define PORT_MBIU0  0x10000000L	// By convention | ||||
|  | ||||
|  | ||||
| // Standard MBus Device MSRs: | ||||
| #define MBD_MSR_CAP                0x2000 | ||||
| #define MBD_MSR_CONFIG             0x2001		// 3 LSBs = subtractive port | ||||
|   // MBIU0: 0x00000002 | ||||
|   // MBIU1: 0x00000004 | ||||
|   // MBIU2: 0x00000004 | ||||
|  | ||||
| #define MBD_MSR_SMI                0x2002 | ||||
| #define MBD_MSR_ERROR              0x2003 | ||||
| #define MBD_MSR_PM                 0x2004 | ||||
| #define MBD_MSR_DIAG               0x2005 | ||||
|  | ||||
| // Northbridge MPCI | ||||
| #define MPCI_CTRL                  0x2010 | ||||
|   #define LDE            (1 << 9)    // Enable latency disconnect timer | ||||
| #define MPCI_ARB                   0x2011 | ||||
| #define MPCI_PBUS                  0x2012 | ||||
| #define MPCI_REN                   0x2014		// Fixed Region Enables | ||||
| #define MPCI_A0_BF                 0x2015		// Fixed Regions Properties A0000-BFFFF | ||||
| #define MPCI_C0_DF                 0x2016		// Fixed Regions Properties C0000-DFFFF | ||||
| #define MPCI_E0_FF                 0x2017		// Fixed Regions Properties E0000-FFFFF | ||||
| #define MPCI_R0                    0x2018		// Base memory | ||||
| #define MPCI_R1                    0x2019		// Extended memory | ||||
| #define MPCI_R2                    0x201A		// SMM memory | ||||
| #define MPCI_R3                    0x201B | ||||
| #define MPCI_R4                    0x201C | ||||
| #define MPCI_R5                    0x201D | ||||
|   // MPCI Region Control Registers (see page 89 of MPCI spec) | ||||
|   #define REGION_CD      (1L << 0)	// Cache disabled | ||||
|   #define REGION_DD      (1L << 1)	// Discard data | ||||
|   #define REGION_WP      (1L << 2)	// Write protect | ||||
|   #define REGION_WT      (1L << 3)	// Write through | ||||
|   #define REGION_WC      (1L << 4)	// Write combine | ||||
|   #define REGION_PF      (1L << 5)	// Prefetchable | ||||
|  | ||||
| #define MPCI_ExtMSR                0x201E | ||||
|  | ||||
|  | ||||
|  | ||||
| // Revision IDs | ||||
| #define CPU_REV_1_0				0x11 | ||||
| #define CPU_REV_1_1				0x12 | ||||
| #define CPU_REV_2_0				0x20 | ||||
|  | ||||
|  | ||||
| // MBus Device IDs: | ||||
| #define ID_SHIFT                   12 | ||||
| #define ID_MBIU                    0x01 | ||||
| #define ID_MC                      0x20 | ||||
| #define ID_VAIL                    0x86 | ||||
| #define ID_AES                     0x30 | ||||
| #define ID_VIP                     0x3C | ||||
| #define ID_GP                      0x3D | ||||
| #define ID_VG                      0x3E | ||||
| #define ID_DF                      0x3F | ||||
| #define ID_MCP                     0x02 | ||||
| #define ID_MPCI                    0x05 | ||||
| #define ID_FG                      0xF0 | ||||
| #define ID_OHCI                    0x42 | ||||
| #define ID_USB_20                  0x43 | ||||
| #define ID_ATA                     0x47 | ||||
| #define ID_ATA100                  0x48 | ||||
| #define ID_MDD                     0xDF | ||||
| #define ID_AC97                    0x33 | ||||
|  | ||||
| 		 | ||||
|  | ||||
| ///////////////////////////////////////////////////////////// | ||||
| //                     Northbridge | ||||
| ///////////////////////////////////////////////////////////// | ||||
| // MBIU0 | ||||
| // | ||||
| // Capabilities: 22711830 010C1086 | ||||
| // P2D_BM  = 6;    0x20-0x25 | ||||
| // P2D_BMO = 2;    0x26-0x27 | ||||
| // P2D_R   = 1;    0x28 | ||||
| // P2D_RO  = 3;    0x29-0x2B | ||||
| // P2D_SC  = 1;    0x2C | ||||
| // P2D_SCO = 0; | ||||
| // IOD_BM  = 3;    0xE0-0xE2 | ||||
| // IOD_SC  = 6;    0xE3-0xE8 | ||||
| // NPORTS  = 5; | ||||
| // STATS   = 2; | ||||
| // | ||||
| //  Port   Dev_ID        Routing          FS/2     Device Description | ||||
| // -----  -------- -------------------  --------   ------------------ | ||||
| //   0      01h    10000000  0.1.0.0.0  20000000   MBIU0 | ||||
| //   1      20h    20000000  1.0.0.0.0  24000000   Memory Controller | ||||
| //   2      01h    40000000  2.0.0.0.0             MBIU1 (subtractive) | ||||
| //   3      86h    60000000  3.0.0.0.0  2C000000   Vail (self-reference) | ||||
| //   4      3Eh    80000000  4.0.0.0.0  30000000   Video Generator | ||||
| //   5      3Dh    A0000000  5.0.0.0.0  34000000   Graphics Processor | ||||
| //   6      3Fh    C0000000  6.0.0.0.0  38000000   Display Filter | ||||
| //   7                                             <empty> | ||||
|  | ||||
| #define VG_PORT         4L | ||||
| #define GP_PORT			5L | ||||
| #define VG_SMI_MSR		(VG_PORT << 29) + MBD_MSR_SMI | ||||
| #define GP_SMI_MSR		(GP_PORT << 29) + MBD_MSR_SMI | ||||
|  | ||||
|  | ||||
| // | ||||
| // MBIU1 | ||||
| // | ||||
| // Capabilities: 20281830 01004009 | ||||
| // P2D_BM  = 9;    0x20-0x28 | ||||
| // P2D_BMO = 0;  | ||||
| // P2D_R   = 4;    0x29-0x2C | ||||
| // P2D_RO  = 0; | ||||
| // P2D_SC  = 1;    0x2D | ||||
| // P2D_SCO = 0; | ||||
| // IOD_BM  = 3;    0xE0-0xE2 | ||||
| // IOD_SC  = 6;    0xE3-0xE8 | ||||
| // NPORTS  = 5; | ||||
| // STATS   = 2; | ||||
| // | ||||
| //  Port   Dev_ID        Routing         FS/2       Device Description | ||||
| // -----  -------- -------------------  --------   ------------------ | ||||
| //   0                                             <empty> | ||||
| //   1      01h    44000000  2.1.0.0.0  01000000   MBIU1 (self-reference) | ||||
| //   2                                             <empty> | ||||
| //   3      02h    4C000000  2.3.0.0.0  00000000   MCP | ||||
| //   4      05h    50000000  2.4.0.0.0  80000000   MPCI Northbridge (subtractive) | ||||
| //   5      F0h    54000000  2.5.0.0.0  A0000000   FooGlue | ||||
| //   6                                             <empty> | ||||
| //   7                                             <empty> | ||||
|  | ||||
| #define MBIU0_PORT		1  // From MBIU1's point of view | ||||
|  | ||||
|  | ||||
| ///////////////////////////////////////////////////////////// | ||||
| //                  CS5535 | ||||
| ///////////////////////////////////////////////////////////// | ||||
| // | ||||
| // Capabilities: 327920A0 80000003	  (simulator: 303820a0) | ||||
| // P2D_BM  = 3;    0x20-0x22 | ||||
| // P2D_BMK = 2;    0x23-0x24 | ||||
| // IOD_BM  = 10;   0xE0-0xE9 | ||||
| // IOD_SC  = 8;    0xEA-0xF1 | ||||
| // NPORTS  = 7; | ||||
| // STATS   = 3; | ||||
| // | ||||
| // | ||||
| //  Port   Dev_ID        Routing         FS/2      Device Description | ||||
| // -----  -------- -------------------  --------   ----------------- | ||||
| //          05h    51000000  2.4.2.0.0  88000000   MPCI Southbridge | ||||
| //   0      01h    51020000  2.4.2.0.1  88100000   MBIU2 | ||||
| //   1             51100000  2.4.2.1.0             MPCI (self-reference) | ||||
| //   2      42h    51200000  2.4.2.2.0  89000000   OHCI #2 | ||||
| //   3      47h    51300000  2.4.2.3.0  89800000   ATA-5 | ||||
| //   4      DFh    51400000  2.4.2.4.0  8A000000   MDD (subtractive) | ||||
| //   5      33h    51500000  2.4.2.5.0  8A800000   AC97 codec | ||||
| //   6      42h    51600000  2.4.2.6.0  8B000000   OHCI #1 | ||||
| //   7      02h    51700000  2.4.2.7.0  8B800000   MCP | ||||
|  | ||||
|  | ||||
| ///////////////////////////////////////////////////////////// | ||||
| //                  CS5536 | ||||
| ///////////////////////////////////////////////////////////// | ||||
| // | ||||
| // Capabilities: 327920A0 80000003 | ||||
| // P2D_BM  = 3;    0x20-0x22 | ||||
| // P2D_BMK = 2;    0x23-0x24 | ||||
| // IOD_BM  = 10;   0xE0-0xE9 | ||||
| // IOD_SC  = 8;    0xEA-0xF1 | ||||
| // NPORTS  = 7; | ||||
| // STATS   = 3; | ||||
| // | ||||
| // | ||||
| //  Port   Dev_ID        Routing         FS/2      Device Description | ||||
| // -----  -------- -------------------  --------   ----------------- | ||||
| //          05h    51000000  2.4.2.0.0  88000000   MPCI Southbridge | ||||
| //   0      01h    51020000  2.4.2.0.1  88100000   MBIU2 | ||||
| //   1             51100000  2.4.2.1.0             MPCI (self-reference) | ||||
| //   2      42h    51200000  2.4.2.2.0  89000000   <empty> | ||||
| //   3      47h    51300000  2.4.2.3.0  89800000   ATA-5 | ||||
| //   4      DFh    51400000  2.4.2.4.0  8A000000   MDD (subtractive) | ||||
| //   5      33h    51500000  2.4.2.5.0  8A800000   AC97 codec | ||||
| //   6      43h    51600000  2.4.2.6.0  8B000000   USB 2.0 | ||||
| //   7      02h    51700000  2.4.2.7.0  8B800000   MCP | ||||
|  | ||||
|  | ||||
| // | ||||
| //				Arcturus | ||||
| // | ||||
| //	Device     AD PIN    Physical Device | ||||
| //  ------     ------    --------------------------------------------------- | ||||
| //	  13         23      MacPhyter | ||||
| //	  14         24      PCI Slot 1   | ||||
| //	  15         25      PCI Slot 2 | ||||
| //	  16         26      Chipset Register Space - pin H26 High | ||||
| //	  17         27      USB Register Space     - pin H26 High | ||||
| //	  18         28      Chipset Register Space - pin H26 Low | ||||
| //	  19         29      USB Register Space     - pin H26 Low | ||||
|  | ||||
|  | ||||
| // | ||||
| //                  MPCI | ||||
| // | ||||
|  | ||||
| // Fields for both MPCI_MSR_SMI and MPCI_MSR_ERROR | ||||
|   #define MARM         (1L << 0) | ||||
|   #define TARM         (1L << 1) | ||||
|   #define BMM          (1L << 2) | ||||
|   #define SSMM         (1L << 2)   // only in MPCI SB MSR_SMI | ||||
|   #define VPHM         (1L << 3)	// only in MPCI NB MSR_SMI | ||||
|   #define SYSM         (1L << 4) | ||||
|   #define PARM         (1L << 5) | ||||
|   #define MARE         (1L << 16) | ||||
|   #define TARE         (1L << 17) | ||||
|   #define BME          (1L << 18)  // Northbridge only ? | ||||
|   #define VPHE         (1L << 19)	// only in MPCI NB MSR_SMI | ||||
|   #define SYSE         (1L << 20) | ||||
|   #define PARE         (1L << 21) | ||||
|   #define TASE         (1L << 22) | ||||
|  | ||||
|  | ||||
|  | ||||
| // FooGlue MSRs: | ||||
| #define FG_IIOC                    0x0010 | ||||
|   #define MODE_5530    0 | ||||
|   #define MODE_5535A   1 | ||||
|   #define MODE_5535B   2 | ||||
| #define FG_A20M                    0x0011 | ||||
|   #define A20M         (1 << 0) | ||||
| #define FG_NMI                     0x0012 | ||||
|   #define NMI          (1 << 0) | ||||
|  | ||||
| #define FG_INIT                    0x0013 | ||||
|   #define INIT         (1 << 0) | ||||
|  | ||||
|  | ||||
|  | ||||
| #define MBIU_COH                   0x0080 | ||||
| #define MBIU_PAE                   0x0081 | ||||
| #define MBIU_ARB                   0x0082 | ||||
| #define MBIU_ASMI                  0x0083 | ||||
| #define MBIU_ERR                   0x0084 | ||||
| #define MBIU_DEBUG                 0x0085 | ||||
| #define MBIU_CAP                   0x0086 | ||||
| #define MBIU_NOUT_RESP             0x0087 | ||||
| #define MBIU_NOUT_WDATA            0x0088 | ||||
| #define MBIU_WHOAMI                0x008B | ||||
|   // MBIU_WHOAMI tells self-reference: | ||||
|   // MBIU0: 0x00000003 | ||||
|   // MBIU1: 0x00000001 | ||||
|   // MBIU2: 0x00000001 | ||||
| #define MBIU_SLV                   0x008C | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| // | ||||
| // Descriptor MSRs | ||||
| // | ||||
| #define MSR_MEM_DESCR              0x0020 | ||||
| #define MSR_IO_DESCR               0x00E0 | ||||
|   // Defines for IOD_SC | ||||
|   #define REN            (1L << 20) | ||||
|   #define WEN            (1L << 21) | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| // | ||||
| // Descriptor Statistics MSRs | ||||
| // | ||||
| #define MSR_STATISTICS_CNT         0x00A0		// and A4, A8, AC | ||||
|   // High dword is Load Value;  Low dword is Count | ||||
| #define MSR_STATISTICS_MASK        0x00A1		// and A5, A9, AD | ||||
|   // High dword is IOD mask;    Low dword is P2D mask  | ||||
| #define MSR_STATISTICS_ACTION      0x00A2		// and A6, AA, AE | ||||
|   #define HIT_LDEN       (1L << 0)		// Load CNT on descriptor hit | ||||
|   #define HIT_DEC        (1L << 1)		// Decrement CNT on descriptor hit | ||||
|   #define HIT_SMI        (1L << 2)		// Assert ASMI on descriptor hit | ||||
|   #define HIT_ERR        (1L << 3)		// Assert AERR on descriptor hit | ||||
|   #define ALWAYS_DEC     (1L << 4)		// Always decrement CNT (unless loading or (CNT = 0 & !RELOAD)) | ||||
|   #define ZERO_SMI       (1L << 5)		// Assert ASMI on CNT = 0 | ||||
|   #define ZERO_ERR       (1L << 6)		// Assert AERR on CNT = 0 | ||||
|   #define WRAP           (1L << 7)		// Reload CNT from LOAD_VAL on CNT = 0 | ||||
|  | ||||
| // Vail PM stuff | ||||
| #define BC_MSR0                    0x1900 | ||||
|   #define SUSP_EN        (0x1000L) | ||||
|  | ||||
| #define XC_CONFIG                  0x1210 | ||||
|   #define XC_CLK_SUSP    (0x01L) | ||||
|  | ||||
| // GX2 Memory Controller PM stuff | ||||
|  | ||||
| // MC PMode1 Up Delay | ||||
| #define MC_CF1017_DATA             0x001A | ||||
|   #define PM1_UP_DLY_MASK	(0xFF00L) | ||||
| 	// 240ns delay, DDR spec. state minimum delay is 200ns | ||||
|   #define PM1_UP_DLY_VAL	(0xF000L) | ||||
|  | ||||
| // MC PMode Sensitivity | ||||
| // bits[63:32]=PMode1, bits[31:0]=PMode0 | ||||
| #define MC_CF_PMCTR	            0x0020 | ||||
|   // number of MC clocks that MC must be inactive | ||||
|   // before entering PMode1 | ||||
|   #define PM1_SENS_VAL   (0x020L) | ||||
|  | ||||
|  | ||||
| // GX2 GLCP PM stuff | ||||
|  | ||||
| // Clock Disable Delay | ||||
| #define MCP_CLK_DIS_DLY            0x0008 | ||||
|   #define CLKDIS_MASK    (0x00FFFFFFL) | ||||
|  | ||||
| // PM Clock Disable | ||||
| #define MCP_PMCLKDISABLE (0x0009) | ||||
|  | ||||
| #define MCP_PMCLKOFF     (0x0010) | ||||
|  | ||||
| // PM CLK4ACK MSR | ||||
| #define MCP_CLK4ACK                0x0013 | ||||
|   #define S3_CLK4ACK     (0x07BE7FC3L) | ||||
|   #define S1_CLK4ACK     S3_CLK4ACK | ||||
|  | ||||
| //  Throttling PM I/O regs default location | ||||
| #define MCP_GLB_PM                 0x000B | ||||
|   #define MCP_GLB_THEN   (0x01L) | ||||
|  | ||||
| #define MCP_DOTPLL                 0x0015 | ||||
| #define MCP_DBGCLKCTL              0x0016 | ||||
|  | ||||
| // default location to map GLCP P_CNT I/O space regs | ||||
| #define PMGX2_BASE                 (0x9E00) | ||||
| /* offset from PMGX2_BASE */ | ||||
| #define P_CNT_OFS        (0)  | ||||
| #define P_LVL2_OFS       (4) | ||||
| #define P_LVL3_OFS       (8) | ||||
|  | ||||
| // GLCP MSR offsets for clock throttling | ||||
| #define MCP_CNT                    (0x0018) | ||||
|   #define CNT_THEN       (0x10L) | ||||
|   #define CNT_MASK       (0x0FL) | ||||
|   #define CNT_MAX        (0x01L) | ||||
|   #define CNT_NONE       (0x0FL) | ||||
| #define MCP_LVL2                   (0x0019) | ||||
| #define MCP_TH_SD                  (0x001C) | ||||
|   #define SD_MASK        (0x0FFFL) | ||||
|   #define PLVL2_IN       (0x1000L) | ||||
| #define MCP_TH_SF                  (0x001D) | ||||
|   #define SF_MASK        (0x0FFL) | ||||
| #define MCP_TH_OD                  (0x001E) | ||||
|   #define OD_IRQ         (0x8000L) | ||||
|   #define OD_SMI         (0x4000L) | ||||
|   #define OD_MASK        (0x3FFFL) | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										97
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/hce.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										97
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/hce.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,97 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| typedef struct { | ||||
|   union { | ||||
|     unsigned long  HceUlong; | ||||
|     unsigned short HceUshort; | ||||
| 	struct { | ||||
|      unsigned short EmulationEnable: 1; | ||||
|      unsigned short EmulationInterrupt: 1; | ||||
|      unsigned short CharacterPending: 1; | ||||
|      unsigned short IRQEn: 1; | ||||
|      unsigned short ExternalIRQEn: 1; | ||||
|      unsigned short GateA20Sequence: 1; | ||||
|      unsigned short IRQ1Active: 1; | ||||
|      unsigned short IRQ12Active: 1; | ||||
|      unsigned short A20State: 1; | ||||
|     }; | ||||
|   }; | ||||
| } HCE_CONTROL; | ||||
|  | ||||
|  | ||||
| // Host Controller Operational Registers | ||||
| typedef struct { | ||||
|   unsigned long HcRevision; | ||||
|   unsigned long HcControl; | ||||
|   unsigned long HcCommandStatus; | ||||
|   unsigned long HcInterruptStatus; | ||||
|   unsigned long HcInterruptEnable; | ||||
|   unsigned long HcInterruptDisable; | ||||
|   unsigned long HcHCCA; | ||||
|   unsigned long HcPeriodCurrentED; | ||||
|   unsigned long HcControlHeadED; | ||||
|   unsigned long HcControlCurrentED; | ||||
|   unsigned long HcBulkHeadED; | ||||
|   unsigned long HcBulkCurrentED; | ||||
|   unsigned long HcDoneHead; | ||||
|   unsigned long HcFmInterval; | ||||
|   unsigned long HcFmRemaining; | ||||
|   unsigned long HcFmNumber; | ||||
|   unsigned long HcPeriodicStart; | ||||
|   unsigned long HcLSThreshold; | ||||
|   unsigned long HcRhDescriptorA; | ||||
|   unsigned long HcRhDescriptorB; | ||||
|   unsigned long HcRhStatus; | ||||
|   unsigned long HcRhPortStatus[2]; | ||||
|  | ||||
|   unsigned char  Reserved[0x100-0x54-2*4];	// Reserved for use by HC | ||||
|   HCE_CONTROL HceControl;	// 0x100 | ||||
|   unsigned long  HceInput;			// 0x104 | ||||
|   unsigned long  HceOutput;			// 0x108 | ||||
|   unsigned long  HceStatus;			// 0x10C | ||||
| } HCOR; | ||||
|  | ||||
|  | ||||
| // HcInterruptStatus & HcInterruptDisable fields: | ||||
| #define SO		0x00000001L		// Scheduling Overrun | ||||
| #define WDH		0x00000002L		// HcDoneHead Writeback | ||||
| #define SF		0x00000004L		// Start of Frame | ||||
| #define RD		0x00000008L		// Resume Detect | ||||
| #define UE		0x00000010L		// Unrecoverable Error | ||||
| #define FNO		0x00000020L		// Frame Number Overflow | ||||
| #define RHSC	0x00000040L		// Root Hub Status Change | ||||
| #define OC		0x40000000L		// Ownership Change | ||||
| #define MIE		0x80000000L		// Master Interrupt Enable | ||||
|  | ||||
|  | ||||
| // HceControl fields: | ||||
| #define EMULATION_ENABLE    0x01 | ||||
| #define EMULATION_INTERRUPT 0x02 | ||||
| #define CHARACTER_PENDING   0x04 | ||||
| #define IRQ_ENABLE          0x08 | ||||
| #define EXTERNAL_IRQ_ENABLE 0x10 | ||||
| #define GATE_A20_SEQUENCE   0x20 | ||||
| #define IRQ1_ACTIVE         0x40 | ||||
| #define IRQ12_ACTIVE        0x80 | ||||
| #define A20_STATE		   0x100 | ||||
|  | ||||
| // HceStatus fields: | ||||
| #define CMD_DATA			0x08 | ||||
|  | ||||
							
								
								
									
										183
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/isa.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										183
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/isa.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,183 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| // Real Time Clock (RTC) definitions | ||||
| #define CMOS_INDEX			0x70 | ||||
| #define CMOS_DATA			CMOS_INDEX+1 | ||||
| #define	CMOS_SECONDS		0x00 | ||||
| #define	CMOS_MINUTES		0x02 | ||||
| #define	CMOS_HOURS			0x04 | ||||
| #define	CMOS_DAY			0x07 | ||||
| #define	CMOS_MONTH			0x08 | ||||
| #define	CMOS_YEAR			0x09 | ||||
| #define	CMOS_STATUS_A		0x0A | ||||
|   #define UIP				0x80 | ||||
| #define	CMOS_STATUS_B		0x0B | ||||
|   #define SET				0x80 | ||||
|   #define PI 				0x40 | ||||
|   #define AI 				0x20 | ||||
|   #define UI 				0x10 | ||||
|   #define SQUARE			0x08 | ||||
|   #define DM 				0x04 | ||||
|   #define HOUR24			0x02 | ||||
|   #define DLS				0x01 | ||||
| #define	CMOS_STATUS_C		0x0C | ||||
|   #define IRQ				0x80 | ||||
|   #define PS 				0x40 | ||||
|   #define AS 				0x20 | ||||
|   #define US 				0x10 | ||||
| #define	CMOS_CENTURY		0x32 | ||||
|  | ||||
|  | ||||
|  | ||||
| // Programmable Interrupt Controller (PIC) definitions | ||||
| #define PIC1_BASE			0x20 | ||||
| #define PIC1_MASK			PIC1_BASE+1 | ||||
| #define PIC2_BASE			0xA0 | ||||
| #define PIC2_MASK			PIC2_BASE+1 | ||||
| #define NONSPECIFIC_EOI		0x20 | ||||
| #define SPECIFIC_EOI		0x60 | ||||
| #define PIC1_EDGE			0x4D0 | ||||
| #define PIC2_EDGE			0x4D1 | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| #define         PIC1_ICW1       0x20 | ||||
| #define         PIC1_ICW2       0x21 | ||||
| #define         PIC1_ICW3       0x21 | ||||
| #define         PIC1_ICW4       0x21 | ||||
| #define         PIC1_OCW1       0x21 | ||||
| #define         PIC1_OCW2       0x20 | ||||
| #define         PIC1_OCW3       0x20 | ||||
| #define         PIC2_ICW1       0xA0 | ||||
| #define         PIC2_ICW2       0xA1 | ||||
| #define         PIC2_ICW3       0xA1 | ||||
| #define         PIC2_ICW4       0xA1 | ||||
| #define         PIC2_OCW1       0xA1 | ||||
| #define         PIC2_OCW2       0xA0 | ||||
| #define         PIC2_OCW3       0xA0 | ||||
|  | ||||
|  | ||||
| // DMA definitions | ||||
| #define TRANSFER_MASK  (0x0C) | ||||
|   #define DMA_VERIFY   (0x00) | ||||
|   #define DMA_WRITE    (0x04) | ||||
|   #define DMA_READ     (0x08) | ||||
| #define MODE_MASK      (0xC0) | ||||
|   #define MODE_DEMAND  (0x00) | ||||
|   #define MODE_SINGLE  (0x40) | ||||
|   #define MODE_BLOCK   (0x80) | ||||
|   #define MODE_CASCADE (0xC0) | ||||
|  | ||||
| #define         DMA1_ADDR0      0x00 | ||||
| #define         DMA1_CNT0       0x01 | ||||
| #define         DMA1_ADDR1      0x02 | ||||
| #define         DMA1_CNT1       0x03 | ||||
| #define         DMA1_ADDR2      0x04 | ||||
| #define         DMA1_CNT2       0x05 | ||||
| #define         DMA1_ADDR3      0x06 | ||||
| #define         DMA1_CNT3       0x07 | ||||
| #define         DMA1_MODE       0x0B | ||||
| #define         DMA1_CPTR       0x0C | ||||
| #define         DMA1_MASK       0x0F | ||||
| #define         DMA2_ADDR0      0xC0 | ||||
| #define         DMA2_CNT0       0xC2 | ||||
| #define         DMA2_ADDR1      0xC4 | ||||
| #define         DMA2_CNT1       0xC6 | ||||
| #define         DMA2_ADDR2      0xC8 | ||||
| #define         DMA2_CNT2       0xCA | ||||
| #define         DMA2_ADDR3      0xCC | ||||
| #define         DMA2_CNT3       0xCE | ||||
| #define         DMA2_MODE       0xD6 | ||||
| #define         DMA2_CPTR       0xD8 | ||||
| #define         DMA2_MASK       0xDE | ||||
| #define         DMA_PAGE        0x80 | ||||
| #define         DMA_HPAGE       0x480 | ||||
|  | ||||
|  | ||||
|  | ||||
| // Programmable Interval Timer (PIT) definitions | ||||
| #define         PIT_CTR0        0x40 | ||||
| #define         PIT_CTR1        0x41 | ||||
| #define         PIT_CTR2        0x42 | ||||
| #define         PIT_CMD         0x43 | ||||
| #define         PIT_CMD_BOTH_BYTES      0x30 // Sets CMD word to read/write both bytes | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| #define	READ_IRR			0x0A | ||||
| #define	READ_ISR			0x0B | ||||
|  | ||||
| // Keyboard controller registers | ||||
| #define KYBD_DATA			0x60 | ||||
| #define KYBD_STATUS			0x64 | ||||
|   #define STAT_OBF			  0x01 | ||||
|   #define STAT_IBF			  0x02 | ||||
|   #define STAT_FLAG			  0x04 | ||||
|   #define STAT_CMD			  0x08 | ||||
|   #define STAT_INHIBIT 		  0x10 | ||||
|   #define STAT_AUX_OBF		  0x20 | ||||
|   #define STAT_TIMEOUT		  0x40 | ||||
|   #define STAT_PARITY		  0x80 | ||||
| #define KYBD_COMMAND		0x64 | ||||
|  | ||||
| // Keyboard controller output port bits | ||||
| #define KYBD_SYSR			0x01			// Processor reset | ||||
| #define KYBD_GA20			0x02			// Gate A20 (1=on) | ||||
| #define KYBD_ADAT			0x04			// AUX data     | ||||
| #define KYBD_ACLK			0x08			// AUX clock | ||||
| #define KYBD_KOBF			0x10			// Keyboard OBF | ||||
| #define KYBD_AOBF			0x20			// AUX OBF | ||||
| #define KYBD_KCLK			0x40			// Keyboard clock | ||||
| #define KYBD_KDAT			0x80			// Keyboard data | ||||
|  | ||||
| // Keyboard controller commands | ||||
| #define KYBD_RD_OUT			0xD0 | ||||
| #define KYBD_WR_OUT			0xD1 | ||||
|  | ||||
| // Keyboard controller command byte | ||||
| #define OBF_INTERRUPT		0x01 | ||||
| #define AUX_INTERRUPT		0x02 | ||||
| #define SYSTEM_STATUS		0x04 | ||||
| #define KBD_DISABLED		0x10 | ||||
| #define AUX_DISABLED		0x20 | ||||
| #define XT_SCANSET			0x40 | ||||
|  | ||||
|  | ||||
| #define PORT_B				0x92 | ||||
| #define GAMEPORT			0x200 | ||||
| #define PRIMARY_IDE			0x1F6 | ||||
| #define SECONDARY_IDE		0x176 | ||||
| #define PRIMARY_FLOPPY		0x3F5 | ||||
| #define SECONDARY_FLOPPY	0x375 | ||||
|  | ||||
| #define COM1				0x3F8 | ||||
| #define COM2				0x2F8 | ||||
| #define COM3				0x3E8 | ||||
| #define COM4				0x2E8 | ||||
|  | ||||
| #define LPT1				0x378 | ||||
| #define LPT2				0x278 | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										111
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/pci.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										111
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/pci.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,111 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| // PCI related definitions | ||||
| #define PCI_CONFIG_ADDRESS	0xCF8 | ||||
| #define PCI_CONFIG_DATA		0xCFC | ||||
|  | ||||
| #define VENDOR_ID			0x00 | ||||
| #define COMMAND				0x04 | ||||
|   #define IO_SPACE				(1 << 0) | ||||
|   #define MEM_SPACE				(1 << 1) | ||||
|   #define BUS_MASTER			(1 << 2) | ||||
|   #define SPECIAL_CYCLES		(1 << 3) | ||||
|   #define MEM_WR_INVALIDATE		(1 << 4) | ||||
|   #define VGA_PALETTE_SNOOP		(1 << 5) | ||||
|   #define PARITY_RESPONSE		(1 << 6) | ||||
|   #define WAIT_CYCLE_CONTROL	(1 << 7) | ||||
|   #define SERR_ENABLE			(1 << 8) | ||||
|   #define FAST_BACK_TO_BACK		(1 << 9) | ||||
|  | ||||
| #define STATUS              0x06 | ||||
|   #define CAPABILITIES_LIST		(1L << 20) | ||||
|   #define PCI_66MHZ_CAPABLE		(1L << 21) | ||||
|   #define BACK2BACK_CAPABLE		(1L << 23) | ||||
|   #define MASTER_PARITY_ERROR	(1L << 24) | ||||
|   #define DEVSEL_FAST			(0L << 25) | ||||
|   #define DEVSEL_MEDIUM 		(1L << 25) | ||||
|   #define DEVSEL_SLOW			(2L << 25) | ||||
|   #define SIGNALED_TARGET_ABORT	(1L << 27) | ||||
|   #define RECEIVED_TARGET_ABORT	(1L << 28) | ||||
|   #define RECEIVED_MASTER_ABORT	(1L << 29) | ||||
|   #define SIGNALED_SYSTEM_ERROR	(1L << 30) | ||||
|   #define DETECTED_PARITY_ERROR	(1L << 31) | ||||
|  | ||||
|  | ||||
|  | ||||
| #define REVISION_ID			0x08 | ||||
| #define CACHE_LINE			0x0C | ||||
| #define LATENCY_TIMER		0x0D | ||||
| #define HEADER_TYPE			0x0E | ||||
| #define BIST				0x0F | ||||
|  | ||||
|  | ||||
| // Capability List IDs | ||||
| #define CAP_ID_PM			0x01 | ||||
| #define CAP_ID_AGP			0x02 | ||||
| #define CAP_ID_VPD			0x03 | ||||
| #define CAP_ID_SLOT			0x04 | ||||
| #define CAP_ID_MSI			0x05 | ||||
| #define CAP_ID_HOT_SWAP		0x06 | ||||
|  | ||||
|  | ||||
| #define SUBSYSTEM_VENDOR_ID 0x2C | ||||
|  | ||||
| #define INTERRUPT_LINE		0x3C | ||||
| #define INTERRUPT_PIN		0x3D | ||||
| #define MIN_GNT				0x3E | ||||
| #define MAX_LAT				0x3F | ||||
|  | ||||
|  | ||||
| #define BAR0				0x10 | ||||
| #define BAR1				0x14 | ||||
| #define BAR2				0x18 | ||||
| #define BAR3				0x1C | ||||
| #define BAR4				0x20 | ||||
| #define BAR5				0x24 | ||||
|  | ||||
| // PCI Power Management: | ||||
| #define PCI_PM_REG			0x40 | ||||
|  | ||||
| // Graphics-specific registers: | ||||
| #define OEM_BAR0			0x50 | ||||
| #define OEM_BAR1			0x54 | ||||
| #define OEM_BAR2			0x58 | ||||
| #define OEM_BAR3			0x5C | ||||
|  | ||||
| // EHCI-specific registers | ||||
| #define EECP				0x50 | ||||
| #define USBLEGSUP			(EECP) | ||||
|   #define OS_OWNED_SEMAPHORE    0x01000000 | ||||
|   #define BIOS_OWNED_SEMAPHORE  0x00010000 | ||||
| #define USBLEGCTLSTS		(EECP+4) | ||||
|   #define SMI_ON_BAR			0x80000000 | ||||
|   #define SMI_ON_COMMAND		0x40000000 | ||||
|   #define SMI_ON_OC				0x20000000 | ||||
|  | ||||
| #define SRBN_REG			0x60 | ||||
|  | ||||
| // 5536 B0 ATA-specific registers: | ||||
| #define IDE_CFG				0x40 | ||||
| #define IDE_DTC				0x48 | ||||
| #define IDE_CAST			0x4C | ||||
| #define IDE_ETC				0x50 | ||||
| #define IDE_PM				0x54 | ||||
|  | ||||
							
								
								
									
										485
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/vr.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										485
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/vr.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,485 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| #define VRC_INDEX				0xAC1C	// Index register  | ||||
| #define VRC_DATA				0xAC1E	// Data register | ||||
| #define VR_UNLOCK				0xFC53	// Virtual register unlock code | ||||
| #define NO_VR					-1		// No virtual registers | ||||
|  | ||||
| #define	VRC_MISCELLANEOUS		0x00	// Miscellaneous Class | ||||
|     #define VSA_VERSION_NUM     0x00 | ||||
| 	#define HIGH_MEM_ACCESS		0x01 | ||||
|     #define GET_VSM_INFO        0x02	// Used by INFO | ||||
|        #define GET_BASICS       0x00 | ||||
|        #define GET_EVENT        0x01 | ||||
|        #define GET_STATISTICS   0x02 | ||||
|        #define GET_HISTORY      0x03 | ||||
|        #define GET_HARDWARE     0x04 | ||||
|        #define GET_ERROR        0x05 | ||||
|        #define SET_VSM_TYPE     0x06 | ||||
| 	#define SIGNATURE			0x03 | ||||
|        #define VSA2_SIGNATURE	0x56534132	// 'VSA2' returned in EAX  | ||||
|  | ||||
|     #define GET_HW_INFO			0x04 | ||||
|     #define VSM_VERSION			0x05 | ||||
| 	#define CTRL_ALT_DEL		0x06 | ||||
|     #define MSR_ACCESS          0x07 | ||||
|     #define GET_DESCR_INFO		0x08 | ||||
|     #define PCI_INT_AB			0x09	// GPIO pins for INTA# and INTB# | ||||
|     #define PCI_INT_CD			0x0A	// GPIO pins for INTC# and INTD#	 | ||||
|     #define WATCHDOG			0x0B	// Watchdog timer | ||||
|  | ||||
|     #define MAX_MISC           	WATCHDOG | ||||
|  | ||||
|  | ||||
| // NOTE:  Do not change the order of the following registers: | ||||
| #define	VRC_AUDIO      			0x01	// XpressAudio Class | ||||
| 	#define AUDIO_VERSION      	0x00 | ||||
| 	#define PM_STATE        	0x01 | ||||
| 	#define SB_16_IO_BASE   	0x02 | ||||
| 	#define MIDI_BASE       	0x03 | ||||
| 	#define CPU_USAGE       	0x04 | ||||
| 	#define CODEC_TYPE      	0x05 | ||||
| 	#define STATE_INDEX     	0x06 | ||||
| 	#define STATE_DATA      	0x07 | ||||
| 	#define AUDIO_IRQ	      	0x08	// For use by native audio drivers  | ||||
| 	#define STATUS_PTR			0x09	// For use by native audio drivers | ||||
| 	#define MAX_AUDIO           STATUS_PTR | ||||
|  | ||||
| #define	VRC_VG					0x02	// SoftVG Class | ||||
| #define	VRC_VGA					0x02	// SoftVGA Class | ||||
| 	#define	VG_MEM_SIZE			0x00	// bits 7:0 - 512K unit size, bit 8 controller priority | ||||
| 	#define	VG_CONFIG			0x00	// Main configuration register | ||||
| 		#define VG_CFG_BYPASS		0x0001	// DOTPLL bypass bit | ||||
| 		#define VG_MEM_MASK			0x00FE	// Memory size mask bits, 2MB increment | ||||
| 		#define VG_CFG_DSMASK		0x0700	// Active display mask bits | ||||
| 			#define VG_CFG_DSCRT		0x0000	// Active display is CRT | ||||
| 			#define VG_CFG_DSPAN		0x0100	// Active display is panel | ||||
| 			#define VG_CFG_DSTV			0x0200	// Active display is TV | ||||
| 			#define VG_CFG_DSSIM		0x0400	// Simultaneous CRT | ||||
| 		#define VG_CFG_PRIORITY		0x0800	// Controller priority bit | ||||
| 		#define VG_CFG_MONO			0x1000	// External monochrome card support bit | ||||
| 		#define VG_CFG_DRIVER		0x2000	// Driver active bit | ||||
| 		#define VG_CRTC_DIAG		0x8000	// Enable CRTC emulation | ||||
|  | ||||
| 	// Defined for LX/LXVG | ||||
| 	#define	VG_REFRESH			0x01	// Mode refresh, a mode switch without changing modes | ||||
| 		#define VG_FRSH_REF_MASK	0xE000	// Refresh rate mask | ||||
| 		#define VG_FRSH_REF_GO		0x1000	// Refresh rate GO bit | ||||
| 			// Uses CFP_REF_xxx values from below | ||||
| 		#define VG_FRSH_BPP_MASK	0x0E00	// Color depth mask | ||||
| 		#define VG_FRSH_BPP_GO		0x0100	// Color depth GO bit | ||||
| 			#define FRSH_BPP_8RGB		0x0200	// 8 bits per pixel, RGB | ||||
| 			#define FRSH_BPP_16ARGB		0x0400	// 16BPP, ARGB (4:4:4:4) | ||||
| 			#define FRSH_BPP_15RGB		0x0600	// 15BPP, RGB (1:5:5:5) | ||||
| 			#define FRSH_BPP_16RGB		0x0800	// 16BPP, RGB (5:6:5) | ||||
| 			#define FRSH_BPP_24RGB		0x0A00	// 24BPP, RGB (0:8:8:8) | ||||
| 			#define FRSH_BPP_32ARGB		0x0C00	// 32BPP, ARGB (8:8:8:8) | ||||
| 		#define VG_CFG_DPMS			0x00C0	// DPMS mask bits | ||||
| 			#define VG_CFG_DPMS_H		0x0040	// HSYNC mask bit | ||||
| 			#define VG_CFG_DPMS_V		0x0080	// VSYNC mask bit | ||||
| 		#define VG_VESA_SV_RST		0x0020	// VESA Save/Restore state flag | ||||
| 			#define VG_VESA_RST			0x0000	// VESA Restore state | ||||
| 			#define VG_VESA_SV			0x0020	// VESA Save state  | ||||
| 		#define VG_FRSH_MODE		0x0002	// Mode refresh flag | ||||
| 		#define VG_FRSH_TIMINGS		0x0001	// Timings only refresh flag | ||||
|  | ||||
| 	// Defined for GX2/SoftVG | ||||
| 	#define	VG_PLL_REF			0x01	// PLL reference frequency selection register | ||||
| 		#define	PLL_14MHZ			0x0000	// 14.31818MHz PLL reference frequency (Default) | ||||
| 		#define	PLL_48MHZ			0x0100	// 48MHz PLL reference frequency | ||||
|  | ||||
| 	// Defined for GX1/SoftVGA | ||||
| 	#define	VGA_MEM_SIZE		0x01	// bits 7:1 - 128K unit size, bit 0 controller enable | ||||
|  | ||||
| 	#define	VG_FP_TYPE			0x02	// Flat panel type data | ||||
| 	// VG_FP_TYPE definitions for GX2/SoftVG | ||||
| 		#define FP_TYPE_SSTN		0x0000	// SSTN panel type value | ||||
| 		#define FP_TYPE_DSTN		0x0001	// DSTN panel type value | ||||
| 		#define FP_TYPE_TFT			0x0002	// TFT panel type value | ||||
| 		#define FP_TYPE_LVDS		0x0003	// LVDS panel type value | ||||
| 		#define FP_RES_6X4			0x0000	// 640x480 resolution value | ||||
| 		#define FP_RES_8X6			0x0008	// 800x600 resolution value | ||||
| 		#define FP_RES_10X7			0x0010	// 1024x768 resolution value | ||||
| 		#define FP_RES_11X8			0x0018	// 1152x864 resolution value | ||||
| 		#define FP_RES_12X10		0x0020	// 1280x1024 resolution value | ||||
| 		#define FP_RES_16X12		0x0028	// 1600x1200 resolution value | ||||
| 		#define FP_WIDTH_8			0x0000	// 8 bit data bus width | ||||
| 		#define FP_WIDTH_9			0x0040	// 9 bit data bus width | ||||
| 		#define FP_WIDTH_12			0x0080	// 12 bit data bus width | ||||
| 		#define FP_WIDTH_18			0x00C0	// 18 bit data bus width | ||||
| 		#define FP_WIDTH_24			0x0100	// 24 bit data bus width | ||||
| 		#define FP_WIDTH_16			0x0140	// 16 bit data bus width - 16 bit Mono DSTN only | ||||
| 		#define FP_COLOR_COLOR		0x0000	// Color panel | ||||
| 		#define FP_COLOR_MONO		0x0200	// Mono Panel | ||||
| 		#define FP_PPC_1PPC			0x0000	// One pixel per clock | ||||
| 		#define FP_PPC_2PPC			0x0400	// Two pixels per clock | ||||
| 		#define	FP_H_POL_LGH		0x0000	// HSync at panel, normally low, active high | ||||
| 		#define FP_H_POL_HGL		0x0800	// HSync at panel, normally high, active low | ||||
| 		#define FP_V_POL_LGH		0x0000	// VSync at panel, normally low, active high | ||||
| 		#define FP_V_POL_HGL		0x1000	// VSync at panel, normally high, active low | ||||
| 		#define FP_REF_60			0x0000	// 60Hz refresh rate | ||||
| 		#define FP_REF_65			0x2000	// 65Hz refresh rate | ||||
| 		#define FP_REF_70			0x4000	// 70Hz refresh rate | ||||
| 		#define FP_REF_72			0x6000	// 72Hz refresh rate | ||||
| 		#define FP_REF_75			0x8000	// 75Hz refresh rate | ||||
| 		#define FP_REF_85			0xA000	// 85Hz refresh rate | ||||
|  | ||||
| 	// VG_FP_TYPE definitions for LX/LXVG | ||||
| 		#define FP_TYPE_TYPE	0x0003		// Flat panel type bits mask | ||||
| 			#define CFP_TYPE_TFT	0x0000		// TFT panel type value | ||||
| 			#define CFP_TYPE_LVDS	0x0001		// LVDS panel type value | ||||
| 		#define FP_TYPE_RES		0x0038		// Panel resolution bits mask | ||||
| 			#define CFP_RES_3X2		0x0000		// 320x240 resolution value | ||||
| 			#define CFP_RES_6X4		0x0008		// 640x480 resolution value | ||||
| 			#define CFP_RES_8X6		0x0010		// 800x600 resolution value | ||||
| 			#define CFP_RES_10X7	0x0018		// 1024x768 resolution value | ||||
| 			#define CFP_RES_11X8	0x0020		// 1152x864 resolution value | ||||
| 			#define CFP_RES_12X10	0x0028		// 1280x1024 resolution value | ||||
| 			#define CFP_RES_16X12	0x0030		// 1600x1200 resolution value | ||||
| 		#define FP_TYPE_BUS		0x00C0		// Data bus width and pixels/clock mask | ||||
| 			#define CFP_BUS_1PPC	0x0040		// 9, 12, 18 or 24 bit data bus, 1 pixel per clock | ||||
| 			#define CFP_BUS_2PPC	0x0080		// 18 or 24 bit data bus, 2 pixels per clock | ||||
| 		#define FP_TYPE_HPOL	0x0800		// HSYNC polarity into the panel | ||||
| 			#define CFP_HPOL_HGL	0x0000	// HSync at panel, normally high, active low | ||||
| 			#define	CFP_HPOL_LGH	0x0800	// HSync at panel, normally low, active high | ||||
| 		#define FP_TYPE_VPOL	0x1000		// VSYNC polarity into the panel | ||||
| 			#define CFP_VPOL_HGL	0x0000	// VSync at panel, normally high, active low | ||||
| 			#define CFP_VPOL_LGH	0x1000	// VSync at panel, normally low, active high | ||||
| 		#define FP_TYPE_REF		0xE000		// Panel refresh rate | ||||
| 			#define CFP_REF_60		0x0000	// 60Hz refresh rate | ||||
| 			#define CFP_REF_70		0x2000	// 70Hz refresh rate | ||||
| 			#define CFP_REF_75		0x4000	// 75Hz refresh rate | ||||
| 			#define CFP_REF_85		0x6000	// 85Hz refresh rate | ||||
| 			#define CFP_REF_100		0x8000	// 100Hz refresh rate | ||||
|  | ||||
| 	#define	VG_FP_OPTION		0x03	// Flat panel option data | ||||
| 		#define FP_OPT_SCLK_NORMAL		0x0000		// SHFTClk not inverted to panel | ||||
| 		#define FP_OPT_SCLK_INVERTED	0x0010		// SHFTClk inverted to panel | ||||
| 		#define FP_OPT_SCLK_ACT_ACTIVE	0x0000		// SHFTClk active during "active" only | ||||
| 		#define FP_OPT_SCLK_ACT_FREE	0x0020		// SHFTClk free-running | ||||
| 		#define FP_OPT_LP_ACT_FREE		0x0000		// LP free-running | ||||
| 		#define FP_OPT_LP_ACT_ACTIVE	0x0040		// LP active during "active" only | ||||
| 		#define FP_OPT_LDE_POL_LGH		0x0000		// LDE/MOD, normally low, active high | ||||
| 		#define FP_OPT_LDE_POL_HGL		0x0080		// LDE/MOD, normally high, active low | ||||
| 		#define FP_OPT_PWR_DLY_32MS		0x0000		// 32MS delay for each step of pwr seq. | ||||
| 		#define FP_OPT_PWR_DLY_128MS	0x0100		// 128MS delay for each step of pwr seq. | ||||
|  | ||||
| 	#define	VG_TV_CONFIG		0x04	// TV configuration register | ||||
| 		#define VG_TV_ENC			0x000F	// TV encoder select mask | ||||
| 			#define VG_TV_ADV7171		0x0000	// ADV7171 Encoder | ||||
| 			#define VG_TV_SAA7127		0x0001	// ADV7171 Encoder | ||||
| 			#define VG_TV_ADV7300		0x0002	// ADV7300 Encoder | ||||
| 			#define VG_TV_FS454			0x0003	// FS454 Encoder | ||||
| 		#define VG_TV_FMT			0x0070	// TV encoder output format mask | ||||
| 			#define VG_TV_FMT_SHIFT		0x0004	// Right shift value | ||||
| 			#define VG_TV_NTSC			0x0000	// NTSC output format | ||||
| 			#define VG_TV_PAL			0x0010	// PAL output format | ||||
| 			#define VG_TV_HDTV			0x0020	// HDTV output format | ||||
|  | ||||
| 		// The meaning of the VG_TV_RES field is dependent on the selected   | ||||
| 		// encoder and output format.  The translations are: | ||||
| 		//		ADV7171 - Not Used | ||||
| 		//		SAA7127 - Not Used | ||||
| 		//		ADV7300 - HDTV resolutions only | ||||
| 		//			LO  -> 720x480p | ||||
| 		//	   		MED -> 1280x720p | ||||
| 		//			HI  -> 1920x1080i | ||||
| 		// 		FS454   - Both SD and HD resolutions	 | ||||
| 		// 			SD Resolutions - NTSC and PAL | ||||
| 		//				LO  -> 640x480 | ||||
| 		//	   			MED -> 800x600 | ||||
| 		//				HI  -> 1024x768 | ||||
| 		// 			HD Resolutions | ||||
| 		//				LO  -> 720x480p | ||||
| 		//	   			MED -> 1280x720p | ||||
| 		//				HI  -> 1920x1080i | ||||
| 		#define VG_TV_RES			0x0780	// TV resolution select mask | ||||
| 			#define VG_TV_RES_SHIFT		0x0007	// Right shift value | ||||
| 			#define VG_TV_RES_LO		0x0000	// Low resolution | ||||
| 			#define VG_TV_RES_MED		0x0080	// Medium resolution | ||||
| 			#define VG_TV_RES_HI 		0x0100	// High resolution | ||||
| 		#define VG_TV_PASSTHRU		0x0800	// TV passthru mode | ||||
|  | ||||
| 	#define	VG_TV_SCALE_ADJ		0x05	// Modifies scaling factors for TV resolutions | ||||
| 		#define VG_TV_HACT_ADJ		0x00FF		// Horizontal active scale adjust value mask | ||||
| 		#define VG_TV_VACT_ADJ		0xFF00		// Vertical active scale adjust value mask | ||||
|  | ||||
| 	#define	VG_DEBUG			0x0F	// A debug register | ||||
|  | ||||
| 	#define	VG_FT_HTOT			0x10	// Fixed timings, horizontal total | ||||
| 	#define	VG_FT_HACT			0x11	// Fixed timings, horizontal active | ||||
| 	#define	VG_FT_HBST			0x12	// Fixed timings, horizontal blank start | ||||
| 	#define	VG_FT_HBND			0x13	// Fixed timings, horizontal blank end | ||||
| 	#define	VG_FT_HSST			0x14	// Fixed timings, horizontal sync start | ||||
| 	#define	VG_FT_HSND			0x15	// Fixed timings, horizontal sync end | ||||
|  | ||||
| 	#define	VG_FT_VTOT			0x16	// Fixed timings, vertical total | ||||
| 	#define	VG_FT_VACT			0x17	// Fixed timings, vertical active | ||||
| 	#define	VG_FT_VBST			0x18	// Fixed timings, vertical blank start | ||||
| 	#define	VG_FT_VBND			0x19	// Fixed timings, vertical blank end | ||||
| 	#define	VG_FT_VSST			0x1A	// Fixed timings, vertical sync start | ||||
| 	#define	VG_FT_VSND			0x1B	// Fixed timings, vertical sync end | ||||
|  | ||||
| 	#define	VG_START_OFFS_LO	0x20	// Framebuffer start offset bits 15:0 | ||||
| 	#define	VG_START_OFFS_HI	0x21	// Framebuffer start offset bits 27:16 | ||||
|  | ||||
| 	#define	VG_FT_VEACT			0x28	// Fixed timings, vertical active | ||||
| 	#define	VG_FT_VETOT			0x29	// Fixed timings, vertical total | ||||
| 	#define	VG_FT_VEBST			0x2A	// Fixed timings, vertical blank start | ||||
| 	#define	VG_FT_VEBND			0x2B	// Fixed timings, vertical blank end | ||||
| 	#define	VG_FT_VESST			0x2C	// Fixed timings, vertical sync start | ||||
| 	#define	VG_FT_VESND			0x2D	// Fixed timings, vertical sync end | ||||
|  | ||||
| 	#define MAX_VGA           	VGA_MEM_SIZE | ||||
| //	#define MAX_VG           	VG_FP_OPTION | ||||
| //	#define MAX_VG           	VG_START_OFFS_HI | ||||
| 	#define MAX_VG           	VG_FT_VESND | ||||
|  | ||||
| #define	VRC_APM					0x03 | ||||
|     #define REPORT_EVENT		0x00 | ||||
|     #define CAPABILITIES    	0x01 | ||||
| 	#define APM_PRESENT		0x02 | ||||
| 	#define MAX_APM           	APM_PRESENT | ||||
|  | ||||
|  | ||||
| #define	VRC_PM					0x04	// Legacy PM Class | ||||
| 	#define	POWER_MODE			0x00 | ||||
| 	#define POWER_STATE			0x01 | ||||
| 	#define	DOZE_TIMEOUT		0x02 | ||||
| 	#define	STANDBY_TIMEOUT	   	0x03 | ||||
| 	#define	SUSPEND_TIMEOUT	   	0x04 | ||||
|     #define PS2_TIMEOUT		    0x05 | ||||
| 	#define RESUME_ON_RING		0x06 | ||||
| 	#define VIDEO_TIMEOUT		0x07 | ||||
| 	#define	DISK_TIMEOUT		0x08 | ||||
| 	#define	FLOPPY_TIMEOUT	   	0x09 | ||||
| 	#define	SERIAL_TIMEOUT	    0x0A | ||||
| 	#define	PARALLEL_TIMEOUT	0x0B | ||||
| 	#define IRQ_WAKEUP_MASK	   	0x0C | ||||
| //	#define SUSPEND_MODULATION 	0x0D | ||||
| 	#define SLEEP_PIN			0x0E | ||||
| 	#define SLEEP_PIN_ATTR		0x0F | ||||
| //	#define SMI_WAKEUP_MASK		0x10 | ||||
| 	#define INACTIVITY_CONTROL	0x11 | ||||
| 	#define PM_S1_CLOCKS		0x12 | ||||
| 		#define S1_CLOCKS_ON		0x00 | ||||
| 		#define S1_CLOCKS_OFF		0x01 | ||||
| //	#define PM_S2_CLOCKS		0x13 | ||||
| //	#define PM_S3_CLOCKS		0x14 | ||||
| //	#define PM_S4_CLOCKS		0x15 | ||||
| //	#define PM_S5_CLOCKS		0x16 | ||||
|     #define PM_S0_LED           0x17 | ||||
|     #define PM_S1_LED           0x18 | ||||
|     #define PM_S2_LED           0x19 | ||||
|     #define PM_S3_LED           0x1A | ||||
|     #define PM_S4_LED           0x1B | ||||
|     #define PM_S5_LED           0x1C | ||||
| 	#define PM_LED_GPIO			0x1D | ||||
|     #define PM_IMM_LED			0x1E | ||||
|     #define PM_PWR_LEDS			0x1F | ||||
| 	    #define MB_LED0				0x01 | ||||
| 	    #define MB_LED1				0x02 | ||||
| 	    #define MB_LED2				0x04 | ||||
| 	    #define MB_LED3				0x08 | ||||
| 	    #define SIO_LED0			0x10 | ||||
| 	    #define SIO_LED1			0x20 | ||||
| 	    #define SIO_LED2			0x40 | ||||
| 	    #define SIO_LED3			0x80 | ||||
| 	#define PM_PME_MASK			0x20 | ||||
|     #define MAX_PM              PM_PME_MASK | ||||
|  | ||||
| #define VRC_INFRARED			0x05 | ||||
| 	#define MAX_INFRARED        NO_VR | ||||
|  | ||||
| #define	VRC_TV					0x06	// TV Encoder Class | ||||
| 	#define TV_ENCODER_TYPE		0x00 | ||||
| 	#define TV_CALLBACK_MASK	0x01 | ||||
| 	#define TV_MODE				0x02 | ||||
| 	#define TV_POSITION			0x03 | ||||
| 	#define TV_BRIGHTNESS		0x04 | ||||
| 	#define TV_CONTRAST			0x05 | ||||
| 	#define TV_OUTPUT			0x06 | ||||
| 	#define TV_TIMING			0x10	// 0x10...0x1D are all timings | ||||
| 	#define MAX_TV           	TV_TIMING | ||||
|  | ||||
|  | ||||
|  | ||||
| #define VRC_EXTERNAL_AMP		0x07 | ||||
|     #define EAPD_VERSION        0x00 | ||||
|     #define AMP_POWER          	0x01 | ||||
| 	   #define AMP_OFF          0x00 | ||||
| 	   #define AMP_ON           0x01 | ||||
| 	#define AMP_TYPE            0x02 | ||||
| 	#define MAX_EXTERNAL_AMP    	AMP_TYPE | ||||
|  | ||||
|  | ||||
| #define	VRC_ACPI				0x08 | ||||
|     #define	ENABLE_ACPI			0x00	// Enable ACPI Mode | ||||
| 	#define SCI_IRQ			   	0x01	// Set the IRQ the SCI is mapped to, sysbios use. | ||||
| 	#define ACPINVS_LO			0x02	// new calls to send 32bit physAddress of | ||||
| 	#define ACPINVS_HI		  	0x03	// ACPI NVS region to VSA | ||||
| 	#define GLOBAL_LOCK			0x04	// read requests semaphore, write clears | ||||
| 	#define ACPI_UNUSED1		0x05 | ||||
| 	#define RW_PIRQ				0x06	// read/write PCI IRQ router regs in SB Func0 cfg space | ||||
| 	#define SLPB_CLEAR			0x07	// clear sleep button GPIO status's | ||||
| 	#define PIRQ_ROUTING		0x08	// read the PCI IRQ routing based on BIOS setup | ||||
| 	#define ACPI_UNUSED2		0x09	 | ||||
| 	#define ACPI_UNUSED3		0x0A	 | ||||
| 	#define PIC_INTERRUPT		0x0B | ||||
| 	#define ACPI_PRESENT		0x0C | ||||
| 	#define	ACPI_GEN_COMMAND	0x0D | ||||
| 	#define	ACPI_GEN_PARAM1		0x0E | ||||
| 	#define	ACPI_GEN_PARAM2		0x0F | ||||
| 	#define	ACPI_GEN_PARAM3		0x10 | ||||
| 	#define	ACPI_GEN_RETVAL		0x11 | ||||
| 	#define MAX_ACPI	        ACPI_GEN_RETVAL | ||||
|  | ||||
| #define	VRC_ACPI_OEM			0x09 | ||||
| 	#define MAX_ACPI_OEM        NO_VR | ||||
|  | ||||
| #define VRC_POWER               0x0A | ||||
|     #define BATTERY_UNITS       0x00	// No. battery units | ||||
|     #define BATTERY_SELECT      0x01 | ||||
|     #define AC_STATUS           0x02 | ||||
| 	#define BATTERY_STATUS		0x03 | ||||
| 	#define BATTERY_FLAG		0x04 | ||||
| 	#define BATTERY_PERCENTAGE	0x05 | ||||
|     #define BATTERY_TIME        0x06 | ||||
| 	#define MAX_POWER           BATTERY_TIME | ||||
|  | ||||
|  | ||||
|  | ||||
| #define VRC_OHCI				0x0B	// OHCI Class | ||||
|     #define SET_LED             0x00 | ||||
|     #define INIT_OHCI			0x01 | ||||
|     #define MAX_OHCI            INIT_OHCI | ||||
|  | ||||
| #define VRC_KEYBOARD            0x0C	// Kbd Controller Class | ||||
|     #define KEYBOARD_PRESENT    0x00 | ||||
|     #define SCANCODE            0x01 | ||||
|     #define MOUSE_PRESENT		0x02 | ||||
|     #define MOUSE_BUTTONS       0x03 | ||||
| 	#define MOUSE_XY            0x04 | ||||
| 	#define TYPEMATIC_DISABLE	0x05 | ||||
| 	#define MAX_KEYBOARD        TYPEMATIC_DISABLE | ||||
|  | ||||
|  | ||||
| #define VRC_DDC     			0x0D	// Video DDC Class | ||||
| 	#define VRC_DDC_ENABLE 		0x00	// Enable/disable register | ||||
| 		#define DDC_DISABLE		0x00 | ||||
| 		#define DDC_ENABLE 		0x01 | ||||
| 	#define VRC_DDC_IO	  		0x01	// A non-zero value for safety | ||||
| 	#define MAX_DDC           	VRC_DDC_IO | ||||
|  | ||||
| #define VRC_DEBUGGER			0x0E | ||||
| 	#define MAX_DEBUGGER        NO_VR | ||||
| 						    | ||||
|  | ||||
| #define	VRC_STR					0x0F		// Virtual Register class | ||||
| 	#define RESTORE_ADDR		0x00		// Physical address of MSR restore table | ||||
|  | ||||
|  | ||||
| #define	VRC_COP8				0x10		// Virtual Register class | ||||
| 	#define	VRC_HIB_ENABLE		0x00		// HIB enable/disable index | ||||
| 	#define		HIB_ENABLE		0x00		// HIB enable command | ||||
| 	#define		HIB_DISABLE		0x01		// HIB disable command | ||||
| 	#define	VRC_HIB_SEND		0x01		// Send packet to COP8 | ||||
| 	#define	VRC_HIB_READUART	0x02		// Read byte from COP8 UART | ||||
| 	#define	VRC_HIB_VERSION		0x03		// Read COP8 version | ||||
| 	#define	VRC_HIB_SERIAL		0x04		// Read 8 byte serial number | ||||
| 	#define	VRC_HIB_USRBTN		0x05		// Read POST button pressed status | ||||
| 	#define MAX_COP8	        NO_VR | ||||
|  | ||||
| #define	VRC_OWL					0x11		// Virtual Register class | ||||
| 	#define	VRC_OWL_DAC			0x00		// DAC (Backlight) Control | ||||
| 	#define	VRC_OWL_GPIO 		0x01		// GPIO Control | ||||
| 	#define MAX_OWL				VRC_OWL_GPIO | ||||
|  | ||||
| #define	VRC_SYSINFO				0x12		// Virtual Register class | ||||
| 	#define	VRC_SI_VERSION				0x00		// Sysinfo VSM version | ||||
| 	#define	VRC_SI_CPU_MHZ				0x01	// CPU speed in MHZ  | ||||
| 	#define	VRC_SI_CHIPSET_BASE_LOW		0x02 | ||||
| 	#define	VRC_SI_CHIPSET_BASE_HI		0x03 | ||||
| 	#define	VRC_SI_CHIPSET_ID			0x04 | ||||
| 	#define	VRC_SI_CHIPSET_REV			0x05 | ||||
| 	#define	VRC_SI_CPU_ID				0x06 | ||||
| 	#define	VRC_SI_CPU_REV				0x07 | ||||
| 	#define	MAX_SYSINFO			VRC_SI_CPU_REV | ||||
|  | ||||
| #define VRC_SUPERIO				0x13 | ||||
| 	#define VRC_SIO_CHIPID				0x00 | ||||
| 	#define VRC_SIO_NUMLD				0x01 | ||||
| 	#define VRC_SIO_FDCEN				0x02 | ||||
| 	#define VRC_SIO_FDCIO				0x03 | ||||
| 	#define VRC_SIO_FDCIRQ				0x04 | ||||
| 	#define VRC_SIO_FDCDMA				0x05 | ||||
| 	#define VRC_SIO_FDCCFG1				0x06 | ||||
| 	#define VRC_SIO_FDCCFG2				0x07 | ||||
| 	#define VRC_SIO_PP1EN				0x08 | ||||
| 	#define VRC_SIO_PP1IO				0x09 | ||||
| 	#define VRC_SIO_PP1IRQ				0x0A | ||||
| 	#define VRC_SIO_PP1DMA				0x0B | ||||
| 	#define VRC_SIO_PP1CFG1				0x0C | ||||
| 	#define VRC_SIO_SP1EN				0x0D | ||||
| 	#define VRC_SIO_SP1IO				0x0E | ||||
| 	#define VRC_SIO_SP1IRQ				0x0F | ||||
| 	#define VRC_SIO_SP1CFG1				0x10 | ||||
| 	#define VRC_SIO_SP2EN				0x11 | ||||
| 	#define VRC_SIO_SP2IO				0x12 | ||||
| 	#define VRC_SIO_SP2IRQ				0x13 | ||||
| 	#define VRC_SIO_SP2CFG1				0x14 | ||||
| 	#define VRC_SIO_KBEN				0x15 | ||||
| 	#define VRC_SIO_KBIO1				0x16 | ||||
| 	#define VRC_SIO_KBIO2				0x17 | ||||
| 	#define VRC_SIO_KBIRQ				0x18 | ||||
| 	#define VRC_SIO_KBCFG1				0x19 | ||||
| 	#define VRC_SIO_MSEN				0x1A | ||||
| 	#define VRC_SIO_MSIO				0x1B | ||||
| 	#define VRC_SIO_MSIRQ				0x1C | ||||
| 	#define VRC_SIO_RTCEN				0x1D | ||||
| 	#define VRC_SIO_RTCIO1				0x1E | ||||
| 	#define VRC_SIO_RTCIO2				0x1F | ||||
| 	#define VRC_SIO_RTCIRQ				0x20 | ||||
| 	#define VRC_SIO_RTCCFG1				0x21 | ||||
| 	#define VRC_SIO_RTCCFG2				0x22 | ||||
| 	#define VRC_SIO_RTCCFG3				0x23 | ||||
| 	#define VRC_SIO_RTCCFG4				0x24 | ||||
| 	#define MAX_SUPERIO			VRC_SIO_RTCCFG4 | ||||
|  | ||||
| #define VRC_CHIPSET				0x14 | ||||
| 	#define VRC_CS_PWRBTN		0x00 | ||||
| 	#define VRC_CS_UART1		0x01 | ||||
| 	#define VRC_CS_UART2		0x02 | ||||
| 	#define MAX_CHIPSET			VRC_CS_UART2 | ||||
|  | ||||
| #define VRC_THERMAL     0x15 | ||||
|     #define VRC_THERMAL_CURR_RTEMP      0x00        // read only | ||||
|     #define VRC_THERMAL_CURR_LTEMP      0x01        // read only | ||||
|     #define VRC_THERMAL_FAN             0x02 | ||||
|     #define VRC_THERMAL_LOW_THRESHOLD   0x03 | ||||
|     #define VRC_THERMAL_HIGH_THRESHOLD  0x04 | ||||
|     #define VRC_THERMAL_INDEX           0x05 | ||||
|     #define VRC_THERMAL_DATA            0x06 | ||||
|     #define VRC_THERMAL_SMB_ADDRESS     0x07 | ||||
|     #define VRC_THERMAL_SMB_INDEX       0x08 | ||||
|     #define VRC_THERMAL_SMB_DATA        0x09 | ||||
|     #define MAX_THERMAL         VRC_THERMAL_SMB_DATA | ||||
|  | ||||
| #define MAX_VR_CLASS	  		VRC_THERMAL | ||||
							
								
								
									
										700
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/vsa2.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										700
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/inc/vsa2.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,700 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| #define VSM_SIGNATURE		0x204D5356	// 'VSM ' | ||||
| #define VSA_VERSION		0x03B0		// SysMgr Version | ||||
|  | ||||
|  | ||||
| #define BYTE_IO                0x01 | ||||
| #define WORD_IO                0x03 | ||||
| #define DWORD_IO               0x0F | ||||
| #define IO_WRITE               0x80 | ||||
|  | ||||
|  | ||||
|  | ||||
| typedef  unsigned char UCHAR; | ||||
| typedef  unsigned long ULONG; | ||||
| typedef  unsigned short USHORT; | ||||
|  | ||||
|  | ||||
|  | ||||
| #define HIWORD(p)  ((USHORT) ((p) >> 16)) | ||||
|  | ||||
| typedef struct { | ||||
| 	unsigned short Alignment: 5;		// 2^(n+5)  (e.g. 00000 = 32-byte boundary) | ||||
| 	unsigned short LoadHi: 1;			// 1 = must load VSM above top of memory | ||||
| 	unsigned short LoadLo: 1;			// 1 = must load VSM below 1 MB | ||||
| 	unsigned short SkipMe: 1;			// 1 = Skip this VSM | ||||
| 	unsigned short Reserved: 8; | ||||
| } Requirements; | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //********************************************************************* | ||||
| // 			Structures | ||||
| //********************************************************************* | ||||
|  | ||||
| typedef struct { | ||||
|   union { | ||||
|     ULONG  Reg_EAX; | ||||
|     USHORT Reg_AX; | ||||
| 	struct { | ||||
| 	  UCHAR Reg_AL; | ||||
| 	  UCHAR Reg_AH; | ||||
| 	}; | ||||
|   }; | ||||
|   union { | ||||
|     ULONG  Reg_EBX; | ||||
|     USHORT Reg_BX; | ||||
| 	struct { | ||||
| 	  UCHAR Reg_BL; | ||||
| 	  UCHAR Reg_BH; | ||||
| 	}; | ||||
|   }; | ||||
|   union { | ||||
|     ULONG  Reg_ECX; | ||||
|     USHORT Reg_CX; | ||||
| 	struct { | ||||
| 	  UCHAR Reg_CL; | ||||
| 	  UCHAR Reg_CH; | ||||
| 	}; | ||||
|   }; | ||||
|   union { | ||||
|     ULONG  Reg_EDX; | ||||
|     USHORT Reg_DX; | ||||
| 	struct { | ||||
| 	  UCHAR Reg_DL; | ||||
| 	  UCHAR Reg_DH; | ||||
| 	}; | ||||
|   }; | ||||
|   union { | ||||
|     ULONG  Reg_EBP; | ||||
|     USHORT Reg_BP; | ||||
|   }; | ||||
|   union { | ||||
|     ULONG  Reg_ESI; | ||||
|     USHORT Reg_SI; | ||||
|   }; | ||||
|   union { | ||||
|     ULONG  Reg_EDI; | ||||
|     USHORT Reg_DI; | ||||
|   }; | ||||
|   USHORT Reg_DS; | ||||
|   USHORT Reg_ES; | ||||
|   USHORT Flags; | ||||
|   UCHAR PIC0_Mask; | ||||
|   UCHAR PIC1_Mask;			 | ||||
| } INT_REGS; | ||||
|  | ||||
|  | ||||
|  | ||||
| typedef struct {			// Used by SVDC & RSDC instructions | ||||
| 	USHORT	limit_15_0; | ||||
| 	USHORT	base_15_0; | ||||
| 	UCHAR	base_23_16; | ||||
| 	UCHAR	attr; | ||||
| #define G_BIT				0x80 | ||||
| #define D_BIT				0x40 | ||||
|  | ||||
| 	UCHAR	limit_19_16; | ||||
| 	UCHAR	base_31_24; | ||||
| 	USHORT	selector; | ||||
| } Descriptor; | ||||
|  | ||||
|  | ||||
| typedef struct { | ||||
| 	ULONG	Reserved; | ||||
| 	ULONG	SMM_CTL_MSR; | ||||
| 	ULONG	write_data; | ||||
| 	USHORT	IO_addr; | ||||
| 	USHORT	data_size; | ||||
|     union { | ||||
|   	  struct { | ||||
| 	    USHORT CS_Writable: 1; | ||||
| 	    USHORT IO_Write:    1; | ||||
| 	    USHORT REP_Prefix:  1; | ||||
| 	    USHORT SMINT:       1; | ||||
|  | ||||
| 	    USHORT HALT:        1; | ||||
| 	    USHORT Ext_IO_Trap: 1; | ||||
| 	    USHORT External:    1; | ||||
| 	    USHORT IO_Trap:     1; | ||||
|  | ||||
| 	    USHORT Nested:      1; | ||||
| 	    USHORT Reserved:    6; | ||||
| 	    USHORT CS_Readable: 1; | ||||
| 	  } SMI_Flags; | ||||
| 	  USHORT SMI_Flags_Ushort; | ||||
| 	}; | ||||
|    | ||||
| 	USHORT SS_Flags; | ||||
|  | ||||
|     struct { | ||||
|       ULONG limit; | ||||
|       ULONG	 base; | ||||
|       USHORT selector; | ||||
|       USHORT attr; | ||||
| 	} _CS; | ||||
|  | ||||
|     union { | ||||
|       USHORT Next_IP; | ||||
| 	  ULONG	Next_EIP; | ||||
|     }; | ||||
|     union { | ||||
|       USHORT Current_IP; | ||||
| 	  ULONG	Current_EIP; | ||||
|     }; | ||||
| 	ULONG	r_CR0; | ||||
| 	ULONG	EFLAGS; | ||||
| 	ULONG	r_DR7; | ||||
| } SmiHeader; | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| typedef USHORT MSG; | ||||
| typedef USHORT PRIORITY; | ||||
| typedef USHORT EVENT; | ||||
| typedef ULONG  VSM; | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| #define MAX_MSG_PARAM       4	// Parameter count | ||||
| #define MAX_MSG_CNT	 	10 	// # entries in message queue | ||||
|  | ||||
| typedef struct { | ||||
|    MSG Msg;				// Message code | ||||
|    PRIORITY Priority;			// Priority | ||||
|    ULONG From_VSM;				// VSM that sent the message | ||||
|    ULONG Param[MAX_MSG_PARAM];	// Parameters | ||||
|    ULONG Timestamp;			// Timestamp when message was entered | ||||
| } Message; | ||||
|  | ||||
|  | ||||
| typedef struct { | ||||
|  | ||||
|   // VSM's state | ||||
|   SmiHeader State;				// SMM header for this VSM | ||||
|  | ||||
|   // NOTE: Flink field must be immediately after State structure | ||||
|   ULONG Flink;				// Forward link to next VSM | ||||
|   ULONG Blink;	 			// Backward link to previous VSM | ||||
|   ULONG SavedESP;				// VSM's stack pointer | ||||
|   ULONG SysMgr_Ptr;			// Ptr to SysMgr's InfoStuff structure | ||||
|   ULONG Southbridge;			// PCI address of Southbridge | ||||
|  | ||||
|  | ||||
|   // Statistics | ||||
|   ULONG Adjustment;			// Clocks used by SMM entry/exit | ||||
|   ULONG Clocks[2];				// Total clocks used by this VSM | ||||
|   ULONG NumSMIs[2];			// Total SMI count for this VSM | ||||
|   ULONG FrozenClocks[2]; 		// Copied from Clocks[] | ||||
|   ULONG FrozenNumSMIs[2];		// Copied from NumSMIs[] | ||||
|   ULONG StartTime[2];			// Timestamp @ start of timeslice | ||||
|   ULONG StartClocks[2];		// Timestamp of last INFO /S | ||||
|  | ||||
|   // Floating Point | ||||
|   UCHAR FPU_State[108];   		// Saved FPU state | ||||
|   UCHAR FPU_Flag;              // Non-zero if FPU in use | ||||
|  | ||||
|   UCHAR RunFlag;				// VSM's scheduler state | ||||
|  | ||||
|   USHORT ResumeVector;			// Used by SaveToRAM | ||||
|   USHORT Pad[5]; | ||||
|  | ||||
|   // Message Queue | ||||
|   USHORT EndMsgQ;	 	 		// Offset of *end* of message queue | ||||
|   USHORT Qhead;				// Message queue head offset | ||||
|   USHORT Qtail; 				// Message queue tail offset | ||||
|  | ||||
|   // MsgQueue is variable length, so it must be the last field | ||||
|   Message MsgQueue[MAX_MSG_CNT];	// The VSM's message queue | ||||
|  | ||||
| } System; | ||||
|  | ||||
|  | ||||
|  | ||||
| //********************************************************************* | ||||
| // 			VSM Header | ||||
| //********************************************************************* | ||||
|  | ||||
| typedef struct  { | ||||
| 	ULONG  Signature;			// 'VSM ' | ||||
| 	UCHAR  VSM_Type;   			// Type of VSM | ||||
| 	UCHAR  ForCPU;				// Required CPU  (FFFFh for any) | ||||
| 	USHORT ForChipset;			// Required companion I/O  (FFFFh for any) | ||||
| 	USHORT VSM_Version;			// Version of VSM | ||||
| 	ULONG  VSM_Length; 			// Length of VSM module in bytes | ||||
| 	USHORT EntryPoint;	 		// Offset of entry point | ||||
| 	ULONG  DS_Limit; | ||||
| 	Requirements Flag;			// Special requirements/capabilities | ||||
| 	USHORT VSA_Version; | ||||
| 	Descriptor _SS;				// SS: descriptor for this VSM | ||||
| 	Descriptor _DS;			 	// DS: descriptor for this VSM | ||||
| 	Descriptor _ES;				// ES: descriptor for this VSM | ||||
| 	USHORT AlignSystem;			// SysStuff must be DWORD aligned | ||||
| 	System SysStuff;			// Reserved for use by System Manager | ||||
|  | ||||
| } VSM_Header; | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //********************************************************************* | ||||
| // 			VSM Types | ||||
| //********************************************************************* | ||||
| #define VSM_SYS_MGR        0x00		// System Manager | ||||
| #define VSM_AUDIO          0x01		// Xpress Audio | ||||
| #define VSM_VGA            0x02		// SoftVGA | ||||
| #define VSM_LEGACY         0x03		// Standard AT peripherals | ||||
| #define VSM_PM             0x04		// Legacy Power Management | ||||
| #define VSM_OHCI           0x05		// OHCI | ||||
| #define VSM_i8042          0x06		// 8042 emulator | ||||
| #define VSM_DEBUGGER       0x07		// SMI based debugger | ||||
| #define VSM_ACPI           0x08		// Virtual ACPI | ||||
| #define VSM_APM            0x09		// APM 1.2 | ||||
| #define VSM_OEM_ACPI       0x0A		// OEM ACPI customizations | ||||
| #define VSM_SMB            0x0B		// System Management Bus | ||||
| #define VSM_BATTERY        0x0C		// Battery controller | ||||
| #define VSM_RTC            0x0D		// Virtual RTC | ||||
| #define VSM_S2D            0x0E		// SaveToDisk | ||||
| #define VSM_EXT_AMP        0x0F		// External audio amplifier | ||||
| #define VSM_PCMCIA         0x10		// PCMCIA | ||||
| #define VSM_SPY            0x11		// Spy. Receives ALL messages first. | ||||
| #define VSM_NETWORK        0x12		// Network | ||||
| #define VSM_GPIO           0x13		// GPIO handler | ||||
| #define VSM_KEYBOARD       0x14		// USB keyboard to PC/AT emulation | ||||
| #define VSM_MOUSE          0x15		// USB mouse to PS/2 emulation | ||||
| #define VSM_USB            0x16		// Universal Serial Bus | ||||
| #define VSM_FLASH          0x17		// FLASH | ||||
| #define VSM_INFRARED       0x18		// Infrared | ||||
| #define VSM_THERMAL        0x19		// Thermal monitor | ||||
| #define VSM_NULL           0x1A		// Unspecified | ||||
| #define VSM_MPEG           0x1B		// MPEG video decoder (EMMA) | ||||
| #define VSM_VIP            0x1C		// Video processor (VIDEC) | ||||
| #define VSM_LPC            0x1D		// Low Pin Count bus | ||||
| #define VSM_VUART          0x1E		// Virtual UART | ||||
| #define VSM_MICRO          0x1F		// MicroController | ||||
| #define VSM_USER1          0x20		// USER 1 | ||||
| #define VSM_USER2          0x21		// USER 2 | ||||
| #define VSM_USER3          0x22		// USER 3 | ||||
| #define VSM_SYSINFO        0x23		// System Information | ||||
| #define VSM_SUPERIO        0x24		// PM for SuperIO | ||||
| #define VSM_EHCI           0x25		// EHCI | ||||
| #define VSM_MAX_TYPE       VSM_EHCI	// Highest valid VSM type | ||||
|  | ||||
| #define VSM_ANY            0xFF		// Wildcard for SYS_BROADCAST | ||||
| #define VSM_NOT_SELF       0x4000	// Flag used by SYS_BROADCAST | ||||
| #define VSM_ALL_EXCEPT     0x8000	// Flag used by SYS_BROADCAST | ||||
|  | ||||
|  | ||||
| //********************************************************************* | ||||
| // SMINT codes used by non-VSA components (BIOS, INIT, etc.) | ||||
| //********************************************************************* | ||||
| #define SYS_BIOS_INIT          0x00F0   // VSA installation	from POST | ||||
| #define SYS_DOS_INSTALL        0x00F2   // VSA installation from DOS prompt | ||||
| #define SYS_VSM_INSTALL        0x00F3   // Install VSM dynamically | ||||
| #define SYS_REMOVE             0x00F4   // Unregister events belonging to VSM | ||||
| #define SYS_INT_RETURN         0x00F5   // Return from call to INT vector | ||||
| #define SYS_RESUME_FROM_RAM    0x6789   // Resume from RAM | ||||
| #define SYS_END_OF_POST        0x5000   // Issued by GeodeROM at end of POST | ||||
| #define SYS_INT13_SMI          0x5001   // Issued by Int 13 module (USB floppy) | ||||
| #define SYS_INT13CDR_SMI       0x5003   // Issued by Int 13 module (USB CD-ROM) | ||||
| #define SYS_USB_DEVICE_SMI     0x7777   // Issued by USBBOOT.ROM to access device table | ||||
|  | ||||
| //********************************************************************* | ||||
| //			Event Priorities | ||||
| //********************************************************************* | ||||
| #define NORMAL_PRIORITY        0x0000 | ||||
| #define MAX_PRIORITY           0x7FFF | ||||
| #define BROADCAST_PRIORITY     0x9000 | ||||
| #define UNREGISTER_PRIORITY    0xFFF0 | ||||
|  | ||||
| //********************************************************************* | ||||
| //			Messages | ||||
| //********************************************************************* | ||||
|  | ||||
| #define MSG_INITIALIZE		   0		// Perform VSM initialization | ||||
|   #define EARLY_INIT           0 | ||||
|   #define END_OF_POST_INIT     1 | ||||
|  | ||||
| #define MSG_SHUTDOWN           1		// Prepare for system shutdown (cold boot) | ||||
| #define MSG_SAVE_STATE         2		// Save entire state of device(s) controlled by VSM | ||||
| #define MSG_RESTORE_STATE      3		// Restore saved state of device(s) controlled by VSM | ||||
| #define MSG_SET_POWER_STATE    4		// Set device(s) to specified power state | ||||
| #define MSG_EVENT              5		// A registered  event has occurred | ||||
| #define MSG_QUEUE_OVERFLOW     6		// The message queue is full. | ||||
| #define MSG_WARM_BOOT          7		// Prepare for a warm boot | ||||
| #define MSG_SET_POWER_MODE     9		// Restore saved state of device(s) controlled by VSM | ||||
| #define MSG_ABORT_POWER_STATE  10		// Power state is to be aborted | ||||
|  | ||||
| //********************************************************************* | ||||
| //			Events | ||||
| //********************************************************************* | ||||
|  | ||||
| #define EVENT_GRAPHICS         1		// Video event | ||||
| #define EVENT_AUDIO            2		// Audio event | ||||
| #define EVENT_USB              3		// USB event | ||||
| #define EVENT_ACPI             4		// ACPI register access | ||||
| #define EVENT_ACPI_TIMER       5		// The ACPI timer expired | ||||
| #define EVENT_IO_TRAP          6		// I/O trap | ||||
| #define EVENT_IO_TIMEOUT       7		// I/O timeout | ||||
| #define EVENT_PME              8		// Power Management | ||||
| #define EVENT_KEL              9		// KEL | ||||
| #define EVENT_VIDEO_INACTIVITY 0x0A	// Not supported in GX2 | ||||
| #define EVENT_GPIO             0x0B	// GPIO transition | ||||
|   #define FALLING_EDGE          (1 << 0) | ||||
|   #define RISING_EDGE           (1 << 1) | ||||
|   #define BOTH_EDGES            (FALLING_EDGE | RISING_EDGE)  | ||||
|   #define PME                   (1 << 2) | ||||
|   #define DEBOUNCE              (1 << 3) | ||||
|   #define PULLDOWN              (1 << 4) | ||||
|   #define PULLUP                (1 << 5) | ||||
|   #define INVERT                (1 << 6) | ||||
|   #define OUTPUT                (1 << 7) | ||||
|   #define OPEN_DRAIN            (1 << 8) | ||||
|   // INPUT may be removed as if it is not OUTPUT it is assumed to be INPUT | ||||
|   // this will have almost no impact on the code | ||||
|   // Do Not use INPUT | ||||
|   #define INPUT                 (1 << 9)  | ||||
|   #define AUX1                  (1 << 10) | ||||
|   #define AUX2                  (1 << 11) | ||||
|   #define NO_ASMI               (1 << 12) | ||||
|   #define PM1                   (1 << 13) | ||||
|   #define GPE                   (1 << 14) | ||||
|   #define NO_ENABLE             (1L << 15) // do not enable in GPE0_EN or PM1_EN | ||||
|                                           // when using EVENT_PME | ||||
| #define EVENT_SOFTWARE_SMI      0x0C	// Software SMI | ||||
| #define EVENT_PCI_TRAP          0x0D	// PCI trap | ||||
| #define EVENT_VIRTUAL_REGISTER  0x0E	// Virtual register access | ||||
| #define EVENT_NMI               0x0F	// NMI | ||||
| #define EVENT_TIMER             0x10	// Millisecond timer | ||||
| #define EVENT_DEVICE_TIMEOUT    0x11	// Device timeout | ||||
| #define EVENT_SEMAPHORE         0x12	// ACPI global lock | ||||
| #define EVENT_VBLANK            0x13    // Vertical blank | ||||
| #define EVENT_A20               0x14	// A20 mask toggled | ||||
| #define EVENT_SMB               0x15	// SMB Controller | ||||
| #define EVENT_RTC               0x16	// RTC Alarm | ||||
| #define EVENT_THERMAL           0x17    // THRM pin | ||||
| #define EVENT_LPC               0x18    // Low Pin Count bus | ||||
| #define EVENT_UART              0x19 | ||||
| #define EVENT_BLOCKIO           0x1A | ||||
| #define EVENT_PWM               0x1B | ||||
| #define MAX_EVENT               EVENT_PWM | ||||
|  | ||||
| // Flags for event registration | ||||
| #define WRITES_ONLY            (1L << 16) | ||||
| #define READS_ONLY             (1L << 17) | ||||
| #define GLIU_ID                (1L << 19) | ||||
| #define NOT_GLIU0              (1L << 20) | ||||
| #define NOT_GLIU1              (1L << 21) | ||||
| #define NOT_GLIU2              (1L << 22) | ||||
| #define ALL_GLIUS              (NOT_GLIU0 | NOT_GLIU1 | NOT_GLIU2) | ||||
| // Flags used for EVENT_TIMER must be >= bit 24 | ||||
| #define ONE_SHOT               (1L << 24) | ||||
| #define FOR_STANDBY            (1L << 25) | ||||
|  | ||||
|  | ||||
| //********************************************************************* | ||||
| //			Resources | ||||
| //********************************************************************* | ||||
| #define RESOURCE_MEMORY        0		// Physical Memory | ||||
| #define RESOURCE_MMIO          1		// Memory mapped I/O | ||||
| #define RESOURCE_IO            2		// I/O space | ||||
| #define RESOURCE_SCIO          3		// Swiss-cheese I/O | ||||
| #define RESOURCE_GPIO          4		// General-purpose I/O pin | ||||
| #define RESOURCE_IRQ           5		// IRQ | ||||
|  | ||||
|  | ||||
|    | ||||
| //********************************************************************* | ||||
| //			Macros | ||||
| //********************************************************************* | ||||
|  | ||||
| #define SYS_GET_NEXT_MSG(p)                 sys_get_next_msg(p) | ||||
| #define SYS_QUERY_MSG_QUEUE(p)              sys_query_msg_queue(p) | ||||
| #define SYS_UNREGISTER_EVENT(e, p1, p2)     sys_register_event(e, p1, p2, UNREGISTER_PRIORITY) | ||||
| #define SYS_REGISTER_EVENT(e, p1, p2, p)    sys_register_event(e, p1, p2, p) | ||||
| #define SYS_PASS_EVENT(e, p1, p2, p3) 		 // no longer needed | ||||
| #define SYS_VSM_PRESENT(vsm)                sys_vsm_present(vsm) | ||||
| #define SYS_YIELD_CONTROL(p1)               sys_yield_control(p1) | ||||
| #define SYS_SW_INTERRUPT(interrupt, regs)   sys_software_interrupt(interrupt, regs) | ||||
| #define SYS_BROADCAST_MSG(msg, p, vsm)      sys_broadcast_msg(msg, p, vsm) | ||||
| #define SYS_GET_SYSTEM_INFO(buffer)         sys_get_system_info(buffer) | ||||
| #define SYS_REPORT_ERROR(err, info1, info2) sys_report_error(err, info1, info2) | ||||
| #define SYS_GENERATE_IRQ(irq)               sys_generate_IRQ(irq) | ||||
| #define SYS_UNLOAD_VSM()                    sys_unload_vsm() | ||||
| #define SYS_LOGICAL_TO_PHYSICAL(addr)       sys_logical_to_physical(addr) | ||||
| #define SYS_ALLOCATE_RESOURCE(f,p,q,r,s)    sys_resource(f, p, q, r, s) | ||||
| #define SYS_DEALLOCATE_RESOURCE(f,p,q,r,s)  sys_resource((UCHAR)(f|0x80), p, q, r, s) | ||||
| #define SYS_MBUS_DESCRIPTOR(addr, p)        sys_mbus_descriptor(addr, p, 0) | ||||
| #define SYS_IO_DESCRIPTOR(addr, p)          sys_mbus_descriptor(addr, p, 3) | ||||
| #define SYS_LOOKUP_DEVICE(id, i)            sys_lookup_device(id, i) | ||||
| #define SYS_SAVE_STATE(buffer)              sys_state(0, buffer) | ||||
| #define SYS_RESTORE_STATE(buffer)           sys_state(1, buffer) | ||||
| #define SYS_SET_DECODE(addr, flag)          sys_address_decode(addr, flag) | ||||
| #define SYS_MAP_IRQ(Source, Irq)            sys_map_irq(Source, Irq) | ||||
| #define SYS_RETURN_RESULT(Data)             sys_return_result(Data) | ||||
| #define SYS_DUPLICATE_VSM(MemModel)         sys_duplicate_vsm(MemModel) | ||||
|  | ||||
| #define READ_PCI_BYTE(addr)                 read_PCI_byte(addr) | ||||
| #define READ_PCI_WORD(addr)                 read_PCI_word(addr) | ||||
| #define READ_PCI_DWORD(addr)                read_PCI_dword(addr) | ||||
| #define WRITE_PCI_BYTE(addr, data)          write_PCI_byte(addr, data) | ||||
| #define WRITE_PCI_WORD(addr, data)          write_PCI_word(addr, data) | ||||
| #define WRITE_PCI_DWORD(addr, data)         write_PCI_dword(addr, data) | ||||
|  | ||||
| #define WRITE_PCI_BYTE_NO_TRAP(addr, data)  write_PCI_no_trap(addr, (ULONG)data, BYTE_IO) | ||||
| #define WRITE_PCI_WORD_NO_TRAP(addr, data)  write_PCI_no_trap(addr, (ULONG)data, WORD_IO) | ||||
| #define WRITE_PCI_DWORD_NO_TRAP(addr, data) write_PCI_no_trap(addr, data, DWORD_IO) | ||||
| #define READ_PCI_BYTE_NO_TRAP(addr)         ((UCHAR)read_PCI_no_trap(addr, BYTE_IO)) | ||||
| #define READ_PCI_WORD_NO_TRAP(addr)         ((USHORT)read_PCI_no_trap(addr, WORD_IO)) | ||||
| #define READ_PCI_DWORD_NO_TRAP(addr)        read_PCI_no_trap(addr, DWORD_IO) | ||||
|  | ||||
| #define WRITE_MEMORY(addr, data)            write_flat(addr, data) | ||||
| #define READ_MEMORY(addr)                   read_flat(addr) | ||||
|  | ||||
| #define ENTER_CRITICAL_SECTION              EnterCriticalSection(); | ||||
| #define EXIT_CRITICAL_SECTION               ExitCriticalSection(); | ||||
|  | ||||
|  | ||||
|  | ||||
| void __pascal sys_register_event(EVENT, ULONG, ULONG, USHORT); | ||||
| void __pascal sys_software_interrupt(USHORT, INT_REGS *); | ||||
| void __pascal sys_broadcast_msg(MSG, void *, USHORT); | ||||
| void __pascal sys_yield_control(ULONG); | ||||
| void __pascal sys_get_system_info(void *); | ||||
| void __pascal sys_generate_IRQ(USHORT); | ||||
| void __pascal sys_state(USHORT, void *); | ||||
| void __pascal sys_address_decode(USHORT, USHORT); | ||||
| void __pascal sys_map_irq(UCHAR, UCHAR);  | ||||
| void __pascal sys_return_result(ULONG); | ||||
| void __pascal sys_get_descriptor(USHORT, void *); | ||||
| void __pascal sys_set_descriptor(USHORT, void *); | ||||
| void __pascal sys_set_header_data(USHORT, ULONG); | ||||
| void __pascal sys_set_register(USHORT, ULONG); | ||||
| void __pascal sys_set_virtual_register(USHORT, USHORT); | ||||
| void __pascal sys_report_error(USHORT, ULONG, ULONG); | ||||
|  | ||||
| void __pascal write_PCI_byte(ULONG, UCHAR); | ||||
| void __pascal write_PCI_word(ULONG, USHORT); | ||||
| void __pascal write_PCI_dword(ULONG, ULONG); | ||||
| void __pascal write_PCI_no_trap(ULONG, ULONG, USHORT); | ||||
|  | ||||
| void EnterCriticalSection(void); | ||||
| void ExitCriticalSection(void); | ||||
| void sys_fast_path_return(void); | ||||
| void sys_unload_vsm(void); | ||||
| void __pascal sys_duplicate_vsm(USHORT); | ||||
|  | ||||
| void __pascal write_flat(ULONG, ULONG); | ||||
| ULONG __pascal read_flat(ULONG); | ||||
| UCHAR  __pascal sys_vsm_present(UCHAR); | ||||
| USHORT __pascal sys_get_virtual_register(USHORT); | ||||
| ULONG  __pascal sys_get_header_data(USHORT); | ||||
| ULONG  __pascal sys_get_register(USHORT); | ||||
| UCHAR  __pascal read_PCI_byte(ULONG); | ||||
| USHORT __pascal read_PCI_word(ULONG); | ||||
| ULONG  __pascal read_PCI_dword(ULONG); | ||||
| ULONG  __pascal read_PCI_no_trap(ULONG, USHORT); | ||||
| ULONG  __pascal sys_logical_to_physical(void *); | ||||
| ULONG  __pascal sys_resource(UCHAR, USHORT, ULONG, USHORT, USHORT); | ||||
| ULONG  __pascal sys_mbus_descriptor(USHORT, ULONG *, USHORT); | ||||
| ULONG  __pascal sys_lookup_device(USHORT, USHORT); | ||||
| MSG    sys_get_next_msg(void *); | ||||
| MSG    sys_query_msg_queue(void *); | ||||
|  | ||||
| // Macros for use by VSMs to access the non-SMM context | ||||
| #define SET_HEADER_DATA(reg, data)   sys_set_header_data(reg, data) | ||||
| #define GET_HEADER_DATA(reg)         (ULONG)sys_get_header_data(reg) | ||||
| #define GET_DESCRIPTOR(reg, buffer)  sys_get_descriptor(reg, buffer); | ||||
| #define SET_DESCRIPTOR(reg, buffer)  sys_set_descriptor(reg, buffer); | ||||
| #define GET_REGISTER(reg)            (ULONG)sys_get_register(reg) | ||||
| #define SET_REGISTER(reg, data)      sys_set_register(reg, data) | ||||
| #define SET_EAX(data)                SET_REGISTER(R_EAX, (ULONG) (data)) | ||||
| #define SET_AX(data)                 SET_REGISTER(R_AX,  (USHORT)(data)) | ||||
| #define SET_AL(data)                 SET_REGISTER(R_AL,  (UCHAR) (data)) | ||||
| #define SET_AH(data)                 SET_REGISTER(R_AH,  (UCHAR) (data)) | ||||
| #define SET_EFLAGS(data)             SET_HEADER_DATA(R_EFLAGS, data) | ||||
| #define GET_EAX()                    ((ULONG) GET_REGISTER(R_EAX)) | ||||
| #define GET_AX()                     ((USHORT)GET_REGISTER(R_AX)) | ||||
| #define GET_AL()                     ((UCHAR) GET_REGISTER(R_AL)) | ||||
| #define GET_AH()                     ((UCHAR) GET_REGISTER(R_AH)) | ||||
| #define GET_EFLAGS()                 (GET_HEADER_DATA(R_EFLAGS)) | ||||
|  | ||||
|  | ||||
| // Macros for accessing virtual registers | ||||
| #define GET_VIRTUAL_REGISTER(reg)          (USHORT)sys_get_virtual_register(reg) | ||||
| #define SET_VIRTUAL_REGISTER(reg, data)    sys_set_virtual_register(reg, data) | ||||
|  | ||||
|  | ||||
| //********************************************************************* | ||||
| //			Error Codes | ||||
| //********************************************************************* | ||||
|  | ||||
| #define ERR_UNDEF_EVENT		1		// Attempt to register an undefined event | ||||
| //#define ERR_SCHEDULER		2		// Scheduler error | ||||
| #define ERR_BAD_PARAMETER		3		// Illegal system call parameter | ||||
| #define ERR_RESOURCE_CONFLICT	4		// Multiple VSMs requested conflicting resources | ||||
| #define ERR_UNHANDLED_EVENT	5		// An event occurred that no VSM handled | ||||
| #define ERR_INVALID_EVENT		6		// SysMgr attempted to send an invalid event | ||||
| //#define ERR_TIME_LIMIT		7		// A VSM exceeded its allotted runtime | ||||
| #define ERR_REGISTRATION_LOST	8		// A registered event is lost due to too many event registrations | ||||
| #define ERR_HW_MISMATCH		9		// A VSM could not find the correct hardware (e.g. OHCI) | ||||
| #define ERR_BAD_DESCRIPTOR		0x0A	// A descriptor in a VSM header is not valid | ||||
| //#define ERR_MSG_QUEUE_FULL	0x0B	// A VSM's message queue is full | ||||
| //#define ERR_MULTIPLE_EVENT   0x0C	// A VSM attempted to register the same event twice | ||||
| #define ERR_UNREGISTRATION     0x0D	// A VSM attempted to unregister an event for which it was not registered | ||||
| #define ERR_UNREGISTERED_EVENT 0x0E	// An event occurred for which no VSM is registered | ||||
| #define ERR_MISALIGNED_IO		0x0F	// An misaligned I/O access occurred | ||||
| //#define ERR_UNEXPECTED_EVENT 0x10    // A handler routine was passed an unexpected SMI event | ||||
| //#define ERR_BAD_VSM			0x11	// A VSM header doesn't look right (no signature, etc.) | ||||
| #define ERR_NESTED_ACCESS		0x12	// A VSM directly accessed a ACPI or virtual register | ||||
| //#define ERR_BAD_MSG			0x13	// An attempt was made to send an illegal message code | ||||
| //#define ERR_UNHANDLED_VIRTUAL 0x14	// An access was made by a VSM to an unhandled virtual register | ||||
| #define ERR_BAD_INTERRUPT      0x15    // A VSM attempted to call an illegal INT vector | ||||
| #define ERR_ILLEGAL_MACRO      0x16    // Illegal use of GET/SET_REGISTER or GET/SET_HEADER_DATA macros | ||||
| #define ERR_UNDEF_SYS_CALL		0x17	// Undefined system call | ||||
| //#define ERR_BAD_POWER_STATE	0x18	// Invalid power state | ||||
| #define ERR_BAD_VR_ACCESS      0x19	// Access to undefined VR class by an application | ||||
| #define ERR_UNDEF_VIRTUAL_REG	0x1A	// Access to undefined VR class by a VSM | ||||
| //#define ERR_UNSUPPORTED_CHIPSET 0x1B // This chipset is not supported | ||||
| #define ERR_PCI_TRAP           0x1C    // A VSM requested an unsupported PCI trap | ||||
| #define ERR_RESOURCE_NOT_FOUND 0x1D    // A VSM requested an unsupported resource | ||||
| #define ERR_NO_MORE_DESCRIPTORS 0x1E   // Out of MBIU descriptors | ||||
| //#define ERR_INTERNAL_ERROR    0x1F   // System error, e.g. inconsistent data structure | ||||
| #define ERR_DATA_STRUCTURE      0x20	// A system structure is too small | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| // Used as 2nd parameter to SYS_SET_DECODE macro: | ||||
| #define POSITIVE_DECODE			1 | ||||
| #define SUBTRACTIVE_DECODE		0 | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //**************************************************************************************************** | ||||
| #define FROM_HEADER            0x2000 | ||||
| #define WORD_SIZE              0x4000 | ||||
| #define DWORD_SIZE             0x8000 | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| // Field names for GET_REGISTER and SET_REGISTER macros | ||||
| // These offsets must match the register order on the stack (PUSHAD) | ||||
|  | ||||
| #define R_DI			 0   + WORD_SIZE  | ||||
| #define R_EDI			 0   + DWORD_SIZE | ||||
| 				 | ||||
| #define R_SI			 4   + WORD_SIZE | ||||
| #define R_ESI			 4   + DWORD_SIZE | ||||
|  | ||||
| #define R_BP			 8   + WORD_SIZE | ||||
| #define R_EBP			 8   + DWORD_SIZE | ||||
| 				 | ||||
| #define R_BL			16 | ||||
| #define R_BH			R_BL + 1 | ||||
| #define R_BX			R_BL + WORD_SIZE | ||||
| #define R_EBX			R_BL + DWORD_SIZE | ||||
|  | ||||
| #define R_DL			20 | ||||
| #define R_DH			R_DL + 1 | ||||
| #define R_DX			R_DL + WORD_SIZE | ||||
| #define R_EDX			R_DL + DWORD_SIZE | ||||
| 		 | ||||
| #define R_CL			24 | ||||
| #define R_CH			R_CL + 1 | ||||
| #define R_CX			R_CL + WORD_SIZE | ||||
| #define R_ECX			R_CL + DWORD_SIZE | ||||
|  | ||||
| #define R_AL			28 | ||||
| #define R_AH			R_AL + 1 | ||||
| #define R_AX			R_AL + WORD_SIZE | ||||
| #define R_EAX			R_AL + DWORD_SIZE | ||||
|  | ||||
| #define R_SP			32   + WORD_SIZE | ||||
| #define R_ESP			32   + DWORD_SIZE | ||||
|  | ||||
|  | ||||
| // Segment registers | ||||
| // NOTE: offset points to .selector field | ||||
| #define DESCRIPTOR_SIZE 10 // sizeof(Descriptor) | ||||
| #define R_SS			36-2 + DESCRIPTOR_SIZE + WORD_SIZE | ||||
| #define R_DS			R_SS + DESCRIPTOR_SIZE | ||||
| #define R_ES			R_DS + DESCRIPTOR_SIZE | ||||
| #define R_FS			R_ES + DESCRIPTOR_SIZE | ||||
| #define R_GS			R_FS + DESCRIPTOR_SIZE | ||||
|  | ||||
| // Fields from SMM header | ||||
| #define WRITE_DATA		0x08 + DWORD_SIZE + FROM_HEADER | ||||
| #define IO_ADDRESS		0x0C + WORD_SIZE  + FROM_HEADER | ||||
| #define DATA_SIZE		0x0E              + FROM_HEADER | ||||
| #define SMM_FLAGS		0x10 + WORD_SIZE  + FROM_HEADER | ||||
| #define CS_LIMIT		0x14 + DWORD_SIZE + FROM_HEADER | ||||
| #define CS_BASE	   	0x18 + DWORD_SIZE + FROM_HEADER | ||||
| #define CS_SELECTOR	0x1C + WORD_SIZE  + FROM_HEADER | ||||
| #define CS_ATTR		0x1E + WORD_SIZE  + FROM_HEADER  | ||||
| #define R_CS		0x1C + WORD_SIZE  + FROM_HEADER | ||||
| #define R_IP		0x20 + WORD_SIZE  + FROM_HEADER | ||||
| #define R_EIP		0x20 + DWORD_SIZE + FROM_HEADER | ||||
| #define CURRENT_EIP  	0x24 + DWORD_SIZE + FROM_HEADER | ||||
| #define R_CR0		0x28 + DWORD_SIZE + FROM_HEADER | ||||
| #define R_EFLAGS   	0x2C + DWORD_SIZE + FROM_HEADER | ||||
|   #define EFLAGS_CF    0x0001 | ||||
|   #define EFLAGS_ZF    0x0040 | ||||
|   #define EFLAGS_IF	0x0200 | ||||
|   #define EFLAGS_DF    0x0400 | ||||
| #define R_DR7 	   	0x30 + DWORD_SIZE + FROM_HEADER | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| typedef struct { | ||||
|   ULONG  Chipset_Base; | ||||
|   USHORT Chipset_ID; | ||||
|   USHORT Chipset_Rev; | ||||
|   USHORT CPU_ID; | ||||
|   USHORT CPU_Revision; | ||||
|   USHORT CPU_MHz; | ||||
|   ULONG  SystemMemory;		// Units = bytes | ||||
|   ULONG  VSA_Location;		// Physical location | ||||
|   USHORT VSA_Size;			// Units = KB | ||||
|   USHORT PCI_MHz; | ||||
|   USHORT DRAM_MHz; | ||||
| } Hardware; | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										88
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/blockio.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										88
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/blockio.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,88 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //*   Function:                                                         * | ||||
| //*     Handler for blocked PIO during UDMA     | ||||
|  | ||||
| #include "vsa2.h" | ||||
| #include "protos.h" | ||||
|  | ||||
|  | ||||
| #define RESET_DRIVE     0x08 | ||||
|  | ||||
|  | ||||
| USHORT UDMA_IO_Base; | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Enables/disables BLOCKIO | ||||
| //*********************************************************************** | ||||
| void pascal BlockIO(UCHAR EnableFlag)  | ||||
| { USHORT Priority=UNREGISTER_PRIORITY; | ||||
|  | ||||
|   if (EnableFlag) { | ||||
|     Priority = MAX_PRIORITY; | ||||
|   } | ||||
|  | ||||
|   SYS_REGISTER_EVENT(EVENT_BLOCKIO, 0, 0, Priority); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Handler for EVENT_BLOCKIO | ||||
| //*********************************************************************** | ||||
| void Handle_BLOCKIO(USHORT IO_Address, ULONG Data, UCHAR DataSize) | ||||
| { UCHAR Command; | ||||
|  | ||||
|   switch (IO_Address) { | ||||
|  | ||||
|     case 0x1F7: | ||||
|       // Check for drive reset command | ||||
|       if ((UCHAR)Data == RESET_DRIVE) { | ||||
|         break; | ||||
|       } | ||||
|       return; | ||||
|  | ||||
|     case 0x3F6: | ||||
|       if ((UCHAR)Data & 4) { | ||||
|         break; | ||||
|       }   | ||||
|  | ||||
|     default: | ||||
|       // Ignore I/O to all other IDE registers | ||||
| 	  return; | ||||
|   } | ||||
|  | ||||
|   // Disable BLOCKIO | ||||
|   BlockIO(0); | ||||
|  | ||||
|   // Terminate bus mastering | ||||
|   Command = in_8(UDMA_IO_Base); | ||||
|   out_8(UDMA_IO_Base, (UCHAR)(Command & ~1)); | ||||
|  | ||||
|   // Re-issue the I/O | ||||
|   out_8(IO_Address, (UCHAR)Data); | ||||
|  | ||||
|   // Re-enable BLOCKIO | ||||
|   BlockIO(1); | ||||
|  | ||||
| } | ||||
							
								
								
									
										479
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/cs5536.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										479
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/cs5536.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,479 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //*	  Function:                                                         * | ||||
| //*     This file contains routines specific to the CS5536.  | ||||
|  | ||||
| #include "vsa2.h" | ||||
| #include "chipset.h" | ||||
| #include "pci.h" | ||||
| #include "vr.h" | ||||
| #include "mapper.h" | ||||
| #include "gx2.h" | ||||
| #include "legacy.h" | ||||
| #include "protos.h" | ||||
| #include "isa.h" | ||||
|  | ||||
|  | ||||
|  | ||||
| // External Function prototypes | ||||
| extern void GetDrivesPresent(void); | ||||
| extern void Allocate_Flash_BARs(void); | ||||
| extern void pascal Flash_IDE_Switch(USHORT, ULONG); | ||||
| extern void BlockIO(UCHAR); | ||||
| extern void Register_DMA_Fix(void); | ||||
| extern UCHAR FlashIsEnabled(void); | ||||
|  | ||||
| // Local function prototypes: | ||||
| void Handle_5536_PCI_Traps(USHORT, USHORT, ULONG); | ||||
| void Register_PCI_Trap(USHORT, UCHAR); | ||||
|  | ||||
| // External variables: | ||||
| extern Hardware SystemInfo; | ||||
| extern ULONG ChipsetBase; | ||||
| extern ULONG Param[]; | ||||
| extern USHORT UDMA_IO_Base; | ||||
| extern ULONG OHCI_Address[]; | ||||
|  | ||||
| // Local variables: | ||||
| typedef void (* PCI_HANDLER)(USHORT, USHORT, ULONG); | ||||
| extern PCI_HANDLER Handle_PCI_Traps; | ||||
|  | ||||
| USHORT uart1 = 0; | ||||
| USHORT uart2 = 0; | ||||
| USHORT Flash_Function=0x00FF, IDE_Function = 0x00FF; | ||||
| USHORT PCI_Int_AB = ((USHORT)((INTB_PIN << 8) | INTA_PIN)); | ||||
| USHORT PCI_Int_CD = ((USHORT)((INTD_PIN << 8) | INTC_PIN)); | ||||
| USHORT Y_Sources[8]; | ||||
| USHORT Flash_PME; | ||||
| USHORT Steering = 0x0000; | ||||
| USHORT Hidden_Function = 0x0000; | ||||
| UCHAR IDE_Allocated = 0; | ||||
| UCHAR Flash_Allocated = 0; | ||||
| ULONG MDD_Base; | ||||
| USHORT pmc_base = 0; | ||||
| USHORT gpio_base = 0; | ||||
| USHORT acpi_base = 0; | ||||
|  | ||||
| typedef struct { | ||||
|   UCHAR Pin; | ||||
|   UCHAR Z_Source; | ||||
|   UCHAR Lbar; | ||||
| } PCI_INTERRUPT; | ||||
|  | ||||
| PCI_INTERRUPT PCI_Interrupt[] = { | ||||
| //    Pin     Z_Source | ||||
|   {INTA_PIN, Z_IRQ_INTA}, | ||||
|   {INTB_PIN, Z_IRQ_INTB}, | ||||
|   {INTC_PIN, Z_IRQ_INTC}, | ||||
|   {INTD_PIN, Z_IRQ_INTD} | ||||
| }; | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Hides the PCI header of the specified function | ||||
| //*********************************************************************** | ||||
| void Hide_Hdr(USHORT Function) | ||||
| { | ||||
|  | ||||
|   // If a function is currently being hidden, un-hide it | ||||
|   if (Hidden_Function) { | ||||
|     SYS_UNREGISTER_EVENT(EVENT_PCI_TRAP, ChipsetBase+Hidden_Function, 0x000000FF); | ||||
|     SYS_UNREGISTER_EVENT(EVENT_PCI_TRAP, ChipsetBase+Function+0x40,  WRITES_ONLY); | ||||
|   } | ||||
|  | ||||
|   // Register for IDE/Flash config space (to make invisible) | ||||
|   Register_PCI_Trap(Function, 0xFF); | ||||
|  | ||||
|   // Record which function is hidden | ||||
|   Hidden_Function = Function; | ||||
|  | ||||
|   // Get the 'other' function | ||||
|   if (Function == IDE_Function) { | ||||
|     Function = Flash_Function; | ||||
|   } else { | ||||
|     Function = IDE_Function; | ||||
|   } | ||||
|  | ||||
|   // Trap IDE/Flash register 0x40 (used for Flash<->IDE switch) | ||||
|   SYS_REGISTER_EVENT(EVENT_PCI_TRAP, ChipsetBase+Function+0x40, WRITES_ONLY, 0); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Maps the NAND Flash PMEs to the specified IRQ | ||||
| //*********************************************************************** | ||||
| void Map_Flash_IRQ(UCHAR Irq) | ||||
| { | ||||
|   SYS_MAP_IRQ((UCHAR)(Flash_PME+0), Irq); | ||||
|   SYS_MAP_IRQ((UCHAR)(Flash_PME+1), Irq); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Hides the IDE function and un-hides the Flash function | ||||
| //*********************************************************************** | ||||
| void Hide_IDE_Hdr(void) | ||||
| { UCHAR Shift, Irq; | ||||
|  | ||||
|   // Map NAND Flash interrupts | ||||
|   Shift = (UCHAR)(((Flash_PME >> 8)-1) * 4); | ||||
|   Irq = (UCHAR)(Steering >> Shift) & 0x0F; | ||||
|   Map_Flash_IRQ(Irq); | ||||
|  | ||||
|   // Hide the IDE header | ||||
|   Hide_Hdr(IDE_Function); | ||||
| }  | ||||
|   | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Hides the Flash function and un-hides the IDE function | ||||
| //*********************************************************************** | ||||
| void Hide_Flash_Hdr(void) | ||||
| { USHORT Bar; | ||||
|  | ||||
|   // Unmap NAND Flash interrupts | ||||
|   Map_Flash_IRQ(0); | ||||
|  | ||||
|   // If Flash BARs have been allocated, then zero them to disable linked MSRs | ||||
|   if (Flash_Allocated) { | ||||
|     for (Bar = BAR0; Bar <= BAR3; Bar += 0x10) { | ||||
|       WRITE_PCI_DWORD(ChipsetBase+IDE_Function+Bar, 0x00000000); | ||||
|     } | ||||
|   } | ||||
|   Hide_Hdr(Flash_Function); | ||||
|  | ||||
|   if (!IDE_Allocated) { | ||||
|  | ||||
|     // Allocate UDMA BAR | ||||
|     SYS_ALLOCATE_RESOURCE(RESOURCE_IO, BAR4, 16, DEVICE_ID_AMD_THOR,  ID_ATA); | ||||
|  | ||||
|     IDE_Allocated = 1; | ||||
|   } | ||||
| }  | ||||
|   | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Performs early initialization for CS5536 | ||||
| //*********************************************************************** | ||||
| void CS5536_Early_Init(void) | ||||
| { USHORT Function; | ||||
|   ULONG PciAddr, PciData; | ||||
|  | ||||
|   Handle_PCI_Traps = Handle_5536_PCI_Traps; | ||||
|  | ||||
|   MDD_Base = SYS_LOOKUP_DEVICE(ID_MDD, 1); | ||||
|   // Get I/O base of PMC, ACPI & GPIO | ||||
|   pmc_base  = READ_PCI_WORD(ChipsetBase + BAR4) & 0xFFFE; | ||||
|   gpio_base = READ_PCI_WORD(ChipsetBase + BAR1) & 0xFFFE; | ||||
|   acpi_base = READ_PCI_WORD(ChipsetBase + BAR5) & 0xFFFE; | ||||
|  | ||||
| 					  | ||||
|   // Scan Southbridge functions to: | ||||
|   // - Get Unrestricted Sources Y IRQ. | ||||
|   // - Find Flash & IDE functions. | ||||
|   for (Function = 0; Function < 8; Function++) { | ||||
|  | ||||
|     // Generate PCI configuration address | ||||
|     PciAddr = ChipsetBase | (Function << 8); | ||||
|      | ||||
|     // For functions that have PCI interrupts, Interrupt Line  | ||||
|     // contains Y Sources field number. | ||||
|     (UCHAR)PciAddr = INTERRUPT_LINE; | ||||
|  | ||||
|     // If PCI interrupt is defined, record linked Unrestricted Y Source | ||||
|     Y_Sources[Function] = READ_PCI_WORD(PciAddr); | ||||
|     if (Y_Sources[Function]) { | ||||
|       // clear Interrupt Line | ||||
|       WRITE_PCI_WORD(PciAddr, 0x0000); | ||||
|     } | ||||
|  | ||||
|     // Read Class Code | ||||
|     (UCHAR)PciAddr = REVISION_ID; | ||||
|     PciData = READ_PCI_DWORD(PciAddr); | ||||
|     // Ignore Revision ID | ||||
|     PciData &= 0xFFFFFF00; | ||||
|  | ||||
|     // Record function # of Flash header | ||||
|     if (PciData == 0x05010000) { | ||||
|       Flash_Function = (USHORT)PciAddr & 0x0700; | ||||
|       Flash_PME = Y_Sources[Function]; | ||||
|     } | ||||
|     // Record function # of IDE header | ||||
|     if (PciData == 0x01018000) { | ||||
|       IDE_Function   = (USHORT)PciAddr & 0x0700; | ||||
|       Y_Sources[Function] = Flash_PME+1; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   switch (SystemInfo.Chipset_ID) { | ||||
|     case DEVICE_ID_5536: | ||||
|       SYS_REGISTER_EVENT(EVENT_PCI_TRAP, ChipsetBase+IDE_Function+BAR4, WRITES_ONLY, 0); | ||||
|       break; | ||||
|   } | ||||
|  | ||||
|  | ||||
|   // Is Flash controller enabled ? | ||||
|   if (FlashIsEnabled()) { | ||||
|  | ||||
|     // Allocate Flash BARs | ||||
|     Allocate_Flash_BARs(); | ||||
|  | ||||
|     // Hide the IDE header | ||||
|     Hide_IDE_Hdr(); | ||||
|  | ||||
|   } else { | ||||
|  | ||||
|     // Hide the Flash header | ||||
|     Hide_Flash_Hdr(); | ||||
|   } | ||||
|  | ||||
|   // Register for virtual registers VRC_MISCELLANEOUS::PCI_INT_AB->WATCHDOG | ||||
|   SYS_REGISTER_EVENT(EVENT_VIRTUAL_REGISTER, VRC_MISCELLANEOUS, (PCI_INT_AB<<8) | WATCHDOG, MAX_PRIORITY); | ||||
|  | ||||
|   // Register for SB PCI register 0x5C-0x5D (emulation of 5530 PCI steering register) | ||||
|   Register_PCI_Trap(0x005C, 0x01); | ||||
|  | ||||
| /*MEJ | ||||
|   // If Power Management VSM is present... | ||||
|   if (SYS_VSM_PRESENT(VSM_PM)) { | ||||
|     // Register for virtual register timeouts on legacy devices | ||||
|     SYS_REGISTER_EVENT(EVENT_VIRTUAL_REGISTER, VRC_PM, (DISK_TIMEOUT<<8) | PARALLEL_TIMEOUT, 0); | ||||
|   } | ||||
| */ | ||||
|  | ||||
|   // Register for virtual register class VRC_CHIPSET | ||||
|   SYS_REGISTER_EVENT(EVENT_VIRTUAL_REGISTER, VRC_CHIPSET, 0, NORMAL_PRIORITY); | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Performs End-of-POST initialization for CS5536 | ||||
| //*********************************************************************** | ||||
| void CS5536_Late_Init(void)  | ||||
| { | ||||
|   // Determine how many ATA drives are present | ||||
|   GetDrivesPresent(); | ||||
|  | ||||
|   // Set ISA bridge Latency Timer to 0x40 | ||||
|   WRITE_PCI_BYTE(ChipsetBase + LATENCY_TIMER, 0x40); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Handler for writes to VRC_MISCELLANEOUS PCI_INT_AB & PCI_INT_CD | ||||
| // These registers define what GPIOs are to be used for PCI interrupts. | ||||
| //*********************************************************************** | ||||
| void Handle_Misc_VR(UCHAR Index, USHORT Data) | ||||
| { int i, j; | ||||
|   ULONG Param2; | ||||
|   static UCHAR Flag = 0x00; | ||||
|  | ||||
|  | ||||
|   if (Index == PCI_INT_AB) { | ||||
|     // PCI interrupt GPIOs can only be allocated once | ||||
|     if (Flag & 1) { | ||||
|       return; | ||||
|     } | ||||
|     // Record data for readback | ||||
|     PCI_Int_AB = Data; | ||||
|     Flag |= 1; | ||||
|     i = 0; | ||||
|   } else { | ||||
|     // PCI interrupt GPIOs can only be allocated once | ||||
|     if (Flag & 2) { | ||||
|       return; | ||||
|     } | ||||
|     // Record data for readback | ||||
|     PCI_Int_CD = Data; | ||||
|     Flag |= 2; | ||||
|     i = 2; | ||||
|   } | ||||
|  | ||||
|   // Set GPIOs as level-sensitive (no ASMI!), inverted inputs | ||||
|   j = i + 2; | ||||
|   while (i < j) { | ||||
|  | ||||
|     // Record the GPIO pin | ||||
|     PCI_Interrupt[i].Pin = (UCHAR)Data; | ||||
|  | ||||
|     if (PCI_Interrupt[i].Pin < 32) { | ||||
|       Param2 = ((ULONG)PCI_Interrupt[i].Z_Source << 16) | PCI_Interrupt[i].Pin; | ||||
|       SYS_REGISTER_EVENT(EVENT_GPIO, Param2, INVERT, MAX_PRIORITY); | ||||
|     } | ||||
|  | ||||
|     // Shift the next pin # into the 8 LSBs | ||||
|     Data >>= 8; | ||||
|  | ||||
|     i++; | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Emulates CS5530's PCI Interrupt steering registers 0x5C & 0x5D | ||||
| // Register 0x5C: | ||||
| //   3:0	INTA# | ||||
| //   7:4	INTB# | ||||
| // Register 0x5D: | ||||
| //   3:0	INTC# | ||||
| //   7:4	INTD# | ||||
| // Maps PCI INT pins to Unrestricted Z sources | ||||
| //*********************************************************************** | ||||
| void PCI_Interrupt_Steering(USHORT Data) | ||||
| { UCHAR i, j, Irq; | ||||
|  | ||||
|   // Register for PCI interrupt GPIOs in case BIOS never wrote to the VR | ||||
|   Handle_Misc_VR(PCI_INT_AB, PCI_Int_AB); | ||||
|   Handle_Misc_VR(PCI_INT_CD, PCI_Int_CD); | ||||
|  | ||||
|   for (i=0; i < 4; i++) { | ||||
|  | ||||
|     // Extract IRQ from next nibble | ||||
|     Irq = (UCHAR)(Data & 0x0F); | ||||
|   | ||||
|     // Don't allow IRQ2 (SMI) | ||||
|     if (Irq != 2) { | ||||
|       // Map the Unrestricted Z Source to the requested IRQ | ||||
|       SYS_MAP_IRQ((UCHAR)(PCI_Interrupt[i].Z_Source+16), Irq); | ||||
|  | ||||
|       // Map the Unrestricted Y Source (if any) to the requested IRQ | ||||
|       for (j=0; j < 8; j++) { | ||||
|         UCHAR InterruptPin; | ||||
|  | ||||
|         InterruptPin = (UCHAR)(Y_Sources[j] >> 8); | ||||
|         if (InterruptPin == i+1) { | ||||
|           SYS_MAP_IRQ((UCHAR)Y_Sources[j], Irq); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // Shift the next nibble into the 4 LSBs | ||||
|     Data >>= 4; | ||||
|   } | ||||
| } | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Handler for emulation of 5530 PCI steering registers on a 5536 system | ||||
| //*********************************************************************** | ||||
| void Handle_5536_PCI_Traps(USHORT PCI_Addr, USHORT IO_Params, ULONG Data) | ||||
| { UCHAR PCI_Reg, Shift, IO_Size; | ||||
|   USHORT Function; | ||||
|  | ||||
|  | ||||
|   PCI_Reg  = (UCHAR) PCI_Addr; | ||||
|   IO_Size  = (UCHAR) IO_Params; | ||||
|   Function = PCI_Addr & 0x0700; | ||||
|   Shift    = (PCI_Reg & 3) << 3; | ||||
|  | ||||
|   // Record OHCI BAR values | ||||
|   if (PCI_Addr == 0x7C10 || PCI_Addr == 0x7D10) { | ||||
|     if (IO_Params & IO_WRITE) { | ||||
|       Function = (Function >> 8) - 4; | ||||
|       OHCI_Address[Function] = Data & 0xFFFFF000; | ||||
|     } | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   // PCI Interrupt Steering register | ||||
|   if (Function == 0x0000) { | ||||
|  | ||||
|     if (IO_Params & IO_WRITE) { | ||||
|       // Handle mis-aligned accesses | ||||
|       if (Shift) { | ||||
|         Steering &= 0x00FF; | ||||
|         Steering |= (USHORT)Data << 8; | ||||
|       } else { | ||||
|         Steering = (USHORT)Data; | ||||
|       } | ||||
|       PCI_Interrupt_Steering(Steering); | ||||
|       return; | ||||
|  | ||||
|     } else { | ||||
|       if (PCI_Reg < 0x5C) { | ||||
|         Data = (ULONG)Steering << (32-Shift); | ||||
|         Shift = 0; | ||||
|       } else { | ||||
|         Data = Steering; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|   } else { | ||||
|  | ||||
|     // Flash/IDE configuration space | ||||
|     if (Function == Flash_Function || Function == IDE_Function) { | ||||
|  | ||||
|       if (IO_Params & IO_WRITE) { | ||||
|  | ||||
|         // PCI writes to IDE/Flash function | ||||
|         switch (PCI_Reg) { | ||||
|           case BAR4: | ||||
|             if (Function == IDE_Function && (USHORT)Data != 0xFFFF) { | ||||
|               // Record UDMA I/O base for BLOCK_IO logic | ||||
|               UDMA_IO_Base = (USHORT)Data & 0xFFF0; | ||||
|             } | ||||
|             break; | ||||
|  | ||||
|           // Write to IDE<->Flash switch | ||||
|           case 0x40: | ||||
|             if (Data == 0xDEADBEEF || Data == 0xBEEFDEAD) { | ||||
|               // Switch Flash<->IDE  | ||||
|               Flash_IDE_Switch(Function, Data); | ||||
|             } | ||||
|         } | ||||
|         return; | ||||
|  | ||||
|       } else { | ||||
|  | ||||
|         // PCI reads of hidden function | ||||
|         if (Function == Hidden_Function) { | ||||
|           Data = 0xFFFFFFFF; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|  | ||||
|   // Handle non-dword aligned accesses | ||||
|   Data >>= Shift; | ||||
|   Data  |= 0xFFFFFFFFL << (32-Shift); | ||||
|  | ||||
|   // Return the PCI register value | ||||
|   SYS_RETURN_RESULT(Data); | ||||
|  | ||||
| } | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Registers a PCI trap for the specified Addr/Mask | ||||
| //*********************************************************************** | ||||
| void Register_PCI_Trap(USHORT Addr, UCHAR Mask) | ||||
| { | ||||
|   SYS_REGISTER_EVENT(EVENT_PCI_TRAP, ChipsetBase+Addr, (ULONG)Mask, 0); | ||||
| } | ||||
|  | ||||
							
								
								
									
										145
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/events.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										145
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/events.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,145 @@ | ||||
| /* | ||||
| * Copyright (c) 2006 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //*   Function:                                                         * | ||||
| //*     This file handles the Legacy VSM's event messages.  | ||||
|  | ||||
| #include "vsa2.h" | ||||
| #include "chipset.h" | ||||
| #include "vr.h" | ||||
| #include "legacy.h" | ||||
| #include "protos.h" | ||||
| #include "pci.h" | ||||
| #include "isa.h" | ||||
|  | ||||
| // Function prototypes | ||||
| extern void Handle_BLOCKIO(USHORT, ULONG, UCHAR); | ||||
| extern void Handle_VirtualRegs(UCHAR, UCHAR, UCHAR, USHORT); | ||||
| extern void Do_OHCI_SWAPSiF(void); | ||||
|  | ||||
| // External variables: | ||||
| extern ULONG ChipsetBase; | ||||
| extern USHORT DiskTimeout, SerialTimeout, ParallelTimeout, FloppyTimeout; | ||||
|  | ||||
| // Local variables: | ||||
| USHORT IDE_Interface = MASTER_IDE;  // Default to "bus master capable" | ||||
|  | ||||
| typedef void (* PCI_HANDLER)(USHORT, USHORT, ULONG); | ||||
| PCI_HANDLER Handle_PCI_Traps; | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Register I/O trap to fix 118.409	- Block/Demand mode fails | ||||
| //*********************************************************************** | ||||
| void Register_DMA_Fix(void) | ||||
| { | ||||
| #define DMA_FLAGS (WRITES_ONLY | ONE_SHOT) | ||||
|  | ||||
|    SYS_REGISTER_EVENT(EVENT_IO_TRAP, DMA1_MODE, DMA_FLAGS | 1, 0); | ||||
| }    | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Handler for MSG_EVENT | ||||
| //*********************************************************************** | ||||
| void Handle_Events(ULONG * Param) | ||||
| { USHORT Event, IO_Address; | ||||
|   ULONG Data; | ||||
|   UCHAR WrFlag, DataSize, Class, Index; | ||||
|  | ||||
|   Event = (USHORT)Param[0]; | ||||
|   IO_Address = (USHORT)Param[2]; | ||||
|   DataSize = (UCHAR)(Param[2] >> 16); | ||||
|   Data = Param[3]; | ||||
|  | ||||
|   switch (Event) { | ||||
|  | ||||
|     case EVENT_IO_TRAP: | ||||
|       // If it is an I/O to the 8237 DMA controller... | ||||
|       if (IO_Address == DMA1_MODE) { | ||||
|         static UCHAR Mode = 0x00; | ||||
|         UCHAR ByteData; | ||||
|  | ||||
|         // and it is a I/O write... | ||||
|         if (Param[1] & 2) { | ||||
|           ByteData = (UCHAR)Data; | ||||
|           // and the Mode is either Block or Demand... | ||||
|           Mode = ByteData & MODE_MASK; | ||||
|           if (Mode == MODE_DEMAND || Mode == MODE_BLOCK) { | ||||
|             // then change the mode to Single | ||||
|             ByteData &= ~MODE_MASK; | ||||
|             ByteData |=  MODE_SINGLE; | ||||
|           } | ||||
|  | ||||
|           // Re-issue the I/O (trapping is disabled since it was a ONE_SHOT) | ||||
|           out_8(DMA1_MODE, ByteData); | ||||
| 	    } | ||||
|         // Re-register for the I/O trap | ||||
|         Register_DMA_Fix(); | ||||
|         break; | ||||
|       } | ||||
|  | ||||
|       // Handle PM traps here... | ||||
|       break; | ||||
|  | ||||
|     case EVENT_IO_TIMEOUT: | ||||
|       // Handle PM timeout here... | ||||
|       break; | ||||
|  | ||||
|     case EVENT_SOFTWARE_SMI: | ||||
|       if (Param[1] == SYS_DMA_DRIVER) { | ||||
|         // Allow the UDMA driver to see that IDE is bus master capable. | ||||
|         IDE_Interface = MASTER_IDE;  | ||||
|       } else if (Param[1] == SYS_DMA_DRIVER+1) { | ||||
|         // Prevent the UDMA driver from seeing that IDE is bus master capable. | ||||
|         IDE_Interface = 0;  | ||||
|       } | ||||
|       break; | ||||
|  | ||||
|     case EVENT_PCI_TRAP: | ||||
|       Handle_PCI_Traps((USHORT)Param[1], (USHORT)Param[2], Data); | ||||
|       break; | ||||
|  | ||||
|     case EVENT_VIRTUAL_REGISTER: | ||||
|       // Extract virtual register parameters from message | ||||
|       Class = (UCHAR)(Param[1] >> 8); | ||||
|       Index = (UCHAR)Param[1]; | ||||
|       WrFlag = (UCHAR)Param[2]; | ||||
|       Handle_VirtualRegs(Class, Index, WrFlag, (USHORT)Data); | ||||
|       break; | ||||
|  | ||||
|     case EVENT_BLOCKIO: | ||||
|       Handle_BLOCKIO(IO_Address, Data, DataSize); | ||||
|       break; | ||||
|  | ||||
|     case EVENT_TIMER: | ||||
|       // Fix for attach/detach hardware bug | ||||
|       if (Param[2] == USBF_HANDLE) { | ||||
|         Do_OHCI_SWAPSiF(); | ||||
|         break; | ||||
|       } | ||||
|  | ||||
| /*MEJ      // Broadcast to all VSM's | ||||
|       Param[0] = S5_STATE; | ||||
|       Param[1] = CLASS_ALL; | ||||
|       SYS_BROADCAST_MSG(MSG_SET_POWER_STATE, &Param[0], VSM_ANY); | ||||
| */ | ||||
|       break; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										174
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/flash.bak
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										174
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/flash.bak
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,174 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //****************************************************************************** | ||||
| //*    Routines related to the Flash device.   | ||||
| //****************************************************************************** | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| #include "VSA2.H" | ||||
| #include "CHIPSET.H" | ||||
| #include "SYSMGR.H" | ||||
| #include "MDD.H" | ||||
| #include "PCI.H" | ||||
| #include "GX2.H" | ||||
| #include "LEGACY.H" | ||||
| #include "PROTOS.H" | ||||
|  | ||||
| // Function prototypes: | ||||
| extern void Hide_IDE_Hdr(void); | ||||
| extern void Hide_Flash_Hdr(void); | ||||
|  | ||||
|  | ||||
| // External variables: | ||||
| extern ULONG MDD_Base; | ||||
| extern USHORT Flash_Function, IDE_Function; | ||||
| extern UCHAR Flash_Allocated; | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Returns non-zero if Flash device is enabled | ||||
| //*********************************************************************** | ||||
| UCHAR FlashIsEnabled(void) | ||||
| { UCHAR Pin; | ||||
|  | ||||
|   Pin = (UCHAR)Read_MSR_LO(MDD_Base + MSR_PIN_OPTS) & PIN_OPT_IDE; | ||||
|   Pin ^= PIN_OPT_IDE; | ||||
|   return Pin; | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Allocates Flash BARs | ||||
| //*********************************************************************** | ||||
| void Allocate_Flash_BARs(void) | ||||
| { ULONG MsrAddr, MsrData[2], Size; | ||||
|   USHORT Bar; | ||||
|   UCHAR Resource; | ||||
|   static UCHAR Flash_LBARs[4] = { | ||||
|     MSR_LBAR_FLSH0, | ||||
|     MSR_LBAR_FLSH1, | ||||
|     MSR_LBAR_FLSH2, | ||||
|     MSR_LBAR_FLSH3, | ||||
|   }; | ||||
|  | ||||
|  | ||||
|   // BARs are only to be allocated once | ||||
|   if (Flash_Allocated == 0) { | ||||
|  | ||||
|     Flash_Allocated = 1; | ||||
|     // Determine type/size of PCI BAR for each Flash device | ||||
|     MsrAddr = MDD_Base; | ||||
|     for (Bar = BAR0; Bar <= BAR3; Bar += 4) { | ||||
|       // Read the Flash LBAR | ||||
|       (UCHAR)MsrAddr = Flash_LBARs[(Bar-BAR0)/4]; | ||||
|       Read_MSR(MsrAddr, MsrData); | ||||
|  | ||||
|       // If LBAR size has not been programmed, then don't configure the PCI BAR | ||||
|       Size = MsrData[1] & ~(MEM_IO | NOR_NAND | LBAR_EN); | ||||
|       if (Size == 0x00000000) { | ||||
|         continue; | ||||
|       } | ||||
|  | ||||
|       // NAND or NOR Flash ? | ||||
|       if (MsrData[1] & NOR_NAND) { | ||||
|         // NAND Flash | ||||
|         // Required for proper byte count calculation | ||||
|         Size |= 0xFFFF0000; | ||||
|         Resource = RESOURCE_IO; | ||||
|       } else { | ||||
|         // NOR Flash | ||||
|         Size &= LBAR_MEM_MASK; | ||||
|         Resource = RESOURCE_MMIO; | ||||
|       } | ||||
|       // Convert mask to byte count | ||||
|       Size = ~Size + 1; | ||||
|       // Allocate BAR | ||||
|       SYS_ALLOCATE_RESOURCE(Resource, Bar, Size, DEVICE_ID_AMD_FLASH, ID_MDD); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Switches between Flash and IDE headers | ||||
| //*********************************************************************** | ||||
| void pascal Flash_IDE_Switch(USHORT Function, ULONG Data) | ||||
| { ULONG PinOptions, PinMsr, FlashMsr, LBar[2], SavedLBar[2]; | ||||
|  | ||||
|   // Switch pins to Flash mode | ||||
|   PinMsr = MDD_Base + MSR_PIN_OPTS; | ||||
|   PinOptions = Read_MSR_LO(PinMsr); | ||||
|  | ||||
|   if (Function == Flash_Function) { | ||||
|     // Currently in Flash mode | ||||
|  | ||||
|     // Switching to IDE mode ? | ||||
|     if (Data == 0xBEEFDEAD) { | ||||
|  | ||||
|       // Hide the Flash header | ||||
|       Hide_Flash_Hdr(); | ||||
|  | ||||
|       // Switch pins to IDE mode | ||||
|       PinOptions |= PIN_OPT_IDE; | ||||
|       Write_MSR_LO(PinMsr, PinOptions); | ||||
|  | ||||
|       // Disconnect the ROM from the DMA pins | ||||
|       in_8(0x3F6); | ||||
|     } | ||||
|  | ||||
|   }	else { | ||||
|  | ||||
|     // Currently in IDE mode | ||||
|  | ||||
|     // Switching to Flash mode ? | ||||
|     if (Data == 0xDEADBEEF) { | ||||
|  | ||||
|       // Hide the IDE header | ||||
|       Hide_IDE_Hdr(); | ||||
|  | ||||
|       // Allocate Flash BARs | ||||
|       Allocate_Flash_BARs(); | ||||
|  | ||||
|       // Enable Flash mode | ||||
|       PinOptions &= ~PIN_OPT_IDE; | ||||
|       Write_MSR_LO(PinMsr, PinOptions); | ||||
|  | ||||
|       // Handle Canary circuit | ||||
|  | ||||
|       // Set CS1# to respond to I/O address 22h | ||||
|       FlashMsr = MDD_Base + MSR_LBAR_FLSH1; | ||||
|       Read_MSR(FlashMsr, SavedLBar); | ||||
|       LBar[0] = 0x00000022; | ||||
|       LBar[1] = 0x0000FFF0 | LBAR_EN; | ||||
|       Write_MSR(FlashMsr, LBar); | ||||
|  | ||||
|       // Turn Canary circuit on | ||||
|       in_8(0x22); | ||||
|  | ||||
|       // Restore CS1 LBAR | ||||
|       Write_MSR(FlashMsr, SavedLBar); | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										174
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/flash.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										174
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/flash.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,174 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //****************************************************************************** | ||||
| //*    Routines related to the Flash device.   | ||||
| //****************************************************************************** | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| #include "VSA2.H" | ||||
| #include "CHIPSET.H" | ||||
| #include "SYSMGR.H" | ||||
| #include "MDD.H" | ||||
| #include "PCI.H" | ||||
| #include "GX2.H" | ||||
| #include "LEGACY.H" | ||||
| #include "PROTOS.H" | ||||
|  | ||||
| // Function prototypes: | ||||
| extern void Hide_IDE_Hdr(void); | ||||
| extern void Hide_Flash_Hdr(void); | ||||
|  | ||||
|  | ||||
| // External variables: | ||||
| extern ULONG MDD_Base; | ||||
| extern USHORT Flash_Function, IDE_Function; | ||||
| extern UCHAR Flash_Allocated; | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Returns non-zero if Flash device is enabled | ||||
| //*********************************************************************** | ||||
| UCHAR FlashIsEnabled(void) | ||||
| { UCHAR Pin; | ||||
|  | ||||
|   Pin = (UCHAR)Read_MSR_LO(MDD_Base + MSR_PIN_OPTS) & PIN_OPT_IDE; | ||||
|   Pin ^= PIN_OPT_IDE; | ||||
|   return Pin; | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Allocates Flash BARs | ||||
| //*********************************************************************** | ||||
| void Allocate_Flash_BARs(void) | ||||
| { ULONG MsrAddr, MsrData[2], Size; | ||||
|   USHORT Bar; | ||||
|   UCHAR Resource; | ||||
|   static UCHAR Flash_LBARs[4] = { | ||||
|     MSR_LBAR_FLSH0, | ||||
|     MSR_LBAR_FLSH1, | ||||
|     MSR_LBAR_FLSH2, | ||||
|     MSR_LBAR_FLSH3, | ||||
|   }; | ||||
|  | ||||
|  | ||||
|   // BARs are only to be allocated once | ||||
|   if (Flash_Allocated == 0) { | ||||
|  | ||||
|     Flash_Allocated = 1; | ||||
|     // Determine type/size of PCI BAR for each Flash device | ||||
|     MsrAddr = MDD_Base; | ||||
|     for (Bar = BAR0; Bar <= BAR3; Bar += 4) { | ||||
|       // Read the Flash LBAR | ||||
|       (UCHAR)MsrAddr = Flash_LBARs[(Bar-BAR0)/4]; | ||||
|       Read_MSR(MsrAddr, MsrData); | ||||
|  | ||||
|       // If LBAR size has not been programmed, then don't configure the PCI BAR | ||||
|       Size = MsrData[1] & ~(MEM_IO | NOR_NAND | LBAR_EN); | ||||
|       if (Size == 0x00000000) { | ||||
|         continue; | ||||
|       } | ||||
|  | ||||
|       // MMIO or IO resource | ||||
|       if (MsrData[1] & MEM_IO ) { | ||||
|         // MMIO mode | ||||
|         Size &= LBAR_MEM_MASK; | ||||
|         Resource = RESOURCE_MMIO; | ||||
|       } else { | ||||
|         // IO mode | ||||
|         // Required for proper byte count calculation | ||||
|         Size |= 0xFFFF0000; | ||||
|         Resource = RESOURCE_IO; | ||||
|       } | ||||
|       // Convert mask to byte count | ||||
|       Size = ~Size + 1; | ||||
|       // Allocate BAR | ||||
|       SYS_ALLOCATE_RESOURCE(Resource, Bar, Size, DEVICE_ID_AMD_FLASH, ID_MDD); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Switches between Flash and IDE headers | ||||
| //*********************************************************************** | ||||
| void pascal Flash_IDE_Switch(USHORT Function, ULONG Data) | ||||
| { ULONG PinOptions, PinMsr, FlashMsr, LBar[2], SavedLBar[2]; | ||||
|  | ||||
|   // Switch pins to Flash mode | ||||
|   PinMsr = MDD_Base + MSR_PIN_OPTS; | ||||
|   PinOptions = Read_MSR_LO(PinMsr); | ||||
|  | ||||
|   if (Function == Flash_Function) { | ||||
|     // Currently in Flash mode | ||||
|  | ||||
|     // Switching to IDE mode ? | ||||
|     if (Data == 0xBEEFDEAD) { | ||||
|  | ||||
|       // Hide the Flash header | ||||
|       Hide_Flash_Hdr(); | ||||
|  | ||||
|       // Switch pins to IDE mode | ||||
|       PinOptions |= PIN_OPT_IDE; | ||||
|       Write_MSR_LO(PinMsr, PinOptions); | ||||
|  | ||||
|       // Disconnect the ROM from the DMA pins | ||||
|       in_8(0x3F6); | ||||
|     } | ||||
|  | ||||
|   }	else { | ||||
|  | ||||
|     // Currently in IDE mode | ||||
|  | ||||
|     // Switching to Flash mode ? | ||||
|     if (Data == 0xDEADBEEF) { | ||||
|  | ||||
|       // Hide the IDE header | ||||
|       Hide_IDE_Hdr(); | ||||
|  | ||||
|       // Allocate Flash BARs | ||||
|       Allocate_Flash_BARs(); | ||||
|  | ||||
|       // Enable Flash mode | ||||
|       PinOptions &= ~PIN_OPT_IDE; | ||||
|       Write_MSR_LO(PinMsr, PinOptions); | ||||
|  | ||||
|       // Handle Canary circuit | ||||
|  | ||||
|       // Set CS1# to respond to I/O address 22h | ||||
|       FlashMsr = MDD_Base + MSR_LBAR_FLSH1; | ||||
|       Read_MSR(FlashMsr, SavedLBar); | ||||
|       LBar[0] = 0x00000022; | ||||
|       LBar[1] = 0x0000FFF0 | LBAR_EN; | ||||
|       Write_MSR(FlashMsr, LBar); | ||||
|  | ||||
|       // Turn Canary circuit on | ||||
|       in_8(0x22); | ||||
|  | ||||
|       // Restore CS1 LBAR | ||||
|       Write_MSR(FlashMsr, SavedLBar); | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										53
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/header.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										53
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/header.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,53 @@ | ||||
| ;  | ||||
| ; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| ;  | ||||
| ; This library is free software; you can redistribute it and/or modify | ||||
| ; it under the terms of the GNU Lesser General Public License as | ||||
| ; published by the Free Software Foundation; either version 2.1 of the | ||||
| ; License, or (at your option) any later version. | ||||
| ;  | ||||
| ; This code is distributed in the hope that it will be useful, | ||||
| ; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| ; Lesser General Public License for more details. | ||||
| ;  | ||||
| ; You should have received a copy of the GNU Lesser General | ||||
| ; Public License along with this library; if not, write to the | ||||
| ; Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| ; Boston, MA 02111-1307 USA  | ||||
| ;  | ||||
|  | ||||
| ;*   Function:                                                         * | ||||
| ;*     This file contains the VSM header for the legacy VSM   | ||||
|  | ||||
|  | ||||
| .model tiny,c | ||||
| .586 | ||||
| .CODE | ||||
|  | ||||
|  include VSA2.INC | ||||
|  | ||||
| externdef edata:proc | ||||
| externdef _end:proc | ||||
| externdef VSM_msg_loop:proc | ||||
| public  VSM_Hdr | ||||
|  | ||||
|  | ||||
|  | ||||
| VSM_Hdr: | ||||
| 	dd	VSM_SIGNATURE		; VSM signature | ||||
| 	db	VSM_LEGACY		; VSM type | ||||
| 	db	0FFh			; Any CPU | ||||
| 	dw	0FFFFh			; Any Chipset | ||||
| 	dw	0106h			; VSM version | ||||
| 	dd	OFFSET edata		; Size of VSM module | ||||
| 	dw	OFFSET VSM_msg_loop	; EntryPoint | ||||
| 	dd	OFFSET _end		; DS Limit | ||||
| 	dw	0000h			; Requirements | ||||
| 	dw	VSA_VERSION		; VSA version | ||||
|  | ||||
| 	db	sizeof(VSM_Header) - ($-VSM_Hdr) dup (0) | ||||
|  | ||||
|  | ||||
| 	END | ||||
|  | ||||
							
								
								
									
										158
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/ide.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										158
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/ide.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,158 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //*	 Function:                                                          * | ||||
| //*     This file contains code for power-managing the ATA drives. | ||||
|  | ||||
|  | ||||
| #include "vsa2.h" | ||||
| #include "isa.h" | ||||
|  | ||||
| extern UCHAR pascal in_8(USHORT); | ||||
| extern void pascal out_8(USHORT, UCHAR); | ||||
|  | ||||
|  | ||||
| // NOTE: Win95 touches CD-ROMs every 4.2 seconds for AutoDetect | ||||
|  | ||||
| #define HDD0		1 | ||||
| #define HDD1		2 | ||||
| #define HDD2		4  | ||||
| #define HDD3		8 | ||||
|  | ||||
| #define IDE_BSY		0x80		// Status register | ||||
| #define IDE_RDY		0x40		// Status register | ||||
| #define IDE_MSK		IDE_BSY+IDE_RDY | ||||
|  | ||||
| #define	IDE_CMD_SPINDOWN			0xE0	// Spindown Command | ||||
| #define	IDE_CMD_SPINUP				0xE1	// Spinup   Command | ||||
| #define	IDE_CMD_CHECK_POWER_MODE	0xE5	// Get Power Management State Command | ||||
| #define IDE_CMD_SLEEP				0xE6 | ||||
|  | ||||
| UCHAR DrivesPresent = 0, DrvHd; | ||||
|  | ||||
|  | ||||
| //************************************************************************* | ||||
| // Issues specified command to one or more drive units | ||||
| //************************************************************************* | ||||
| void pascal IDE_Command(UCHAR DriveUnit, UCHAR Command) | ||||
| { UCHAR DriveSelect, Mask = 1; | ||||
|   USHORT IO_Port; | ||||
|   ULONG Timeout;  | ||||
|  | ||||
|   // Only spindown drives that are present | ||||
|   DriveUnit &= DrivesPresent; | ||||
|  | ||||
|   while (DriveUnit) { | ||||
|  | ||||
|     // Is drive present ? | ||||
|     if (DriveUnit & Mask) { | ||||
|  | ||||
|       // Yes, determine I/O port | ||||
|       IO_Port = PRIMARY_IDE; | ||||
|       if (Mask & (HDD2+HDD3)) { | ||||
|         IO_Port = SECONDARY_IDE; | ||||
|       } | ||||
|  | ||||
|       // Determine master/slave | ||||
|       DriveSelect = 0xA0;					// Master drive | ||||
|       if (Mask & (HDD1+HDD3)) { | ||||
|         DriveSelect = 0xB0;					// Slave drive | ||||
|       } | ||||
|  | ||||
|       // Wait for IDE channel READY | ||||
|       for (Timeout=0xFFFFF; Timeout; Timeout--) { | ||||
|         if ((IDE_MSK & in_8(IO_Port+1)) == IDE_RDY) | ||||
|           break; | ||||
|       } | ||||
|  | ||||
|       DrvHd = in_8(IO_Port);     	 		// Save Drive/Head register | ||||
|  | ||||
|       out_8(IO_Port, DriveSelect);			// Select drive to spin down | ||||
|       out_8(IO_Port+1, Command);			// Issue command to the the drive | ||||
|  | ||||
| 	  for (Timeout=0xFFFFF; Timeout; Timeout--) { | ||||
| 		if (!(in_8(IO_Port+1) & IDE_BSY)) | ||||
| 			break; | ||||
| 	  } | ||||
|  | ||||
| 	  in_8(IO_Port+1);						// Clear IRQ | ||||
|  | ||||
|       DriveUnit &= ~Mask; | ||||
|     } | ||||
|  | ||||
|     // Next drive | ||||
|     Mask <<= 1; | ||||
|   } | ||||
| } | ||||
|  | ||||
| //************************************************************************* | ||||
| // Spins down specified drive(s) | ||||
| //************************************************************************* | ||||
| void pascal SpinDownHardDrive(UCHAR DriveUnit) | ||||
| { | ||||
|   IDE_Command(DriveUnit, IDE_CMD_SPINDOWN); | ||||
| } | ||||
|  | ||||
|  | ||||
| //************************************************************************* | ||||
| // Puts drive(s) into sleep mode | ||||
| //************************************************************************* | ||||
| void pascal DriveSleep(UCHAR DriveUnit) | ||||
| { | ||||
| //  IDE_Command(DriveUnit, IDE_CMD_SLEEP); | ||||
| } | ||||
|  | ||||
| //************************************************************************* | ||||
| // Determines what hard drives are present | ||||
| // Input:  I/O address of IDE Drive/Head register | ||||
| //************************************************************************* | ||||
| UCHAR Check_IDE_Channel(USHORT IDE_DrvHd) | ||||
| { UCHAR HDD_Status, DrivesPresent=0; | ||||
|  | ||||
|   DrvHd = in_8(IDE_DrvHd);					// Save Drive/Head register | ||||
|  | ||||
|   out_8(IDE_DrvHd, (UCHAR)(DrvHd & ~0x10));	// Select master drive | ||||
|   HDD_Status = in_8(IDE_DrvHd); | ||||
|   if (in_8(IDE_DrvHd+1) == 0x50) {			// Is drive present ? | ||||
|     DrivesPresent |= HDD0; | ||||
|  | ||||
|     out_8(IDE_DrvHd, (UCHAR)(DrvHd | 0x10));	// Select slave drive | ||||
|     HDD_Status = in_8(IDE_DrvHd); | ||||
|     if (in_8(IDE_DrvHd+1) == 0x50) {			// Is drive present ? | ||||
|       DrivesPresent |= HDD1; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Restore Drive/Head register | ||||
|   out_8(IDE_DrvHd, DrvHd); | ||||
|   return DrivesPresent; | ||||
| } | ||||
|  | ||||
|  | ||||
| //************************************************************************* | ||||
| // Determines what hard drives are present | ||||
| // Input:  I/O address of IDE Drive/Head register | ||||
| //************************************************************************* | ||||
| UCHAR GetDrivesPresent(void) | ||||
| { | ||||
|   DrivesPresent  = Check_IDE_Channel(PRIMARY_IDE); | ||||
|   DrivesPresent |= Check_IDE_Channel(SECONDARY_IDE) << 2; | ||||
|  | ||||
|   return DrivesPresent; | ||||
| } | ||||
							
								
								
									
										83
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/init.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										83
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/init.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,83 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //***************************************************************************** | ||||
| //*     This file performs Legacy VSM initialization.  | ||||
| //***************************************************************************** | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| #include "vsa2.h" | ||||
| #include "chipset.h" | ||||
| #include "sysmgr.h" | ||||
| #include "vr.h" | ||||
|  | ||||
|  | ||||
|  | ||||
| // External variables: | ||||
| extern Hardware SystemInfo; | ||||
|  | ||||
| // Function prototypes: | ||||
| extern void pascal out_8(USHORT, UCHAR); | ||||
| extern void CS5536_Early_Init(void); | ||||
| extern void CS5536_Late_Init(void); | ||||
| extern void Init_OHCI_SWAPSiF(UCHAR); | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Performs early initialization | ||||
| //*********************************************************************** | ||||
| void Legacy_Early_Init(void) | ||||
| { | ||||
|  | ||||
|   // Register for VRC_SYSINFO virtual registers | ||||
|   SYS_REGISTER_EVENT(EVENT_VIRTUAL_REGISTER, VRC_SYSINFO,  0, NORMAL_PRIORITY); | ||||
|  | ||||
|  | ||||
|   switch (SystemInfo.Chipset_ID) { | ||||
|  | ||||
|     case DEVICE_ID_5536: | ||||
|       CS5536_Early_Init(); | ||||
|       break; | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Performs End-of-POST initialization | ||||
| //*********************************************************************** | ||||
| void Legacy_Late_Init(void) | ||||
| { | ||||
|  | ||||
|   switch (SystemInfo.Chipset_ID) { | ||||
|  | ||||
|     case DEVICE_ID_5536: | ||||
|       CS5536_Late_Init(); | ||||
|       break; | ||||
|   } | ||||
|  | ||||
|   // Initialize A20 to '1MB wrap' | ||||
|   // SDG - removed for OLPC | ||||
|   // out_8(0x92, 0); | ||||
|              | ||||
| } | ||||
							
								
								
									
										92
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/legacy.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										92
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/legacy.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,92 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //*  Function:                                                          * | ||||
| //*     This file implements miscellaneous VSA functionality:           * | ||||
| //*                                                                     * | ||||
| //*     All chipsets:                                                   * | ||||
| //*       1) SYSINFO virtual registers                                  * | ||||
| //*                                                                     * | ||||
| //*     CS5536 :                                                        * | ||||
| //*       1) Emulation of CS5530 PCI interrupt steering registers.      * | ||||
| //*       2) Flash-IDE switching                                        * | ||||
| //*       3) Power management                                           *  | ||||
|  | ||||
|  | ||||
| #include "vsa2.h" | ||||
| #include "chipset.h" | ||||
| #include "protos.h" | ||||
|  | ||||
| // Function prototypes | ||||
| extern void Legacy_Early_Init(void); | ||||
| extern void Legacy_Late_Init(void); | ||||
| extern void Handle_Events(ULONG *); | ||||
|  | ||||
|  | ||||
| // Local variables | ||||
| Hardware SystemInfo; | ||||
| ULONG ChipsetBase; | ||||
| ULONG Param[MAX_MSG_PARAM]; | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Message handler for the Legacy VSM | ||||
| //*********************************************************************** | ||||
| void VSM_msg_loop() | ||||
| { MSG Msg; | ||||
|  | ||||
|   // Get information about the system I'm executing on. | ||||
|   SYS_GET_SYSTEM_INFO(&SystemInfo); | ||||
|   ChipsetBase = SystemInfo.Chipset_Base; | ||||
|  | ||||
|   // | ||||
|   // Message Handling Loop | ||||
|   // | ||||
|   do { | ||||
|  | ||||
|     // Get the next message | ||||
|     Msg = SYS_GET_NEXT_MSG(&Param); | ||||
|  | ||||
|     switch (Msg) { | ||||
|  | ||||
|       case MSG_INITIALIZE: | ||||
|         switch (Param[0]) { | ||||
|           case EARLY_INIT: | ||||
|             Legacy_Early_Init(); | ||||
|             break; | ||||
|  | ||||
|           case END_OF_POST_INIT: | ||||
|             Legacy_Late_Init(); | ||||
|             break; | ||||
|         } | ||||
|         break; | ||||
|  | ||||
|       case MSG_EVENT: | ||||
|         Handle_Events(Param); | ||||
|         break; | ||||
|  | ||||
|       case MSG_SET_POWER_MODE: | ||||
|       case MSG_SET_POWER_STATE: | ||||
|       case MSG_SAVE_STATE: | ||||
|       case MSG_RESTORE_STATE: | ||||
|         break; | ||||
|     } // end switch(Msg) | ||||
|   } while (1); | ||||
| } | ||||
							
								
								
									
										37
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/legacy.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										37
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/legacy.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| #define SYS_DMA_DRIVER	0x5006 | ||||
| #define MASTER_IDE		0x8000 | ||||
|  | ||||
|  | ||||
|  | ||||
| // Default GPIOs for PCI interrupts on the Hawk reference design | ||||
| #define INTA_PIN  		0 | ||||
| #define INTB_PIN  		7 | ||||
| #define INTC_PIN  		12 | ||||
| #define INTD_PIN  		13 | ||||
|  | ||||
|  | ||||
|  | ||||
| #define USBF_PERIOD		2000		// 2 seconds | ||||
| #define USBF_HANDLE		0x3333 | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										165
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/makefile
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										165
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/makefile
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,165 @@ | ||||
| # | ||||
| # Copyright (c) 2006 Advanced Micro Devices,Inc. ("AMD"). | ||||
| # | ||||
| # This library is free software; you can redistribute it and/or modify | ||||
| # it under the terms of the GNU Lesser General Public License as | ||||
| # published by the Free Software Foundation; either version 2.1 of the | ||||
| # License, or (at your option) any later version. | ||||
| # | ||||
| # This code is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| # Lesser General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU Lesser General | ||||
| # Public License along with this library; if not, write to the | ||||
| # Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| # Boston, MA 02111-1307 USA  | ||||
| # | ||||
| # | ||||
| ###################################################################### | ||||
| # | ||||
| #                               Init variables | ||||
| # | ||||
| ###################################################################### | ||||
| .SUFFIXES: .asm .c .h .inc .map .obj .mac | ||||
|  | ||||
| !ifndef VSA2ROOT | ||||
| VSA2ROOT        = .. | ||||
| !endif | ||||
|  | ||||
| BUILD_DIR       = $(VSA2ROOT)\build | ||||
| OBJECT		= obj | ||||
| !include $(BUILD_DIR)\setvars.mak | ||||
|  | ||||
| INCLUDE		= $(OBJECT);$(INCLUDE) | ||||
|  | ||||
| VSMNAME	= legacy | ||||
|  | ||||
|  | ||||
| ###################################################################### | ||||
| # | ||||
| #                               Build Macros | ||||
| # | ||||
| ###################################################################### | ||||
|  | ||||
| LEGACY_ASM_OBJS = \ | ||||
| 	$(OBJECT)\header.obj \ | ||||
| 	$(OBJECT)\msr.obj \ | ||||
|  | ||||
| LEGACY_C_OBJS	= \ | ||||
| 	$(OBJECT)\legacy.obj \ | ||||
| 	$(OBJECT)\init.obj \ | ||||
| 	$(OBJECT)\events.obj \ | ||||
| 	$(OBJECT)\flash.obj \ | ||||
| 	$(OBJECT)\cs5536.obj \ | ||||
| 	$(OBJECT)\ide.obj \ | ||||
| 	$(OBJECT)\blockio.obj \ | ||||
| 	$(OBJECT)\uarts.obj \ | ||||
| 	$(OBJECT)\virtregs.obj \ | ||||
| 	$(OBJECT)\swapsif.obj \ | ||||
| 	$(OBJECT)\sysinfo.obj \ | ||||
|  | ||||
| LEGACY_LNK_OBJS	= \ | ||||
| 	header.obj  \ | ||||
| 	legacy.obj \ | ||||
| 	msr.obj \ | ||||
| 	init.obj \ | ||||
| 	events.obj \ | ||||
| 	flash.obj \ | ||||
| 	cs5536.obj \ | ||||
| 	ide.obj \ | ||||
| 	blockio.obj \ | ||||
| 	uarts.obj \ | ||||
| 	virtregs.obj \ | ||||
| 	swapsif.obj \ | ||||
| 	sysinfo.obj \ | ||||
|  | ||||
|  | ||||
| LEGACY_OBJS = $(LEGACY_ASM_OBJS) $(LEGACY_C_OBJS)  | ||||
| LEGACY_VSM	= legacy.vsm | ||||
|  | ||||
| ####################################################################### | ||||
| # | ||||
| #                               Targets | ||||
| # | ||||
| ####################################################################### | ||||
|  | ||||
| all: $(OBJECT) setenv legacy.vsm | ||||
| 	$(COPY) $(LEGACY_VSM) $(BUILDOBJ) | ||||
|  | ||||
| legacy.vsm: $(LEGACY_OBJS) | ||||
|    cd $(OBJECT) | ||||
| 	$(LN) $(LOPTS_VSM) $(LEGACY_LNK_OBJS), ..\$(LEGACY_VSM),, ..\..\build\obj\$(TOOL_LIB); | ||||
| 	cd .. | ||||
|  | ||||
| #This and only this clean target must exist as it is called by cleanall | ||||
| #cleanall and cleanlocal are defined in rules.mak | ||||
|  | ||||
| clean: cleanlocal cleanlib | ||||
|  | ||||
| $(OBJECT): | ||||
| 	-@md $(OBJECT) | ||||
|  | ||||
| ####################################################################### | ||||
| # | ||||
| #                               Dependencies | ||||
| # | ||||
| ####################################################################### | ||||
|  | ||||
| $(LEGACY_ASM_OBJS): $(MAKEDIR)\makefile \ | ||||
| 		$(OBJECT)\sysmgr.inc \ | ||||
| 		$(OBJECT)\smimac.mac \ | ||||
| 		$(OBJECT)\vsa2.inc \ | ||||
| 		$(OBJECT)\isa.inc \ | ||||
| 		$(OBJECT)\chipset.inc \ | ||||
| 		$(OBJECT)\vr.inc \ | ||||
| 		$(OBJECT)\pci.inc \ | ||||
| 		$(OBJECT)\acpi.inc \ | ||||
| 		$(OBJECT)\gx2.inc \ | ||||
| 		$(OBJECT)\cs5536.inc \ | ||||
| 		$(OBJECT)\pci.inc \ | ||||
| 		$(OBJECT)\mdd.inc \ | ||||
| 		 | ||||
| $(LEGACY_C_OBJS): $(MAKEDIR)\makefile \ | ||||
| 		$(BUILD_DIR)\obj\$(TOOL_LIB) \ | ||||
| 		$(OBJECT)\sysmgr.h \ | ||||
| 		$(OBJECT)\vsa2.h \ | ||||
| 		$(OBJECT)\isa.h \ | ||||
| 		$(OBJECT)\chipset.h  \ | ||||
| 		$(OBJECT)\vr.h \ | ||||
| 		$(OBJECT)\pci.h \ | ||||
| 		$(OBJECT)\legacy.h \ | ||||
| 		$(OBJECT)\mapper.h \ | ||||
| 		$(OBJECT)\protos.h \ | ||||
| 		$(OBJECT)\mdd.h \ | ||||
| 		$(OBJECT)\acpi.h \ | ||||
| 		$(OBJECT)\gx2.h \ | ||||
| 		$(OBJECT)\cs5536.h \ | ||||
| 		 | ||||
| ###################################################################### | ||||
| # | ||||
| #				Common Targets | ||||
| # | ||||
| ###################################################################### | ||||
| # include common targets and inference rules | ||||
| !include $(BUILD_DIR)\rules.mak | ||||
|  | ||||
| ###################################################################### | ||||
| # | ||||
| #				Inference Rules | ||||
| # | ||||
| ###################################################################### | ||||
| # Override common inference rules here | ||||
|  | ||||
| {$(INC_DIR)}.h{$(OBJECT)}.inc: | ||||
| 	$(H2) /Fa$(OBJECT)\$(@F) /nologo /Zni /C $< | ||||
|  | ||||
| {$(INC_DIR)\$(CPU)}.h{$(OBJECT)}.inc: | ||||
| 	$(H2) /Fa$(OBJECT)\$(@F) /nologo /Zni /C $< | ||||
|  | ||||
| {$(SYSMGR_SRC)}.h{$(OBJECT)}.inc: | ||||
| 	$(H2) /Fa$(OBJECT)\$(@F) /nologo /Zns /C $< | ||||
|  | ||||
| {$(SYSMGR_SRC)\$(CPU)}.h{$(OBJECT)}.inc: | ||||
| 	$(H2) /Fa$(OBJECT)\$(@F) /nologo /Zns /C $< | ||||
							
								
								
									
										97
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/msr.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										97
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/msr.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,97 @@ | ||||
| ;  | ||||
| ; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| ;  | ||||
| ; This library is free software; you can redistribute it and/or modify | ||||
| ; it under the terms of the GNU Lesser General Public License as | ||||
| ; published by the Free Software Foundation; either version 2.1 of the | ||||
| ; License, or (at your option) any later version. | ||||
| ;  | ||||
| ; This code is distributed in the hope that it will be useful, | ||||
| ; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| ; Lesser General Public License for more details. | ||||
| ;  | ||||
| ; You should have received a copy of the GNU Lesser General | ||||
| ; Public License along with this library; if not, write to the | ||||
| ; Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| ; Boston, MA 02111-1307 USA  | ||||
| ;  | ||||
|  | ||||
| .model tiny,c | ||||
| .586p | ||||
| .CODE | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Returns the low DWORD of an MSR. | ||||
| ; Usage: LowMsrValue = Read_MSR_LO(Msr_Address); | ||||
| ;*********************************************************************** | ||||
| Read_MSR_LO proc pascal \ | ||||
| 	Msr:	dword | ||||
|  | ||||
| 	mov	ecx, [Msr] | ||||
| 	rdmsr | ||||
| 	mov	edx, eax | ||||
| 	shr	edx, 16 | ||||
| 	ret | ||||
|  | ||||
| Read_MSR_LO endp | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Writes the low DWORD of an MSR. The high DWORD is preserved. | ||||
| ; Usage: Write_MSR_LO(Msr_Address, Data); | ||||
| ;*********************************************************************** | ||||
| Write_MSR_LO proc pascal \ | ||||
| 	Msr:	dword, \ | ||||
|         Data:   dword	 | ||||
| 	 | ||||
| 	mov	ecx, [Msr] | ||||
| 	rdmsr		; Get high 32 bits | ||||
| 	mov	eax, [Data] | ||||
| 	wrmsr | ||||
| 	ret | ||||
|  | ||||
| Write_MSR_LO endp | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Returns an MSR value in a buffer. | ||||
| ; Usage: Read_MSR(ULONG Msr, ULONG * Buffer); | ||||
| ;*********************************************************************** | ||||
| Read_MSR proc pascal \ | ||||
| 	Msr:	dword, \ | ||||
| 	Buffer: PTR | ||||
| 	 | ||||
| 	mov	ecx, [Msr] | ||||
| 	rdmsr | ||||
| 	 | ||||
| 	mov	bx, [Buffer] | ||||
| 	mov	[bx+0], eax | ||||
| 	mov	[bx+4], edx | ||||
| 	ret | ||||
|  | ||||
| Read_MSR endp | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Writes an MSR. | ||||
| ; Usage: Write_MSR(ULONG Msr, ULONG * Buffer); | ||||
| ;*********************************************************************** | ||||
| Write_MSR proc pascal \ | ||||
| 	Msr:	dword, \ | ||||
| 	Buffer: PTR | ||||
| 	 | ||||
| 	mov	ecx, [Msr] | ||||
| 	mov	bx, [Buffer] | ||||
| 	mov	eax, [bx+0] | ||||
| 	mov	edx, [bx+4] | ||||
| 	wrmsr | ||||
| 	ret | ||||
|  | ||||
| Write_MSR endp | ||||
|  | ||||
|  | ||||
| 	END | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										130
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/swapsif.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										130
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/swapsif.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,130 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //****************************************************************************** | ||||
| //*     This file contains SWAPSiFs | ||||
| //****************************************************************************** | ||||
|  | ||||
|  | ||||
|  | ||||
| #include "vsa2.h" | ||||
| #include "protos.h" | ||||
| #include "chipset.h" | ||||
| #include "legacy.h" | ||||
| #include "pci.h" | ||||
|  | ||||
|  | ||||
| // External variables | ||||
| extern Hardware SystemInfo; | ||||
|  | ||||
| // Local variables | ||||
| ULONG OHCI_Address[2]; | ||||
| UCHAR WinCE_Flag = 1; | ||||
|  | ||||
|  | ||||
| //***************************************************************** | ||||
| // Fixes 118.438 - OHCI May Not Recognize Device Attach/Removal | ||||
| //***************************************************************** | ||||
| void pascal OHCI_SWAPSiF(UCHAR Flag) | ||||
| { PRIORITY Priority = 0; | ||||
|   static PRIORITY LastPriority = 0x5555; | ||||
|  | ||||
|   switch (SystemInfo.Chipset_ID) { | ||||
|     case DEVICE_ID_5536: | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       if (Flag == 0) { | ||||
|         Priority = UNREGISTER_PRIORITY; | ||||
|       } | ||||
|       if (Priority != LastPriority) { | ||||
|         LastPriority = Priority; | ||||
|         SYS_REGISTER_EVENT(EVENT_TIMER, USBF_PERIOD, USBF_HANDLE, Priority); | ||||
|       } | ||||
|       break; | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
| #define HcControl 0x0004 | ||||
|   #define HCFS				0x000000C0L | ||||
|   #define USB_RESET			0x00000000L | ||||
|   #define USB_RESUME		0x00000040L | ||||
|   #define USB_OPERATIONAL	0x00000080L | ||||
|   #define USB_SUSPEND	 	0x000000C0L | ||||
|   #define IR				0x00000100L | ||||
| #define HceControl 0x0100 | ||||
|  | ||||
| //*********************************************************************** | ||||
| void Do_OHCI_SWAPSif(void) | ||||
| { ULONG i, PCI_Addr, HC_Addr, OldValue; | ||||
|  | ||||
|   for (i=0; i<=1; i++) { | ||||
|  | ||||
|     // Get base of Host Controller's registers | ||||
|     HC_Addr = OHCI_Address[i]; | ||||
|  | ||||
|     // Ignore this tick if BAR is being sized | ||||
|     if (HC_Addr == 0xFFFFF000 || HC_Addr == 0x00000000) { | ||||
|       continue; | ||||
|     } | ||||
|  | ||||
|     // Check if Host Controller registers are accessible | ||||
|     PCI_Addr = 0x80007C00L + (i<<8); | ||||
|     if (READ_PCI_BYTE(PCI_Addr + COMMAND) & MEM_SPACE) { | ||||
|  | ||||
|       OldValue = READ_MEMORY(HC_Addr + HcControl); | ||||
|  | ||||
|       // WinCE doesn't perform a valid Ownership Change. | ||||
|       // It disables MIE then performs the Ownership Change request. | ||||
|       // This code detects that situation and turns emulation off. | ||||
|       // Otherwise, neither the USB keyboard or PS/2 keyboard works. | ||||
|       if ((i == 0) && (OldValue & IR) == 0 && WinCE_Flag) { | ||||
|         WinCE_Flag = 0;   // Only do this once | ||||
|         WRITE_MEMORY(HC_Addr + HceControl, 0x00); | ||||
|       } | ||||
|  | ||||
|       // Transition through Operational to clear possible attach/detach glitch | ||||
|       if ((OldValue & USB_SUSPEND) == USB_SUSPEND) { | ||||
|         WRITE_MEMORY(HC_Addr + HcControl, USB_OPERATIONAL); | ||||
|         WRITE_MEMORY(HC_Addr + HcControl, OldValue); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Initialization for the OHCI attach/detach hardware bug | ||||
| //*********************************************************************** | ||||
| void Init_OHCI_SWAPSiF(UCHAR InitStage) | ||||
| { | ||||
|   switch (InitStage) { | ||||
|     case EARLY_INIT: | ||||
|       // Trap writes to SB F4 & F5 BAR0 in order keep current OHCI BAR values | ||||
|       SYS_REGISTER_EVENT(EVENT_PCI_TRAP, 0x7C10, WRITES_ONLY | 0x100, 0); | ||||
|       break; | ||||
|  | ||||
|     case END_OF_POST_INIT: | ||||
|       // Turn on the timer | ||||
|       OHCI_SWAPSiF(1); | ||||
|       break; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										78
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/sysinfo.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										78
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/sysinfo.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,78 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //*	  Function:                                                         * | ||||
| //*     This file implementes the SYSINFO virtual registers.   | ||||
|  | ||||
| #include "vsa2.h" | ||||
| #include "vr.h" | ||||
|  | ||||
| void pascal Hex_8(UCHAR); | ||||
| void pascal Hex_16(USHORT); | ||||
| void pascal Hex_32(ULONG); | ||||
|  | ||||
|  | ||||
| // Local variables | ||||
| extern Hardware SystemInfo; | ||||
|  | ||||
|  | ||||
| void Handle_SysInfo_VR(UCHAR i) | ||||
| { USHORT Data; | ||||
|  | ||||
|  | ||||
|   switch (i) { | ||||
|     case VRC_SI_VERSION: | ||||
|       Data = 0x100;				// Version 1.0 | ||||
|       break; | ||||
|  | ||||
|     case VRC_SI_CPU_MHZ: | ||||
|       Data = SystemInfo.CPU_MHz; | ||||
|       break; | ||||
|  | ||||
|     case VRC_SI_CHIPSET_BASE_LOW: | ||||
|       Data = (USHORT) SystemInfo.Chipset_Base; | ||||
|       break; | ||||
|  | ||||
|     case VRC_SI_CHIPSET_BASE_HI: | ||||
|       Data = (USHORT) (SystemInfo.Chipset_Base >> 16); | ||||
|       break; | ||||
|  | ||||
|     case VRC_SI_CHIPSET_ID: | ||||
|       Data = SystemInfo.Chipset_ID; | ||||
|       break; | ||||
|  | ||||
|     case VRC_SI_CHIPSET_REV: | ||||
|       Data = SystemInfo.Chipset_Rev; | ||||
|       break; | ||||
|  | ||||
|     case VRC_SI_CPU_ID: | ||||
|       Data = SystemInfo.CPU_ID; | ||||
|       break; | ||||
|  | ||||
|     case VRC_SI_CPU_REV: | ||||
|       Data = SystemInfo.CPU_Revision; | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       Data = 0xFFFF; | ||||
|       break; | ||||
|   } | ||||
|  | ||||
|   SET_AX(Data); | ||||
| } | ||||
							
								
								
									
										210
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/uarts.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										210
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/uarts.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,210 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
| //*	  Function:                                                         * | ||||
| //*     This file contains routines specific to the CS5536 UARTs.  | ||||
|  | ||||
| #include "vsa2.h" | ||||
| #include "vr.h" | ||||
| #include "mdd.h" | ||||
| #include "protos.h" | ||||
|  | ||||
|  | ||||
| // Function prototypes: | ||||
| void Handle_5536_UART(UCHAR, UCHAR, USHORT); | ||||
| USHORT Get_5536_UART(USHORT); | ||||
| void Prog_5536_UART(USHORT, USHORT); | ||||
|  | ||||
| // External variables: | ||||
| extern ULONG MDD_Base; | ||||
| extern USHORT gpio_base; | ||||
|  | ||||
|  | ||||
| // 5536 implements two UART's. The resources for both are controlled | ||||
| // by MDD MSR_LEG_IO, MSR_IRQM_YHIGH. | ||||
| // IRQ Enable, Clock freeze and soft reset controlled by MSR_UARTx_CONF | ||||
| // | ||||
| // One Virtual Register is implemented for each UART. | ||||
| // bit15 = 1 Soft-Reset | ||||
| // bits[14:13] = unused | ||||
| // bit12 = 1 UART GPIO's have been setup by BIOS, RO bit | ||||
| // bit11 = 1 enable UART I/O space extended register banks | ||||
| // bit10 = 1 enable test mode | ||||
| // bit9 = 1 Freeze device clocks, IRQ still enabled | ||||
| // bit8 = 1 enable interrupt & functionality, doesn't affect I/O | ||||
| // bits[7:4] = IRQ number | ||||
| // bit3 = unused | ||||
| // bit2 = 1 I/O decode enabled | ||||
| // bits[1:0] = I/O location | ||||
| // | ||||
| void Handle_5536_UART(UCHAR vrIndex, UCHAR wFlag, USHORT wData) | ||||
| { | ||||
| 	if (wFlag) {	// write | ||||
| 		Prog_5536_UART(vrIndex, wData); | ||||
| 	} else { | ||||
| 		SYS_RETURN_RESULT((ULONG)Get_5536_UART(vrIndex)); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| USHORT Get_5536_UART(USHORT vri) | ||||
| { | ||||
| 	ULONG d; | ||||
| 	USHORT u; | ||||
| 	 | ||||
| 	u = 0; | ||||
| 		 | ||||
| 	(USHORT)MDD_Base = MSR_LEG_IO; | ||||
| 	d = Read_MSR_LO(MDD_Base); | ||||
| 	switch (vri) { | ||||
| 		case VRC_CS_UART1: | ||||
| 			d >>= UART1_SHIFT; | ||||
| 			break; | ||||
|  | ||||
| 		case VRC_CS_UART2: | ||||
| 			d >>= UART2_SHIFT; | ||||
| 			break; | ||||
|  | ||||
| 		default: | ||||
| 			return 0; | ||||
| 	} | ||||
|  | ||||
| 	u = (USHORT)d & UART_MASK; | ||||
|  | ||||
| 	// get the IRQ number | ||||
| 	(USHORT)MDD_Base = MSR_IRQM_YHIGH; | ||||
| 	d = Read_MSR_LO(MDD_Base); | ||||
| 	if (vri == VRC_CS_UART1) { | ||||
| 		d >>= 20; | ||||
| 	} else { | ||||
| 		d >>= 24; | ||||
| 	} | ||||
| 	u |= ((USHORT)d & 0x00F0); | ||||
|  | ||||
| 	// fill in the other flags from MSR_UARTx_CONF | ||||
| 	if (vri == VRC_CS_UART1) { | ||||
| 		(USHORT)MDD_Base = MSR_UART1_CONF; | ||||
| 	} else { | ||||
| 		(USHORT)MDD_Base = MSR_UART2_CONF; | ||||
| 	} | ||||
| 	d = Read_MSR_LO(MDD_Base); | ||||
| 	// MSR bit0 = soft-reset -> bit15 | ||||
| 	// MSR bit1 = deven -> bit8 | ||||
| 	// MSR bit2 = freeze -> bit9 | ||||
| 	// MSR bit3 = test mode -> bit10 | ||||
| 	// MSR bit4 = upper banks -> bit11 | ||||
| 	if ((USHORT)d & 0x0001) { | ||||
| 		u |= 0x8000; | ||||
| 	} | ||||
| 	d <<= 7; | ||||
| 	u |= ((USHORT)d & 0x0F00); | ||||
|  | ||||
| 	// check if GPIO's for this UART have been setup | ||||
| 	// This is used as an indicator the UART is 'hidden' from OS | ||||
| 	d = in_32(gpio_base + GPIO_IN_AUX1_SELECT); | ||||
| 	if (vri == VRC_CS_UART1) { | ||||
| 		// UART1 GPIO9 should be IN_AUX | ||||
| 		if (d & 0x0200L) { | ||||
| 			u |= 0x1000;	// set bit12 | ||||
| 		} | ||||
| 	} else { | ||||
| 		// UART2 GPIO3 should be IN_AUX | ||||
| 		if (d & 0x0008L) { | ||||
| 			u |= 0x1000;	// set bit12 | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return u;	 | ||||
| } | ||||
|  | ||||
|  | ||||
| void Prog_5536_UART(USHORT vri, USHORT vrval) | ||||
| { | ||||
| 	ULONG d, r; | ||||
| 	USHORT curval, uartmsr, shift, irqshift; | ||||
|  | ||||
| 	r = 0L; | ||||
|  | ||||
| 	// clear reserved/unused bits | ||||
| 	vrval &= 0x8FF7; | ||||
|  | ||||
| 	switch (vri) { | ||||
| 		case VRC_CS_UART1: | ||||
| 			uartmsr = MSR_UART1_CONF; | ||||
| 			shift = UART1_SHIFT; | ||||
| 			irqshift = 24; | ||||
| 			break; | ||||
|  | ||||
| 		case VRC_CS_UART2: | ||||
| 			uartmsr = MSR_UART2_CONF; | ||||
| 			shift = UART2_SHIFT; | ||||
| 			irqshift = 28; | ||||
| 			break; | ||||
|  | ||||
| 		default: | ||||
| 			return; | ||||
| 	} | ||||
|  | ||||
| 	// get current settings | ||||
| 	curval = Get_5536_UART(vri); | ||||
|  | ||||
| 	// change? | ||||
| 	if (curval ^ vrval) {	// Yes | ||||
| 		// I/O change? | ||||
| 		if ((curval & 0x0007) ^ (vrval & 0x0007)) { | ||||
| 			// Program I/O | ||||
| 			(USHORT)MDD_Base = MSR_LEG_IO; | ||||
| 			d = Read_MSR_LO(MDD_Base); | ||||
| 			// don't trust C compiler when expanding a 'define' to | ||||
| 			// long unless 'define' is a long constant. | ||||
| 			(USHORT)r = UART_MASK; | ||||
| 			d &= ~(r << shift); | ||||
| 			d |= ((ULONG)(vrval & 0x0007)) << shift; | ||||
| 			Write_MSR_LO(MDD_Base, d); | ||||
| 		} | ||||
|  | ||||
| 		// IRQ change? | ||||
| 		if ((curval & 0x00F0) ^ (vrval & 0x00F0)) {				  | ||||
| 			// Program IRQ | ||||
| 			(USHORT)MDD_Base = MSR_IRQM_YHIGH; | ||||
| 			d = Read_MSR_LO(MDD_Base); | ||||
| 			d &= ~(0x0FL << irqshift); | ||||
| 			d |= ((ULONG)(vrval & 0x00F0)) << (irqshift-4); | ||||
| 			Write_MSR_LO(MDD_Base, d); | ||||
| 		} | ||||
|  | ||||
| 		// control bit(s) changed? | ||||
| 		if ((curval & 0x8F00) ^ (vrval & 0x8F00)) { | ||||
| 			// Program control bits in MSR_UARTx_CONF | ||||
| 			// bits[11:8] of vr map to bits[4:1] of MSR | ||||
| 			// bit[15] of vr maps to bit[0] of MSR | ||||
| 			(USHORT)MDD_Base = uartmsr; | ||||
| 			d = Read_MSR_LO(MDD_Base); | ||||
| 			// clear bits[4:0] | ||||
| 			d &= ~(0x1FL); | ||||
| 			(USHORT)d |= ((vrval & 0x0F00) >> 7); | ||||
| 			if (vrval & 0x8000) { | ||||
| 				(USHORT)d |= 0x0001; | ||||
| 			} | ||||
| 			Write_MSR_LO(MDD_Base, d); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										131
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/virtregs.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										131
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/legacy/virtregs.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,131 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //*   Function:                                                         * | ||||
| //*     This file handles virtual registers.  | ||||
|  | ||||
| #include "vsa2.h" | ||||
| #include "chipset.h" | ||||
| #include "vr.h" | ||||
| #include "protos.h" | ||||
| #include "acpi.h" | ||||
|  | ||||
| extern void Handle_Misc_VR(UCHAR, USHORT); | ||||
| extern void Handle_SysInfo_VR(UCHAR); | ||||
| extern void Handle_5536_UART(UCHAR, UCHAR, USHORT); | ||||
|  | ||||
| extern USHORT PCI_Int_AB, PCI_Int_CD; | ||||
| extern USHORT DiskTimeout, SerialTimeout, ParallelTimeout, FloppyTimeout; | ||||
| USHORT WatchDogDelay; | ||||
|  | ||||
| void Handle_VirtualRegs(UCHAR Class, UCHAR Index, UCHAR WrFlag, USHORT Data) | ||||
| { | ||||
|   ULONG Param[MAX_MSG_PARAM];  // Select on virtual register class | ||||
|   switch (Class) { | ||||
|  | ||||
|     case VRC_MISCELLANEOUS: | ||||
|       if (WrFlag) { | ||||
|         if (Index == WATCHDOG) { | ||||
|           static ULONG WatchDogKey=0; | ||||
|           ULONG Key; | ||||
|  | ||||
|           Key = GET_REGISTER(R_ECX); | ||||
|           if (WatchDogKey) { | ||||
|             // The key has already been set...check it | ||||
|             if (WatchDogKey != Key) { | ||||
| /*MEJ              // Broadcast to all VSM's | ||||
|               Param[0] = S5_STATE; | ||||
|               Param[1] = CLASS_ALL; | ||||
|               SYS_BROADCAST_MSG(MSG_SET_POWER_STATE, &Param[0], VSM_ANY); | ||||
| */ | ||||
|             } | ||||
|           } else { | ||||
|             // Set the key (only once) | ||||
|             WatchDogKey = Key; | ||||
|           } | ||||
|           WatchDogDelay = Data; | ||||
|           SYS_REGISTER_EVENT(EVENT_TIMER, WatchDogDelay*1000L, ONE_SHOT, 0); | ||||
|           break; | ||||
|         } | ||||
|         Handle_Misc_VR(Index, Data); | ||||
|       } else { | ||||
|         switch (Index) { | ||||
|           case PCI_INT_AB: | ||||
|             SET_AX(PCI_Int_AB); | ||||
|             break; | ||||
|  | ||||
|           case PCI_INT_CD: | ||||
|             SET_AX(PCI_Int_CD); | ||||
|             break; | ||||
|  | ||||
|           case WATCHDOG: | ||||
|             SET_AX(WatchDogDelay); | ||||
|             break; | ||||
|         } | ||||
|       } | ||||
|       break; | ||||
|  | ||||
|     case VRC_PM: | ||||
|       // Ignore READs | ||||
|       if (WrFlag) { | ||||
| /*MEJ        switch (Index) { | ||||
|           case DISK_TIMEOUT: | ||||
|             DiskTimeout = Data; | ||||
|             break; | ||||
|  | ||||
|           case SERIAL_TIMEOUT: | ||||
|             SerialTimeout = Data; | ||||
|             break; | ||||
|  | ||||
|           case PARALLEL_TIMEOUT: | ||||
|             ParallelTimeout = Data; | ||||
|             break; | ||||
|  | ||||
|           case FLOPPY_TIMEOUT: | ||||
|             FloppyTimeout = Data; | ||||
|             break; | ||||
|         } | ||||
| */ | ||||
|       } | ||||
|       break; | ||||
|  | ||||
|     case VRC_SYSINFO: | ||||
|       if (!WrFlag) { | ||||
|         Handle_SysInfo_VR(Index); | ||||
|       } | ||||
|       break; | ||||
|  | ||||
|  | ||||
|     case VRC_CHIPSET: | ||||
|       switch (Index) { | ||||
|         case VRC_CS_UART1: | ||||
|         case VRC_CS_UART2: | ||||
|           Handle_5536_UART(Index, WrFlag, Data); | ||||
|           break; | ||||
|  | ||||
|       } | ||||
|       break; | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										194
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/decode.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										194
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/decode.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,194 @@ | ||||
| /* | ||||
| * Copyright (c) 2007-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA | ||||
| */ | ||||
| // This module decodes the SoftVG SMI sources. | ||||
|  | ||||
|  | ||||
| #include "lxvg.h" | ||||
| #include "vsa2.h" | ||||
| #include "vr.h" | ||||
| #include "pci.h" | ||||
|  | ||||
| extern void pascal out_8(USHORT, UCHAR); | ||||
| extern void pascal out_16(USHORT, USHORT); | ||||
| extern UCHAR pascal in_8(USHORT); | ||||
| extern USHORT pascal in_16(USHORT); | ||||
|  | ||||
| //--------------------------------------------------------------------------- | ||||
| // virtual_register_event | ||||
| // | ||||
| // This routine is called when LXVG receives a VRC_VG virtual register | ||||
| // access event. | ||||
| // | ||||
| //--------------------------------------------------------------------------- | ||||
|  | ||||
| void virtual_register_event(unsigned char reg, unsigned long rwFlag, unsigned long vrData) | ||||
| { | ||||
|  | ||||
| 	// Look for virtual register read case first | ||||
| 	if (!(rwFlag & SMM_VR_WRITE)) | ||||
| 	{ | ||||
| 		// Determine if we are initialized | ||||
| 		if (!(VGState & SF_SECONDARY)) | ||||
| 		{ | ||||
| 			SET_AX(0xFFFF); | ||||
| 		}else{ | ||||
| 			SET_AX(vReg[reg]); | ||||
| 		} | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	// If we get here, we know its a write, so handle the requests | ||||
| 	switch (reg) | ||||
| 	{ | ||||
| 		case VG_CONFIG: | ||||
| 			// We only need to initialize once! | ||||
| 			if (!(VGState & SF_SECONDARY)) | ||||
| 			{ | ||||
| 				// Initialize the secondary controller portion of the engine. | ||||
| 				lxvg_initialize((unsigned short)vrData); | ||||
|  | ||||
| 				// REGISTER PCI EVENTS - DO NOT ENABLE PCI EVENTS IF DISABLED. | ||||
|  | ||||
| 				if (VGState & SF_SECONDARY) | ||||
| 				{ | ||||
| 					// If we've initialized to the secondary state, we need to support | ||||
| 					// PCI config accesses.	 If we are disabled, the SysMgr will handle | ||||
| 					// the support.	 We may be initialized to the primary state, but the | ||||
| 					// minimum level is secondary. | ||||
| 					SYS_REGISTER_EVENT(EVENT_PCI_TRAP, vga_config_addr, 0xFF, NORMAL_PRIORITY); | ||||
| 				} | ||||
| 			} | ||||
| 			break; | ||||
|  | ||||
| 		default: | ||||
| 			break; | ||||
| 	} | ||||
|  | ||||
| 	// Finally, store the data... | ||||
| 	vReg[reg] = (unsigned short)vrData; | ||||
|  | ||||
| 	return; | ||||
| } | ||||
|  | ||||
| //--------------------------------------------------------------------------- | ||||
| // pci_trap_event | ||||
| // | ||||
| // This routine is called when the VSA2 system manager receives an SMI for | ||||
| // a PCI configuration cycle that we have registered for. | ||||
| // | ||||
| // The "flags" parameter indicates the size in bits [3:0] (0x1 = byte, | ||||
| // 0x3 = word, and 0xF = dword).  Bit 7 indicates a write. | ||||
| //--------------------------------------------------------------------------- | ||||
|  | ||||
| void pci_trap_event(unsigned long address, unsigned long flags, unsigned long data) | ||||
| { | ||||
| 	unsigned char reg = (unsigned char) address & 0x000000FF; | ||||
| 	unsigned char size = (unsigned char) flags & 0x0000000F; | ||||
| 	unsigned long pciSave; | ||||
|  | ||||
| 	if ((address & PCI_CONFIG_MASK) == vga_config_addr) | ||||
| 	{ | ||||
|  | ||||
| 		// CHECK IF PCI WRITE | ||||
| 		if (flags & PCI_TRAP_WRITE) | ||||
| 		{ | ||||
| 			// Handle the trapped register writes | ||||
| 			if (reg == PCI_CMD_REG) | ||||
| 			{ | ||||
| 				if ((unsigned char)data & PCI_MEM_SPACE) | ||||
| 					// Change the frame buffer base realated stuff. | ||||
| 					hw_fb_map_init(framebuffer_base); | ||||
| 			} | ||||
| 			else if ((reg >= BAR0) && (reg <= BAR4)) | ||||
| 			{ | ||||
| 				// NOTE: SysMgr now delivers DWORD aligned values with all reserved bits zeroed. | ||||
| 				if ((data < VGdata.pci_fb_mask) && (data != 0L)) | ||||
| 				{ | ||||
| 					// We have to assume that the changing agent won't put the framebuffer | ||||
| 					// on top of program memory.  The check for zero above was added when | ||||
| 					// Windows was observed clearing out the BARS by writing 0's to them. | ||||
| 					// This is still susceptible to failure due to bad address choices by | ||||
| 					// the changing agent. | ||||
| 					switch (reg) | ||||
| 					{ | ||||
| 						case BAR0: | ||||
| 							if ((data != framebuffer_base) && (data >= 0x1000000)) | ||||
| 							{ | ||||
| 								// Set the frame buffer base. | ||||
| 								framebuffer_base = data; | ||||
|  | ||||
| 								// If the PCI memory is on, change the framebuffer base | ||||
| 								// related stuff. | ||||
| 								pciSave = READ_PCI_DWORD_NO_TRAP(PCI_CMD_REG); | ||||
| 								if (pciSave & PCI_MEM_SPACE) | ||||
| 									// Change the frame buffer base realated stuff. | ||||
| 									hw_fb_map_init(framebuffer_base); | ||||
| 							} | ||||
| 							break; | ||||
|  | ||||
| 						case BAR1: | ||||
| 							// Set the GP register base | ||||
| 							GPregister_base = data; | ||||
| 							break; | ||||
|  | ||||
| 						case BAR2: | ||||
| 							// Set the VG register base | ||||
| 							VGregister_base = data; | ||||
| 							break; | ||||
|  | ||||
| 						case BAR3: | ||||
| 							// Set the DF register base | ||||
| 							DFregister_base = data; | ||||
| 							break; | ||||
|  | ||||
| 						case BAR4: | ||||
| 							// Set the VIP register base | ||||
| 							VIPregister_base = data; | ||||
| 							break; | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			// Always mask off the invalid bits, but preserve the | ||||
| 			// bottom 4 bits. | ||||
| 			if (size == DWORD_IO) | ||||
| 			{ | ||||
| 				pciSave = GET_EAX(); | ||||
| 				switch (reg) | ||||
| 				{ | ||||
| 					case BAR0: | ||||
| 						pciSave &= VGdata.pci_fb_mask | 0x0000000F; | ||||
| 						break; | ||||
|  | ||||
| 					case BAR1: | ||||
| 					case BAR2: | ||||
| 					case BAR3: | ||||
| 					case BAR4: | ||||
| 						pciSave &= MASK16K; | ||||
| 						break; | ||||
| 				} | ||||
| 				SET_EAX(pciSave); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // END OF FILE | ||||
							
								
								
									
										74
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/init.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										74
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/init.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,74 @@ | ||||
| /* | ||||
| * Copyright (c) 2007-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA | ||||
| */ | ||||
| // This module performs LXVG initialization. | ||||
|  | ||||
|  | ||||
| #include "lxvg.h" | ||||
| #include "vsa2.h" | ||||
| #include "pci.h" | ||||
| #include "vr.h" | ||||
|  | ||||
|  | ||||
| //--------------------------------------------------------------------------- | ||||
| // lxvg_initialize | ||||
| // | ||||
| // This routine initializes LXVG.  This is the routine called when | ||||
| // VG_CONFIG virtual register is written the first time. | ||||
| //--------------------------------------------------------------------------- | ||||
|  | ||||
| void lxvg_initialize(unsigned short init_parms) | ||||
| { | ||||
| 	int index; | ||||
| 	unsigned char *ptr; | ||||
|  | ||||
| 	// CLEAR THE ENTIRE LXVG DATA STRUCTURE TO ZERO - This is a tedious loop | ||||
|  | ||||
| 	ptr = (unsigned char *) &VGdata; | ||||
| 	for (index = 0; index < sizeof(VGdata); index++) | ||||
| 		*ptr++ = 0; | ||||
|  | ||||
| 	// Start with virtual registers = 0 | ||||
| 	for (index = 0; index < MAX_VG+1; index++) | ||||
| 	{ | ||||
| 		if (index != VG_CONFIG) | ||||
| 		{ | ||||
| 			vReg[index] = 0; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// DEVICE DEPENDENT INITIALIZATION | ||||
| 	// ------------------------------- | ||||
| 	// This MUST be done first.	 The routine handles all of the MBUS related | ||||
| 	// initialization and determines various register and base address values | ||||
| 	// that get used during later initialization. | ||||
| 	hw_initialize(init_parms); | ||||
|  | ||||
| 	// If we haven't initialized because of error, just leave... | ||||
| 	if (VGState & SF_DISABLED) return; | ||||
|  | ||||
|  | ||||
| 	// LXVG is operating strictly as a secondary controller | ||||
| 	VGState |= SF_DRIVER_ENABLED; | ||||
|  | ||||
| 	// Disable the graphics system in the PCI header command register | ||||
| 	WRITE_PCI_BYTE(vga_config_addr+0x04, 0); | ||||
| 	return; | ||||
| } | ||||
|  | ||||
| // END OF FILE | ||||
							
								
								
									
										298
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/lxhwctl.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										298
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/lxhwctl.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,298 @@ | ||||
| /* | ||||
| * Copyright (c) 2007-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA | ||||
| */ | ||||
| //	  This module contains the routines that access the LX hardware. | ||||
|  | ||||
|  | ||||
| #include "lxvg.h" | ||||
| #include "vsa2.h" | ||||
| #include "vr.h" | ||||
| #include "pci.h" | ||||
|  | ||||
| // This is required here because of inclusion problems in LXVG.h | ||||
| extern Hardware SystemInfo; | ||||
|  | ||||
|  | ||||
| //--------------------------------------------------------------------------- | ||||
| // hw_initialize | ||||
| // | ||||
| // This routine performs the device dependent initialization. | ||||
| //--------------------------------------------------------------------------- | ||||
|  | ||||
| void hw_initialize(unsigned short config) | ||||
| { | ||||
| 	unsigned long base,tbase; | ||||
| 	struct mValue mVal; | ||||
| 	unsigned short i; | ||||
|  | ||||
| 	// Find the list of devices so we can get to their MSRs.  If any one | ||||
| 	// device is missing, bail out because we don't know how to handle | ||||
| 	// partial systems. | ||||
|  | ||||
| 	if (FALSE == msrInit()) | ||||
| 	{ | ||||
| 		VGState = SF_DISABLED; | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	// Initialize the MSRs for the graphics processor | ||||
| 	hw_gp_msr_init(); | ||||
|  | ||||
| 	// Initialize the MSRs for the video generator | ||||
| 	hw_vg_msr_init(); | ||||
|  | ||||
| 	// Initialize the MSRs for the display filter | ||||
| 	hw_df_msr_init(); | ||||
|  | ||||
| 	// Initialize the MSRs for the display filter | ||||
| 	hw_vip_msr_init(); | ||||
|  | ||||
| 	// Initialize the DOT PLL MSR in the MCP | ||||
| 	hw_mcp_msr_init(); | ||||
|  | ||||
| 	// Compute graphics memory requirement from config.	 The following strips | ||||
| 	// off the PLL bypass bit and shifts the number of 1MB hunks up | ||||
| 	// to the point where it is a size in bytes.  Base is used as a temp. | ||||
| 	base = (unsigned long)(config & MEM_SIZE_MASK) << 20; | ||||
|  | ||||
| 	// Now compute the memory size mask we will use when we return the contents of | ||||
| 	// BAR0 | ||||
| 	VGdata.pci_fb_mask = 0; | ||||
| 	tbase = base; | ||||
| 	for (i=0;i<32,tbase!=0L;i++) | ||||
| 	{ | ||||
| 		VGdata.pci_fb_mask |= (1L << i); | ||||
| 		tbase = tbase >> 1; | ||||
| 	} | ||||
| 	VGdata.pci_fb_mask = ~(VGdata.pci_fb_mask); | ||||
|  | ||||
| 	// ALLOCATE DESCRIPTORS | ||||
| 	vga_config_addr = SYS_ALLOCATE_RESOURCE(RESOURCE_MEMORY, BAR0, base, PCI_DEV_ID, ID_MC);	// Graphics memory | ||||
| 	SYS_ALLOCATE_RESOURCE(RESOURCE_MMIO, BAR1, SIZE16K, PCI_DEV_ID, ID_GP);		// GP registers | ||||
| 	SYS_ALLOCATE_RESOURCE(RESOURCE_MMIO, BAR2, SIZE16K, PCI_DEV_ID, ID_VG);		// VG registers | ||||
| 	SYS_ALLOCATE_RESOURCE(RESOURCE_MMIO, BAR3, SIZE16K, PCI_DEV_ID, ID_DF);		// DF registers | ||||
| 	SYS_ALLOCATE_RESOURCE(RESOURCE_MMIO, BAR4, SIZE16K, PCI_DEV_ID, ID_VIP);	// VIP registers | ||||
|  | ||||
| 	// Modify vga_config_addr to point to the beginning of the header, because all the accesses | ||||
| 	// to the header are based on the beginning of the header rather than BAR0. | ||||
| 	vga_config_addr -= BAR0; | ||||
|  | ||||
| 	// SET BASE ADDRESS VALUES. | ||||
|  | ||||
| 	// The base addresses are all relative to the framebuffer base address which | ||||
| 	// is defined to be on the next 256MB boundary above the SYSMGR.  Initially, | ||||
| 	// it was hard coded to be at 0x50000000, and now it should show up at 0x90000000. | ||||
| 	framebuffer_base = (SYS_LOGICAL_TO_PHYSICAL(0) & 0xF0000000) + 0x10000000; | ||||
| 	WRITE_PCI_DWORD_NO_TRAP(vga_config_addr+BAR0, framebuffer_base);	// Frame buffer address | ||||
|  | ||||
| 	GPregister_base = framebuffer_base - 0x00004000; | ||||
| 	WRITE_PCI_DWORD_NO_TRAP(vga_config_addr+BAR1, GPregister_base);	// Graphics processor register space | ||||
|  | ||||
| 	VGregister_base = GPregister_base - 0x00004000; | ||||
| 	WRITE_PCI_DWORD_NO_TRAP(vga_config_addr+BAR2, VGregister_base);	// Video generator register space | ||||
|  | ||||
| 	DFregister_base = VGregister_base - 0x00004000; | ||||
| 	WRITE_PCI_DWORD_NO_TRAP(vga_config_addr+BAR3, DFregister_base);	// Display filter register space | ||||
|  | ||||
| 	VIPregister_base = DFregister_base - 0x00004000; | ||||
| 	WRITE_PCI_DWORD_NO_TRAP(vga_config_addr+BAR4, VIPregister_base);	// Display filter register space | ||||
|  | ||||
| 	// Turn on the descriptors | ||||
| 	WRITE_PCI_BYTE(vga_config_addr+0x04,PCI_MEM_SPACE); | ||||
|  | ||||
| 	// Unlock the display controller registers | ||||
| 	saveLock = read_vg_32(DC_UNLOCK); | ||||
| 	write_vg_32(DC_UNLOCK, DC_UNLOCK_VALUE); | ||||
|  | ||||
| 	// Set up the DV Address offset in the DC_DV_CTL register to the offset from frame | ||||
| 	// buffer descriptor.  First, get the frame buffer descriptor so we can set the | ||||
| 	// DV Address Offset in the DV_CTL register.  Because this is a pointer to real | ||||
| 	// silicon memory, we don't need to do this whenever we change the framebuffer BAR, | ||||
| 	// so it isn't included in the hw_fb_map_init routine. | ||||
| 	SYS_MBUS_DESCRIPTOR((unsigned short)(vga_config_addr+BAR0),(void *)&mVal); | ||||
| 	mVal.high &= DESC_OFFSET_MASK; | ||||
| 	mVal.high <<= 4; | ||||
| 	mVal.high += framebuffer_base;	// Watch for overflow issues here... | ||||
| 	write_vg_32(DC_DV_CTL, mVal.high); | ||||
|  | ||||
| 	// Initialize the frame buffer base realated stuff. | ||||
| 	hw_fb_map_init(framebuffer_base); | ||||
|  | ||||
| 	// CLEAR Video Generator START ADDRESS VALUES | ||||
| 	write_vg_32(DC_FB_ST_OFFSET, 0L); | ||||
| 	write_vg_32(DC_CB_ST_OFFSET, 0L); | ||||
| 	write_vg_32(DC_CURS_ST_OFFSET, 0L); | ||||
| 	write_vg_32(DC_UNLOCK, saveLock); | ||||
|  | ||||
|  | ||||
| 	// Put VIP input and output sections into reset state with default values. | ||||
| 	write_vip_32(VIP_CTRL1, 0x42000001); | ||||
|  | ||||
| 	// Set flags indicating the hardware registers are available and that we are not | ||||
| 	// disabled.  Among other things, the SF_SECONDARY flag controls the hardware | ||||
| 	// register locking and unlocking at the top of the message handling loop. | ||||
| 	VGState |= SF_SECONDARY; | ||||
| 	VGState &= ~SF_DISABLED; | ||||
|  | ||||
| 	return; | ||||
| } | ||||
|  | ||||
|  | ||||
| // Initialize the graphics processor MSR registers. | ||||
| void hw_gp_msr_init(void) | ||||
| { | ||||
| 	// Initialize the configuration MSR - 0x00000000 00000010 | ||||
| 	msrModify(msrIdx_GP, MBD_MSR_CONFIG, MSR_CLR_ALL, MSR_CLR_ALL_BUT_PID, 0, GP_DEF_PRI); | ||||
|  | ||||
| 	// Initialize the SMI MSR.	Clear and disable all SMIs - 0x00000001 00000001 | ||||
| 	msrModify(msrIdx_GP, MBD_MSR_SMI, MSR_CLR_ALL, MSR_CLR_ALL, GP_SMI_CLR, GP_SMI_DIS); | ||||
|  | ||||
| 	return; | ||||
| } | ||||
|  | ||||
| // Initialize the video input port MSR registers. | ||||
| void hw_vip_msr_init(void) | ||||
| { | ||||
| 	msrModify(msrIdx_VIP, MBD_MSR_CONFIG, MSR_CLR_ALL, MSR_CLR_ALL_BUT_PID, 0L, VIP_DEF_PRI); | ||||
|  | ||||
| 	// Initialize the SMI MSR.	Clear and disable all SMIs - 0x00000000 7FFF7FFF | ||||
| 	msrModify(msrIdx_VIP, MBD_MSR_SMI, MSR_CLR_ALL, MSR_CLR_ALL, 0L, 0x7FFF7FFF); | ||||
|  | ||||
| 	return; | ||||
| } | ||||
|  | ||||
| // Initialize the video generator MSR registers. | ||||
| void hw_vg_msr_init(void) | ||||
| { | ||||
| 	// Initialize the configuration MSR - 0x00000000 00000320 | ||||
| 	msrModify(msrIdx_VG, MBD_MSR_CONFIG, MSR_CLR_ALL, MSR_CLR_ALL_BUT_PID, 0, VG_DEF_PRI); | ||||
|  | ||||
| 	// Initialize the SMI MSR.	Clear and disable all SMIs - 0x0000001f 0000001f | ||||
| 	msrModify(msrIdx_VG, MBD_MSR_SMI, MSR_CLR_ALL, MSR_CLR_ALL, VG_SMI_DIS, VG_SMI_DIS); | ||||
|  | ||||
| 	// Initialize the DELAY MSR. | ||||
| 	msrModify(msrIdx_VG, MBD_MSR_DELAY, MSR_CLR_ALL, MSR_CLR_ALL, 0L, 0x00000302); | ||||
|  | ||||
| 	// Turn off the bad VG fetch state machine hardware fix and the video FIFO watermarks | ||||
| 	msrModify(msrIdx_VG, MBD_MSR_SPARE, MSR_CLR_ALL, MSR_CLR_ALL, 0L, 0x00000042); | ||||
|  | ||||
| 	return; | ||||
| } | ||||
|  | ||||
| // Initialize the display filter MSR registers. | ||||
| void hw_mcp_msr_init(void) | ||||
| { | ||||
| 	unsigned long orValLo, orValHi; | ||||
| 	struct mValue mVal; | ||||
| 	unsigned char i; | ||||
|  | ||||
| 	// Initialize the DOT PLL MSR.	We need to default to a known clock so | ||||
| 	// the PLL doesn't exceed its limits, and if the bypass bit is set, we | ||||
| 	// need to also set the power down bit. | ||||
| 	if (vReg[VG_CONFIG] & VG_CFG_BYPASS) | ||||
| 	{ | ||||
| 		// Bypassed, so just set the bypass and power down bits. | ||||
| 		orValLo = DOTPLL_BYPASS | DOTPLL_PDBIT; | ||||
| 		orValHi = 0L; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		orValLo = DOTPLL_RESET; | ||||
| 		orValHi = 0x0000216C;	// 28.322MHz | ||||
| 	} | ||||
|  | ||||
| 	msrModify(msrIdx_MCP, MCP_DOTPLL, MSR_CLR_ALL, MSR_CLR_ALL, orValHi, orValLo); | ||||
|  | ||||
| 	// LEDA has indicated that there may be up to a 42 clock delay from the time the | ||||
| 	// DOTPLL comes out of powerdown until the lock bit is guaranteed to go low.  In | ||||
| 	// order to make sure we don't read an errant value, we need to delay a bit. | ||||
| 	for (i=0;i<8;i++) | ||||
| 		outp(0xed,0xf5); | ||||
|  | ||||
| 	// Wait for lock (maybe) | ||||
| 	msrRead(msrIdx_MCP, MCP_DOTPLL, &mVal); | ||||
| 	while (!(mVal.low & DOTPLL_LOCKBIT)) | ||||
| 	{ | ||||
| 		// Read the current contents... | ||||
| 		msrRead(msrIdx_MCP, MCP_DOTPLL, &mVal); | ||||
| 	}; | ||||
|  | ||||
| 	msrModify(msrIdx_MCP, MCP_DOTPLL, 0, MSR_CLR_ALL, 0, 0);		// Clear the reset bit | ||||
|  | ||||
| 	return; | ||||
| } | ||||
|  | ||||
| // Initialize the display filter MSR registers. | ||||
| void hw_df_msr_init(void) | ||||
| { | ||||
| 	unsigned long orVal; | ||||
| 	unsigned long mDiv, mMul, pSpd, mSpd, mbClk; | ||||
| 	struct mValue mVal; | ||||
|  | ||||
| 	// Get a colletion of information necessary to compute the divisor for the | ||||
| 	// CONFIG MSR.	This includes the processor speed, the CPU multiplier and | ||||
| 	// divisor and the MBus multiplier and divisor.	 There are two different | ||||
| 	// versions of the computation.	 The commented out version doesn't depend | ||||
| 	// on the bootstrap pin, and the other starts with a known PCI speed based | ||||
| 	// on that pin. | ||||
| 	msrRead(msrIdx_MCP, MCP_SYSPLL, &mVal);		// Returns the divisors... | ||||
|  | ||||
| 	pSpd = (mVal.low & 0x00000008)?66:33; | ||||
|  | ||||
| 	mDiv = ((mVal.high & 0x00000040) >> 6) + 1; | ||||
| 	mMul = ((mVal.high & 0x00000F80) >> 7) + 1; | ||||
|  | ||||
| 	mbClk = (pSpd * mMul) / mDiv; | ||||
|  | ||||
| 	mSpd = (mbClk / 14) & 0x0000003F; | ||||
|  | ||||
| 	// Initialize the configuration MSR | ||||
| 	orVal = DF_DEF_PRI; | ||||
| 	orVal |= (mSpd << 8); | ||||
| 	msrModify(msrIdx_DF, MBD_MSR_CONFIG, MSR_CLR_ALL, MSR_CLR_ALL_BUT_PID, 0, orVal); | ||||
|  | ||||
| 	return; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //--------------------------------------------------------------------------- | ||||
| // hw_fb_map_init | ||||
| // | ||||
| // This routine initializes the hardware pointers that are specifically | ||||
| // related to the framebuffer address. | ||||
| //--------------------------------------------------------------------------- | ||||
| void hw_fb_map_init(unsigned long fbLoc) | ||||
| { | ||||
| 	unsigned long ltemp; | ||||
|  | ||||
| 	// Insist upon a certain alignment... | ||||
| 	fbLoc &= VGdata.pci_fb_mask; | ||||
|  | ||||
| 	// Set the MBus Memory Offset register. | ||||
| 	write_vg_32(PHY_MEM_OFFSET, fbLoc); | ||||
|  | ||||
| 	// Set GP2 base offset - different from Redcloud.  There are both source | ||||
| 	// and destination fields the need to be set. | ||||
| 	ltemp = fbLoc | (fbLoc >> 10); | ||||
| 	write_gp_32(GP2_BASE_OFFSET, ltemp); | ||||
|  | ||||
| 	return; | ||||
| } | ||||
|  | ||||
							
								
								
									
										915
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/lxvg.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										915
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/lxvg.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,915 @@ | ||||
| /* | ||||
| * Copyright (c) 2007-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA | ||||
| */ | ||||
|  | ||||
| // This is the main header file for LXVG. | ||||
|  | ||||
| // VERSION NUMBERS | ||||
|  | ||||
| #define LXVG_MAJOR_VER			0x00 | ||||
| #define LXVG_MINOR_VER			0x11 | ||||
|  | ||||
| // PROCESSOR IDS | ||||
| // Keep as bitwise flags to make "either" comparisons easier. | ||||
|  | ||||
| #define PROCESSOR_GXM				0x01 | ||||
| #define PROCESSOR_REDC				0x02 | ||||
| #define PROCESSOR_CSTL				0x03 | ||||
|  | ||||
| // A pair of LONG generic masks | ||||
| #define CLR_HIWORD					0x0000FFFF | ||||
| #define CLR_LOWORD					0xFFFF0000 | ||||
|  | ||||
|  | ||||
| // Some LXVG configuration flags and masks | ||||
| #define MEM_SIZE_MASK				0x00FE		// Bits 7:1 (size in 2MB hunks) | ||||
| #define ADAPTER_PRIMARY				0x0100		// Bit 8 | ||||
|  | ||||
| #define PLL_REF_MASK				0x0600		// Bits 10:9 | ||||
| #define PLL_BYPASS					0x0800		// Bit 11 | ||||
| #define		VGDATA_PLL_14MHZ			0x00	// VGdata PLL reference frequency flag value | ||||
| #define		VGDATA_PLL_48MHZ			0x01	// VGdata PLL reference frequency flag value | ||||
| #define		VGDATA_PLL_ERROR			0xFF	// Bad PLL or hardware error | ||||
| #define MONOCHROME_CARD				0x1000		// Bit 12 | ||||
|  | ||||
| // SOME REDCLOUD DEFINITIONS | ||||
|  | ||||
| #define FAKE_ADDRESS				0xFFFFFFFF | ||||
| #define CLASS_MASK					0x000FF000 | ||||
| #define DEVID_MASK					0x00FFFF00 | ||||
|  | ||||
| // A memory space enable value for the PCI command register | ||||
| #define PCI_CMD_REG					0x04 | ||||
| #define PCI_IO_SPACE				(1 << 0) | ||||
| #define PCI_MEM_SPACE				(1 << 1) | ||||
|  | ||||
| // Some commonly used size definitions | ||||
| #define SIZE4K						0x00001000	// A 4K range indicator | ||||
| #define SIZE16K						0x00004000	// A 16K range indicator | ||||
| #define MASK16K						0xFFFFC00F	// A 16K range mask | ||||
| #define SIZE32K						0x00008000	// A 32K range indicator | ||||
| #define SIZE64K						0x00010000	// A 64K range indicator | ||||
| #define SIZE128K					0x00020000	// A 128K range indicator | ||||
|  | ||||
| // PCI device ID assigned to LX graphics system | ||||
| #define PCI_DEV_ID					0x2081 | ||||
|  | ||||
| // MBus device IDs.	 These IDs will have to be shifted into place by the System | ||||
| // manager when it goes to access the devices. | ||||
| #define ID_MBIU						0x01		// Default MBIU device ID | ||||
| #define ID_MCP						0x02		// MBus Control Processor device ID | ||||
| #define ID_MC						0x20		// Default Memory Controller device ID | ||||
| #define ID_GP						0x3D		// Graphics Processor device ID | ||||
| #define ID_VG						0x3E		// Video Generator device ID | ||||
| #define ID_DF						0x3F		// Display Filter device ID | ||||
| #define ID_VIP						0x3C		// Display Filter device ID | ||||
|  | ||||
| // MSR Register Offsets | ||||
| #define MBD_MSR_CAP			0x2000 | ||||
| #define MBD_MSR_CONFIG		0x2001 | ||||
| #define MBD_MSR_SMI			0x2002 | ||||
| #define MBD_MSR_ERROR		0x2003 | ||||
| #define MBD_MSR_PM			0x2004 | ||||
| #define MBD_MSR_DIAG		0x2005 | ||||
| #define MBD_MSR_SPARE		0x2011 | ||||
| #define MBD_MSR_DELAY		0x2012 | ||||
|  | ||||
| // DF specific MSRs | ||||
| #define DF_MSR_DIAG_DF		0x2010 | ||||
| #define DF_MSR_PAD_SEL		0x2011 | ||||
|  | ||||
| // MSR stuff specific to the MCP_DOTPLL | ||||
| #define MCP_SYSPLL			0x0014 | ||||
| #define MCP_DOTPLL			0x0015 | ||||
| #define DOTPLL_DIV_MASK		0x00007FFF | ||||
| #define DOTPLL_DIV4			0x00010000 | ||||
|  | ||||
| #define DOTPLL_RESET		0x00000001 | ||||
| #define DOTPLL_CAPEN		0x00002000 | ||||
| #define DOTPLL_PDBIT		0x00004000 | ||||
| #define DOTPLL_BYPASS		0x00008000 | ||||
| #define DOTPLL_HALFPIX		0x01000000 | ||||
| #define DOTPLL_LOCKBIT		0x02000000 | ||||
|  | ||||
| // MCP Error and SMI MSR error bits related to the DOTPLL reset during power-on bug PBz#3344. | ||||
| #define MCP_SMI_ERRBIT		0x00010000 | ||||
| #define MCP_DOTPLL_ERRBIT	0x00000004 | ||||
|  | ||||
| #define MCP_CHIPREV			0x0017 | ||||
|  | ||||
| // | ||||
| // msrDev indices for the devices that we care about/know about | ||||
| // | ||||
| #define msrIdx_MCP		0 | ||||
| #define msrIdx_MC		1 | ||||
| #define msrIdx_GP		2 | ||||
| #define msrIdx_VG		3 | ||||
| #define msrIdx_DF		4 | ||||
| #define msrIdx_VIP		5 | ||||
| #define msrIdx_MBIU		6 | ||||
|  | ||||
| // A mask to isolate the offset field of the frame buffer descriptor. | ||||
| #define DESC_OFFSET_MASK	0x0FFFFF00 | ||||
| #define DV_OFFSET_MASK		0xFFFFF000 | ||||
| #define DV_LINE_1K			0x00000000 | ||||
| #define DV_LINE_2K			0x00000400 | ||||
| #define DV_LINE_4K			0x00000800 | ||||
| #define DV_LINE_8K			0x00000C00 | ||||
|  | ||||
| // Structures of MSRs. | ||||
| // | ||||
| // Proper usage is as follows: | ||||
| // | ||||
| //	MSR access routines (MSRAR) should first check the 'Present' field and : | ||||
| // | ||||
| //	1) If the field is set to 'REQ_NOT_FOUND' : | ||||
| //		- The device was not detected on the MBUS but a request was made to | ||||
| //			find it at some point since/during initization [ see msrInit() ]. | ||||
| //			Therefore, MSRAR should not attempt to access the device. | ||||
| // | ||||
| //	2) If the field is set to 'FOUND' : | ||||
| //		- The device was detected on the MBUS, the rest of the structure | ||||
| //		  has been filled in and MSRAR should use the address provided. | ||||
| // | ||||
| //	3) If the field is set to 'UNKNOWN' : | ||||
| //		- There has never been a request to find this device.  MSRAR returns | ||||
| //		  to caller.  Caller should first call msrInit(). | ||||
| // | ||||
| //	The address field is set to FAKE_ADDRESS just in case "renegade software" doesn't | ||||
| //		 check the 'Present' field and just grabs the 'address' field. | ||||
| //		 FAKE_ADDRESS has been set to a value that should never appear in | ||||
| //		 a real system.	  It is only meant to protect the system 99% | ||||
| //		 of the time from badly written software.... | ||||
|  | ||||
| typedef struct tagMSR { | ||||
| 	unsigned short	Present;		// Present - Read above under "Structures of MSRs" | ||||
| 	unsigned short	Id;				// Id - Device ID number (from MSR specs) | ||||
| 	unsigned long	Routing;		// Routing - 32-bit address at which 'Id' was found | ||||
| } MSR; | ||||
|  | ||||
| // | ||||
| // mValue is used to hold the 64-bit msr data value. | ||||
| // | ||||
| typedef struct mValue { | ||||
| 	unsigned long low; | ||||
| 	unsigned long high; | ||||
| }; | ||||
|  | ||||
| // Capabilities bits | ||||
| #define DF_BOND_MASK		0x000000C0		// CRT bond value | ||||
| #define BOND_CRT			0x00			// CRT bond value | ||||
| #define BOND_FP				0x40			// flat panel bond value | ||||
|  | ||||
| #define HALF_MEG			0x00080000			// 512K | ||||
| #define QRTR_MEG			0x00040000			// 256K | ||||
| #define MAX_ICON			0x4C00			// 19K | ||||
|  | ||||
| // MSR AND masks used by rc_msrModify.	These masks define bits that are | ||||
| // always cleared in the register. | ||||
| #define MSR_CLR_ALL			0xFFFFFFFF		// Clear all bits | ||||
| #define MSR_CLR_NONE		0L				// Clear no bits | ||||
| #define MSR_CLR_OUT			0x00008038		// Clear bits 15, 5:3 | ||||
| #define MSR_CLR_ALL_BUT_PID	0xFFFFFFF8		// Clear all bits except [2:0] | ||||
|  | ||||
|  | ||||
| // GP | ||||
| #define GP_SMI_MSK_HI		0xFFFFFFFF		// SMI MSR | ||||
| #define GP_SMI_MSK_LO		0xFFE0FFE0 | ||||
| #define GP_ERR_MSK_HI		0xFFFFFFFF		// Error MSR | ||||
| #define GP_ERR_MSK_LO		0xFFF0FFF0 | ||||
| #define GP_PM_MSK_HI		0xFFFFFFFC		// PM MSR | ||||
| #define GP_PM_MSK_LO		0xFFFFFFF0 | ||||
|  | ||||
| // VG | ||||
| #define VG_SMI_MSK_HI		0xFFFFFFFF		// SMI MSR | ||||
| #define VG_SMI_MSK_LO		0xFFE0FFE0 | ||||
| #define VG_ERR_MSK_HI		0xFFFFFFFF		// Error MSR | ||||
| #define VG_ERR_MSK_LO		0xFFF0FFF0 | ||||
| #define VG_PM_MSK_HI		0xFFFFFFFC		// PM MSR | ||||
| #define VG_PM_MSK_LO		0xFFFFFFF0 | ||||
|  | ||||
| // DF | ||||
| #define DF_SMI_MSK_HI		0xFFFFFFFF		// SMI MSR | ||||
| #define DF_SMI_MSK_LO		0xFFFCFFFC | ||||
| #define DF_ERR_MSK_HI		0xFFFFFFFE		// Error MSR | ||||
| #define DF_ERR_MSK_LO		0xFFFFFFFE | ||||
| #define DF_PM_MSK_HI		0xFFFFFFE0		// PM MSR | ||||
| #define DF_PM_MSK_LO		0xF0FFFC00 | ||||
|  | ||||
|  | ||||
| // MSR bit field AND masks.	 These are added to the above masks to | ||||
| // clear particular fields | ||||
|  | ||||
| // GP | ||||
| #define GP_CFG_PRI			0x00000070		// Both priority fields | ||||
| #define GP_CFG_PID			0x00000007		// PID field | ||||
| #define GP_DEF_PRI			0x00000010		// Default priorities | ||||
|  | ||||
| #define GP_SMI_CLR			0x00000001		// SMI clear bits | ||||
| #define GP_SMI_DIS			0x00000001		// SMI disable bits | ||||
|  | ||||
| #define GP_CLK_RQ			0x00000001		// Software clock PM request bits field | ||||
| #define GP_PM_MODE			0x00000003		// Clock PM mode fields | ||||
| #define GP_CLK_ON			0x00000000		// Both clocks always on | ||||
| #define GP_CLK_HW			0x00000001		// Both clocks hardware gated | ||||
| #define GP_CLK_SW			0x00000002		// Both clocks software gated | ||||
| #define GP_CLK_BOTH			0x00000003		// Both clocks software and hardware gated | ||||
|  | ||||
| // VG | ||||
| #define VG_CFG_PRI			0x00000770		// Both priority fields | ||||
| #define VG_CFG_PID			0x00000007		// PID field | ||||
| #define VG_DEF_PRI			0x00000720		// Default priorities | ||||
| #define VG_DEF_PRI_10		0x00000620		// Default priorities for 1.0 parts | ||||
|  | ||||
| // LX 2.0 changes | ||||
| #define VG_SMI_DIS			0x1001FFFF		// SMI disable and clear bits | ||||
| #define VG_SMI_ALLNB		0x10000016		// All "Standard" SMIs but VBLANKs | ||||
|  | ||||
| #define VG_SMI_INV_CRTC		0x00000010		// Invalid CRTC SMI disable mask | ||||
| #define VG_SMI_VBLANK		0x00000009		// Vertical blanks SMI disable mask | ||||
| #define VG_SMI_ISR0			0x00000004		// Input status register SMI disable mask | ||||
| #define VG_SMI_MISC_W		0x00000002		// Miscellaneous output register SMI disable mask | ||||
|  | ||||
| #define VG_SMI_ALLCRTC		0x00000060		// All CRTC reads and writes | ||||
| #define VG_SMI_ALLSEQ		0x00000180		// All SEQ reads and writes | ||||
| #define VG_SMI_ALLGDC		0x00000600		// All GFX reads and writes | ||||
| #define VG_SMI_ALLATC		0x00001800		// All ATC reads and writes | ||||
| #define VG_SMI_ALLDAC		0x00006000		// All DAC reads and writes | ||||
|  | ||||
| #define VG_SMI_CRTC_W		0x00000020		// All CRTC writes | ||||
| #define VG_SMI_CRTC_R		0x00000040		// All CRTC reads | ||||
| #define VG_SMI_SEQ_W		0x00000080		// All SEQ writes | ||||
| #define VG_SMI_SEQ_R		0x00000100		// All SEQ reads | ||||
| #define VG_SMI_GDC_W		0x00000200		// All GDC writes | ||||
| #define VG_SMI_GDC_R		0x00000400		// All GDC reads | ||||
| #define VG_SMI_ATC_W		0x00000800		// All ATC writes | ||||
| #define VG_SMI_ATC_R		0x00001000		// All ATC reads | ||||
| #define VG_SMI_DAC_W		0x00002000		// All DAC writes | ||||
| #define VG_SMI_DAC_R		0x00004000		// All DAC reads | ||||
| #define VG_SMI_MISC_R		0x00008000		// Miscellaneous output register reads | ||||
| #define VG_SMI_ISR1_R		0x00010000		// Input status register 1 reads | ||||
|  | ||||
| // VG_DEBUG trap request bits | ||||
| #define TRAP_ALL_CRTC		0x0100 | ||||
| #define TRAP_ALL_SEQ		0x0200 | ||||
| #define TRAP_ALL_GDC		0x0400 | ||||
| #define TRAP_ALL_ATC		0x0800 | ||||
| #define TRAP_ALL_DAC		0x1000 | ||||
| #define TRAP_MISC_RDS		0x2000 | ||||
| #define TRAP_ISR1_RDS		0x4000 | ||||
| // LX 2.0 changes | ||||
|  | ||||
| #define VG_CLK_RQ			0x00000003		// Software clock PM request bits field | ||||
| #define VG_PM_MODE			0x0000000F		// Clock PM mode fields | ||||
| #define VG_CLK_ON			0x00000000		// Both clocks always on | ||||
| #define VG_CLK_HW			0x00000005		// Both clocks hardware gated | ||||
| #define VG_CLK_SW			0x0000000A		// Both clocks software gated | ||||
| #define VG_CLK_BOTH			0x0000000F		// Both clocks software and hardware gated | ||||
|  | ||||
|  | ||||
| // DF | ||||
| #define DF_CFG_PID			0x00000007		// PID field | ||||
| #define DF_CFG_FMT			0x00000038		// Output format select field | ||||
| #define DF_CFG_FMBO			0x000000C0		// Output format byte order field | ||||
| #define DF_CFG_DIV			0x00003F00		// Clock divider field | ||||
| #define DF_CFG_IUV			0x00004000		// Interchange UV field | ||||
| #define DF_CFG_FPC			0x00008000		// Simultaneous CRT and panel/VOP bit | ||||
| #define DF_CFG_PRI			0x00070000		// MBus master priority field | ||||
| #define DF_DEF_PRI			0x00040000		// Default priority | ||||
| #define DF_DEF_DIV			0x00003F00		// Default clock divider | ||||
|  | ||||
| //#define DF_SMI_CLR			0x00030000		// SMI clear bits | ||||
| #define DF_SMI_CLR			0x00000000		// SMI clear bits | ||||
| #define DF_SMI_DIS			0x00000003		// SMI disable bits | ||||
|  | ||||
| #define DF_CLK_RQ			0x0000001F		// Software clock PM request bits field | ||||
| #define DF_PM_MODE			0x000003FF		// Clock PM mode fields | ||||
| #define DF_CLK_ON			0x00000000		// All clocks always on | ||||
| #define DF_CLK_HW			0x00000155		// All clocks hardware gated | ||||
| #define DF_CLK_SW			0x000002AA		// All clocks software gated | ||||
| #define DF_CLK_BOTH			0x000003FF		// All clocks software and hardware gated | ||||
|  | ||||
| #define DF_CLR_CRC			0x80000000		// Clear the CRC select bit | ||||
|  | ||||
| // VIP | ||||
| #define VIP_CFG_PID			0x00000007		// PID field | ||||
| #define VIP_PRI_PRI			0x00000070		// MBus master priority field | ||||
| #define VIP_SEC_PRI			0x00000700		// Default priority | ||||
| #define VIP_DEF_PRI_10		0x00000630		// Default priority | ||||
| #define VIP_DEF_PRI			0x00000620		// Default priority | ||||
|  | ||||
| #define VIP_SMI_CLR			0x3FFF0000		// SMI clear bits | ||||
| #define VIP_SMI_DIS			0x00003FFF		// SMI disable bits | ||||
|  | ||||
| #define VIP_CLK_RQ			0x0000001F		// Software clock PM request bits field | ||||
| #define VIP_PM_MODE			0x000003FF		// Clock PM mode fields | ||||
| #define VIP_CLK_ON			0x00000000		// All clocks always on | ||||
| #define VIP_CLK_HW			0x00000155		// All clocks hardware gated | ||||
| #define VIP_CLK_SW			0x000002AA		// All clocks software gated | ||||
| #define VIP_CLK_BOTH		0x000003FF		// All clocks software and hardware gated | ||||
|  | ||||
| // | ||||
| // SMI event id bits | ||||
| // | ||||
| #define EVT_VG_VBLANK		0x00000001 | ||||
| #define EVT_VG_MISC_WR		0x00000002 | ||||
| #define EVT_VG_ISR0_RD		0x00000004 | ||||
| #define EVT_VGA_VBLANK		0x00000008 | ||||
| #define EVT_VG_INV_CRTC		0x00000010 | ||||
| #define EVT_VG_CRTC_W		0x00000020 | ||||
| #define EVT_VG_CRTC_R		0x00000040 | ||||
| #define EVT_VG_SEQ_W		0x00000080 | ||||
| #define EVT_VG_SEQ_R		0x00000100 | ||||
| #define EVT_VG_GFX_W		0x00000200 | ||||
| #define EVT_VG_GFX_R		0x00000400 | ||||
| #define EVT_VG_ATC_W		0x00000800 | ||||
| #define EVT_VG_ATC_R		0x00001000 | ||||
| #define EVT_VG_DAC_W		0x00002000 | ||||
| #define EVT_VG_DAC_R		0x00004000 | ||||
| #define EVT_VG_MISC_R		0x00008000 | ||||
| #define EVT_VG_ISR1_R		0x00010000 | ||||
| #define EVT_VGA_RES_CHG		0x10000000 | ||||
|  | ||||
| #define EVT_WRITES			0x00000AB2		// The register write bits | ||||
| #define EVT_READS			0x0001D554		// The register read bits + ISR0 & Inv CRTC | ||||
| //#define EVT_GP_SMI0			0x20000000 | ||||
| //#define EVT_DF_SMI0			0x40000000 | ||||
| //#define EVT_DF_SMI1			0x80000000 | ||||
| // Castle 2.0 Defs | ||||
|  | ||||
|  | ||||
| // | ||||
| // GP2 Memory Mapped Register Set | ||||
| // | ||||
| #define GP2_DST_OFFSET			0x0000 | ||||
| #define GP2_SRC_OFFSET			0x0004 | ||||
| #define GP2_VEC_ERR				0x0004 | ||||
| #define GP2_STRIDE				0x0008 | ||||
| #define GP2_WID_HEIGHT			0x000C | ||||
| #define GP2_SRC_COLOR_FG		0x0010 | ||||
| #define GP2_SRC_COLOR_BG		0x0014 | ||||
| #define GP2_PAT_COLOR_0			0x0018 | ||||
| #define GP2_PAT_COLOR_1			0x001C | ||||
| #define GP2_PAT_COLOR_2			0x0020 | ||||
| #define GP2_PAT_COLOR_3			0x0024 | ||||
| #define GP2_PAT_COLOR_4			0x0028 | ||||
| #define GP2_PAT_COLOR_5			0x002C | ||||
| #define GP2_PAT_DATA_0			0x0030 | ||||
| #define GP2_PAT_DATA_1			0x0034 | ||||
| #define GP2_RASTER_MODE			0x0038 | ||||
| #define GP2_VECTOR_MODE			0x003C | ||||
| #define GP2_BLT_MODE			0x0040 | ||||
| #define GP2_BLT_STATUS			0x0044 | ||||
| #define GP2_RESET				0x0044 | ||||
| #define GP2_HST_SRC				0x0048 | ||||
| #define GP2_BASE_OFFSET			0x004C | ||||
|  | ||||
| // | ||||
| // VG Memory Mapped Register Set | ||||
| // | ||||
| #define DC_UNLOCK				0x0000 | ||||
| #define DC_GENERAL_CFG			0x0004 | ||||
| #define DC_DISPLAY_CFG			0x0008 | ||||
| #define DC_ARB_CFG				0x000C | ||||
| //#define DC_GFX_SCL				0x000C | ||||
| #define DC_FB_ST_OFFSET			0x0010 | ||||
| #define DC_CB_ST_OFFSET			0x0014 | ||||
| #define DC_CURS_ST_OFFSET		0x0018 | ||||
| //#define DC_ICON_ST_OFFSET			0x001C | ||||
| #define DC_VID_Y_ST_OFFSET		0x0020 | ||||
| #define DC_VID_U_ST_OFFSET		0x0024 | ||||
| #define DC_VID_V_ST_OFFSET		0x0028 | ||||
| #define DC_DV_TOP				0x002C | ||||
| //#define DC_VID_SP_ST_OFFSET		0x002C | ||||
| #define DC_LINE_SIZE			0x0030 | ||||
| #define DC_GFX_PITCH			0x0034 | ||||
| #define DC_VID_YUV_PITCH		0x0038 | ||||
| //#define DC_VID_SP_PITCH			0x003C | ||||
| #define DC_H_ACTIVE_TIMING		0x0040 | ||||
| #define DC_H_BLANK_TIMING		0x0044 | ||||
| #define DC_H_SYNC_TIMING		0x0048 | ||||
| //#define DC_FP_HSYNC_TIMING		0x004C | ||||
| #define DC_V_ACTIVE_TIMING		0x0050 | ||||
| #define DC_V_BLANK_TIMING		0x0054 | ||||
| #define DC_V_SYNC_TIMING		0x0058 | ||||
| #define DC_FB_ACTIVE			0x005C | ||||
| //#define DC_FP_VSYNC_TIMING		0x005C | ||||
| #define DC_CURSOR_X				0x0060 | ||||
| #define DC_CURSOR_Y				0x0064 | ||||
| //#define DC_ICON_X					0x0068 | ||||
| #define DC_LINE_CNT				0x006C | ||||
| #define DC_PAL_ADDRESS			0x0070 | ||||
| #define DC_PAL_DATA				0x0074 | ||||
| #define DC_DFIFO_DIAG			0x0078 | ||||
| #define DC_CFIFO_DIAG			0x007C | ||||
| #define DC_VID_DS_DELTA			0x0080 | ||||
| #define PHY_MEM_OFFSET			0x0084 | ||||
| #define DC_DV_CTL				0x0088 | ||||
| #define DC_ACCESS				0x008C | ||||
|  | ||||
| #define DC_GFX_SCALE			0x0090 | ||||
| #define DC_IRQ_FLT_CTL			0x0094 | ||||
| #define DC_FLT_COEFF1			0x0098 | ||||
| #define DC_FLT_COEFF2			0x009C | ||||
|  | ||||
| #define DC_VBI_EVN_CTL			0x00A0 | ||||
| #define DC_VBI_ODD_CTL			0x00A4 | ||||
| #define DC_VBI_HOR_CTL			0x00A8 | ||||
| #define DC_VBI_LN_ODD			0x00AC | ||||
| #define DC_VBI_LN_EVN			0x00B0 | ||||
| #define DC_VBI_PITCH			0x00B4 | ||||
| #define DC_VBI_CLR_KEY			0x00B8 | ||||
| #define DC_VBI_CK_MASK			0x00BC | ||||
| #define DC_VBI_CK_X				0x00C0 | ||||
| #define DC_VBI_CK_Y				0x00C4 | ||||
|  | ||||
| #define DC_IRQ					0x00C8 | ||||
| #define DC_GENLK_CTL			0x00D4 | ||||
|  | ||||
| #define DC_VID_EVN_Y_ST			0x00D8 | ||||
| #define DC_VID_EVN_U_ST			0x00DC | ||||
| #define DC_VID_EVN_V_ST			0x00E0 | ||||
|  | ||||
| #define DC_VID_EVN_ACT			0x00E4 | ||||
| #define DC_VID_EVN_BLANK		0x00E8 | ||||
| #define DC_VID_EVN_SYNC			0x00EC | ||||
|  | ||||
| #define DC_VGA_CONFIG			0x0100 | ||||
| #define DC_VGA_STATUS			0x0104 | ||||
| //#define DC_VGA_EXTADDR			0x0108 | ||||
|  | ||||
| #define DC_UNLOCK_VALUE		0x00004758 | ||||
| #define DC_LOCK_VALUE		0x00000000 | ||||
|  | ||||
| //-----------------------------------// | ||||
| //	DC_GENERAL_CFG Bit Definitions	 // | ||||
| //-----------------------------------// | ||||
| // DC_GCFG_CLR_MASK turns off everything but VGA fixed timing enable, VGA enable, | ||||
| // compression and decompression enables and Display-FIFO Load Enable | ||||
| #define DC_GCFG_CLR_MASK		0x0004FF00 | ||||
|  | ||||
| #define	DC_GCFG_DFLE			0x00000001 | ||||
| #define DC_GCFG_CURE			0x00000002 | ||||
| #define DC_GCFG_ICNE			0x00000004 | ||||
| #define DC_GCFG_VIDE			0x00000008 | ||||
| //#define DC_GCFG_VSPE				0x00000010 | ||||
| #define DC_GCFG_FSSEL			0x00000010 | ||||
| #define DC_GCFG_CMPE			0x00000020 | ||||
| #define DC_GCFG_DECE			0x00000040 | ||||
| #define DC_GCFG_VGAE			0x00000080 | ||||
|  | ||||
| #define DC_GCFG_DFIFO_ST		0x00000F00 | ||||
| #define DC_GCFG_DFIFO_END		0x0000F000 | ||||
| #define DC_GCFG_WATERMARKS		0x00007200 | ||||
| #define DC_GCFG_STFM			0x00010000 | ||||
| #define DC_GCFG_FDTY			0x00020000 | ||||
| #define DC_GCFG_VGAFT			0x00040000 | ||||
| #define DC_GCFG_VDSE			0x00080000 | ||||
| #define DC_GCFG_YUVM			0x00100000 | ||||
| //#define DC_GCFG_FTSTR				0x00200000 | ||||
| #define DC_GCFG_FRC8PIX			0x00400000 | ||||
| #define DC_GCFG_SIGSEL			0x00800000 | ||||
| #define DC_GCFG_CLR_CRC			0xF8FFFFFF | ||||
| //#define DC_GCFG_CLR_CRC_ALL		0xF07FFFFF | ||||
| #define DC_GCFG_CLR_CRC_ALL		0xF07FFFEF | ||||
| #define DC_GCFG_SIGE			0x01000000 | ||||
| #define DC_GCFG_SGRE			0x02000000 | ||||
| #define DC_GCFG_SGFR			0x04000000 | ||||
| #define DC_GCFG_CRCMODE			0x08000000 | ||||
| //#define DC_GCFG_GXRFS4			0x08000000 | ||||
|  | ||||
|  | ||||
| //-----------------------------------// | ||||
| //	DC_DISPLAY_CFG Bit Definitions	 // | ||||
| //-----------------------------------// | ||||
| // DC_DCFG_CLR_MASK turns off everything but display center, color depth fields, | ||||
| // and scale enable. | ||||
| #define DC_DCFG_CLR_MASK		0xC0000F00 | ||||
| #define DC_DCFG_BLANK_MASK		0xFFFFFFC0 | ||||
|  | ||||
| #define DC_DCFG_TGEN			0x00000001 | ||||
| //#define DC_DCFG_PCKE			0x00000002 | ||||
| //#define DC_DCFG_VCKE			0x00000004 | ||||
| #define DC_DCFG_GDEN			0x00000008 | ||||
| //#define DC_DCFG_VDEN			0x00000010 | ||||
| #define DC_DCFG_VIEN			0x00000020 | ||||
| #define DC_DCFG_TRUP			0x00000040 | ||||
| #define DC_DCFG_SCLE			0x00000080 | ||||
|  | ||||
| // Color depth related masks and values | ||||
| #define DC_DCFG_MODE_MASK		0x00000F00 | ||||
| #define DC_DCFG_16BPP_MODE		0x00000C00 | ||||
| #define DC_DCFG_DISP_MODE		0x00000300 | ||||
|  | ||||
| #define DC_DCFG_BPP16			0x00000100 | ||||
| #define DC_DCFG_BPP15			0x00000500 | ||||
| #define DC_DCFG_BPP12			0x00000900 | ||||
| #define DC_DCFG_BPP32			0x00000200 | ||||
|  | ||||
| #define DC_DCFG_VFHPSL			0x0000F000 | ||||
| //#define DC_DCFG_PLNR			0x00001000 | ||||
| //#define DC_DCFG_SSLC			0x00002000 | ||||
| //#define DC_DCFG_PXDB			0x00004000 | ||||
| //#define DC_DCFG_LNDB			0x00008000 | ||||
|  | ||||
| #define DC_DCFG_VFHPEL			0x000F0000 | ||||
| //#define DC_DCFG_BLNK			0x00010000 | ||||
| //#define DC_DCFG_BKRT			0x00020000 | ||||
| //#define DC_DCFG_RFS4			0x00040000 | ||||
| //#define DC_DCFG_DCEN			0x00080000 | ||||
|  | ||||
| //#define DC_DCFG_PIX_PAN		0x00F00000 | ||||
| //#define DC_DCFG_PPC			0x01000000 | ||||
| #define	DC_DCFG_DCEN			0x01000000 | ||||
| #define	DC_DCFG_PALB			0x02000000 | ||||
| //#define DC_DCFG_FRLK			0x04000000 | ||||
| #define	DC_DCFG_VISL			0x08000000 | ||||
| //#define DC_DCFG_A18M			0x40000000 | ||||
| //#define DC_DCFG_A20M			0x80000000 | ||||
|  | ||||
| //-----------------------------------// | ||||
| //	DC_IRQ_FLT_CTL Bit Definitions	 // | ||||
| //-----------------------------------// | ||||
| #define	IF_FLT_ADDR_MASK		0x000000FF | ||||
| #define	IF_HFILT_SEL			0x00000400 | ||||
| #define	IF_INTL_EN				0x00000800 | ||||
| #define	IF_HFILT_EN				0x00001000 | ||||
| #define	IF_VFILT_EN				0x00002000 | ||||
| #define	IF_HALPH_FILT_EN		0x00004000 | ||||
| #define	IF_VALPH_FILT_EN		0x00008000 | ||||
| #define	IF_LIN_CNT_MASK			0x07FF0000 | ||||
| #define	IF_IRQ_EN				0x08000000 | ||||
| #define	IF_INTL_ADDR			0x10000000 | ||||
|  | ||||
|  | ||||
|  | ||||
| // | ||||
| // DF Memory Mapped Register Set | ||||
| // | ||||
| #define	DF_VCFG					0x0000 | ||||
| #define	DF_DCFG					0x0008 | ||||
| #define	DF_VID_X				0x0010 | ||||
| #define	DF_VID_Y				0x0018 | ||||
| #define	DF_VID_SCL				0x0020 | ||||
| #define	DF_VID_CK				0x0028 | ||||
| #define	DF_VID_CM				0x0030 | ||||
| #define	DF_PAL_ADDR				0x0038 | ||||
| #define	DF_PAL_DATA				0x0040 | ||||
|  | ||||
| #define	DF_SLR					0x0048 | ||||
|  | ||||
| #define	DF_MISC					0x0050 | ||||
| #define	DF_CRT_CS				0x0058 | ||||
|  | ||||
| #define	DF_VYS					0x0060 | ||||
| #define	DF_VXS					0x0068 | ||||
|  | ||||
| #define	DF_VID_DSC				0x0078 | ||||
| //#define	DF_VID_DCO				0x0080 | ||||
|  | ||||
| #define	DF_CRC_SIG				0x0088 | ||||
| #define DF_CRCS_CLR_CRC			0xFFFFFFF8 | ||||
| #define DF_CRCS_SIGE			0x00000001 | ||||
| #define DF_CRCS_SGFR			0x00000004 | ||||
| #define	DF_CRC32_SIG			0x0090 | ||||
|  | ||||
| #define	DF_VID_VDE				0x0098 | ||||
| #define	DF_VID_CCK				0x00A0 | ||||
| #define	DF_VID_CCM				0x00A8 | ||||
| #define	DF_VID_CC1				0x00B0 | ||||
| #define	DF_VID_CC2				0x00B8 | ||||
| #define	DF_VID_A1X				0x00C0 | ||||
| #define	DF_VID_A1Y				0x00C8 | ||||
| #define	DF_VID_A1C				0x00D0 | ||||
| #define	DF_VID_A1T				0x00D8 | ||||
| #define	DF_VID_A2X				0x00E0 | ||||
| #define	DF_VID_A2Y				0x00E8 | ||||
| #define	DF_VID_A2C				0x00F0 | ||||
| #define	DF_VID_A2T				0x00F8 | ||||
| #define	DF_VID_A3X				0x0100 | ||||
| #define	DF_VID_A3Y				0x0108 | ||||
| #define	DF_VID_A3C				0x0110 | ||||
| #define	DF_VID_A3T				0x0118 | ||||
| #define	DF_VID_VRR				0x0120 | ||||
| #define	DF_VID_AWT				0x0128 | ||||
|  | ||||
| // Flat panel specific | ||||
| #define	DF_FP_PT1				0x0400 | ||||
| #define	DF_FP_PT2				0x0408 | ||||
| #define	DF_FP_PM				0x0410 | ||||
| #define	DF_FP_DFC				0x0418 | ||||
| #define		DF_DFC_NO_DITHER		0x00000070 | ||||
| //#define	DF_FP_BLFSR				0x0420 | ||||
| //#define	DF_FP_RLFSR				0x0428 | ||||
| //#define	DF_FP_FMI				0x0430 | ||||
| //#define	DF_FP_FMD				0x0438 | ||||
| //#define	DF_FP_RSVD				0x0440 | ||||
| #define	DF_FP_DCA				0x0448 | ||||
| #define	DF_FP_DMD				0x0450 | ||||
| #define	DF_FP_CRC				0x0458 | ||||
| //#define	DF_FP_FBB				0x0460 | ||||
| #define	DF_FP_CRC32				0x0468 | ||||
|  | ||||
| // VOP specific | ||||
| #define	DF_VOP_CFG				0x0800 | ||||
| #define	DF_VOP_SIG				0x0808 | ||||
|  | ||||
| #define	DF_VID_VCR				0x1000 | ||||
|  | ||||
| #define DF_DCFG_VID_EN				0x00000001 | ||||
|  | ||||
| //-----------------------------------// | ||||
| //	DF_DCFG Bit Definitions			 // | ||||
| //-----------------------------------// | ||||
| // DF_DCFG_CLR_MASK turns off everything but CRT sync skew.	 The blank mask turns off | ||||
| // CRT DACs, the CRT sync enables and resets the display logic. | ||||
| #define DF_DCFG_CLR_MASK			0x0001C000 | ||||
| #define DF_DCFG_BLANK_MASK			0xFFFFFFF0	// 0xF431FF30 | ||||
| #define DF_DCFG_ENABLE_MASK			0x0000000F | ||||
| #define DF_DCFG_DPMS_STBY			0x00000005 | ||||
| #define DF_DCFG_DPMS_SUSP			0x00000003 | ||||
|  | ||||
| #define DF_DCFG_DIS_EN				0x00000001 | ||||
| #define DF_DCFG_HSYNC_EN			0x00000002 | ||||
| #define DF_DCFG_VSYNC_EN			0x00000004 | ||||
| #define DF_DCFG_DAC_BL_EN			0x00000008 | ||||
| //#define DF_DCFG_DAC_PWDNX			0x00000020 | ||||
| //#define DF_DCFG_FP_PWR_EN			0x00000040 | ||||
| //#define DF_DCFG_FP_DATA_EN		0x00000080 | ||||
| #define DF_DCFG_CRT_HSYNC_POL		0x00000100 | ||||
| #define DF_DCFG_CRT_VSYNC_POL		0x00000200 | ||||
| //#define DF_DCFG_FP_HSYNC_POL		0x00000400 | ||||
| //#define DF_DCFG_FP_VSYNC_POL		0x00000800 | ||||
| //#define DF_DCFG_XGA_FP			0x00001000 | ||||
| //#define DF_DCFG_FP_DITH_EN		0x00002000 | ||||
| #define DF_DCFG_CRT_SYNC_SKW_MASK	0x0001C000 | ||||
| #define DF_DCFG_CRT_SYNC_SKW_POS	14 | ||||
| //#define DF_DCFG_PWR_SEQ_DLY_MASK	0x000E0000 | ||||
| //#define DF_DCFG_PWR_SEQ_DLY_POS	17 | ||||
| //#define DF_DCFG_PWR_SEQ_DLY_VAL	0x00080000 | ||||
| #define DF_DCFG_VG_CK				0x00100000 | ||||
| #define DF_DCFG_GV_PAL_BYP			0x00200000 | ||||
| //#define DF_DCFG_DDC_SCL			0x00400000 | ||||
| //#define DF_DCFG_DDC_SDA			0x00800000 | ||||
| //#define DF_DCFG_DDC_OE			0x01000000 | ||||
| #define DF_DCFG_DAC_VREF			0x04000000 | ||||
| //#define DF_DCFG_FP_PWR_ON			0x08000000 | ||||
|  | ||||
|  | ||||
| //-----------------------------------// | ||||
| //	DF_FP_PT1 Bit Definitions		 // | ||||
| //-----------------------------------// | ||||
| #define DF_PT1_HPULSE_MASK			0x0000001F | ||||
| #define DF_PT1_HDELAY_MASK			0x000000E0	// Not used in LXVG | ||||
| #define DF_PT1_HDELAY_SHIFT							5 | ||||
| #define DF_PT1_O					0x00004000 | ||||
| #define DF_PT1_U					0x00008000 | ||||
| #define DF_PT1_VSIZE_MASK			0x07FF0000 | ||||
| #define DF_PT1_VSIZE_SHIFT							16 | ||||
| #define DF_PT1_HSRC					0x08000000 | ||||
| #define DF_PT1_HSIP					0x20000000 | ||||
| #define DF_PT1_VSIP					0x40000000 | ||||
|  | ||||
|  | ||||
| //-----------------------------------// | ||||
| //	DF_FP_PT2 Bit Definitions		 // | ||||
| //-----------------------------------// | ||||
| #define DF_PT2_CLP					0x00002000 | ||||
| #define DF_PT2_PIXF_MASK			0x00070000 | ||||
| #define DF_PT2_PIXF_SHIFT							16 | ||||
| #define DF_PT2_PIXF_000				0x00000000 | ||||
| #define DF_PT2_PIXF_001				0x00010000 | ||||
| #define DF_PT2_PIXF_002				0x00020000 | ||||
| #define DF_PT2_PIXF_003				0x00030000 | ||||
| #define DF_PT2_MCS					0x00080000 | ||||
| #define DF_PT2_PSEL_MASK			0x00300000 | ||||
| #define DF_PT2_PSEL_STN				0x00000000 | ||||
| #define DF_PT2_PSEL_TFT				0x00100000 | ||||
| #define DF_PT2_HSP					0x00400000 | ||||
| #define DF_PT2_VSP					0x00800000 | ||||
| #define DF_PT2_VFS					0x01000000 | ||||
| #define DF_PT2_LMS					0x02000000 | ||||
| #define DF_PT2_LHS					0x04000000 | ||||
| #define DF_PT2_SCRC					0x08000000 | ||||
| #define DF_PT2_LPOL					0x20000000 | ||||
| #define DF_PT2_TPASS				0x40000000 | ||||
|  | ||||
| //-----------------------------------// | ||||
| //	DF_FP_PM Bit Definitions		 // | ||||
| //-----------------------------------// | ||||
| #define DF_PM_SINV					0x00002000 | ||||
| #define DF_PM_VDEL_MASK				0x0000C000 | ||||
| #define DF_PM_VDEL_SHIFT							14 | ||||
| #define DF_PM_HDEL_MASK				0x00030000 | ||||
| #define DF_PM_HDEL_SHIFT							16 | ||||
| #define DF_PM_PD0					0x00040000 | ||||
| #define DF_PM_PD1					0x00080000 | ||||
| #define DF_PM_PD2					0x00100000 | ||||
| #define DF_PM_PUB0					0x00200000 | ||||
| #define DF_PM_PUB1					0x00400000 | ||||
| #define DF_PM_PUB2					0x00800000 | ||||
| #define DF_PM_P						0x01000000 | ||||
| #define DF_PM_D						0x02000000 | ||||
| #define DF_PM_PWR_SEQ				0x08000000 | ||||
|  | ||||
| //-----------------------------------// | ||||
| //	DF_VOP_CFG Bit Definitions		   // | ||||
| //-----------------------------------// | ||||
| #define DF_VOP_ENABLE_MASK			0x00000003 | ||||
| #define DF_VOP_VIP11				0x00000001 | ||||
| #define DF_VOP_VIP2					0x00000002 | ||||
| #define DF_VOP_CCIR656				0x00000003 | ||||
| #define DF_VOP_LVL2					0x00000004 | ||||
| #define DF_VOP_EXTSAV				0x00000008 | ||||
| #define DF_VOP_422CO				0x00000000 | ||||
| #define DF_VOP_422RCO				0x00000010 | ||||
| #define DF_VOP_422ASS				0x00000020 | ||||
| #define DF_VOP_SC120X				0x00000040 | ||||
| #define DF_VOP_SIGE					0x00000080 | ||||
| #define DF_VOP_SIGFR				0x00000100 | ||||
|  | ||||
|  | ||||
| // | ||||
| // VIP Memory Mapped Register Set | ||||
| // | ||||
| #define	VIP_CTRL1					0x0000 | ||||
| #define	VIP_CTRL2					0x0004 | ||||
| #define	VIP_STATUS					0x0008 | ||||
| #define	VIP_INTS					0x000C | ||||
| #define	VIP_CURTGT					0x0010 | ||||
| #define	VIP_MAX_ADDR				0x0014 | ||||
|  | ||||
| #define	VIP_AVID_EBASE				0x0018 | ||||
| #define	VIP_AVID_OBASE				0x001C | ||||
| #define	VIP_AVBI_EBASE				0x0020 | ||||
| #define	VIP_AVBI_OBASE				0x0024 | ||||
| #define	VIP_A_PITCH					0x0028 | ||||
| #define	VIP_CTRL3					0x002C | ||||
| #define	VIP_A_VOBUF					0x0030 | ||||
| #define	VIP_A_UOBUF					0x0034 | ||||
|  | ||||
| #define	VIP_BVID_EBASE				0x0038 | ||||
| #define	VIP_BVID_OBASE				0x003C | ||||
| #define	VIP_BVBI_EBASE				0x0040 | ||||
| #define	VIP_BVBI_OBASE				0x0044 | ||||
| #define	VIP_B_PITCH					0x0048 | ||||
| #define	VIP_B_VBUF					0x0050 | ||||
| #define	VIP_B_UBUF					0x0054 | ||||
|  | ||||
| #define	VIP_AMSG_1BASE				0x0058 | ||||
| #define	VIP_AMSG_2BASE				0x005C | ||||
| #define	VIP_AMSG_SIZE				0x0060 | ||||
|  | ||||
| #define	VIP_PAGE_OFFS				0x0068 | ||||
| #define	VIP_VERT_ST					0x006C | ||||
| #define	VIP_FIFO_ADDR				0x0070 | ||||
| #define	VIP_FIFO_RW					0x0074 | ||||
| #define	VIP_FRM_DCNT				0x0078 | ||||
| #define	VIP_A_VEBUF					0x007C | ||||
| #define	VIP_A_UEBUF					0x0080 | ||||
|  | ||||
|  | ||||
|  | ||||
| // CHIPSET IDS | ||||
| // Keep as bitwise flags to make "either" comparisons easier. | ||||
|  | ||||
| #define CHIPSET_CX5530				0x01 | ||||
| #define CHIPSET_REDC				0x02 | ||||
| #define CHIPSET_DHRUVA				0x10 | ||||
| #define CHIPSET_BHARGAVA			0x20 | ||||
| #define CX5530_DISPLAY_CONFIG		0x00000004 | ||||
|  | ||||
| // TRAPPED PCI DEVICES | ||||
|  | ||||
| #define PCI_CONFIG_MASK				0xFFFFFF00		// bits for comparison | ||||
| #define PCI_NSM_FLAGS_REG0			0x44			// register for flags | ||||
| #define PCI_NSM_FLAGS_REG1			0x45			// register for flags | ||||
| #define PCI_NSM_FLAGS_REG2			0x46			// register for flags | ||||
| #define PCI_NSM_FLAGS_REG3			0x47			// register for flags | ||||
| #define PCI_NSM_FLAG_DISABLE		0x01			// flag to disable LXVG | ||||
|  | ||||
| // SYSTEM FLAGS (stored in VGState) | ||||
|  | ||||
| #define SF_DISABLED				0x00000001		// LXVG is disabled | ||||
| #define SF_SECONDARY			0x00000002		// Init to secondary controller capability | ||||
| #define SF_PRIMARY				0x00000004		// Init to primary controller capability | ||||
| // The next flag indicates a mode switch has occurred.	Generally only the first mode | ||||
| // switch is interesting. | ||||
| #define SF_MODE_SET				0x00000008 | ||||
| #define SF_END_POST				0x00000010		// POST is complete | ||||
| #define SF_DRIVER_ENABLED		0x00000020		// Graphics driver is controlling system | ||||
| #define SF_DIAG_SMI				0x00000040		// Use diagnostic SMI settings | ||||
|  | ||||
| #define SF_MONOCHROME			0x00000100		// monochrome mode | ||||
| #define SF_3D0_RANGE			0x00000200		// remembers state of ioaddr bit in misc output | ||||
| #define SF_SCALE_DISABLED		0x00000400		// Disable graphics scaling during fixed timings | ||||
| #define SF_FORCE_VALIDATION		0x00000800		// force all HW validation | ||||
|  | ||||
|  | ||||
| // SMM HEADER FLAGS | ||||
|  | ||||
| #define SMM_IO_WRITE			0x0002 | ||||
| #define SMM_VR_WRITE			0x0001 | ||||
|  | ||||
| // FLAGS FOR PCI TRAP EVENTS | ||||
|  | ||||
| #define PCI_TRAP_WRITE			0x80 | ||||
|  | ||||
| #include "VGdata.h" | ||||
|  | ||||
| #define TRUE 1 | ||||
| #define FALSE 0 | ||||
|  | ||||
|  | ||||
| extern VGDATA VGdata; | ||||
| extern unsigned long VGState; | ||||
| extern unsigned long lockNest;			// Nested SMI recognition scheme | ||||
| extern unsigned long saveLock;			// Nested SMI recognition scheme | ||||
| extern unsigned short vReg[]; | ||||
| extern unsigned long vga_config_addr; | ||||
| extern unsigned long GPregister_base; | ||||
| extern unsigned long VGregister_base; | ||||
| extern unsigned long DFregister_base; | ||||
| extern unsigned long VIPregister_base; | ||||
| extern unsigned long framebuffer_base; | ||||
| extern unsigned long VG_SMI_Mask; | ||||
| extern unsigned char crc_time; | ||||
|  | ||||
|  | ||||
| //------------// | ||||
| //	ROUTINES  // | ||||
| //------------// | ||||
|  | ||||
| // ROUTINES IN MSR.C | ||||
|  | ||||
| unsigned char msrInit(void); | ||||
| unsigned short msrFindDevice(struct tagMSR *); | ||||
| unsigned short msrIdDevice(unsigned long); | ||||
| unsigned short msrRead(unsigned short msrIdx, unsigned short msrReg, struct mValue *); | ||||
| unsigned short msrWrite(unsigned short msrIdx, unsigned short msrReg, unsigned long outHi, unsigned long outLo); | ||||
| void msrModify(unsigned short msrIdx, unsigned short msrReg, | ||||
| 				unsigned long andHi, unsigned long andLo, unsigned long orHi, unsigned long orLo); | ||||
| void msrSave(unsigned short msrIdx, unsigned short *, struct mValue *); | ||||
| void msrRestore(unsigned short msrIdx, unsigned short *, struct mValue *); | ||||
| void msrDump(unsigned short msrIdx, unsigned short msrReg); | ||||
|  | ||||
|  | ||||
| // ROUTINES IN VSA2.C | ||||
|  | ||||
| void decode_vsa2_event(void); | ||||
| void vsa2_io_read(unsigned short size, unsigned long data); | ||||
|  | ||||
|  | ||||
| // ROUTINES IN DECODE.C | ||||
|  | ||||
| void virtual_register_event(unsigned char reg, unsigned long rwFlag, unsigned long vrData); | ||||
| void pci_trap_event(unsigned long address, unsigned long size,	unsigned long data); | ||||
|  | ||||
|  | ||||
| // ROUTINES IN GXHWCTL.C | ||||
|  | ||||
| void hw_initialize(unsigned short config); | ||||
| void hw_gp_msr_init(void); | ||||
| void hw_vip_msr_init(void); | ||||
| void hw_vg_msr_init(void); | ||||
| void hw_df_msr_init(void); | ||||
| void hw_mcp_msr_init(void); | ||||
| void hw_fb_map_init(unsigned long fbLoc); | ||||
|  | ||||
| // ROUTINES IN INIT.C | ||||
|  | ||||
| void lxvg_initialize(unsigned short init_parms); | ||||
|  | ||||
|  | ||||
| // ROUTINES IN UTILS.ASM | ||||
|  | ||||
| unsigned long read_fb_32(unsigned long offset); | ||||
| void write_fb_32(unsigned long offset, unsigned long data); | ||||
| unsigned long read_gp_32(unsigned long offset); | ||||
| void write_gp_32(unsigned long offset, unsigned long data); | ||||
| unsigned char read_vg_8(unsigned long offset); | ||||
| void write_vg_8(unsigned long offset, unsigned char data); | ||||
| unsigned long read_vg_32(unsigned long offset); | ||||
| void write_vg_32(unsigned long offset, unsigned long data); | ||||
| unsigned long read_df_32(unsigned long offset); | ||||
| void write_df_32(unsigned long offset, unsigned long data); | ||||
| unsigned long read_vip_32(unsigned long offset); | ||||
| void write_vip_32(unsigned long offset, unsigned long data); | ||||
| void asmRead(unsigned short msrReg, unsigned long msrAddr, unsigned long *ptrHigh, unsigned long *ptrLow); | ||||
| void asmWrite(unsigned short msrReg, unsigned long msrAddr, unsigned long *ptrHigh, unsigned long *ptrLow); | ||||
|  | ||||
							
								
								
									
										55
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/main.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										55
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/main.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| ;/* | ||||
| ;* Copyright (c) 2007-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| ;* | ||||
| ;* This library is free software; you can redistribute it and/or modify | ||||
| ;* it under the terms of the GNU Lesser General Public License as | ||||
| ;* published by the Free Software Foundation; either version 2.1 of the | ||||
| ;* License, or (at your option) any later version. | ||||
| ;* | ||||
| ;* This code is distributed in the hope that it will be useful, | ||||
| ;* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| ;* Lesser General Public License for more details. | ||||
| ; | ||||
| ;* You should have received a copy of the GNU Lesser General | ||||
| ;* Public License along with this library; if not, write to the | ||||
| ;* Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| ;* Boston, MA 02111-1307 USA | ||||
| ;*/ | ||||
|  | ||||
| ;*     This file contains the VSM header for the LXVG VSM   | ||||
|  | ||||
|  | ||||
| .model tiny,c | ||||
| .486 | ||||
| .CODE | ||||
|  | ||||
| include VSA2.INC | ||||
|  | ||||
| externdef edata:proc | ||||
| externdef _end:proc | ||||
| externdef vsa2_message_loop:proc | ||||
|  | ||||
| public  VSM_Hdr | ||||
|  | ||||
|  | ||||
| VSM_Hdr: | ||||
|  | ||||
| 	dd	VSM_SIGNATURE		; VSM signature | ||||
| 	db	VSM_VGA			; VSM type | ||||
| 	db	0FFh			; Any CPU | ||||
| 	dw	0FFFFh			; Any Chipset | ||||
| 	dw	0101h			; VSM version 01.01 | ||||
| 	dd	OFFSET edata		; Size of VSM module | ||||
| 	dw	OFFSET vsa2_message_loop; EntryPoint | ||||
| 	dd	OFFSET _end		; DS Limit | ||||
| 	dw	0000h			; Requirements | ||||
| 	dw	VSA_VERSION		; VSA version | ||||
| 	db	sizeof(VSM_Header) - ($-VSM_Hdr) dup (0) | ||||
|  | ||||
|  | ||||
| 	END	VSM_Hdr | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										158
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/makefile
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										158
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/makefile
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,158 @@ | ||||
| # Copyright (c) 2007-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| # | ||||
| # This library is free software; you can redistribute it and/or modify | ||||
| # it under the terms of the GNU Lesser General Public License as | ||||
| # published by the Free Software Foundation; either version 2.1 of the | ||||
| # License, or (at your option) any later version. | ||||
| # | ||||
| # This code is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| # Lesser General Public License for more details. | ||||
|  | ||||
| # You should have received a copy of the GNU Lesser General | ||||
| # Public License along with this library; if not, write to the | ||||
| # Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| # Boston, MA 02111-1307 USA | ||||
|  | ||||
| ###################################################################### | ||||
| # | ||||
| #				Init variables | ||||
| # | ||||
| ###################################################################### | ||||
| !ifndef VSA2ROOT | ||||
| VSA2ROOT	= .. | ||||
| !endif | ||||
|  | ||||
| BUILD_DIR	= $(VSA2ROOT)\build | ||||
| OBJECT		= obj | ||||
| !include $(BUILD_DIR)\setvars.mak | ||||
|  | ||||
| .SUFFIXES: .asm .c .h .inc .map .obj .mac | ||||
|  | ||||
| INCLUDE		= $(OBJECT) | ||||
|  | ||||
|  | ||||
| ###################################################################### | ||||
| # | ||||
| #				Build Macros | ||||
| # | ||||
| ###################################################################### | ||||
|  | ||||
| VGA_C_OBJS	= \ | ||||
| 		$(OBJECT)\vsa2.obj \ | ||||
| 		$(OBJECT)\init.obj \ | ||||
| 		$(OBJECT)\msr.obj \ | ||||
| 		$(OBJECT)\decode.obj \ | ||||
| 		$(OBJECT)\vgdata.obj \ | ||||
| 		$(OBJECT)\lxhwctl.obj \ | ||||
|  | ||||
| VGA_ASM_OBJS	= \ | ||||
| 		$(OBJECT)\main.obj \ | ||||
| 		$(OBJECT)\utils.obj \ | ||||
|  | ||||
|  | ||||
| VGA_OBJS	= $(VGA_ASM_OBJS)  $(VGA_C_OBJS) | ||||
|  | ||||
| VGA_VSM	= $(OBJECT)\lxvg.vsm | ||||
|  | ||||
| ####################################################################### | ||||
| # | ||||
| #				Targets | ||||
| # | ||||
| ####################################################################### | ||||
|  | ||||
|  | ||||
| all: setenv | ||||
| 	$(MAKE) lxvga.vsm "CPU=lx" | ||||
|  | ||||
| lxvga.vsm: $(OBJECT) $(VGA_OBJS) | ||||
| 	$(LN) $(LOPTS_VSM) @<< | ||||
| $(VGA_OBJS:	 =+^ | ||||
| ) | ||||
| $(VGA_VSM) | ||||
| lxvg.map | ||||
| $(BUILD_DIR)\obj\$(TOOL_LIB) ; | ||||
| <<NOKEEP | ||||
| 	$(COPY) $(VGA_VSM) $(BUILDOBJ) | ||||
|  | ||||
| #This and only this clean target must exist as it is called by cleanall | ||||
| #cleanall and cleanlocal are defined in rules.mak | ||||
|  | ||||
| clean: cleanlocal cleanlib | ||||
|  | ||||
| $(OBJECT): | ||||
| 	-@md $(OBJECT) | ||||
|  | ||||
| ####################################################################### | ||||
| # | ||||
| #				Dependencies | ||||
| # | ||||
| ####################################################################### | ||||
|  | ||||
| $(VGA_ASM_OBJS): $(MAKEDIR)\makefile \ | ||||
| 		$(OBJECT)\vsa2.inc \ | ||||
|  | ||||
| $(VGA_C_OBJS): $(MAKEDIR)\makefile \ | ||||
| 		$(BUILD_DIR)\obj\$(TOOL_LIB) \ | ||||
| 		$(OBJECT)\vsa2.h \ | ||||
| 		$(OBJECT)\isa.h \ | ||||
| 		$(OBJECT)\chipset.h \ | ||||
| 		$(OBJECT)\vr.h \ | ||||
| 		$(OBJECT)\pci.h \ | ||||
| 		$(OBJECT)\lxvg.h \ | ||||
| 		$(OBJECT)\vgdata.h \ | ||||
|  | ||||
| ###################################################################### | ||||
| # | ||||
| #				Common Targets | ||||
| # | ||||
| ###################################################################### | ||||
| # include common targets and inference rules | ||||
| !include $(BUILD_DIR)\rules.mak | ||||
|  | ||||
| ###################################################################### | ||||
| # | ||||
| #				Inference Rules | ||||
| # | ||||
| ###################################################################### | ||||
| # Override common inference rules here | ||||
|  | ||||
| {$(INC_DIR)}.h{$(OBJECT)}.inc: | ||||
| 	$(H2) /Fa$(OBJECT)\$(@F) /nologo /Zni /C $< | ||||
|  | ||||
| {$(INC_DIR)\$(CPU)}.h{$(OBJECT)}.inc: | ||||
| 	$(H2) /Fa$(OBJECT)\$(@F) /nologo /Zni /C $< | ||||
|  | ||||
| {$(SYSMGR_SRC)}.h{$(OBJECT)}.inc: | ||||
| 	$(H2) /Fa$(OBJECT)\$(@F) /nologo /Zns /C $< | ||||
|  | ||||
| {$(SYSMGR_SRC)\$(CPU)}.h{$(OBJECT)}.inc: | ||||
| 	$(H2) /Fa$(OBJECT)\$(@F) /nologo /Zns /C $< | ||||
|  | ||||
| {$(MAKEDIR)}.c{$(OBJECT)}.obj: | ||||
| 	$(CC) /AT /W3 /G3s /Gx /Oi /c /I$(OBJECT) $(CDEFS) /Fo$@ $< | ||||
|  | ||||
| {$(MAKEDIR)\$(CPU)}.c{$(OBJECT)}.obj: | ||||
| 	$(CC) /AT /W3 /G3s /Gx /Oi /c /I$(OBJECT) $(CDEFS) /Fo$@ $< | ||||
|  | ||||
| {$(MAKEDIR)}.asm{$(OBJECT)}.obj: | ||||
| 	$(AS) /nologo $(AS_OPTS) $(CDEFS) /Fo$@ $< | ||||
|  | ||||
| {$(MAKEDIR)\$(CPU)}.asm{$(OBJECT)}.obj: | ||||
| 	$(AS) /nologo $(AS_OPTS) $(CDEFS) /Fo$@ $< | ||||
|  | ||||
| {$(MAKEDIR)}.h{$(OBJECT)}.h: | ||||
| 	copy $< $@ | ||||
|  | ||||
| {$(USER)\lxvg}.h{$(OBJECT)}.h: | ||||
| 	copy $< $@ | ||||
|  | ||||
| {$(USER)\lxvg}.h{$(OBJECT)}.inc: | ||||
| 	$(H2) /Fa$(OBJECT)\$(@F) /nologo /Zns /C $< | ||||
|  | ||||
| {$(USER)\lxvg}.asm{$(OBJECT)}.obj: | ||||
| 	$(AS) /nologo $(AS_OPTS) $(CDEFS) /Fo$@ $< | ||||
|  | ||||
| {$(USER)\lxvg}.c{$(OBJECT)}.obj: | ||||
| 	$(CC) /AT /W3 /G3s /Gx /Oi /c /I$(OBJECT) $(CDEFS) /Fo$@ $< | ||||
							
								
								
									
										305
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/msr.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										305
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/msr.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,305 @@ | ||||
| /* | ||||
| * Copyright (c) 2007-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA | ||||
| */ | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| #include "lxvg.h" | ||||
| #include "vsa2.h" | ||||
|  | ||||
| #define FOUND			0 | ||||
| #define UNKNOWN			1 | ||||
| #define REQ_NOT_FOUND	2 | ||||
|  | ||||
| struct tagMSR msrDev[] = {  | ||||
| 	{ UNKNOWN,	ID_MCP,		FAKE_ADDRESS }, | ||||
| 	{ UNKNOWN,	ID_MC,		FAKE_ADDRESS },		 | ||||
| 	{ UNKNOWN,	ID_GP,		FAKE_ADDRESS }, | ||||
| 	{ UNKNOWN,	ID_VG,		FAKE_ADDRESS }, | ||||
| 	{ UNKNOWN,	ID_DF,		FAKE_ADDRESS }, | ||||
| 	{ UNKNOWN,	ID_VIP,		FAKE_ADDRESS }  };		 | ||||
| // DEBUG | ||||
| //	{ UNKNOWN,	ID_MBIU,	FAKE_ADDRESS }  }; | ||||
| // DEBUG | ||||
|  | ||||
| #define NUM_DEVS sizeof(msrDev) / sizeof(struct tagMSR) | ||||
|  | ||||
|  | ||||
| //================================================================= | ||||
| //	BOOL msrInit(void) | ||||
| // | ||||
| //		Handles the details of finding each possible device on the MBUS. | ||||
| //		If a given device is not found, its structure is left inited at default. | ||||
| //		If a given device is found, its structure is updated. | ||||
| // | ||||
| //		This init routine only checks for devices already in the structure. | ||||
| // | ||||
| //		Returns: | ||||
| //			TRUE - If, for every device, its address was found. | ||||
| //			FALSE - If, for any device, an error was encountered. | ||||
| // | ||||
|  | ||||
| unsigned char msrInit(void) | ||||
| { | ||||
| 	unsigned short issues=0, i; | ||||
|  | ||||
| 	// | ||||
| 	// For each item in the list, try to find its address | ||||
| 	// | ||||
| 	for (i=0; i < NUM_DEVS; i++)  | ||||
| 	{ | ||||
| 		msrDev[i].Present = msrFindDevice(&msrDev[i]); | ||||
| 		if (msrDev[i].Present != FOUND) issues++; | ||||
| 	} | ||||
|  | ||||
| 	if (issues) return(FALSE); | ||||
|  | ||||
| /* | ||||
| 	// | ||||
| 	// For each item in the list, get its real device ID | ||||
| 	// | ||||
| 	for (i=0; i < NUM_DEVS; i++) | ||||
| 		msrDev[i].Id = msrIdDevice(msrDev[i].Address); | ||||
| */ | ||||
| 	return(TRUE); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| //================================================================= | ||||
| // unsigned short msrFindDevice(struct msr *pDev) | ||||
| // | ||||
| //		Returns: | ||||
| //			FOUND - if no errors were detected.  msrAddress has been updated. | ||||
| //			REQ_NOT_FOUND - Address for 'devId' is unknown.  Caller should  | ||||
| //					call msrInit() first.  ptr->Address is not updated. | ||||
| // | ||||
| //			NOTE: The structure default for the 'Present' field is "UNKNOWN". | ||||
| //				Therefore, if a given id is passed to msrFindDevice, the 'Present' | ||||
| //				field will be updated with either 'FOUND' or 'REQ_NOT_FOUND'.  If | ||||
| //				a given ID is not passed to msrFindDevice, the 'Present' field will | ||||
| //				be left as 'UNKNOWN'. | ||||
| // | ||||
|  | ||||
| unsigned short msrFindDevice(struct tagMSR *pDev) | ||||
| { | ||||
| 	unsigned long msrAdr; | ||||
| 	msrAdr = SYS_LOOKUP_DEVICE(pDev->Id,1); | ||||
| 	if (0 != msrAdr) | ||||
| 	{ | ||||
| 		pDev->Routing = msrAdr; | ||||
| 		return(FOUND); | ||||
| 	} | ||||
|  | ||||
| 	// All done... | ||||
| 	return(REQ_NOT_FOUND); | ||||
| } | ||||
|  | ||||
|  | ||||
| //================================================================= | ||||
| // unsigned short msrIdDevice(unsigned long address) | ||||
| // | ||||
| //		Reads the capabilities MSR register (typically 0x2000) | ||||
| //		and returns the 'id' field (bits 23:8) | ||||
| // | ||||
| //		Returns: | ||||
| //			Bits 23:8 of MSR low DWORD | ||||
| // | ||||
|  | ||||
| unsigned short msrIdDevice(unsigned long address) | ||||
| { | ||||
| 	struct mValue msrValue; | ||||
|  | ||||
| 	asmRead(MBD_MSR_CAP, address, &msrValue.high, &msrValue.low); | ||||
|  | ||||
| 	return((unsigned short)((msrValue.low & DEVID_MASK) >> 8));  | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| //================================================================= | ||||
| // unsigned short msrRead(unsigned short msrIdx, unsigned short msrReg, struct mValue msrValue) | ||||
| // | ||||
| //		Performs a 64-bit read from 'msrReg' in device 'devID'. | ||||
| // | ||||
| //		Returns: | ||||
| //			FOUND - if no errors were detected and msrValue has been updated. | ||||
| //			UNKNOWN	- an error was detected.  msrValue is not updated. | ||||
| //			REQ_NOT_FOUND - 'msrAddress' for 'devID' is unknown.  Caller | ||||
| //						should call msrInit() first.  msrValue is not updated. | ||||
| // | ||||
|  | ||||
| unsigned short msrRead(unsigned short msrIdx, unsigned short msrReg, struct mValue *msrValue) | ||||
| { | ||||
| 	 | ||||
| 	if (msrDev[msrIdx].Present == FOUND) { | ||||
| 		asmRead(msrReg, msrDev[msrIdx].Routing, &msrValue->high, &msrValue->low); | ||||
| 	} | ||||
|  | ||||
| 	return (msrDev[msrIdx].Present); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| //================================================================= | ||||
| // unsigned short msrWrite(unsigned short msrIdx, unsigned short msrReg, unsigned long outHi, unsigned long outLo) | ||||
| // | ||||
| //		Performs a 64-bit write to 'msrReg' in device 'devID'. | ||||
| // | ||||
| //		Returns: | ||||
| //			FOUND - if no errors were detected and msrValue has been updated. | ||||
| //			UNKNOWN	- an error was detected.  msrValue is not updated. | ||||
| //			REQ_NOT_FOUND - 'msrAddress' for 'devID' is unknown.  Caller | ||||
| //						should call msrInit() first.  msrValue is not updated. | ||||
| // | ||||
|  | ||||
| unsigned short msrWrite(unsigned short msrIdx, unsigned short msrReg, unsigned long outHi, unsigned long outLo) | ||||
| { | ||||
| 	struct mValue mVal; | ||||
|  | ||||
| 	if (msrDev[msrIdx].Present == FOUND) { | ||||
| 		// Incorporate the OR values | ||||
| 		mVal.high = outHi; | ||||
| 		mVal.low = outLo; | ||||
|  | ||||
| 		asmWrite(msrReg, msrDev[msrIdx].Routing, &mVal.high, &mVal.low); | ||||
| 	} | ||||
|  | ||||
| 	return (msrDev[msrIdx].Present); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| //================================================================= | ||||
| // void msrModify(unsigned short msrIdx, unsigned short msrReg, unsigned long maskHi, unsigned long maskLo,  | ||||
| //						unsigned long orHi, unsigned long orLo) | ||||
| // | ||||
| //		Performs a 64-bit read-modify-write of 'msrReg' in device 'msrIdx'. | ||||
| //		The mask values indicate the bits that are to be changed, so the  | ||||
| //		register values are ANDed with the NOT of the mask values to clear | ||||
| //		out the affected bits. | ||||
| // | ||||
| //		Returns: | ||||
| //			NONE | ||||
| // | ||||
|  | ||||
| void msrModify(unsigned short msrIdx, unsigned short msrReg, unsigned long maskHi, unsigned long maskLo, unsigned long orHi, unsigned long orLo)  | ||||
| { | ||||
| 	struct mValue mVal; | ||||
|  | ||||
| 	if (msrDev[msrIdx].Present == FOUND) { | ||||
| 		asmRead(msrReg, msrDev[msrIdx].Routing, &mVal.high, &mVal.low); | ||||
|  | ||||
| 		// Incorporate the AND values | ||||
| 		mVal.high &= ~maskHi; | ||||
| 		mVal.low &= ~maskLo; | ||||
|  | ||||
| 		// Incorporate the OR values | ||||
| 		mVal.high |= orHi; | ||||
| 		mVal.low |= orLo; | ||||
|  | ||||
| 		asmWrite(msrReg, msrDev[msrIdx].Routing, &mVal.high, &mVal.low); | ||||
| 	} | ||||
|  | ||||
| 	return; | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| //================================================================= | ||||
| // void msrSave(unsigned short msrIdx, unsigned short *msrList[], struct mValue *msrValue[]) | ||||
| // | ||||
| //		Saves a list of MSRs limited by an index value of 0xFFFF.  | ||||
| // | ||||
| // | ||||
|  | ||||
| void msrSave(unsigned short msrIdx, unsigned short *msrList, struct mValue *msrValue) | ||||
| { | ||||
| 	unsigned char finished = FALSE; | ||||
| 	unsigned char i = 0; | ||||
|  | ||||
| 	if (msrDev[msrIdx].Present == FOUND) | ||||
| 	{ | ||||
| 		while (FALSE == finished) | ||||
| 		{	 | ||||
| 			if (0xFFFF == msrList[i]) | ||||
| 				finished = TRUE; | ||||
| 			else | ||||
| 			{ | ||||
| 				asmRead(msrList[i], msrDev[msrIdx].Routing, &msrValue[i].high, &msrValue[i].low); | ||||
| 				i++; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return; | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| //================================================================= | ||||
| // void msrRestore(unsigned short msrIdx, unsigned short *msrList[], struct mValue *msrValue[]) | ||||
| // | ||||
| //		Restores a previously saved list of MSRs limited by an index value of 0xFFFF.  | ||||
| // | ||||
| // | ||||
|  | ||||
| void msrRestore(unsigned short msrIdx, unsigned short *msrList, struct mValue *msrValue) | ||||
| { | ||||
| 	unsigned char finished = FALSE; | ||||
| 	unsigned char i = 0; | ||||
|  | ||||
| 	if (msrDev[msrIdx].Present == FOUND) | ||||
| 	{ | ||||
| 		while (FALSE == finished) | ||||
| 		{	 | ||||
| 			if (0xFFFF == msrList[i]) | ||||
| 				finished = TRUE; | ||||
| 			else | ||||
| 			{ | ||||
| 				asmWrite(msrList[i], msrDev[msrIdx].Routing, &msrValue[i].high, &msrValue[i].low); | ||||
| 				i++; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return; | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| //================================================================= | ||||
| // void msrDump(unsigned short msrIdx, unsigned short msrReg) | ||||
| // | ||||
| //		Performs a 64-bit read of 'msrReg' in device 'msrIdx' for debug. | ||||
| // | ||||
| //		Returns: | ||||
| //			NONE | ||||
| // | ||||
|  | ||||
| void msrDump(unsigned short msrIdx, unsigned short msrReg)  | ||||
| { | ||||
| 	struct mValue mVal; | ||||
|  | ||||
| 	asmRead(msrReg, msrDev[msrIdx].Routing, &mVal.high, &mVal.low); | ||||
|  | ||||
| 	return; | ||||
|  | ||||
| } | ||||
|  | ||||
							
								
								
									
										271
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/utils.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										271
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/utils.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,271 @@ | ||||
| ;/* | ||||
| ;* Copyright (c) 2007-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| ;* | ||||
| ;* This library is free software; you can redistribute it and/or modify | ||||
| ;* it under the terms of the GNU Lesser General Public License as | ||||
| ;* published by the Free Software Foundation; either version 2.1 of the | ||||
| ;* License, or (at your option) any later version. | ||||
| ;* | ||||
| ;* This code is distributed in the hope that it will be useful, | ||||
| ;* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| ;* Lesser General Public License for more details. | ||||
| ; | ||||
| ;* You should have received a copy of the GNU Lesser General | ||||
| ;* Public License along with this library; if not, write to the | ||||
| ;* Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| ;* Boston, MA 02111-1307 USA | ||||
| ;*/ | ||||
|  | ||||
|  | ||||
| .MODEL TINY,c | ||||
| .CODE | ||||
| .586p | ||||
|  | ||||
| ;---------------------------------------------------------------------------- | ||||
| ; BASE ADDRESSES | ||||
| ; These global variables are used to access the memory mapped regions. | ||||
| ; VSA II maintains a flat 4 Gig selector in FS. | ||||
| ;---------------------------------------------------------------------------- | ||||
|  | ||||
| extrn framebuffer_base:dword | ||||
| extrn GPregister_base:dword | ||||
| extrn VGregister_base:dword | ||||
| extrn DFregister_base:dword | ||||
| extrn VIPregister_base:dword | ||||
|  | ||||
|  | ||||
|  | ||||
| ;---------------------------------------------------------------------------- | ||||
| ; READ_FB_32: Returns a 32-bit value from the frame buffer. | ||||
| ; | ||||
| ; Parameter specifies 32-bit offset. | ||||
| ;---------------------------------------------------------------------------- | ||||
|  | ||||
| read_fb_32	proc c	address: dword | ||||
|  | ||||
| 	mov		ebx, [address] | ||||
| 	add		ebx, [framebuffer_base] | ||||
| 	mov		eax, fs:[ebx] | ||||
| 	mov		edx, eax | ||||
| 	shr		edx, 16 | ||||
| 	ret | ||||
|  | ||||
| read_fb_32	endp | ||||
|  | ||||
| ;---------------------------------------------------------------------------- | ||||
| ; WRITE_FB_32: Writes a 32-bit value to the frame buffer. | ||||
| ; | ||||
| ; Parameters specify 32-bit offset and 32-bit data value. | ||||
| ;---------------------------------------------------------------------------- | ||||
|  | ||||
| write_fb_32 proc c	address: dword, data: dword | ||||
|  | ||||
| 	mov		ebx, [address] | ||||
| 	add		ebx, [framebuffer_base] | ||||
| 	mov		eax, [data] | ||||
| 	mov		fs:[ebx], eax | ||||
| 	ret | ||||
|  | ||||
| write_fb_32 endp | ||||
|  | ||||
|  | ||||
| ;---------------------------------------------------------------------------- | ||||
| ; READ_GP_32: Returns 32-bit value from the graphics processor register space. | ||||
| ; | ||||
| ; Parameter specifies 32-bit offset. | ||||
| ;---------------------------------------------------------------------------- | ||||
|  | ||||
| read_gp_32	proc c	address: dword | ||||
|  | ||||
| 	mov		ebx, [address] | ||||
| 	add		ebx, [GPregister_base] | ||||
| 	mov		eax, fs:[ebx] | ||||
| 	mov		edx, eax | ||||
| 	shr		edx, 16 | ||||
| 	ret | ||||
|  | ||||
| read_gp_32	endp | ||||
|  | ||||
| ;---------------------------------------------------------------------------- | ||||
| ; WRITE_GP_32: Writes 32-bit value to graphics processor register space. | ||||
| ; | ||||
| ; Parameters specify 32-bit offset and 32-bit data value. | ||||
| ;---------------------------------------------------------------------------- | ||||
|  | ||||
| write_gp_32 proc c	address: dword, data: dword | ||||
|  | ||||
| 	mov		ebx, [address] | ||||
| 	add		ebx, [GPregister_base] | ||||
| 	mov		eax, [data] | ||||
| 	mov		fs:[ebx], eax | ||||
| 	ret | ||||
|  | ||||
| write_gp_32 endp | ||||
|  | ||||
|  | ||||
| ;---------------------------------------------------------------------------- | ||||
| ; READ_VG_8: Returns 8-bit value from the video generator register space. | ||||
| ; | ||||
| ; Parameter specifies 32-bit offset. | ||||
| ;---------------------------------------------------------------------------- | ||||
|  | ||||
| read_vg_8	proc c	address: dword | ||||
|  | ||||
| 	mov		ebx, [address] | ||||
| 	add		ebx, [VGregister_base] | ||||
| 	mov		al, fs:[ebx] | ||||
| 	ret | ||||
|  | ||||
| read_vg_8	endp | ||||
|  | ||||
| ;---------------------------------------------------------------------------- | ||||
| ; WRITE_VG_8: Writes 8-bit value to video generator register space. | ||||
| ; | ||||
| ; Parameters specify 32-bit offset and 8-bit data value. | ||||
| ;---------------------------------------------------------------------------- | ||||
|  | ||||
| write_vg_8 proc c  address: dword, data: byte | ||||
|  | ||||
| 	mov		ebx, [address] | ||||
| 	add		ebx, [VGregister_base] | ||||
| 	mov		al, [data] | ||||
| 	mov		fs:[ebx], al | ||||
| 	ret | ||||
|  | ||||
| write_vg_8 endp | ||||
|  | ||||
|  | ||||
| ;---------------------------------------------------------------------------- | ||||
| ; READ_VG_32: Returns 32-bit value from the video generator register space. | ||||
| ; | ||||
| ; Parameter specifies 32-bit offset. | ||||
| ;---------------------------------------------------------------------------- | ||||
|  | ||||
| read_vg_32	proc c	address: dword | ||||
|  | ||||
| 	mov		ebx, [address] | ||||
| 	add		ebx, [VGregister_base] | ||||
| 	mov		eax, fs:[ebx] | ||||
| 	mov		edx, eax | ||||
| 	shr		edx, 16 | ||||
| 	ret | ||||
|  | ||||
| read_vg_32	endp | ||||
|  | ||||
| ;---------------------------------------------------------------------------- | ||||
| ; WRITE_VG_32: Writes 32-bit value to video generator register space. | ||||
| ; | ||||
| ; Parameters specify 32-bit offset and 32-bit data value. | ||||
| ;---------------------------------------------------------------------------- | ||||
|  | ||||
| write_vg_32 proc c	address: dword, data: dword | ||||
|  | ||||
| 	mov		ebx, [address] | ||||
| 	add		ebx, [VGregister_base] | ||||
| 	mov		eax, [data] | ||||
| 	mov		fs:[ebx], eax | ||||
| 	ret | ||||
|  | ||||
| write_vg_32 endp | ||||
|  | ||||
|  | ||||
| ;---------------------------------------------------------------------------- | ||||
| ; READ_DF_32: Returns 32-bit value from the display filter register space. | ||||
| ; | ||||
| ; Parameter specifies 32-bit offset. | ||||
| ;---------------------------------------------------------------------------- | ||||
|  | ||||
| read_df_32	proc c	address: dword | ||||
|  | ||||
| 	mov		ebx, [address] | ||||
| 	add		ebx, [DFregister_base] | ||||
| 	mov		eax, fs:[ebx] | ||||
| 	mov		edx, eax | ||||
| 	shr		edx, 16 | ||||
| 	ret | ||||
|  | ||||
| read_df_32	endp | ||||
|  | ||||
| ;---------------------------------------------------------------------------- | ||||
| ; WRITE_DF_32: Writes 32-bit value to display filter register space. | ||||
| ; | ||||
| ; Parameters specify 32-bit offset and 32-bit data value. | ||||
| ;---------------------------------------------------------------------------- | ||||
|  | ||||
| write_df_32 proc c	address: dword, data: dword | ||||
|  | ||||
| 	mov		ebx, [address] | ||||
| 	add		ebx, [DFregister_base] | ||||
| 	mov		eax, [data] | ||||
| 	mov		fs:[ebx], eax | ||||
| 	ret | ||||
|  | ||||
| write_df_32 endp | ||||
|  | ||||
|  | ||||
| ;---------------------------------------------------------------------------- | ||||
| ; READ_VIP_32: Returns 32-bit value from the video input port register space. | ||||
| ; | ||||
| ; Parameter specifies 32-bit offset. | ||||
| ;---------------------------------------------------------------------------- | ||||
|  | ||||
| read_vip_32	proc c	address: dword | ||||
|  | ||||
| 	mov		ebx, [address] | ||||
| 	add		ebx, [VIPregister_base] | ||||
| 	mov		eax, fs:[ebx] | ||||
| 	mov		edx, eax | ||||
| 	shr		edx, 16 | ||||
| 	ret | ||||
|  | ||||
| read_vip_32	endp | ||||
|  | ||||
| ;---------------------------------------------------------------------------- | ||||
| ; WRITE_VIP_32: Writes 32-bit value to video input port register space. | ||||
| ; | ||||
| ; Parameters specify 32-bit offset and 32-bit data value. | ||||
| ;---------------------------------------------------------------------------- | ||||
|  | ||||
| write_vip_32 proc c	 address: dword, data: dword | ||||
|  | ||||
| 	mov		ebx, [address] | ||||
| 	add		ebx, [VIPregister_base] | ||||
| 	mov		eax, [data] | ||||
| 	mov		fs:[ebx], eax | ||||
| 	ret | ||||
|  | ||||
| write_vip_32 endp | ||||
|  | ||||
|  | ||||
| asmRead		proc public uses bx eax ecx edx, msrReg:word, msrAddr:dword, ptrHigh:word, ptrLow:word | ||||
| 	mov		ecx, msrAddr | ||||
| 	mov		cx, msrReg | ||||
| 	RDMSR | ||||
|  | ||||
| 	mov		bx, ptrHigh | ||||
| 	mov		[bx], edx | ||||
| 	mov		bx, ptrLow | ||||
| 	mov		[bx], eax | ||||
|  | ||||
| 	ret | ||||
|  | ||||
| asmRead		endp | ||||
|  | ||||
|  | ||||
| asmWrite	proc public uses bx eax ecx edx, msrReg:word, msrAddr:dword, ptrHigh:word, ptrLow:word | ||||
|  | ||||
| 	mov		ecx, msrAddr | ||||
| 	mov		cx, msrReg | ||||
|  | ||||
| 	mov		bx, ptrHigh | ||||
| 	mov		edx, [bx] | ||||
| 	mov		bx, ptrLow | ||||
| 	mov		eax, [bx] | ||||
|  | ||||
| 	WRMSR | ||||
| 	ret | ||||
|  | ||||
| asmWrite	endp | ||||
|  | ||||
| END | ||||
							
								
								
									
										55
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/vgdata.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										55
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/vgdata.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| /* | ||||
| * Copyright (c) 2007-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA | ||||
| */ | ||||
| // This file declares the data structures and arrays used by lxvg. | ||||
|  | ||||
|  | ||||
|  | ||||
| #include "lxvg.h" | ||||
| #include "vsa2.h" | ||||
| #include "vr.h" | ||||
|  | ||||
| //--------------------------------------------------------------------------- | ||||
| // MAIN lxvg DATA STRUCTURE | ||||
| // This data structure maintains the current lxvg state. | ||||
| //--------------------------------------------------------------------------- | ||||
|  | ||||
| VGDATA VGdata; | ||||
|  | ||||
| unsigned long vga_config_addr; | ||||
|  | ||||
| unsigned long GPregister_base; | ||||
| unsigned long VGregister_base; | ||||
| unsigned long DFregister_base; | ||||
| unsigned long VIPregister_base; | ||||
| unsigned long framebuffer_base; | ||||
|  | ||||
| unsigned long VG_SMI_Mask; | ||||
|  | ||||
| // General system information... | ||||
| Hardware SystemInfo; | ||||
|  | ||||
| // The main VG state information flag. | ||||
| unsigned long VGState = SF_DISABLED; | ||||
| unsigned long lockNest = 0;			// Nested SMI recognition scheme | ||||
| unsigned long saveLock;				// Locking | ||||
|  | ||||
| // The virtual registers | ||||
| unsigned short vReg[MAX_VG+1]; | ||||
|  | ||||
| // END OF FILE | ||||
							
								
								
									
										36
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/vgdata.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										36
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/vgdata.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| /* | ||||
| * Copyright (c) 2007-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA | ||||
| */ | ||||
|  | ||||
| // This file defines the main data structure for LXVG. | ||||
|  | ||||
|  | ||||
|  | ||||
| #define SIZE_PCI_HEADER				0x50 | ||||
|  | ||||
| typedef struct tagVGDATA | ||||
| { | ||||
|  | ||||
| 	// PCI HEADER | ||||
|  | ||||
| 	unsigned char pci_header[SIZE_PCI_HEADER];	// PCI header data | ||||
| 	unsigned long pci_fb_mask; | ||||
|  | ||||
| } VGDATA; | ||||
|  | ||||
| // END OF FILE | ||||
							
								
								
									
										133
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/vsa2.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										133
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/lxvg/vsa2.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,133 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA | ||||
| */ | ||||
| // Function: | ||||
| //	  This module contains the main code to handle the VSA II interface. | ||||
|  | ||||
|  | ||||
| #include "vsa2.h" | ||||
| #include "vr.h" | ||||
| #include "lxvg.h" | ||||
|  | ||||
| // This is required here because of inclusion problems in LXVG.h | ||||
| extern Hardware SystemInfo; | ||||
|  | ||||
| // ARRAY TO STORE VSA II MESSAGE PARAMETERS | ||||
| unsigned long VSAparam[MAX_MSG_PARAM]; | ||||
|  | ||||
|  | ||||
| //--------------------------------------------------------------------------- | ||||
| // vsa2_message_loop | ||||
| // | ||||
| // This is the main routine that handles the VSA II message interface. | ||||
| //--------------------------------------------------------------------------- | ||||
|  | ||||
| void vsa2_message_loop(void) | ||||
| { | ||||
| 	MSG Msg; | ||||
|  | ||||
| 	// SPIN FOREVER ON MESSAGE LOOP | ||||
| 	// The VSA system manager branches here after loading the VSM.	Control | ||||
| 	// is returned to the system manager using an SMI. | ||||
|  | ||||
| 	do { | ||||
|  | ||||
| 		// GET THE NEXT MESSAGE | ||||
| 		// If a message is available, the macro reads the parameter data | ||||
| 		// from the VSM header and copies it to the VSAparam global array. | ||||
| 		// If a message is not available, control returns to the main VSA | ||||
| 		// dispatcher. | ||||
| 		Msg = SYS_GET_NEXT_MSG(&VSAparam); | ||||
|  | ||||
| 		// DECODE THE MESSAGE | ||||
| 		switch(Msg) | ||||
| 		{ | ||||
| 			case MSG_INITIALIZE: | ||||
|  | ||||
| 				// CHECK IF NORMAL INITIALIZATION | ||||
| 				// Currently there is no "end of post" initialization. | ||||
| 				if (VSAparam[0] == EARLY_INIT)	{ | ||||
|  | ||||
| 					// Get information about the system I'm executing on. | ||||
| 					SYS_GET_SYSTEM_INFO(&SystemInfo); | ||||
|  | ||||
| 					// REGISTER FOR VGA VIRTUAL REGISTER EVENTS | ||||
| 					SYS_REGISTER_EVENT(EVENT_VIRTUAL_REGISTER, VRC_VG, 0, NORMAL_PRIORITY); | ||||
|  | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					// Now we can handle DPMS and driver active | ||||
| 					VGState |= SF_END_POST; | ||||
| 				} | ||||
| 				break; | ||||
|  | ||||
| 			case MSG_EVENT: | ||||
|  | ||||
| 				// DECODE THE EVENT | ||||
| 				decode_vsa2_event(); | ||||
| 				break; | ||||
|  | ||||
| 			case MSG_WARM_BOOT: | ||||
| 				break; | ||||
|  | ||||
|  | ||||
| 			default: | ||||
| 				break; | ||||
| 		} | ||||
|  | ||||
|  | ||||
| 	} while(1); | ||||
| } | ||||
|  | ||||
| //--------------------------------------------------------------------------- | ||||
| // decode_vsa2_event | ||||
| // | ||||
| // This routine is called when the message loop receives an event. For | ||||
| // LXVG, this is either a Virtual Rgister event or a pci event | ||||
| // (trapping PCI config cycles to our device). | ||||
| //--------------------------------------------------------------------------- | ||||
|  | ||||
| void decode_vsa2_event(void) | ||||
| { | ||||
| 	// PARSE EVENT | ||||
|  | ||||
| 	switch((unsigned short)VSAparam[0]) | ||||
| 	{ | ||||
| 		case EVENT_VIRTUAL_REGISTER: | ||||
| 			if (VRC_VG == (unsigned char)(VSAparam[1] >> 8)) | ||||
| 				virtual_register_event((unsigned char)VSAparam[1], VSAparam[2], VSAparam[3]); | ||||
|  | ||||
| 			break; | ||||
|  | ||||
| 		case EVENT_PCI_TRAP: | ||||
| 			// If LXVG isn't enabled, just leave | ||||
| 			if (VGState & SF_DISABLED) break; | ||||
|  | ||||
| 			// CALL LXVG TO DECODE THE PCI TRAP EVENT | ||||
| 			// address = VSAparam[1] | ||||
| 			// size = VSAparam[2], bit 7 indicates write. | ||||
| 			// data = VSAparam[3] | ||||
|  | ||||
| 			pci_trap_event(VSAparam[1], VSAparam[2], VSAparam[3]); | ||||
| 			break; | ||||
|  | ||||
| 		default: | ||||
| 			break; | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										221
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/bugs.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										221
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/bugs.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,221 @@ | ||||
| ;  | ||||
| ; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| ;  | ||||
| ; This library is free software; you can redistribute it and/or modify | ||||
| ; it under the terms of the GNU Lesser General Public License as | ||||
| ; published by the Free Software Foundation; either version 2.1 of the | ||||
| ; License, or (at your option) any later version. | ||||
| ;  | ||||
| ; This code is distributed in the hope that it will be useful, | ||||
| ; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| ; Lesser General Public License for more details. | ||||
| ;  | ||||
| ; You should have received a copy of the GNU Lesser General | ||||
| ; Public License along with this library; if not, write to the | ||||
| ; Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| ; Boston, MA 02111-1307 USA  | ||||
| ;  | ||||
| ;*   Function:                                                         * | ||||
| ;*     This file contains hardware bug fixes.  | ||||
|  | ||||
| include VSA2.INC | ||||
| include ISA.INC | ||||
| include GX2.INC | ||||
| include CHIPSET.INC | ||||
|  | ||||
| .model tiny,c | ||||
| .586p | ||||
| .CODE | ||||
|  | ||||
| externdef Nested_SMI:       proc | ||||
| externdef SysMgr_Entry:     proc | ||||
| externdef Restore_IDT:      proc | ||||
| externdef Install_IDT:      proc | ||||
| externdef Sample_SMI_Pin:   proc | ||||
| externdef Clear_SMI_Pin:    proc | ||||
| externdef Header_Addr:      dword | ||||
| externdef HC_Status:        dword | ||||
| externdef SMI_Sources:      dword | ||||
| externdef HardwareInfo:     Hardware | ||||
|  | ||||
|  | ||||
| ;******************************************************************************* | ||||
| ; Remove the RTC fix if an RTC VSM is installed. | ||||
| ;******************************************************************************* | ||||
| Remove_RTC_Fix proc | ||||
|  | ||||
| 	mov	word ptr [Fix_RTC], 0C3F8h	; CLC  RET | ||||
| 	ret | ||||
|  | ||||
| Remove_RTC_Fix endp | ||||
|  | ||||
|  | ||||
| ; ******************************************************************************* | ||||
| ; This routine is called upon entry to a non-nested SMI. | ||||
| ; ******************************************************************************* | ||||
| VSA_Entry proc | ||||
|  | ||||
| 	; Patch a "jmp Nested_SMI" at Start | ||||
| 	mov	word ptr ds:[1], OFFSET Nested_SMI-3 | ||||
|  | ||||
| 	; Install exception handlers | ||||
| 	call	Install_IDT | ||||
| 	ret | ||||
|  | ||||
| VSA_Entry endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ; ******************************************************************************* | ||||
| ; This routine is called upon exit from a non-nested SMI. | ||||
| ; It performs: | ||||
| ;   1) RTC fix | ||||
| ;   2) USB fix | ||||
| ;   3) IDT restore | ||||
| ;   4) Re-enable Suspend Modulation | ||||
| ; | ||||
| ; If CF=1 is returned, then loop back to SMI handlers. | ||||
| ; ******************************************************************************* | ||||
| VSA_Exit proc | ||||
|  | ||||
| 	mov	eax, [Header_Addr]	; Restore the original SMM header | ||||
| 	mov	ecx, MSR_SMM_HDR | ||||
| 	wrmsr | ||||
|  | ||||
| 	call	Fix_RTC | ||||
| 	jc	short Exit		; Don't exit from VSA | ||||
|  | ||||
| 	; Restore "JMP SysMgr_Entry" at Start | ||||
| 	mov	word ptr ds:[1], OFFSET SysMgr_Entry-3 | ||||
|  | ||||
|  | ||||
| 	call	Restore_IDT		; Restore IDT | ||||
| 	 | ||||
| 	clc | ||||
|  | ||||
| Exit:	ret | ||||
|  | ||||
| VSA_Exit endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ; ******************************************************************************* | ||||
| ; Handle the case where the RTC UIP bit was clear, application code was about to | ||||
| ; read the RTC, but an SMI occurs.  When VSA returns, the RTC is updating, so the | ||||
| ; application reads a bad value. | ||||
| ; | ||||
| ; The Solution: | ||||
| ; | ||||
| ;   The Time Stamp Counter is read upon entry to VSA.  On exit, if UIP is low or | ||||
| ; it is determined that the SMI has taken < 250 us, then just exit.  This leaves | ||||
| ; 44 us for the application to finish reading the RTC safely.   If the SMI has | ||||
| ; taken > 250 us, then spin for 500 us minus the time spent servicing the SMI.   | ||||
| ; This guarantees the RTC has finished updating.  Then set the SET bit, wait for | ||||
| ; UIP to go low, then clear the SET bit. | ||||
| ; | ||||
| ; ******************************************************************************* | ||||
| RTC_TIME	equ	250 | ||||
|  | ||||
| Fix_RTC	proc | ||||
|  | ||||
| 	in	al, CMOS_INDEX		; Get RTC index | ||||
| 	cmp	al, 9			; Only RTC indices 0-9 are UIP sensitive | ||||
| 	ja	Exit | ||||
|  | ||||
| 	mov	bl, al			; Save RTC index | ||||
| 	push	si | ||||
| 	mov	al, CMOS_STATUS_A	; Read RTC Status A | ||||
| 	out	CMOS_INDEX, al | ||||
| 	in	al, CMOS_DATA | ||||
| 	test	al, UIP | ||||
| 	jz	Restore_RTC_Index | ||||
|  | ||||
|  | ||||
| 	mov	al, CMOS_STATUS_B	; Exit if StatusB[SET] = 1 | ||||
| 	out	CMOS_INDEX, al | ||||
| 	in	al, CMOS_DATA | ||||
| 	test	al, SET | ||||
| 	jz	Restore_RTC_Index | ||||
|  | ||||
|  | ||||
|  | ||||
| 	ASSUME	SI: PTR System		; Compute time servicing SMI in us | ||||
| 	mov	si, OFFSET VSM_Header.SysStuff | ||||
| 	rdtsc		       | ||||
| 	sub	eax, [si+0].StartTime | ||||
| 	sbb	edx, [si+4].StartTime | ||||
| 	movzx	ecx, [HardwareInfo].CPU_MHz | ||||
| 	cmp	edx, ecx		; If sitting in Dowser or Standby too long, | ||||
| 	jae	Restore_RTC_Index	; the divide could overflow. | ||||
| 	div	ecx | ||||
|  | ||||
| 	cmp 	eax, RTC_TIME		; If < RTC_TIME us, exit | ||||
| 	jb	Restore_RTC_Index | ||||
|  | ||||
|  | ||||
| 	call	Clear_SMI_Pin | ||||
| WaitForUpdate: | ||||
| 	call	Sample_SMI_Pin | ||||
| 	stc | ||||
| 	jnz	short SMI_Abort		; Yes, go process it | ||||
|  | ||||
|  | ||||
| 	rdtsc				; Wait for additional 300 us | ||||
| 	sub	eax, [si+0].StartTime | ||||
| 	sbb	edx, [si+4].StartTime | ||||
| 	div	ecx | ||||
| 	cmp	eax, RTC_TIME + 300 | ||||
| 	jb	WaitForUpdate | ||||
|  | ||||
| 	ASSUME	SI: NOTHING | ||||
|  | ||||
|  | ||||
| 	; StatusB[SET] = 1; | ||||
| 	mov	al, CMOS_STATUS_B	; Read RTC StatusB | ||||
| 	out	CMOS_INDEX, al | ||||
| 	in	al, CMOS_DATA | ||||
| 	test	al, SET			; If (SET == 1) | ||||
| 	jnz	short Restore_RTC_Index	;   bail | ||||
| 	or	al, SET			; else | ||||
| 	out	CMOS_DATA, al		;   SET = 1 | ||||
|  | ||||
| 	; Wait for StatusA[UIP] to go inactive | ||||
| 	mov	cx, 0FFFFh		; RTC timeout | ||||
| SpinUIP: | ||||
| 	mov	al, CMOS_STATUS_A	; Yes, spin until UIP is clear | ||||
| 	out	CMOS_INDEX, al | ||||
| 	in	al, CMOS_DATA | ||||
| 	test	al, UIP | ||||
| 	loopnz	SpinUIP | ||||
|  | ||||
| 	mov	al, CMOS_STATUS_B	; SET = 0 | ||||
| 	out	CMOS_INDEX, al | ||||
| 	in	al, CMOS_DATA | ||||
| 	and	al, NOT SET | ||||
| 	out	CMOS_DATA, al | ||||
|  | ||||
| Restore_RTC_Index: | ||||
| 	clc | ||||
| SMI_Abort: | ||||
| 	pop	si | ||||
| 	mov	al, bl			; Restore CMOS index | ||||
| 	out	CMOS_INDEX, al | ||||
| Exit:	ret | ||||
|  | ||||
|  | ||||
| Fix_RTC	endp | ||||
|  | ||||
|  | ||||
|  | ||||
| 	END | ||||
|  | ||||
							
								
								
									
										262
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/chip.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										262
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/chip.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,262 @@ | ||||
| ;  | ||||
| ; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| ;  | ||||
| ; This library is free software; you can redistribute it and/or modify | ||||
| ; it under the terms of the GNU Lesser General Public License as | ||||
| ; published by the Free Software Foundation; either version 2.1 of the | ||||
| ; License, or (at your option) any later version. | ||||
| ;  | ||||
| ; This code is distributed in the hope that it will be useful, | ||||
| ; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| ; Lesser General Public License for more details. | ||||
| ;  | ||||
| ; You should have received a copy of the GNU Lesser General | ||||
| ; Public License along with this library; if not, write to the | ||||
| ; Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| ; Boston, MA 02111-1307 USA  | ||||
| ;  | ||||
| ;******************************************************************************** | ||||
| ;*     This file contains the Southbridge specific code.   | ||||
| ;******************************************************************************** | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| include smimac.mac | ||||
| include chipset.inc | ||||
| include pci.inc | ||||
| include sysmgr.inc | ||||
| include init.inc | ||||
| include cs5536.inc | ||||
|  | ||||
|  | ||||
| .model small,c | ||||
| .586 | ||||
| .CODE | ||||
|  | ||||
|  | ||||
| externdef Errors:	word | ||||
| externdef Device_ID:	word | ||||
| externdef Chipset_Base:	dword | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Clear all SMI source registers | ||||
| ;*********************************************************************** | ||||
| Clear_SMIs proc | ||||
|  | ||||
| 	mov	ax, [Device_ID]		; Get Southbridge Device ID | ||||
| 	cmp	ax, DEVICE_ID_5536	; If CS5536, exit | ||||
| 	clc | ||||
| 	je	Exit | ||||
| 	 | ||||
| 	or	[Errors], ERR_NO_CHIPSET | ||||
| 	stc | ||||
| 	jmp	Exit | ||||
| 	 | ||||
| Exit:	ret | ||||
|  | ||||
| Clear_SMIs endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;**************************************************************** | ||||
| ; Returns information about the Southbridge | ||||
| ; | ||||
| ; On Exit, if CF clear: | ||||
| ;   EBX = PCI address of Southbridge | ||||
| ;    CL = Chipset Revision | ||||
| ;    DX = Device ID | ||||
| ;**************************************************************** | ||||
| Get_Sbridge_Info proc | ||||
|  | ||||
| 	mov	ebx, 80000000h+(15 SHL 11) ; Start at Bus 0;  DevNum 15 | ||||
| SouthbridgeLoop: | ||||
| 	call	Read_PCI32 | ||||
| 	cmp	ax, VENDOR_ID_CYRIX	; Is it a Cyrix chipset ? | ||||
| 	je	short CorrectVendorID | ||||
| 	cmp	ax, VENDOR_ID_NATIONAL	; Is it a National Semiconductor chipset ? | ||||
| 	je	short CorrectVendorID | ||||
| 	cmp	ax, VENDOR_ID_AMD	; Is it an AMD chipset ? | ||||
| 	jne	short NextDevice | ||||
| CorrectVendorID: | ||||
| 	shr	eax, 16 | ||||
| 	push	ax			; Save device ID | ||||
|  | ||||
| 	mov	bl, 8			; Read Class Code & Rev ID | ||||
| 	call	Read_PCI32 | ||||
| 	mov	cl, al			; Save revision in CL | ||||
| 	shr	eax, 16	 | ||||
| 	cmp	ax, 0601h		; Is it an ISA bridge ? | ||||
| 	pop	dx | ||||
| 	mov	bl, 0			; Vendor & Device ID | ||||
| 	je	Exit			; CF is cleared  | ||||
|  | ||||
|  | ||||
| 	; Check the DeviceID | ||||
| 	cmp	dx, DEVICE_ID_5536-1	; Hardware CS5536 Device ID | ||||
| 	jne	NextDevice | ||||
| FoundSB: | ||||
| 	; On CS5536, the virtualized Device ID is h/w Device ID + 1 | ||||
| 	inc	dx | ||||
| 	push	cx | ||||
| 	push	dx | ||||
| 	mov	ecx, 5100002Fh		; Write-post I/O to port 84h for debug | ||||
| 	mov	edx, 00084001h | ||||
| 	mov	eax, edx | ||||
| 	or	al, 8 | ||||
| 	wrmsr | ||||
| 	pop	dx | ||||
| 	pop	cx | ||||
| 	jmp	Exit | ||||
|  | ||||
| NextDevice: | ||||
| 	add	bh, 8			; Next device | ||||
| 	cmp	bh, (19 SHL 3)		; Last possible DevNum ? | ||||
| 	jbe	SouthbridgeLoop | ||||
|  | ||||
| 	; Can't find supported Southbridge chipset | ||||
| 	or	[Errors], ERR_NO_CHIPSET | ||||
| 	stc | ||||
| 	 | ||||
| Exit:	ret | ||||
|  | ||||
| Get_Sbridge_Info endp | ||||
|  | ||||
|  | ||||
| ;**************************************************************** | ||||
| ; Generates a s/w SMI | ||||
| ;**************************************************************** | ||||
| Software_SMI proc | ||||
|  | ||||
| 	smint | ||||
| 	ret | ||||
| 	 | ||||
| Software_SMI endp	 | ||||
|  | ||||
|  | ||||
| ;********************************************************************************* | ||||
| ; Reads 32-bit PCI config register specified by EBX | ||||
| ;********************************************************************************* | ||||
| Read_PCI32 proc | ||||
|  | ||||
| 	mov	dx, PCI_CONFIG_ADDRESS | ||||
| 	mov	eax, ebx | ||||
| 	out	dx, eax | ||||
| 	mov 	dx, PCI_CONFIG_DATA | ||||
| 	in	eax, dx | ||||
| 	ret | ||||
|  | ||||
| Read_PCI32 endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;********************************************************************************* | ||||
| ; Writes a 32 bit Southbridge register | ||||
| ; Input: | ||||
| ;   DL - register offset | ||||
| ;  EAX - value to write | ||||
| ;********************************************************************************* | ||||
| SetReg_32 proc uses bx | ||||
|  | ||||
| 	push	eax | ||||
| 	mov	bl, dl | ||||
| 	call	Address8 | ||||
| 	pop	eax | ||||
| 	out	dx, eax | ||||
| 	ret | ||||
|  | ||||
| SetReg_32 endp | ||||
|  | ||||
|  | ||||
| ;********************************************************************************* | ||||
| ; Writes an 8 bit register | ||||
| ; Input: | ||||
| ;   BL = register # | ||||
| ;   BH = Data | ||||
| ;********************************************************************************* | ||||
| SetReg_8 proc | ||||
|  | ||||
| 	call	Address8 | ||||
| 	mov	al, bh | ||||
| 	out	dx, al | ||||
| 	ret | ||||
|  | ||||
| SetReg_8 endp | ||||
|  | ||||
|  | ||||
|  | ||||
| ;********************************************************************************* | ||||
| ; Reads an 8 bit register | ||||
| ; Input: | ||||
| ;   BL = register # | ||||
| ; Output: | ||||
| ;   AL = Data | ||||
| ;********************************************************************************* | ||||
| GetReg_8 proc | ||||
|  | ||||
| 	call	Address8 | ||||
| 	in	al, dx | ||||
| 	ret | ||||
|  | ||||
| GetReg_8 endp | ||||
|  | ||||
| ;********************************************************************************* | ||||
| ; Helper routine for SetReg_32, SetReg_8 & GetReg_8 | ||||
| ;********************************************************************************* | ||||
| Address8 proc | ||||
|  | ||||
| 	mov	dx, PCI_CONFIG_ADDRESS | ||||
| 	mov	eax, [Chipset_Base] | ||||
| 	mov	al, bl | ||||
| 	and	al, NOT 3 | ||||
| 	out	dx, eax | ||||
| 	mov	dx, PCI_CONFIG_DATA | ||||
| 	and	bl, 3 | ||||
| 	add	dl, bl | ||||
| 	ret | ||||
|  | ||||
| Address8 endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;********************************************************************************* | ||||
| ; Determines the base address of the top-level SMI status register | ||||
| ; On Exit: | ||||
| ;   EAX = address | ||||
| ;********************************************************************************* | ||||
| Get_SMI_Base proc | ||||
| 	 | ||||
| 	mov	ebx, [Chipset_Base]		; Patch SMI_Base | ||||
| 	add	bx, PM_FUNCTION + BAR0 | ||||
| 	call	Read_PCI32 | ||||
| 	mov	al, SMI_STATUS | ||||
| 	ret | ||||
|  | ||||
| Get_SMI_Base endp	 | ||||
| 	 | ||||
|  | ||||
|  | ||||
| ;********************************************************************************* | ||||
| ; Determines the base address of the internal IRQ register | ||||
| ; On Exit: | ||||
| ;   EAX = address | ||||
| ;********************************************************************************* | ||||
| Get_IRQ_Base proc | ||||
| 	 | ||||
| 	mov	ebx, [Chipset_Base]		; Patch SMI_Base | ||||
| 	add	bx, AUDIO_FUNCTION + BAR0	; Patch IRQ_Base | ||||
| 	call	Read_PCI32 | ||||
| 	mov	al, 1Ah | ||||
| 	ret | ||||
|  | ||||
| Get_IRQ_Base endp | ||||
|  | ||||
|  | ||||
|  | ||||
| 	END | ||||
| 	 | ||||
							
								
								
									
										239
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/chipset.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										239
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/chipset.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,239 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| /***************************************************************************** | ||||
|  *    The routines in this file translate requests for hardware | ||||
|  *     support to Southbridge-specific function calls.  | ||||
|  *****************************************************************************/ | ||||
|  | ||||
|  | ||||
| #include "VSA2.H" | ||||
| #include "CHIPSET.H" | ||||
| #include "CS5536.H" | ||||
| #include "ISA.H" | ||||
| #include "SYSMGR.H" | ||||
| #include "PROTOS.H" | ||||
| #include "GX2.H" | ||||
|  | ||||
|  | ||||
| // External function prototypes | ||||
| extern void MillisecondTimer(UCHAR, EVENT_ENTRY *); | ||||
| extern void InitTimers(void); | ||||
| extern void Init_CS5536(void); | ||||
| extern void pascal Enable_USB_5536(UCHAR, USHORT); | ||||
| extern void pascal Address_Decode_5536(UCHAR, USHORT); | ||||
| extern void pascal MBus_IO_Trap(ULONG, ULONG, UCHAR); | ||||
| extern void pascal MBus_IO_Timeout(ULONG, ULONG, UCHAR); | ||||
| extern void pascal A20_Init(UCHAR); | ||||
| extern void pascal InactivityTimer(UCHAR, USHORT, UCHAR); | ||||
| extern void pascal Program_PWM(UCHAR, UCHAR, USHORT, UCHAR); | ||||
|  | ||||
| // External variables | ||||
| extern EVENT_ENTRY Events[];  | ||||
| extern Hardware HardwareInfo; | ||||
| extern ULONG MPCI_NB; | ||||
| extern ULONG ATA_Error; | ||||
|  | ||||
| // Local variables: | ||||
| typedef   void (pascal * CHIPSET_DEPENDENT)(unsigned char, unsigned short); | ||||
| CHIPSET_DEPENDENT Address_Decode; | ||||
| CHIPSET_DEPENDENT Enable_USB; | ||||
| GPIO_FUNCTION GPIO_Control; | ||||
| ULONG ClocksPerMs; | ||||
|  | ||||
|  | ||||
| //***************************************************************************** | ||||
| // Initializes the Southbridge | ||||
| //***************************************************************************** | ||||
| void InitChipset(void) | ||||
| { | ||||
|  | ||||
|   ClocksPerMs = HardwareInfo.CPU_MHz * 1000L; | ||||
|  | ||||
|   InitTimers(); | ||||
|  | ||||
|   switch (HardwareInfo.Chipset_ID) { | ||||
|  | ||||
|     case DEVICE_ID_5536: | ||||
|  | ||||
|       Address_Decode = Address_Decode_5536; | ||||
|       Enable_USB = Enable_USB_5536; | ||||
|  | ||||
|       // Initialize the CS5536 | ||||
|       Init_CS5536(); | ||||
|       break; | ||||
|  | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //***************************************************************************** | ||||
| // Enables trapping of a PCI function | ||||
| // Return value: | ||||
| //   0 = not supported | ||||
| //   1 = already enabled | ||||
| //   2 = previously disabled | ||||
| //***************************************************************************** | ||||
| UCHAR pascal Enable_PCI_Trapping(USHORT PCI_Address, UCHAR EnableFlag)  | ||||
| { UCHAR ReturnValue = 0; | ||||
|  | ||||
|  | ||||
|   // Call the appropriate chipset routine | ||||
|   switch (HardwareInfo.Chipset_ID) { | ||||
|  | ||||
|     default: | ||||
|       // Use PBUS MSR to trap this address | ||||
|       Trap_PCI_IDSEL(PCI_Address, EnableFlag); | ||||
|       ReturnValue = 1; | ||||
|       break; | ||||
|   } | ||||
|  | ||||
|   return ReturnValue; | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| //***************************************************************************** | ||||
| // Diables an event | ||||
| //***************************************************************************** | ||||
| void pascal Disable_Event(EVENT Event, USHORT Index) | ||||
| { | ||||
|   Enable_Event(Event, Index, 0); | ||||
| } | ||||
|  | ||||
| //***************************************************************************** | ||||
| // Enables an event | ||||
| // | ||||
| // EnableFlag: | ||||
| //   0 = Disable event | ||||
| //   1 = Enable event | ||||
| //   2 = Reset event logic (e.g. timer, GPIO) | ||||
| //***************************************************************************** | ||||
| void pascal Enable_Event(EVENT Event, USHORT Index, UCHAR EnableFlag) | ||||
| { USHORT Device_ID; | ||||
|   UCHAR Error = 0; | ||||
|   ULONG Param1, Param2; | ||||
|   EVENT_ENTRY * EventPtr; | ||||
|  | ||||
|   Device_ID = HardwareInfo.Chipset_ID; | ||||
|  | ||||
|   EventPtr = &Events[Index]; | ||||
|   Param1 = EventPtr->Param1; | ||||
|   Param2 = EventPtr->Param2; | ||||
|  | ||||
|  | ||||
|   switch (Event) { | ||||
|  | ||||
|     case EVENT_USB: | ||||
|       Enable_USB(EnableFlag, (USHORT)Param1); | ||||
|     case EVENT_KEL: | ||||
|       break; | ||||
|  | ||||
|     case EVENT_TIMER: | ||||
|       // Initialize RemainingInterval field to Interval | ||||
|       if (EnableFlag == 1) { | ||||
|         EventPtr->RemainingInterval = EventPtr->Param1; | ||||
|       } | ||||
|       MillisecondTimer(EnableFlag, EventPtr); | ||||
|       break; | ||||
|  | ||||
|     case EVENT_IO_TRAP: | ||||
|       MBus_IO_Trap(Param1, Param2, EnableFlag); | ||||
|       break; | ||||
|  | ||||
|     case EVENT_DEVICE_TIMEOUT: | ||||
|       // If programmer forgot to specify Instance, assume 1st instance | ||||
|       if ((USHORT)Param2 == 0x0000) { | ||||
|         (USHORT)Param2 = 1; | ||||
|       } | ||||
|       Param2 |= GLIU_ID; | ||||
|     case EVENT_IO_TIMEOUT: | ||||
|       MBus_IO_Timeout(Param1, Param2, EnableFlag); | ||||
|       break; | ||||
|  | ||||
|     case EVENT_PME: | ||||
|       (USHORT)Param2 |= PME; | ||||
|     case EVENT_GPIO: | ||||
|       GPIO_Control(Param1, Param2, EnableFlag); | ||||
|       break; | ||||
|  | ||||
|     case EVENT_PCI_TRAP: | ||||
|       if (Enable_PCI_Trapping((USHORT)Param1, EnableFlag) == 0) { | ||||
|         // Companion I/O can't trap requested PCI function. | ||||
|         Error = ERR_PCI_TRAP; | ||||
|       } | ||||
|       break; | ||||
|  | ||||
|     case EVENT_ACPI: | ||||
|       switch (Device_ID) { | ||||
|         case DEVICE_ID_5536: | ||||
|           Enable_ACPI_5536(EnableFlag); | ||||
|           break; | ||||
|       } | ||||
|       break; | ||||
|  | ||||
|     case EVENT_PWM: | ||||
|       //                GPIO pin         Duty cycle (%)    Rate (ms) | ||||
|       Program_PWM((UCHAR)Param1, (UCHAR)(Param2 >> 16), (USHORT)(Param1 >> 16), EnableFlag); | ||||
|  | ||||
|       // 8 LSBs are GPIO pin number | ||||
|       Param1 &= 0x000000FF; | ||||
|       // Mask all except valid flags | ||||
|       Param2 &= OPEN_DRAIN | PULLDOWN | PULLUP | INVERT; | ||||
|       // Insert flags appropriate to PWM | ||||
|       Param2 |= OUTPUT | NO_ASMI; | ||||
|       if (EnableFlag) { | ||||
|         Param2 |= AUX1; | ||||
|       } | ||||
|       GPIO_Control(Param1, Param2, EnableFlag); | ||||
|       break; | ||||
|  | ||||
|   }	// end switch (Event) | ||||
|  | ||||
|   if (Error) { | ||||
|     Report_VSM_Error(Error, Event, Param1); | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| void pascal Set_Address_Decode(USHORT Address, UCHAR Decode)  | ||||
| { | ||||
|   Address_Decode(Decode, Address); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| void pascal Allocate_Resource(USHORT Resource, ULONG Param) | ||||
| { | ||||
|  | ||||
|   switch ((UCHAR)Resource) { | ||||
|  | ||||
|     case RESOURCE_IRQ: | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       break; | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										59
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/cpu.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										59
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/cpu.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,59 @@ | ||||
| ;  | ||||
| ; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| ;  | ||||
| ; This library is free software; you can redistribute it and/or modify | ||||
| ; it under the terms of the GNU Lesser General Public License as | ||||
| ; published by the Free Software Foundation; either version 2.1 of the | ||||
| ; License, or (at your option) any later version. | ||||
| ;  | ||||
| ; This code is distributed in the hope that it will be useful, | ||||
| ; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| ; Lesser General Public License for more details. | ||||
| ;  | ||||
| ; You should have received a copy of the GNU Lesser General | ||||
| ; Public License along with this library; if not, write to the | ||||
| ; Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| ; Boston, MA 02111-1307 USA  | ||||
| ;  | ||||
| ;*   Function:                                                         * | ||||
| ;*     Implementation of routines specific to the Vail core.  | ||||
|  | ||||
|  | ||||
| .model tiny,c | ||||
| .586p | ||||
| .ALPHA | ||||
| DGROUP	GROUP _CODE, _TEXT | ||||
| _CODE	SEGMENT PUBLIC use16 'CODE' | ||||
| 	ASSUME DS:_CODE | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;************************************************************************ | ||||
| ;************************************************************************ | ||||
| Sample_SMI_Pin proc | ||||
| 	ret | ||||
| Sample_SMI_Pin endp | ||||
|  | ||||
|  | ||||
|  | ||||
| ;************************************************************************ | ||||
| ;************************************************************************ | ||||
| Clear_SMI_Pin proc | ||||
|  | ||||
| 	ret | ||||
| Clear_SMI_Pin endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| _CODE	ENDS | ||||
|  | ||||
|  | ||||
| 	END | ||||
							
								
								
									
										339
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/cpu_init.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										339
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/cpu_init.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,339 @@ | ||||
| ;  | ||||
| ; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| ;  | ||||
| ; This library is free software; you can redistribute it and/or modify | ||||
| ; it under the terms of the GNU Lesser General Public License as | ||||
| ; published by the Free Software Foundation; either version 2.1 of the | ||||
| ; License, or (at your option) any later version. | ||||
| ;  | ||||
| ; This code is distributed in the hope that it will be useful, | ||||
| ; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| ; Lesser General Public License for more details. | ||||
| ;  | ||||
| ; You should have received a copy of the GNU Lesser General | ||||
| ; Public License along with this library; if not, write to the | ||||
| ; Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| ; Boston, MA 02111-1307 USA  | ||||
| ;  | ||||
| ;*   Function:                                                         * | ||||
| ;*     This file contains code specific to the processor core. | ||||
|  | ||||
| include vsa2.inc | ||||
| include gx2.inc | ||||
| include sysmgr.inc | ||||
| include init.inc | ||||
| include chipset.inc | ||||
|   	 | ||||
| .model small,c | ||||
| .586 | ||||
|  | ||||
| .CODE | ||||
|  | ||||
|  | ||||
| externdef BIOS_ECX: dword | ||||
| externdef BIOS_EDX: dword | ||||
| externdef VSA_Image:byte | ||||
|  | ||||
| SMM_Size	dd	0 | ||||
| FooGlue		dd	54000000h | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Sets CPU dependent fields in the SMM header | ||||
| ; On entry: | ||||
| ;   SI = pointer to VSM header | ||||
| ;*********************************************************************** | ||||
| Set_CPU_Fields proc | ||||
|  | ||||
| SMM_CONTROL  equ EXTL_SMI_EN + INTL_SMI_EN + SMM_INST_EN + NEST_SMI_EN | ||||
|  | ||||
| 	mov	(VSM_Header PTR [si]).SysStuff.State.SMM_CTL_MSR, SMM_CONTROL | ||||
| 	ret | ||||
| 	 | ||||
| Set_CPU_Fields endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; - Sets the SMM entry point to the location in EBX | ||||
| ; - Sets the SMM header location | ||||
| ; - Write protects the SMM regions | ||||
| ;*********************************************************************** | ||||
| Init_SMM_Region proc | ||||
|  | ||||
| 	; Set the SMM entry point | ||||
| 	mov	ecx, MSR_SMM_LOC | ||||
| 	mov	eax, ebx | ||||
| 	mov	edx, [SMM_Size]		; SMM Code Limit | ||||
| 	wrmsr | ||||
|  | ||||
| 	; Set the SMM header location | ||||
| 	lea	eax, (VSM_Header PTR [eax]).SysStuff.State + sizeof(SmiHeader) | ||||
| 	mov	ecx, MSR_SMM_HDR | ||||
| 	xor	edx, edx | ||||
| 	wrmsr | ||||
|  | ||||
|  | ||||
| 	; Write protect the SMM memory | ||||
| 	mov	ecx, MSR_RCONF_SMM | ||||
| 	rdmsr	 | ||||
| 	or	al, REGION_WP | ||||
| 	wrmsr | ||||
|  | ||||
| 	ret | ||||
| 	 | ||||
| Init_SMM_Region endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Returns information about the LX CPU | ||||
| ; On exit: | ||||
| ;  AX = CPU Revision | ||||
| ;  SI = CPU ID | ||||
| ;  BX = PCI MHz | ||||
| ;  CX = CPU MHz | ||||
| ;  DX = DRAM MHz | ||||
| ;*********************************************************************** | ||||
| Get_CPU_Info proc | ||||
|  | ||||
| 	mov	ecx, 4C000014h 					; GLCP_SYS_RSTPLL | ||||
| 	rdmsr | ||||
|  | ||||
| 	; PCI Speed | ||||
| 	mov	bx, 33 | ||||
| 	test al, 1 SHL 7					; RSTPPL_LOWER_PCISPEED_SHIFT | ||||
| 	jz	not66 | ||||
| 	mov	bx, 66 | ||||
| not66:	 | ||||
| 	push bx								; save PCI speed | ||||
|  | ||||
| 	; CPU Speed | ||||
| 	mov	ax, 333							; 33.3MHZ * 10 | ||||
|  | ||||
| 	ror	dx, 1							; RSTPLL_UPPER_CPUMULT_SHIFT | ||||
| 	mov	bx, dx | ||||
| 	rol	dx, 1							; RSTPLL_UPPER_CPUMULT_SHIFT | ||||
| 	push dx								; save RSTPLL | ||||
| 	and	bx, 1Fh | ||||
| 	inc	bx								; 0 = multiply by 1.... | ||||
| 	mul	bx								; ax=PCI * bl=Mul | ||||
|  | ||||
| 	; Rounding divide | ||||
| 	mov	bx, 10 | ||||
| 	xor	dx, dx | ||||
| 	div	bx								; ax= quotent and dx=remainder | ||||
| 	cmp	dx, 5 | ||||
| 	jb	NoRound							; can round because of /10 | ||||
| 	inc	ax								; round up | ||||
| NoRound: | ||||
| 	pop dx								; restore RSTPLL | ||||
| 	pop bx								; restore PCI * 10 | ||||
| 	push ax								; save CPU speed | ||||
|  | ||||
|  | ||||
| 	; DRAM speed | ||||
| 	mov	ax, 333							; 33.3MHZ * 10 | ||||
| 	 | ||||
| 	ror	dx, 7							; RSTPLL_UPPER_GLMULT_SHIFT | ||||
| 	mov	bx, dx | ||||
| 	rol	dx, 7							; RSTPLL_UPPER_GLMULT_SHIFT | ||||
| 	push dx								; save RSTPLL | ||||
| 	and	bx, 1Fh | ||||
| 	inc	bx								; 0 = multiply by 1.... | ||||
| 	mul	bx								; ax=PCI * bl=Mul | ||||
|  | ||||
| 	; Rounding divide | ||||
| 	mov	bx, 10 | ||||
| 	xor	dx, dx | ||||
| 	div	bx								; ax= quotent and dx=remainder | ||||
| 	cmp	dx, 5 | ||||
| 	jb	NoRoundmem						; can round because of /10 | ||||
| 	inc	ax								; round up | ||||
| NoRoundmem: | ||||
|  | ||||
| 	; DDR is 1/2 GeodeLink speed. | ||||
| 	xor	dx, dx | ||||
| 	mov bx, 2 | ||||
| 	div	bx | ||||
| 	push ax								; save mem speed | ||||
|  | ||||
| 	; Get CPU Revision | ||||
| 	mov	cx, 0017h | ||||
| 	rdmsr | ||||
| 	push	ax | ||||
| 	 | ||||
| 	mov	ecx, 10002000h	; Read MBIU0 Capabilities MSR | ||||
| 	rdmsr | ||||
| 	and	ah, 0Fh			; Extract 4 LSBs of DEVID | ||||
| 	cmp	ah, 04h			; Is it LX ? | ||||
| 	mov	si, DEVICE_ID_GX2 | ||||
| 	jne	RestoreInfo | ||||
| 	mov	si, DEVICE_ID_LX	; Yes | ||||
| 	mov	[FooGlue], 4C000020h	; FooGlue is at Northbridge MCP + 20h | ||||
| RestoreInfo: | ||||
| 	pop	ax			; Restore CPU Revision | ||||
| 	pop	dx			; Restore DRAM MHz	 | ||||
| 	pop	cx			; Restore CPU MHz | ||||
| 	pop	bx			; Restore PCI MHz | ||||
| 	ret | ||||
|  | ||||
| Get_CPU_Info endp | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Returns the SMM information | ||||
| ; On Exit: | ||||
| ;    EAX = SMM entry point | ||||
| ;     BX = Size of SMM memory in KB | ||||
| ;*********************************************************************** | ||||
| Get_SMM_Region proc  | ||||
| 	Local Attributes: byte | ||||
|  | ||||
| 	mov	ecx, MSR_RCONF_DEFAULT | ||||
| 	rdmsr | ||||
| 	mov	[Attributes], al | ||||
|  | ||||
|  | ||||
| 	mov	ecx, [BIOS_ECX]		; Descriptor for SMM memory | ||||
| 	rdmsr | ||||
| 	cmp	cl, 27h			; P2D_BMO or P2D_RO ? | ||||
| 	jbe	BaseMaskOffset | ||||
| 	mov	ebx, eax	      	; P2D_RO | ||||
| 	shl	eax, 12			; EAX = SMM base | ||||
| 	shrd	ebx, edx, 8		; EBX = end of SMM range | ||||
| 	and	bx, 0F000h | ||||
| 	sub	ebx, eax		; Compute length of range | ||||
| 	add	ebx, 1000h		; Adjust for 4KB granularity | ||||
| 	shr	ebx, 10			; Convert to KB | ||||
| 	jmp	short Save_SMM_Base | ||||
|  | ||||
| BaseMaskOffset:        | ||||
| 	mov	ebx, eax		; BX = length of SMM memory in KB | ||||
| 	shrd	eax, edx, 8		; EAX = Base | ||||
| 	and	ax, 0F000h | ||||
|  | ||||
| 	or	ebx, 0FFF00000h | ||||
| 	neg	ebx | ||||
| 	shl	ebx, 2			; Adjust for 4KB granularity | ||||
|  | ||||
| Save_SMM_Base: | ||||
| 	push	eax			; Save SMM base | ||||
| 	push	bx			; Save SMM size in KB | ||||
|  | ||||
| 	shl	ebx, 10			; Convert KB to bytes | ||||
| 	dec	ebx | ||||
| 	mov	[SMM_Size], ebx		; Save size for MSR_SMM_LOC | ||||
|  | ||||
| 	; Set SMM RCONF | ||||
| 	and	bx, 0F000h | ||||
| 	mov	edx, ebx		; SMM_TOP = SMM_BASE + sizeof(SMM region) | ||||
| 	add	edx, eax | ||||
| 	mov	dl, [Attributes]	; SMM active properties mirror RCONF_DEFAULT | ||||
| 	or	ah, 1 			; Set Enable | ||||
| 	mov	al, dl			; SMM inactive properties (R/W for now) | ||||
| 	and	al, NOT REGION_WP | ||||
| 	mov	ecx, MSR_RCONF_SMM | ||||
| 	wrmsr | ||||
|  | ||||
| 	pop	bx			; BX = size of SMM region in KB | ||||
| 	pop	eax			; EAX = base of SMM region | ||||
|  | ||||
| 	ret | ||||
| 	 | ||||
| Get_SMM_Region endp | ||||
|  | ||||
|  | ||||
| ;**************************************************************** | ||||
| ; Enables SMIs | ||||
| ;**************************************************************** | ||||
| Enable_SMIs proc | ||||
|  | ||||
| 	; Enable internal and external SMIs | ||||
| 	mov	ecx, MSR_SMM_CTRL | ||||
| 	rdmsr | ||||
| 	or	eax, INTL_SMI_EN + EXTL_SMI_EN | ||||
| 	wrmsr | ||||
|  | ||||
| 	ret | ||||
|  | ||||
| Enable_SMIs endp	 | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Enables the SMM instructions | ||||
| ;*********************************************************************** | ||||
| Enable_SMM_Instr proc | ||||
| 	 | ||||
| 	mov	ecx, MSR_SMM_CTRL | ||||
| 	rdmsr | ||||
| 	or	eax, SMM_INST_EN | ||||
| 	wrmsr | ||||
| 	ret | ||||
|  | ||||
| Enable_SMM_Instr endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Disables the A20 masking at the processor. | ||||
| ;*********************************************************************** | ||||
| Disable_A20 proc | ||||
|  | ||||
| 	mov	ecx, [FooGlue] | ||||
| 	add	cx, FG_A20M | ||||
| 	rdmsr | ||||
| 	and	al, NOT A20M		; A20M = 0 | ||||
| 	wrmsr | ||||
| 	ret | ||||
| 	 | ||||
| Disable_A20 endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Gets the size of physical memory | ||||
| ; On Exit: | ||||
| ;  EAX = physical memory size in bytes | ||||
| ;*********************************************************************** | ||||
| Get_Memory_Size proc	 | ||||
|  | ||||
| 	mov	ecx, [BIOS_EDX]		; P2D_R descriptor of physical memory | ||||
| 	jecxz	Exit | ||||
| 	rdmsr | ||||
| ; EDX = 2000001F | ||||
| ; EAX = FDF00100 | ||||
| ; 1MB thru <512MB-192K) | ||||
| 	 | ||||
| 	shrd	eax, edx, 20		; Extract PMAX field | ||||
| 	shl	eax, 12			; Convert units from 4KB to bytes | ||||
| Exit:	ret | ||||
| 	 | ||||
| Get_Memory_Size endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ; The linker won't allow code to be put in a PARA aligned segment. | ||||
| ; The following will align the next module to a paragraph boundary. | ||||
| TEXT	SEGMENT PARA 'CODE' | ||||
|  | ||||
| 	db	16 dup (0) | ||||
|  | ||||
| TEXT	ENDS | ||||
|  | ||||
| 	END | ||||
| 	 | ||||
							
								
								
									
										328
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/cs5536.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										328
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/cs5536.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,328 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //***************************************************************************** | ||||
| //*    Routines related to the CS5536    | ||||
| //***************************************************************************** | ||||
|  | ||||
| #include "VSA2.H" | ||||
| #include "SYSMGR.H" | ||||
| #include "PROTOS.H" | ||||
| #include "GX2.H" | ||||
| #include "VPCI.H" | ||||
| #include "DESCR.H" | ||||
| #include "PCI.H" | ||||
| #include "CHIPSET.H" | ||||
| #include "CS5536.H" | ||||
| #include "MDD.H" | ||||
|  | ||||
| ULONG Mbiu2   = MPCI_SOUTH + 0x00020000;  // 2.4.2.0.1 | ||||
| ULONG MPCI_SB = MPCI_SOUTH;               // 2.4.2.0.0 | ||||
| ULONG MCP_SB  = MPCI_SOUTH + 0x00700000;  // 2.4.2.7.0 | ||||
| ULONG OHCI1_Smi=0, OHCI2_Smi=0; | ||||
| CAPABILITIES Southbridge_MBIU; | ||||
| ULONG ATA_Error; | ||||
|  | ||||
| // External Functions: | ||||
| extern void CS5536_GPIO_Init(void); | ||||
| extern void Init_MDD(void); | ||||
| extern ULONG Write_EPCI(UCHAR, ULONG); | ||||
| extern void ACPI_PMS_SWAPSiF(void); | ||||
| extern PCI_HEADER_ENTRY * Get_Structure(USHORT); | ||||
| extern void pascal Handle_EHCI_Wr(PCI_HEADER_ENTRY *); | ||||
| extern PCI_HEADER_ENTRY * pascal Find_Register(PCI_HEADER_ENTRY *, UCHAR); | ||||
|  | ||||
| // External Variables: | ||||
| extern ULONG MPCI_NB, MDD_Base; | ||||
| extern Hardware HardwareInfo; | ||||
| extern PCI_HEADER_ENTRY ISA_Hdr[]; | ||||
| extern PCI_HEADER_ENTRY Audio_Hdr[]; | ||||
| extern VIRTUAL_DEVICE * SouthBridge; | ||||
| extern PCI_HEADER_ENTRY * Virtual_5536[]; | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Enables USB SMIs on CS5536 | ||||
| //*********************************************************************** | ||||
| void pascal Enable_USB_5536(UCHAR EnableFlag, USHORT Instance) | ||||
| { ULONG MsrData; | ||||
|   UCHAR Mask; | ||||
|  | ||||
|   // OHCI is the only valid setting for now | ||||
|   if (Instance == 1) { | ||||
|  | ||||
|     MsrData = Read_MSR_LO(OHCI1_Smi); | ||||
|     Mask = 0x10 << (Instance-1); | ||||
|     if (EnableFlag) { | ||||
|       (UCHAR)MsrData &= ~Mask; | ||||
|     } else { | ||||
|       (UCHAR)MsrData |=  Mask; | ||||
|     } | ||||
|     Write_MSR_LO(OHCI1_Smi, MsrData); | ||||
|  | ||||
|   } else { | ||||
|     static UCHAR * Msg_Enable  = "enable"; | ||||
|     static UCHAR * Msg_Disable = "disable"; | ||||
|     UCHAR * OnOff; | ||||
|  | ||||
|     if (EnableFlag) { | ||||
|       OnOff = Msg_Enable; | ||||
|     } else { | ||||
|       OnOff = Msg_Disable; | ||||
|     } | ||||
|     Log_Error("Attempt to %s invalid USB instance: 0x%04X", OnOff, Instance); | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Enables/disables writes to PM1_CNT register | ||||
| //*********************************************************************** | ||||
| void Enable_ACPI_5536(UCHAR EnableFlag) | ||||
| { ULONG MsrAddr, MsrData; | ||||
|  | ||||
|   // Get address to MDDs SMI MSR | ||||
|   MsrAddr = MDD_Base; | ||||
|   (USHORT)MsrAddr = MBD_MSR_SMI; | ||||
|  | ||||
|   // Get current value | ||||
|   MsrData = Read_MSR_LO(MsrAddr); | ||||
|  | ||||
|   // Set/clear enable for trapping of writes to PM1_CNT | ||||
|   if (EnableFlag) { | ||||
|     MsrData |=  PM1_CNT_SSMI_EN; | ||||
|  | ||||
|   } else { | ||||
|     MsrData &= ~PM1_CNT_SSMI_EN; | ||||
|   } | ||||
|  | ||||
|   // Update the MSR | ||||
|   Write_MSR_LO(MsrAddr, MsrData); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Sets positive/subtractive decode | ||||
| //*********************************************************************** | ||||
| void pascal Address_Decode_5536(UCHAR Decode, USHORT Address) | ||||
| { | ||||
|   // Not yet implemented | ||||
| } | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Initializes BARs in the Southbridge virtual headers | ||||
| //*********************************************************************** | ||||
| void Init_SB_Headers(void) | ||||
| { ULONG MsrAddr, BAR_Value; | ||||
|   USHORT PCI_Addr, Bar; | ||||
|  | ||||
|  | ||||
|   //********************************************* | ||||
|   // Allocate BARs for CS5536's F0 header | ||||
|   //********************************************* | ||||
|   MsrAddr = MDD_Base; | ||||
|   for (Bar = BAR0; Bar <= BAR5; Bar += 4) { | ||||
|     ULONG BAR_Length; | ||||
|  | ||||
|     (UCHAR)MsrAddr = ISA_Hdr[Bar/4].LBar; | ||||
|  | ||||
|     // Get current LBAR value | ||||
|     BAR_Value = Read_MSR_LO(MsrAddr); | ||||
|  | ||||
|     // Determine the length of the I/O range | ||||
|     BAR_Length = ISA_Hdr[Bar/4].Mask; | ||||
|  | ||||
|     // Allocate a PCI BAR corresponding to the LBAR | ||||
|     PCI_Addr = Allocate_BAR(RESOURCE_IO, Bar, BAR_Length, ID_MDD, ISA_Hdr[0].Device_ID); | ||||
|  | ||||
|     // Synchronize with any LBARs that have already been initialized by the BIOS | ||||
|     Virtual_PCI_Write_Handler(PCI_Addr, DWORD_IO, BAR_Value); | ||||
|  | ||||
|   } | ||||
|  | ||||
|   // Initialize Southbridge's COMMAND register | ||||
|   (UCHAR)PCI_Addr = COMMAND; | ||||
|   Virtual_PCI_Write_Handler(PCI_Addr, BYTE_IO, SPECIAL_CYCLES | IO_SPACE); | ||||
|  | ||||
|  | ||||
|   //********************************************* | ||||
|   // Allocate Audio BAR | ||||
|   //********************************************* | ||||
|   Allocate_BAR(RESOURCE_IO, BAR0,  128,  ID_AC97, Audio_Hdr[0].Device_ID); | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Initializes the CS5536 chipset | ||||
| //*********************************************************************** | ||||
| void Init_CS5536(void) | ||||
| { register PCI_HEADER_ENTRY * Header; | ||||
|   ULONG MsrAddr, USB20_Msr, MsrData[2]; | ||||
|   UCHAR i, CS5536_DevNum; | ||||
|  | ||||
|  | ||||
|  | ||||
|   //********************************************* | ||||
|   // Get routing address of CS5536's MPCI | ||||
|   //********************************************* | ||||
|   MPCI_SB = MPCI_NB; | ||||
|   CS5536_DevNum = (UCHAR)((USHORT)HardwareInfo.Chipset_Base >> 11); | ||||
|   MsrData[0] = Read_MSR_LO(MPCI_NB + MPCI_ExtMSR); | ||||
|   while (MsrData[0]) { | ||||
|     MPCI_SB += 1L << 23; | ||||
|     if ((UCHAR)MsrData[0] == CS5536_DevNum) { | ||||
|       break; | ||||
|     } | ||||
|     MsrData[0] >>= 8; | ||||
|   } | ||||
|  | ||||
|   //********************************************* | ||||
|   // Get routing address to Southbridge's GLIU | ||||
|   //********************************************* | ||||
|   Mbiu2 = MPCI_SB + 0x00020000; | ||||
|  | ||||
|  | ||||
|   // Read Southbridge's GLIU capabilities | ||||
|   Read_MSR(Mbiu2 + MBIU_CAP, &MsrData[0]); | ||||
|  | ||||
|  | ||||
|   //********************************************* | ||||
|   // Initialize GLIU2 | ||||
|   //********************************************* | ||||
|   Parse_Capabilities(MsrData, &Southbridge_MBIU); | ||||
|   // The NP2D_SCO field is actually the NP2D_BMK field | ||||
|   Southbridge_MBIU.NP2D_BMK = Southbridge_MBIU.NP2D_SCO; | ||||
|   Southbridge_MBIU.NP2D_SCO = 0; | ||||
|  | ||||
|   // SWAPSiF for erroneous P2D_BM/BMK numbering | ||||
|   if (HardwareInfo.Chipset_ID == DEVICE_ID_5536) { | ||||
|     Southbridge_MBIU.NP2D_BM = 3; | ||||
|   } | ||||
|  | ||||
|   // Find address of MCP in Southbridge | ||||
|   MCP_SB = Find_MBus_ID(ID_MCP, 2) & 0xFFFF0000; | ||||
|  | ||||
|   // Default range for IDE P2D_BM descriptor is 16 bytes. | ||||
|   // Change range to 8 bytes. | ||||
|   MsrAddr = Mbiu2 + MSR_IO_DESCR; | ||||
|   Write_MSR_LO(MsrAddr, Read_MSR_LO(MsrAddr) | 0x00000008); | ||||
|   	 | ||||
|   // Initialize the descriptor structure for Southbridge's GLIU | ||||
|   Init_MBIU((UCHAR *)&Southbridge_MBIU, Mbiu2); | ||||
|  | ||||
|   // Get Southbridge's Revision ID from MCP | ||||
|   ISA_Hdr[REVISION_ID/4].Revision_ID = (UCHAR)Read_MSR_LO(MCP_SB + 0x0017); | ||||
|  | ||||
|  | ||||
|   //********************************************* | ||||
|   // Initialize the MDD | ||||
|   //********************************************* | ||||
|   Init_MDD(); | ||||
|  | ||||
|   //********************************************* | ||||
|   // Add MPCI R0-R15 to available descriptor list | ||||
|   //********************************************* | ||||
|   MsrAddr = MPCI_SB; | ||||
|   // REGION_R15 is reserved for port 84h  | ||||
|   for ((USHORT)MsrAddr = REGION_R0; (UCHAR)MsrAddr <= REGION_R15-1; MsrAddr++) { | ||||
|     if (Init_Descr(MPCI_RCONF, MsrAddr)) { | ||||
|       break; | ||||
| 	} | ||||
|   } | ||||
|  | ||||
|   // Enable SSMI Received event | ||||
|   (USHORT)MsrAddr = MBD_MSR_SMI; | ||||
|    Write_MSR_LO(MsrAddr, Read_MSR_LO(MsrAddr) | SSMM); | ||||
|  | ||||
|   // Add ATA LBAR to available descriptor list | ||||
|   // NOTE: Not really part of MDD (just leveraging MDD logic) | ||||
|   MsrAddr = Find_MBus_ID(ID_ATA, 1); | ||||
|   ATA_Error = MsrAddr; | ||||
|   (USHORT)ATA_Error = MBD_MSR_ERROR; | ||||
|  | ||||
| #if 1 | ||||
|   // Enable SSMI Received event | ||||
|   (USHORT)MsrAddr = MBD_MSR_SMI; | ||||
|   Write_MSR_LO(MsrAddr, Read_MSR_LO(MsrAddr) | SSMM); | ||||
| #endif | ||||
|  | ||||
|   (USHORT)MsrAddr = MSR_LBAR_ATA; | ||||
|   Init_Descr(MDD_LBAR, MsrAddr); | ||||
|  | ||||
|  | ||||
|   //********************************************* | ||||
|   // Initialize the virtual Southbridge headers | ||||
|   //********************************************* | ||||
|   Init_SB_Headers(); | ||||
|  | ||||
|   //********************************************* | ||||
|   // Initialize the GPIO logic | ||||
|   //********************************************* | ||||
|   CS5536_GPIO_Init(); | ||||
|  | ||||
|   //********************************************* | ||||
|   // Install workaround for ACPI & PMS bugs | ||||
|   //********************************************* | ||||
|   ACPI_PMS_SWAPSiF(); | ||||
|  | ||||
|  | ||||
|   // Find address of USB 2.0 | ||||
|   OHCI1_Smi = USB20_Msr = Find_MBus_ID(ID_USB_20, 1); | ||||
|  | ||||
|   if (OHCI1_Smi == 0) { | ||||
|     return; | ||||
|   } | ||||
|   (USHORT)OHCI1_Smi = MBD_MSR_SMI; | ||||
|  | ||||
|   // Set PMEEN for each USB 2.0 controller | ||||
|   for (i=USBMSROHCB; i<=USBMSRUOCB; i++) { | ||||
|     (UCHAR)USB20_Msr = i; | ||||
|     Read_MSR(USB20_Msr, MsrData); | ||||
|     MsrData[1] |= PMEEN; | ||||
|     Write_MSR(USB20_Msr, MsrData); | ||||
|   } | ||||
|    | ||||
|  | ||||
|  | ||||
|   // Initialize the USB 2.0 devices | ||||
|   for (i=0; i <= 7; i++) { | ||||
|  | ||||
|     // If the header exists... | ||||
|     if (Header = Virtual_5536[i]) { | ||||
|       // Read Class Code to see it is USB class | ||||
|       if ((Header+REVISION_ID/4)->Class == 0x0C03) { | ||||
|         // Initialize USB LBAR | ||||
|         (UCHAR)USB20_Msr = (Header+BAR0/4)->LBar; | ||||
|         Init_Descr(USB_LBAR, USB20_Msr); | ||||
|  | ||||
|         // Allocate the PCI BAR | ||||
|         Allocate_BAR(RESOURCE_MMIO, BAR0, (Header+BAR0/4)->Mask, ID_USB_20, Header->Device_ID); | ||||
|  | ||||
|         // If EHCI, initialize FLADJ | ||||
|         if (Header->Device_ID == DEVICE_ID_AMD_EHCI) { | ||||
|           Header = Find_Register(Header, SRBN_REG); | ||||
|           if ((USHORT)Header != UNIMPLEMENTED_REGISTER) { | ||||
|             Header->FLADJ = 0x20; | ||||
|             Handle_EHCI_Wr(Header); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										220
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/debug.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										220
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/debug.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,220 @@ | ||||
| ;  | ||||
| ; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| ;  | ||||
| ; This library is free software; you can redistribute it and/or modify | ||||
| ; it under the terms of the GNU Lesser General Public License as | ||||
| ; published by the Free Software Foundation; either version 2.1 of the | ||||
| ; License, or (at your option) any later version. | ||||
| ;  | ||||
| ; This code is distributed in the hope that it will be useful, | ||||
| ; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| ; Lesser General Public License for more details. | ||||
| ;  | ||||
| ; You should have received a copy of the GNU Lesser General | ||||
| ; Public License along with this library; if not, write to the | ||||
| ; Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| ; Boston, MA 02111-1307 USA  | ||||
| ;  | ||||
| ;*   Function:                                                         * | ||||
| ;*     Debug routines for GX2-based systems    | ||||
|  | ||||
|  | ||||
| include vsa2.inc | ||||
| include vr.inc | ||||
| include sysmgr.inc | ||||
|  | ||||
| .model tiny,c | ||||
| .586p | ||||
| .CODE | ||||
|  | ||||
|  | ||||
| CR	equ	0Dh | ||||
| LF	equ	0Ah | ||||
|  | ||||
| externdef SMM_Header: SmiHeader | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Hex dump routines | ||||
| ;*********************************************************************** | ||||
| Hex_32	proc	pascal Num:dword | ||||
|  | ||||
| 	pushad | ||||
| 	mov	ebx, Num | ||||
| 	mov	cx, 8 | ||||
| @@:	rol	ebx, 4 | ||||
| 	call	Hex_4 | ||||
| 	loop	@b | ||||
| 	call	Space | ||||
| 	popad | ||||
| 	ret | ||||
|  | ||||
| Hex_32	endp | ||||
|  | ||||
|  | ||||
|  | ||||
| Hex_16	proc	pascal Num:word | ||||
|  | ||||
| 	pusha | ||||
| 	mov	cx, 4 | ||||
| 	mov	bx, Num | ||||
| @@:	rol	bx, 4 | ||||
| 	call	Hex_4 | ||||
| 	loop	@b | ||||
| 	call	Space | ||||
| 	popa | ||||
| 	ret | ||||
|  | ||||
| Hex_16	endp | ||||
|  | ||||
|  | ||||
| Hex_8	proc	pascal Num:byte | ||||
|  | ||||
| 	pusha | ||||
| 	mov	cx, 2 | ||||
| 	mov	bl, Num | ||||
| @@:	rol	bl, 4 | ||||
| 	call	Hex_4 | ||||
| 	loop	@b | ||||
| 	call	Space | ||||
| 	popa | ||||
| 	ret | ||||
|  | ||||
| Hex_8	endp | ||||
|  | ||||
|  | ||||
| Hex_4:	mov	al, bl | ||||
| 	and	al, 0Fh | ||||
| 	add	al, '0'			; Convert to ASCII | ||||
| 	cmp	al, '9' | ||||
| 	jbe	@f | ||||
| 	add	al, 7			; 'A'-'F' | ||||
| @@:	mov	dx, DBG_PORT | ||||
| 	jmp	Char | ||||
| 	 | ||||
| Space:	mov	al, ' ' | ||||
| Char:	out	dx, al | ||||
| 	in	al, 80h	 | ||||
| 	ret | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Displays SMI source(s) | ||||
| ; | ||||
| ; On Entry: | ||||
| ;  ECX = SMI source(s) | ||||
| ;*********************************************************************** | ||||
| Show_SMI_Source proc | ||||
|  | ||||
| 	pushad | ||||
| 	cld | ||||
|  | ||||
| 	mov	dx, DBG_PORT | ||||
| 	lea	bx, SMI_Source_Strings-2 | ||||
| MsgLoop:jecxz	Exit | ||||
| 	add	bx, 2 | ||||
| 	shr	ecx, 1 | ||||
| 	jnc	MsgLoop | ||||
|  | ||||
| 	mov	si, [bx]		; Get message ptr | ||||
| 	cmp	si, OFFSET Msg_DescrHit | ||||
| 	jne	short CharLoop | ||||
| 	mov	ax, [SMM_Header].IO_addr | ||||
| 	cmp	ax, VRC_INDEX | ||||
| 	je	IsVirtualReg | ||||
| 	cmp	ax, VRC_DATA | ||||
| 	jne	CharLoop | ||||
| IsVirtualReg: | ||||
| 	lea	si, [Msg_VirtReg]	 | ||||
| CharLoop: | ||||
| 	lodsb | ||||
| 	or	al, al			; End of string ? | ||||
| 	jz	Blank | ||||
| 	out	dx, al			; No, display next character | ||||
| 	jmp	CharLoop | ||||
|  | ||||
| Blank:	mov	al, ' '			; Yes, display trailing blank | ||||
| 	out	dx, al | ||||
| 	jmp	MsgLoop | ||||
|  | ||||
| Exit:	popad | ||||
| 	ret | ||||
|  | ||||
|  | ||||
| Show_SMI_Source endp | ||||
|  | ||||
|  | ||||
| SMI_Source_Strings: | ||||
| 	dw	OFFSET Msg_PM | ||||
| 	dw	OFFSET Msg_Audio | ||||
| 	dw	OFFSET Msg_ACPI | ||||
| 	dw	OFFSET Msg_VG | ||||
| 	dw	OFFSET Msg_Reserved | ||||
| 	dw	OFFSET Msg_Retrace | ||||
| 	dw	OFFSET Msg_VGA_Timer | ||||
| 	dw	OFFSET Msg_A20 | ||||
| 	dw	OFFSET Msg_SW_SMI | ||||
| 	dw	OFFSET Msg_GTT | ||||
| 	dw	OFFSET Msg_Reserved | ||||
| 	dw	OFFSET Msg_MFGPT | ||||
| 	dw	OFFSET Msg_NMI | ||||
| 	dw	OFFSET Msg_Reset | ||||
| 	dw	OFFSET Msg_USB | ||||
| 	dw	OFFSET Msg_Graphics | ||||
|  | ||||
| 	dw	OFFSET Msg_GT1 | ||||
| 	dw	OFFSET Msg_GT2 | ||||
| 	dw	OFFSET Msg_USR_DEF_1 | ||||
| 	dw	OFFSET Msg_VirtReg | ||||
| 	dw	OFFSET Msg_USR_DEF_3 | ||||
| 	dw	OFFSET Msg_PCI_Trap | ||||
| 	dw	OFFSET Msg_Reserved | ||||
| 	dw	OFFSET Msg_Reserved | ||||
| 	dw	OFFSET Msg_MPCI | ||||
| 	dw	OFFSET Msg_DescrHit | ||||
| 	dw	OFFSET Msg_Stat_Hit | ||||
| 	dw	OFFSET Msg_PIC | ||||
| 	dw	OFFSET Msg_KEL | ||||
| 	dw	OFFSET Msg_PME | ||||
| 	dw	OFFSET Msg_BlockIO | ||||
| 	dw	OFFSET Msg_Reserved | ||||
|  | ||||
|  | ||||
| Msg_Reserved	db	'???',0 | ||||
| Msg_VG		db	'VG',0 | ||||
| Msg_PM		db	'PM',0 | ||||
| Msg_Audio	db	'Audio',0 | ||||
| Msg_ACPI	db	'ACPI',0 | ||||
| Msg_Retrace	db	'Vsync',0 | ||||
| Msg_VGA_Timer	db	'Vga',0 | ||||
| Msg_SW_SMI	db	'S/W',0 | ||||
| Msg_A20		db	'A20',0 | ||||
| Msg_GTT		db	'GTT',0 | ||||
| Msg_MFGPT	db	'MFGPT',0 | ||||
| Msg_NMI		db	'NMI',0 | ||||
| Msg_GT1		db	'GT1',0 | ||||
| Msg_GT2		db	'Timer',0 | ||||
| Msg_USB		db	'USB',0 | ||||
| Msg_Reset	db	'Reset',0 | ||||
| Msg_Graphics	db	'VGA',0 | ||||
| Msg_USR_DEF_1	db	'PIC',0 | ||||
| Msg_VirtReg	db	'VR',0 | ||||
| Msg_USR_DEF_3	db	'UDef3',0 | ||||
| Msg_PCI_Trap	db	'PCI',0 | ||||
| Msg_MPCI	db	'MPCI',0 | ||||
| Msg_DescrHit	db	'I/O',0 | ||||
| Msg_Stat_Hit	db	'StatHit',0 | ||||
| Msg_PIC		db	'PIC',0 | ||||
| Msg_KEL		db	'KEL',0 | ||||
| Msg_PME		db	'PME',0 | ||||
| Msg_BlockIO	db	'BlockIO',0 | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| 	end | ||||
|  | ||||
							
								
								
									
										521
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/descr.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										521
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/descr.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,521 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //****************************************************************************** | ||||
| //*    Utility routines for managing descriptors  | ||||
| //****************************************************************************** | ||||
|  | ||||
|  | ||||
|  | ||||
| #include "VSA2.H" | ||||
| #include "PROTOS.H" | ||||
| #include "GX2.H" | ||||
| #include "VPCI.H" | ||||
| #include "DESCR.H" | ||||
| #include "SYSMGR.H" | ||||
|  | ||||
|  | ||||
|  | ||||
| // External variables: | ||||
| extern UCHAR NumMbius; | ||||
| extern UCHAR MBIU1_SelfReference; | ||||
|  | ||||
| // Local variables: | ||||
| UCHAR NumDescriptors = 1; | ||||
| DESCRIPTOR MSRs[MAX_DESCR]={0}; | ||||
| UCHAR DynamicVSALoad=0; | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Computes the 32 LSBs of an IOD_SC descriptor from Address/Range | ||||
| //*********************************************************************** | ||||
| ULONG pascal Compute_IOD_SC(ULONG * AddressPtr, USHORT * RangePtr, UCHAR Flag) | ||||
| { ULONG IO_Mask, Address; | ||||
|   USHORT Range; | ||||
|   UCHAR Addr_LSBs, Bit_Mask, Max_Bits; | ||||
|  | ||||
|   Address = * AddressPtr; | ||||
|   Range = * RangePtr; | ||||
|  | ||||
|   // Set IOD_SC Base field | ||||
|   IO_Mask = Address & 0x0000FFF8; | ||||
|  | ||||
|   // Compute the R/W attributes | ||||
|   if (!(Address & WRITES_ONLY)) { | ||||
|     IO_Mask |= REN; | ||||
|   } | ||||
|   if (!(Address & READS_ONLY)) { | ||||
|     IO_Mask |= WEN; | ||||
|   } | ||||
|  | ||||
|   // Initialize bit mask   | ||||
|   Addr_LSBs = (UCHAR)Address & 0x7; | ||||
|   Max_Bits = 8 - Addr_LSBs; | ||||
|   if (Range > Max_Bits) { | ||||
|     Range = Max_Bits; | ||||
|   } | ||||
|   Bit_Mask = (UCHAR)(0x01 << Range) - 1; | ||||
|   Bit_Mask <<= Addr_LSBs; | ||||
|  | ||||
|   // Insert byte enables | ||||
|   IO_Mask |=  (ULONG)Bit_Mask << 24; | ||||
|  | ||||
|  | ||||
|   // Adjust Address & Range parameters by # bytes handled by this descriptor | ||||
|   if (Flag) { | ||||
|     * AddressPtr += (ULONG)Range; | ||||
|     * RangePtr -= (USHORT)Range; | ||||
|   } | ||||
|   return IO_Mask; | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Returns the default value for the given descriptor Type | ||||
| //*********************************************************************** | ||||
| void pascal Get_Descriptor_Default(UCHAR Type, ULONG * Msr) | ||||
| { | ||||
|  | ||||
|   *Msr = *(Msr+1) = 0x00000000; | ||||
|  | ||||
|   switch (Type) { | ||||
|  | ||||
|     case IOD_BM: | ||||
|     case P2D_BM: | ||||
|     case P2D_BMO: | ||||
|     case P2D_BMK: | ||||
|       *Msr     = 0xFFF00000; | ||||
|       *(Msr+1) = 0x000000FF; | ||||
|       break; | ||||
|  | ||||
|     case P2D_R: | ||||
|     case P2D_RO: | ||||
|       *(Msr) = 0x000FFFFF; | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       break; | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Initializes a MSRs[] entry | ||||
| //*********************************************************************** | ||||
| UCHAR pascal Init_Descr(UCHAR Type, ULONG MsrAddr) | ||||
| { register DESCRIPTOR * Descr; | ||||
|  | ||||
|   // Keep count of total # descriptors | ||||
|   if (NumDescriptors >= MAX_DESCR) { | ||||
|     // Log an error:  Not enough descriptor entries. | ||||
|     Report_VSM_Error(ERR_NO_MORE_DESCRIPTORS, MAX_DESCR, 0x77 ); | ||||
|     return 0x01; | ||||
|   } | ||||
|  | ||||
|  | ||||
|  | ||||
|   Descr = &MSRs[NumDescriptors++]; | ||||
|  | ||||
|   // Initialize the descriptor entry | ||||
|   Descr->Mbiu = NumMbius; | ||||
|   Descr->Split = 0x00; | ||||
|   Descr->Flag = AVAILABLE; | ||||
|   Descr->Type = Type; | ||||
|   Descr->Link = 0x00; | ||||
|   Descr->Owner = 0x0000; | ||||
|   Descr->MsrAddr  = MsrAddr; | ||||
|   Descr->Physical = 0x00000000; | ||||
|  | ||||
|   return 0x00; | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Returns a descriptor to the available pool | ||||
| //*********************************************************************** | ||||
| void Deallocate_Descriptor(DESCRIPTOR * Descr) | ||||
| {  | ||||
|   // Mark MSR available | ||||
|   Descr->Flag = AVAILABLE; | ||||
|   Descr->Link = 0x00; | ||||
|   Descr->Owner = 0x0000; | ||||
|   // Set MSR to default value | ||||
|   Get_Descriptor_Default(Descr->Type, Descr->MsrData); | ||||
|   Write_MSR(Descr->MsrAddr, Descr->MsrData); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Restores all descriptors owned by VSA to their default values. | ||||
| // Used when VSA is installed from DOS. | ||||
| //*********************************************************************** | ||||
| void ReInit_Descriptors(void) | ||||
| { register USHORT Index; | ||||
|   register DESCRIPTOR * Descr; | ||||
|   ULONG MDD_Msr; | ||||
|  | ||||
|   DynamicVSALoad = 1; | ||||
|    | ||||
|   Descr = &MSRs[1]; | ||||
|  | ||||
|   MDD_Msr = Find_MBus_ID(ID_MDD, 1) & ROUTING; | ||||
|  | ||||
|   // Restore VSA-owned MSRs to their default values | ||||
|   for (Index = 1; Index < NumDescriptors; Index++) { | ||||
|     // Don't zero MDD LBARs | ||||
|     if ((Descr->MsrAddr & ROUTING) == MDD_Msr) { | ||||
|       Descr->Flag = AVAILABLE; | ||||
|     } else { | ||||
|       if (Descr->MsrAddr == 0x5100002F) { | ||||
|         continue; | ||||
|       } | ||||
|       Deallocate_Descriptor(Descr); | ||||
|     } | ||||
|     Descr++; | ||||
|   } | ||||
|  | ||||
|   NumDescriptors = 1; | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Searches for an unused descriptor of the specified type(s) on the | ||||
| // specified MBIU. | ||||
| // NOTE: This implementation makes multiple passes through the table, but | ||||
| //       this removes the requirement that they be in a particular order. | ||||
| //*********************************************************************** | ||||
| UCHAR pascal Allocate_Descriptor(UCHAR Type, UCHAR EndType, ULONG Msr) | ||||
| { register DESCRIPTOR * Descr; | ||||
|   register UCHAR Index; | ||||
|   ULONG Mask; | ||||
|   UCHAR Incr = 1; | ||||
|    | ||||
|   if (EndType < Type) { | ||||
|     Incr = 0xFF; | ||||
|   } | ||||
|   EndType += Incr; | ||||
|  | ||||
|   do { | ||||
|    | ||||
|     // Find an available descriptor of the right type | ||||
|     Index = 1; | ||||
| 	do { | ||||
|  | ||||
|       Descr = &MSRs[Index]; | ||||
|  | ||||
|       if ((Descr->Flag & AVAILABLE) && (Type == Descr->Type)) { | ||||
|  | ||||
|         switch (Type) { | ||||
|  | ||||
|           case MPCI_RCONF: | ||||
|           case GX2_RCONF: | ||||
|             // Any register will do | ||||
|             Mask = 0x00000000; | ||||
|             break; | ||||
|                      | ||||
|           case USB_LBAR: | ||||
|           case MDD_LBAR: | ||||
|             // Entire MSR must match | ||||
|             Mask = 0xFFFFFFFF; | ||||
|             break; | ||||
|  | ||||
|           case EPCI: | ||||
|             // Entire routing field must match | ||||
|             Mask = ROUTING; | ||||
|             break; | ||||
|  | ||||
|           default: | ||||
|             // MSR must match in 1st 3 routing fields | ||||
|             Mask = 0xFF800000; | ||||
|             break; | ||||
|  | ||||
|         } | ||||
|   | ||||
|         if ((Descr->MsrAddr & Mask) == (Msr & Mask)) { | ||||
|           // Mark descriptor in-use | ||||
|           Descr->Flag &= ~AVAILABLE; | ||||
|           return Index; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       Index++; | ||||
|     } while (Index != NumDescriptors); | ||||
|     Type += Incr;	  | ||||
|   } while (Type != EndType); | ||||
|  | ||||
|   return DESCRIPTOR_NOT_FOUND; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Searches existing descriptors for the specified address range. | ||||
| // If possible, a descriptor is updated to add/remove the new range. | ||||
| // Parameter Enable: | ||||
| // = 0, the range is removed | ||||
| // = 1, the range is added for I/O timeout | ||||
| // = 2, the range is added for I/O trap | ||||
| // = 3, the range is being searched (SYS_IO_DESCRIPTOR) | ||||
| //*********************************************************************** | ||||
| UCHAR pascal Find_Matching_IO_Descriptor(ULONG * AddressPtr, USHORT * RangePtr, UCHAR Enable) | ||||
| { UCHAR Index, HitFlag, DescrFlag; | ||||
|   ULONG Attributes, Mask; | ||||
|   USHORT Address, StartRange, EndRange, Length, Range; | ||||
|   register DESCRIPTOR * Descr; | ||||
|   static ULONG GLIU_Masks[3] = {NOT_GLIU0, NOT_GLIU1, NOT_GLIU2}; | ||||
|  | ||||
|   Range = * RangePtr; | ||||
|   Address = (USHORT) * AddressPtr; | ||||
|   Attributes = * AddressPtr; | ||||
|  | ||||
|  | ||||
|   // Scan descriptors for those used for I/O trap or timeout | ||||
|   // NOTE:  We must be careful about mixing I/O traps with I/O address that | ||||
|   //        are directed to Northbridge devices.  This may cause multiple | ||||
|   //        MBUI descriptors set to the same address. | ||||
|   for (Index = 1; Index < NumDescriptors; Index++) { | ||||
|  | ||||
|       Descr = &MSRs[Index]; | ||||
|       DescrFlag = Descr->Flag; | ||||
|  | ||||
|       // Only examine allocated descriptors | ||||
|       if (DescrFlag & AVAILABLE) { | ||||
|         continue; | ||||
|       } | ||||
|  | ||||
|       // Ignore descriptors that route transactions Northbound | ||||
|       if (Descr->MsrData[1] >> 29 == MBIU1_SelfReference) { | ||||
|         continue; | ||||
|       } | ||||
|  | ||||
|       // If an MBIU is to be excluded, don't allow a match on that MBIU | ||||
|       if (Attributes & GLIU_Masks[Descr->Mbiu]) { | ||||
|         continue; | ||||
|       } | ||||
|  | ||||
|  | ||||
|  | ||||
|       // Check if this descriptor matches the requested address range. | ||||
|       // Cases: | ||||
|       //   - Descriptor needs to be split, since I/O ranges are not compatible. | ||||
|       //   - Subtractive port:  timeout is set for this I/O range | ||||
|       //   - It is currently routed to an MBus device:  change Port to 0 | ||||
|       //   - Address ranges need to be merged | ||||
|       switch (Descr->Type)  { | ||||
|  | ||||
|         case IOD_SC: | ||||
|           HitFlag = 1; | ||||
|           // Does the I/O range overlap an existing Swiss-cheese descriptor ? | ||||
|           if ((USHORT)Descr->MsrData[0] == (Address & 0xFFF8)) { | ||||
|             UCHAR CurrentByteEnables, NewByteEnables, CommonByteEnables; | ||||
|  | ||||
|             // Yes, compute the byte enables | ||||
|             Mask = Compute_IOD_SC(AddressPtr, RangePtr, 1); | ||||
|             CurrentByteEnables = (UCHAR)(Descr->MsrData[0] >> 24); | ||||
|             NewByteEnables = (UCHAR)(Mask >> 24); | ||||
|  | ||||
|             // Compute # bytes of overlap | ||||
|             CommonByteEnables = CurrentByteEnables & NewByteEnables; | ||||
|             Length = 0; | ||||
|             while (CommonByteEnables) { | ||||
|               if (CommonByteEnables & 1) { | ||||
|                 Length++; | ||||
|               } | ||||
|               CommonByteEnables >>= 1; | ||||
|             } | ||||
|  | ||||
|             switch (Enable) { | ||||
|  | ||||
|               case 0: | ||||
|                 if (CurrentByteEnables == NewByteEnables) { | ||||
|                   if (Descr->MsrData[0] == Mask) { | ||||
|                     // Entire range is being disabled | ||||
|                     Deallocate_Descriptor(Descr); | ||||
|                   } else { | ||||
|                     // Only change REN/WEN, not byte enables  | ||||
|                     Mask &= 0x00FFFFFF; | ||||
|                   } | ||||
|                 } else { | ||||
|                   // Only subset of range is being disabled | ||||
|                   // Don't change REN/WEN | ||||
|                   Mask &= ~(WEN | REN); | ||||
|                 } | ||||
|                 if (Length) { | ||||
|                   // Don't change base address | ||||
|                   (USHORT)Mask = 0x0000; | ||||
|                   Descr->MsrData[0] &= ~Mask; | ||||
|                 } else { | ||||
|                   HitFlag = 0; | ||||
|                 }				        | ||||
|                 break; | ||||
|  | ||||
|               case 1: | ||||
|                 if ((Descr->MsrData[0] & (WEN | REN)) != (Mask & (WEN | REN))) { | ||||
|                   // R/W attributes mismatch; descriptor is not compatible | ||||
|                   HitFlag = 0; | ||||
|                 } else { | ||||
|                   // Descriptors are compatible: set additional byte enables | ||||
|                   Descr->MsrData[0] |= Mask; | ||||
|                 } | ||||
|                 break; | ||||
|  | ||||
|               case 2: | ||||
|                 if ((Descr->MsrData[0] & (WEN | REN)) != (Mask & (WEN | REN))) { | ||||
|                   // R/W attributes mismatch. | ||||
|                   // Descriptor is not compatible unless byte enables are the same. | ||||
|                   if (CurrentByteEnables != NewByteEnables) { | ||||
|                     HitFlag = 0; | ||||
|                     break; | ||||
|                   } | ||||
|                 } | ||||
|  | ||||
|                 // Descriptors are compatible: set additional byte enables | ||||
|                 Descr->MsrData[0] |= Mask; | ||||
|  | ||||
|                 // If the descriptors overlap but not exactly (disjoint enables) | ||||
|                 // then Address & Range need to be handled according to special cases | ||||
|                 if (CurrentByteEnables != NewByteEnables) { | ||||
|                   // Restore Address & Range (modified above by Compute_IOD_SC) | ||||
|                   * (USHORT *)AddressPtr = Address; | ||||
|                   * RangePtr = Range; | ||||
|  | ||||
|                   if (NewByteEnables > CurrentByteEnables) { | ||||
|                     // For example:  01110000 - NewByteEnables | ||||
|                     //               00011100 - CurrentByteEnables | ||||
|                     // Increment Address by overlapped range | ||||
|                     * (USHORT *)AddressPtr += Length; | ||||
|                   } | ||||
|  | ||||
|                   // Decrement Range by overlapped range | ||||
|                   * RangePtr -= Length; | ||||
|                 } | ||||
|                 break; | ||||
|  | ||||
|               case 3: | ||||
|                 if (CurrentByteEnables & NewByteEnables) { | ||||
|                   return Index; | ||||
|                 } | ||||
|                 continue; | ||||
|  | ||||
|             } // end switch(Enable) | ||||
|  | ||||
|             Write_MSR(Descr->MsrAddr, Descr->MsrData); | ||||
|  | ||||
|             if (HitFlag == 0) { | ||||
|               // Restore Address/Range. | ||||
|               * (USHORT *)AddressPtr = Address; | ||||
|               * RangePtr = Range; | ||||
|               continue; | ||||
|             } else { | ||||
|               return Index; | ||||
|             } | ||||
|           } | ||||
|           break; | ||||
|  | ||||
|         case IOD_BM: | ||||
|           HitFlag = 0; | ||||
|           Mask = ~((USHORT)Descr->MsrData[0])+1; | ||||
|           Length = 1 << BitScanForward(Mask); | ||||
|           StartRange = Descr->Address; | ||||
|           EndRange = StartRange + Length; | ||||
|  | ||||
|           // Check if the requested range is covered by the existing descriptor | ||||
|           if ((Address >= StartRange) && (Address < EndRange)) { | ||||
|             if (Enable == 3) {			    | ||||
|               return Index; | ||||
|             } | ||||
|             HitFlag = 1; | ||||
|             Range -= Address - StartRange; | ||||
|           } | ||||
|  | ||||
|  | ||||
|           Mask = Address ^ StartRange; | ||||
|  | ||||
|           if (Enable) { | ||||
|             if (HitFlag) { | ||||
|               Length = Range; | ||||
|               break;  //?????????????????????????? | ||||
|             } | ||||
|           } else { | ||||
|  | ||||
|             // Range is being disabled | ||||
|             if (HitFlag) { | ||||
|               if (Length <= Range) { | ||||
|                 Deallocate_Descriptor(Descr); | ||||
|               } else { | ||||
|                 // Descriptor must be trimmed | ||||
|                 if (Address == StartRange) { | ||||
|                   // I/O Base needs to be adjusted up | ||||
|                   Descr->MsrData[0] += (ULONG)Range << 20; | ||||
|                   Mask = (1L << Range) - 1; | ||||
|                   Length = Range; | ||||
|                 } else { | ||||
|                   // Adjust IO_MASK to trim range down | ||||
|                  (USHORT)Descr->MsrData[0] &= ~(Range-1); | ||||
|                 } | ||||
|  | ||||
|                 // Adjust IO_MASK | ||||
|                 (USHORT)Descr->MsrData[0] |= Mask; | ||||
|                 HitFlag = 2; | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|  | ||||
|           // Recompute start address of descriptor | ||||
|           if (HitFlag == 2) { | ||||
|             Descr->Address  = (USHORT)(Descr->MsrData[0] >> 20); | ||||
|             Descr->Address |= (USHORT)(Descr->MsrData[1] << 12); | ||||
|           } | ||||
|  | ||||
|           if (HitFlag) { | ||||
|             if (Length > Range) { | ||||
|               Length = Range; | ||||
|             } | ||||
|             * AddressPtr += Length; | ||||
|             * RangePtr -= Length; | ||||
|  | ||||
|             // Write descriptor if matching descriptor was modified | ||||
|             if (HitFlag == 2) { | ||||
|               Write_MSR(Descr->MsrAddr, Descr->MsrData); | ||||
|             } | ||||
|             return Index; | ||||
|           } | ||||
|           break; | ||||
|  | ||||
|  | ||||
|       }  // end switch(Descr->Type) | ||||
|   } | ||||
|  | ||||
|   // If a descriptor gets deallocated, need to clean up any possible links to a BAR | ||||
|   return DESCRIPTOR_NOT_FOUND; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										47
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/descr.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										47
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/descr.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,47 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| // Descriptor types: (don't use 0) | ||||
|  | ||||
|  | ||||
| #define   P2D_BM		1 | ||||
| #define   P2D_BMO		2 | ||||
| #define   P2D_R			3 | ||||
| #define   P2D_RO		4 | ||||
| #define   P2D_SC		5 | ||||
| #define   P2D_SCO		6 | ||||
| #define   P2D_BMK		7 | ||||
| #define   IOD_BM		8 | ||||
| #define   IOD_SC        9 | ||||
| #define   MDD_LBAR		10 | ||||
| #define   GX2_RCONF     11 | ||||
| #define   MPCI_RCONF    12 | ||||
| #define   EPCI			13 | ||||
| #define   USB_LBAR		14 | ||||
|  | ||||
|  | ||||
| typedef struct { | ||||
|   unsigned long Mbiu; | ||||
|   unsigned long SubtrPid; | ||||
|   unsigned long ClockGating; | ||||
|   unsigned char NumCounters;				// Number of statistic counters on this MBIU | ||||
|   unsigned char ActiveCounters;				// Count of # active statistic counters in use | ||||
| } MBIU_INFO; | ||||
|  | ||||
| #define MAX_MBIU 3 | ||||
							
								
								
									
										371
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/errors.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										371
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/errors.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,371 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //***************************************************************************** | ||||
| //*    Implements the error reporting code.   | ||||
| //***************************************************************************** | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| #include "VSA2.H" | ||||
| #include "SYSMGR.H" | ||||
| #include "PROTOS.H" | ||||
|  | ||||
| extern void pascal write_flat_size(ULONG, ULONG, UCHAR); | ||||
| extern ULONG pascal Get_SysCall_Address(ULONG, UCHAR); | ||||
| extern ULONG VSMs_EAX; | ||||
| extern ULONG Saved_EAX, Saved_EBX, Saved_ECX, Saved_EDX, Saved_ESI, Saved_EDI; | ||||
| extern ULONG Current_VSM; | ||||
|  | ||||
|  | ||||
| #define MAX_ERROR_BUFFER  500 | ||||
| UCHAR ErrorStrings[MAX_ERROR_BUFFER]; | ||||
| UCHAR * ErrorBuffer = ErrorStrings; | ||||
| UCHAR * CurrentError; | ||||
| UCHAR * PreviousError = ErrorStrings; | ||||
| UCHAR DuplicateFlag; | ||||
|  | ||||
| int letbase; | ||||
|  | ||||
|  | ||||
| //*************************************************************************** | ||||
| // Input: | ||||
| //    BH - 1 to clear error log | ||||
| //    CL - Error number (0 for 1st) | ||||
| // Exit: | ||||
| //    AL - 0 if last error | ||||
| //*************************************************************************** | ||||
| void Get_Errors() | ||||
| { USHORT ErrorNumber, Flag; | ||||
|   ULONG Destination; | ||||
|  | ||||
|   // Get parameters passed in from INFO | ||||
|   Flag = (UCHAR)(Saved_EBX >> 8); | ||||
|   ErrorNumber = (UCHAR)Saved_ECX; | ||||
|   Destination = Saved_EDI; | ||||
|  | ||||
|   (UCHAR)Saved_EAX = 0x00; | ||||
|  | ||||
|   // If no errors, return AL = 0; | ||||
|   if (ErrorBuffer == ErrorStrings) { | ||||
| 	 return; | ||||
|   }   | ||||
|  | ||||
|   // If request for 1st error, initialize buffer ptr | ||||
|   if (ErrorNumber == 0) { | ||||
|     CurrentError = ErrorStrings; | ||||
|   }  | ||||
|  | ||||
|  | ||||
|   // Copy next message to EDI | ||||
|   while (CurrentError < ErrorBuffer) { | ||||
|     // Copy 1 byte of error message | ||||
|     write_flat_size(Destination++, (ULONG)*CurrentError, BYTE_IO); | ||||
|     // If end of this message, return | ||||
|     if (*CurrentError++ == 0) { | ||||
|  | ||||
|        write_flat_size(Destination-1, '$', BYTE_IO); | ||||
|  | ||||
|       (UCHAR)Saved_EAX = 1; | ||||
|  | ||||
|       // Is this the last message ? | ||||
|       if (*CurrentError == 0) { | ||||
|         // Clear error log ? (/E flag) | ||||
|         if (Flag == 1) { | ||||
|           PreviousError = ErrorBuffer = ErrorStrings; | ||||
|         } | ||||
|       } | ||||
|       return; | ||||
|     } | ||||
|   } | ||||
| }  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //***************************************************************************** | ||||
| //***************************************************************************** | ||||
| static void printchar(char **str, int c) | ||||
| { | ||||
|   out_8(DBG_PORT, (UCHAR)c); | ||||
|   in_8(0x80); | ||||
|   if (ErrorBuffer < &ErrorStrings[MAX_ERROR_BUFFER-2]) { | ||||
|     *ErrorBuffer = c; | ||||
|     if (*ErrorBuffer++ != *PreviousError++) { | ||||
| 	  DuplicateFlag = 0; | ||||
|     } | ||||
|   }	  | ||||
| } | ||||
|  | ||||
| #define PAD_RIGHT 1 | ||||
| #define PAD_ZERO 2 | ||||
|  | ||||
| //***************************************************************************** | ||||
| //***************************************************************************** | ||||
| static int prints(char **out, const char *string, int width, int pad) | ||||
| { register int pc = 0, padchar = ' '; | ||||
|  | ||||
|   if (width > 0) { | ||||
|     register int len = 0; | ||||
|     register const char *ptr; | ||||
|  | ||||
|     for (ptr = string; *ptr; ++ptr) { | ||||
|       ++len; | ||||
|     } | ||||
|  | ||||
|     if (len >= width) { | ||||
|       width = 0; | ||||
|     } else { | ||||
|       width -= len; | ||||
|     } | ||||
|  | ||||
|     if (pad & PAD_ZERO) { | ||||
|       padchar = '0'; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|  | ||||
|   if (!(pad & PAD_RIGHT)) { | ||||
|     for ( ; width > 0; --width) { | ||||
|       printchar(out, padchar); | ||||
|       ++pc; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   for ( ; *string ; ++string) { | ||||
|     printchar(out, *string); | ||||
|     ++pc; | ||||
|   } | ||||
|  | ||||
|   for ( ; width > 0; --width) { | ||||
|     printchar(out, padchar); | ||||
|     ++pc; | ||||
|   } | ||||
|  | ||||
|   return pc; | ||||
| } | ||||
|  | ||||
| /* the following should be enough for 32 bit int */ | ||||
| #define PRINT_BUF_LEN 12 | ||||
|  | ||||
| //***************************************************************************** | ||||
| // Prints an integer with the specified formatting | ||||
| //***************************************************************************** | ||||
| static int printi(char **out, unsigned long u, int base, int sg, int width, int pad) | ||||
| { char print_buf[PRINT_BUF_LEN]; | ||||
|   register char *s; | ||||
|   register int t, neg = 0, pc = 0; | ||||
|  | ||||
|   if (u == 0) { | ||||
|     print_buf[0] = '0'; | ||||
|     print_buf[1] = '\0'; | ||||
|     return prints (out, print_buf, width, pad); | ||||
|   } | ||||
|   if (sg && (base == 10) && (u & 0x8000)) { | ||||
|     neg = 1; | ||||
|     u = ~u; | ||||
|     u++; | ||||
|   } | ||||
|  | ||||
|   s = print_buf + PRINT_BUF_LEN-1; | ||||
|   *s = '\0'; | ||||
|  | ||||
|   while (u) { | ||||
|     t = (int)(u % base); | ||||
|     if (t >= 10 ) { | ||||
|       t += letbase - '0' - 10; | ||||
|     } | ||||
|     *--s = t + '0'; | ||||
|     u /= base; | ||||
|   } | ||||
|  | ||||
|   if (neg) { | ||||
|     if (width && (pad & PAD_ZERO) ) { | ||||
|       printchar(out, '-'); | ||||
|       ++pc; | ||||
|       --width; | ||||
|     } else { | ||||
|       *--s = '-'; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return pc + prints(out, s, width, pad); | ||||
| } | ||||
|  | ||||
| //***************************************************************************** | ||||
| //***************************************************************************** | ||||
| static int print(char **out, int *varg) | ||||
| { register int width, pad; | ||||
|   register int pc = 0; | ||||
|   register char *format = (char *)(*varg++); | ||||
|   char scr[2]; | ||||
|   unsigned long number; | ||||
|   char *s; | ||||
|  | ||||
|  | ||||
|   for (; *format != 0; ++format) { | ||||
|     if (*format == '%') { | ||||
|       ++format; | ||||
|       pad = 0; | ||||
|       if (*format == '\0') { | ||||
|         break; | ||||
|       } | ||||
|  | ||||
|       switch (*format) { | ||||
|         case '%': | ||||
|           printchar(out, *format); | ||||
|           ++pc; | ||||
|           continue; | ||||
|        | ||||
|         case '-': | ||||
|           ++format; | ||||
|           pad = PAD_RIGHT; | ||||
|           break; | ||||
|       } | ||||
|  | ||||
|       while (*format == '0') { | ||||
|         ++format; | ||||
|         pad |= PAD_ZERO; | ||||
|       } | ||||
|  | ||||
|       for (width = 0; *format >= '0' && *format <= '9'; ++format) { | ||||
|         width *= 10; | ||||
|         width += *format - '0'; | ||||
|       } | ||||
|  | ||||
|       letbase = 'a'; | ||||
|       switch (*format) { | ||||
|  | ||||
|         case 's': | ||||
|           s = *((char **)varg++); | ||||
|           pc += prints (out, s ? s :"(null)", width, pad); | ||||
|           break; | ||||
|  | ||||
|         case 'u': | ||||
|           number = *varg++; | ||||
|           pc += printi (out, number, 10, 0, width, pad); | ||||
|           break; | ||||
|  | ||||
|         case 'd': | ||||
|           number = *varg++; | ||||
|           pc += printi (out, number, 10, 1, width, pad); | ||||
|           break; | ||||
|  | ||||
|         case 'x': | ||||
| //        pc += printi (out, number, 16, 0, width, pad); | ||||
| //        break; | ||||
|  | ||||
|         case 'X': | ||||
|           letbase = 'A'; | ||||
|           number = (USHORT)*varg++; | ||||
|           if (width > 4) { | ||||
|             number |= (ULONG)(*varg++) << 16; | ||||
|           } | ||||
|           pc += printi (out, number, 16, 0, width, pad); | ||||
|           break; | ||||
|  | ||||
|         case 'c': | ||||
|           // char are converted to int then pushed on the stack | ||||
|           scr[0] = *varg++; | ||||
|           scr[1] = '\0'; | ||||
|           pc += prints (out, scr, width, pad); | ||||
|           break; | ||||
|  | ||||
|       } // end switch | ||||
|  | ||||
|     } else { | ||||
|       printchar(out, *format); | ||||
|       ++pc; | ||||
|     } | ||||
|   } // end for | ||||
|  | ||||
| 	if (out) { | ||||
|       **out = '\0'; | ||||
|     } | ||||
| 	return pc; | ||||
| } | ||||
|  | ||||
| //***************************************************************************** | ||||
| //***************************************************************************** | ||||
| void Log_Error(const char *format, ...) | ||||
| { register int *varg = (int *)(&format); | ||||
|   UCHAR * SavedErrorBuffer; | ||||
|   UCHAR * SavedPrevious; | ||||
|  | ||||
|   SavedErrorBuffer = ErrorBuffer; | ||||
|   SavedPrevious = PreviousError; | ||||
|   if (PreviousError == ErrorStrings) { | ||||
|     DuplicateFlag = 0; | ||||
|   } else { | ||||
|     DuplicateFlag = 1; | ||||
|   } | ||||
|  | ||||
|   // Store a formatted error message | ||||
|   print(0, varg); | ||||
|  | ||||
|   // Terminate the error buffer | ||||
|   if (ErrorBuffer < &ErrorStrings[MAX_ERROR_BUFFER]) { | ||||
|     *(ErrorBuffer++) = 0; | ||||
|   } | ||||
|  | ||||
|   // Same error as previous? | ||||
|   if (DuplicateFlag) { | ||||
|     // Yes, then restore ptrs | ||||
| 	PreviousError = SavedPrevious; | ||||
|     ErrorBuffer = SavedErrorBuffer; | ||||
|     *(ErrorBuffer) = 0; | ||||
|   }	else { | ||||
|     // No, then advance previous error buffer ptr | ||||
|     PreviousError = SavedErrorBuffer; | ||||
|   } | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //***************************************************************************** | ||||
| // Inserts an error entry into the error log. | ||||
| //***************************************************************************** | ||||
| void pascal Error_Report(UCHAR ErrorCode, ULONG Info1, ULONG Info2, ULONG Vsm, UCHAR Depth) | ||||
| { ULONG CallingAddress; | ||||
|   static UCHAR ErrorString[50]; | ||||
|  | ||||
|   CallingAddress = Get_SysCall_Address(Vsm, Depth); | ||||
|  | ||||
|   Log_Error("Error code 0x%02X reported at %08X. Parameters: 0x%08X and 0x%08X.", \ | ||||
|             ErrorCode, CallingAddress, Info1, Info2); | ||||
| } | ||||
|  | ||||
|  | ||||
| //***************************************************************************** | ||||
| // Reports an error from a VSM. | ||||
| //***************************************************************************** | ||||
| void pascal Report_VSM_Error(UCHAR ErrorCode, ULONG Info1, ULONG Info2) | ||||
| { | ||||
|   if (Current_VSM == 0) { | ||||
|     Error_Report(ErrorCode, Info1, Info2, SysMgr_VSM,  0); | ||||
|   }	else { | ||||
|     Error_Report(ErrorCode, Info1, Info2, Current_VSM, 1); | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
							
								
								
									
										616
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/events.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										616
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/events.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,616 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //****************************************************************************** | ||||
| //*     This file contains code for: | ||||
| //*       1) Initialization of the Events[] array | ||||
| //*       2) Registering events | ||||
| //*       3) Sending event messages  | ||||
| //****************************************************************************** | ||||
|  | ||||
|  | ||||
|  | ||||
| #include "VSA2.H" | ||||
| #include "SYSMGR.H" | ||||
| #include "PROTOS.H" | ||||
|  | ||||
|  | ||||
| #define MAX_HIT 10		// Max. # of hits on any single event | ||||
|  | ||||
| // External function prototypes: | ||||
| extern USHORT FilterTimer(EVENT_ENTRY *, EVENT); | ||||
| extern UCHAR VSM_Is_Yielded(VSM); | ||||
|  | ||||
| // External variables: | ||||
| extern ULONG VSM_Ptrs[]; | ||||
|  | ||||
| // Local variables: | ||||
| //***************************************************************************** | ||||
| // The first MAX_EVENT entries are indexed by the EVENT code. | ||||
| // The Link field contains the index of the next VSM registered for that event. | ||||
| // A link of 00h terminates the list. | ||||
| //***************************************************************************** | ||||
| EVENT_ENTRY Events[MAX_REGISTRATIONS]; | ||||
| UCHAR FreeEvent;  // Head of available Events[] entries | ||||
| ULONG MsgPacket[MAX_MSG_PARAM+1]; | ||||
| ULONG MsgParams[MAX_HIT][4]; | ||||
|  | ||||
| UCHAR * VsmNames[] = { | ||||
|   "SYS_MGR", | ||||
|   "AUDIO", | ||||
|   "VGA", | ||||
|   "LEGACY", | ||||
|   "PM", | ||||
|   "OHCI", | ||||
|   "i8042", | ||||
|   "DEBUGGER", | ||||
|   "ACPI", | ||||
|   "APM", | ||||
|   "OEM_ACPI", | ||||
|   "SMB", | ||||
|   "BATTERY", | ||||
|   "RTC", | ||||
|   "S2D", | ||||
|   "EXT_AMP", | ||||
|   "PCMCIA", | ||||
|   "SPY", | ||||
|   "NETWORK", | ||||
|   "GPIO", | ||||
|   "KEYBOARD", | ||||
|   "MOUSE", | ||||
|   "USB", | ||||
|   "FLASH", | ||||
|   "INFRARED", | ||||
|   "THERMAL", | ||||
|   "NULL", | ||||
|   "MPEG", | ||||
|   "VIP", | ||||
|   "LPC", | ||||
|   "VUART", | ||||
|   "MICRO", | ||||
|   "USER1", | ||||
|   "USER2", | ||||
|   "USER3", | ||||
|   "SYSINFO", | ||||
|   "SUPERIO", | ||||
|   "EHCI", | ||||
| }; | ||||
|  | ||||
| UCHAR * EventNames[] = { | ||||
|   "????", | ||||
|   "GRAPHICS", | ||||
|   "AUDIO", | ||||
|   "USB", | ||||
|   "ACPI", | ||||
|   "ACPI_TIMER", | ||||
|   "IO_TRAP", | ||||
|   "IO_TIMEOUT", | ||||
|   "PME", | ||||
|   "KEL", | ||||
|   "VIDEO_INACTIVITY", | ||||
|   "GPIO", | ||||
|   "SOFTWARE_SMI", | ||||
|   "PCI_TRAP", | ||||
|   "VIRTUAL_REGISTER", | ||||
|   "NMI", | ||||
|   "TIMER", | ||||
|   "DEVICE_TIMEOUT", | ||||
|   "SEMAPHORE", | ||||
|   "VBLANK", | ||||
|   "A20", | ||||
|   "SMB", | ||||
|   "RTC", | ||||
|   "THERMAL", | ||||
|   "LPC", | ||||
|   "UART", | ||||
|   "BLOCKIO", | ||||
| }; | ||||
|  | ||||
|  | ||||
| //***************************************************************************** | ||||
| // Copies an Events[] entry | ||||
| //***************************************************************************** | ||||
| void pascal Copy_Event(USHORT From, USHORT To) | ||||
| {   | ||||
|   Events[To].Vsm    = Events[From].Vsm; | ||||
|   Events[To].Param1 = Events[From].Param1; | ||||
|   Events[To].Param2 = Events[From].Param2; | ||||
|   Events[To].Param3 = Events[From].Param3; | ||||
|   Events[To].Link   = Events[From].Link; | ||||
|   Events[To].Priority = Events[From].Priority; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //***************************************************************************** | ||||
| // Initializes the Events[] array | ||||
| //***************************************************************************** | ||||
| void Initialize_Events(void)  | ||||
| { int i; | ||||
|  | ||||
|   Events[0].RemainingInterval = 0xFFFFFFFF; | ||||
|  | ||||
|   for (i = 0; i < MAX_REGISTRATIONS ; i++) { | ||||
|     Events[i].Priority = 0xffff; | ||||
|     Events[i].Index = i; | ||||
|   } | ||||
|  | ||||
|   // Initialize the list of free event entries | ||||
|   for (i = MAX_REGISTRATIONS-2; i > MAX_EVENT ; i--) { | ||||
|     Events[i].Link = i+1; | ||||
|   } | ||||
|   FreeEvent = MAX_EVENT+1; | ||||
| } | ||||
|  | ||||
| //***************************************************************************** | ||||
| // Checks Events[EventIndex] for parameters matching those in MsgPacket[]. | ||||
| // Return value is EventIndex if the parameters match else 0x00. | ||||
| //***************************************************************************** | ||||
| USHORT pascal FilterEvent(EVENT Event, EVENT EventIndex) | ||||
| { USHORT IO_Hit, IO_Base, IO_Range, ClassIndex, RdWrAttribute; | ||||
|   UCHAR Size; | ||||
|   ULONG Vsm; | ||||
|   register EVENT_ENTRY * EventPtr; | ||||
|   USHORT PCI_Hit; | ||||
|   static ULONG PCI_Data; | ||||
|   static USHORT PCI_Addr; | ||||
|   static UCHAR PCI_Size; | ||||
|  | ||||
|   EventPtr = &Events[EventIndex]; | ||||
|   Vsm = EventPtr->Vsm; | ||||
|  | ||||
|   switch (Event) { | ||||
|  | ||||
|     case EVENT_USB: | ||||
|       if ((UCHAR)MsgPacket[2] == (UCHAR)EventPtr->Param1) { | ||||
|         return EventIndex; | ||||
|       } | ||||
|       break; | ||||
|  | ||||
|     case EVENT_TIMER: | ||||
|       // Check if the registered interval has expired | ||||
|       return FilterTimer(EventPtr, EventIndex); | ||||
|  | ||||
|     case EVENT_GPIO: | ||||
|       // Verify the pin & edge match the event registration | ||||
|       if (MsgPacket[1] == EventPtr->Pin && (MsgPacket[2] & EventPtr->Attributes)) { | ||||
|         // If GPIO is Sleep button being used to wake system, don't send event | ||||
|           return EventIndex; | ||||
|       } | ||||
|       break; | ||||
|  | ||||
| 	case EVENT_PME: | ||||
|       // MsgPacket[1] = ACPI GPE0_STS | ||||
|       // MsgPacket[2] = ACPI PM1_STS | ||||
|       if (EventPtr->Attributes & GPE) { | ||||
|         if ((1L << EventPtr->Pme) & MsgPacket[1]) { | ||||
|           return EventIndex; | ||||
|         } | ||||
|       } | ||||
|       if (EventPtr->Attributes & PM1) { | ||||
|         if ((1L << EventPtr->Pm1) & MsgPacket[2]) { | ||||
|           return EventIndex; | ||||
|         } | ||||
|       } | ||||
|       break; | ||||
|  | ||||
|     case EVENT_IO_TRAP: | ||||
|     case EVENT_IO_TIMEOUT: | ||||
|       IO_Base  = EventPtr->IO_Base; | ||||
|       IO_Range = EventPtr->IO_Range; | ||||
|       IO_Hit   = (USHORT)MsgPacket[2]; | ||||
|       // Check address range | ||||
|       if ((IO_Hit >= IO_Base) && (IO_Hit <= (IO_Base+IO_Range-1))) { | ||||
|  | ||||
|         if (Event == EVENT_IO_TIMEOUT) { | ||||
|           return EventIndex; | ||||
|         } | ||||
|  | ||||
|         // Filter reads/writes | ||||
|         if (MsgPacket[1] & 2) { | ||||
|           RdWrAttribute = READS_ONLY >> 16; | ||||
|         } else { | ||||
|           RdWrAttribute = WRITES_ONLY >> 16; | ||||
|         } | ||||
|         if (!(EventPtr->Flags & RdWrAttribute)) { | ||||
|           return EventIndex; | ||||
|         } | ||||
|       } | ||||
|       break; | ||||
|  | ||||
|     case EVENT_VIRTUAL_REGISTER: | ||||
|       // Check for correct Class::Index | ||||
|       ClassIndex = (USHORT)MsgPacket[1]; | ||||
|       if ((ClassIndex >= EventPtr->ClassLow) && (ClassIndex <= EventPtr->ClassHigh)) { | ||||
|         return EventIndex; | ||||
|       } | ||||
|       break; | ||||
|  | ||||
|     case EVENT_PCI_TRAP: | ||||
|       if (EventIndex == EVENT_PCI_TRAP) { | ||||
|         // Save original parameters | ||||
|         PCI_Addr = (USHORT)MsgPacket[1]; | ||||
|         PCI_Size = (UCHAR)MsgPacket[2]; | ||||
|         PCI_Data = MsgPacket[3]; | ||||
|       } else { | ||||
|         // Restore original parameters | ||||
|         (USHORT)MsgPacket[1] = PCI_Addr;    | ||||
|         (UCHAR)MsgPacket[2] = PCI_Size;    | ||||
|         MsgPacket[3] = PCI_Data; | ||||
|       } | ||||
|  | ||||
|       // Ignore SysMgr's virtualization | ||||
|       if (Vsm == SysMgr_VSM) { | ||||
|         break;          | ||||
|       } | ||||
|  | ||||
|       if (MsgPacket[2] & 0x20000) { | ||||
|         RdWrAttribute = READS_ONLY >> 16; | ||||
|       } else { | ||||
|         RdWrAttribute = WRITES_ONLY >> 16; | ||||
|       } | ||||
|  | ||||
|  | ||||
|       PCI_Hit = PCI_Addr; | ||||
|       Size = PCI_Size & DWORD_IO; | ||||
|  | ||||
|       while (Size) { | ||||
|  | ||||
|         // Check for PCI address match after applying mask | ||||
|         if (EventPtr->PCI_Addr == (PCI_Hit & ~(EventPtr->PCI_Mask))) { | ||||
|  | ||||
|           // Filter reads/writes | ||||
|           if (!(EventPtr->Flags & RdWrAttribute)) { | ||||
|             // Limit Size to correct boundaries | ||||
|             Size = PCI_Size & DWORD_IO; | ||||
|             switch (PCI_Hit & 0x3) { | ||||
|               case 2: | ||||
|                if (Size == DWORD_IO) { | ||||
|                  Size = WORD_IO; | ||||
|                } | ||||
|                break; | ||||
|               case 3: | ||||
|                Size = BYTE_IO; | ||||
|                break; | ||||
|             } | ||||
|             MsgPacket[2] &= ~DWORD_IO; | ||||
|             MsgPacket[2] |=  Size; | ||||
|             (USHORT)MsgPacket[1] = PCI_Hit; | ||||
|             return EventIndex; | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         // Don't cross DWORD boundaries | ||||
|         if ((++PCI_Hit & 0x3) == 0) { | ||||
|           break; | ||||
|         } | ||||
|         MsgPacket[3] >>= 8; | ||||
|         if (!(PCI_Size & IO_WRITE)) {  | ||||
|           MsgPacket[3] |= 0xFF000000; | ||||
|         } | ||||
|         Size >>= 1; | ||||
|       } | ||||
|       break; | ||||
|  | ||||
|     case EVENT_SOFTWARE_SMI: | ||||
|       // Check for code match after applying mask | ||||
|       if (EventPtr->Param1 == (MsgPacket[1] & ~EventPtr->Param2)) { | ||||
|         return EventIndex; | ||||
|       } | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       return EventIndex; | ||||
|   } | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| //***************************************************************************** | ||||
| // | ||||
| // Sends a MSG_EVENT to all VSMs registered for the specified event. | ||||
| // | ||||
| //***************************************************************************** | ||||
| EVENT pascal Send_Event(EVENT Event, VSM From_VSM) | ||||
| { ULONG To_VSM, ErrorParam = Event; | ||||
|   UCHAR HitCount = 0; | ||||
|   EVENT Hits[MAX_HIT], EventIndex; | ||||
|   USHORT i; | ||||
|   register EVENT_ENTRY * EventPtr; | ||||
|  | ||||
|   // Perform sanity checks | ||||
|   if (Event == 0 || Event > MAX_EVENT) { | ||||
|     Log_Error("Invalid event 0x%04X", Event); | ||||
| 	return 0; | ||||
|   } | ||||
|  | ||||
|   if (Events[Event].Vsm == 0) { | ||||
|     // No VSM has registered this event. | ||||
|     Log_Error("EVENT_%s[0x%08X;0x%08X] is not registered to a VSM", EventNames[Event], MsgPacket[1], MsgPacket[2]); | ||||
|     return 0; | ||||
|   } | ||||
|  | ||||
|   EventIndex = Event; | ||||
|  | ||||
| #if HISTORY | ||||
|   Keep_History(Event, EventIndex); | ||||
| #endif | ||||
|  | ||||
|   // Store Event code as message parameter[0] | ||||
|   MsgPacket[0] = Event; | ||||
|  | ||||
|   // Walk the entire event chain looking for parameter matches | ||||
|   while (EventIndex) { | ||||
|  | ||||
|     EventPtr = &Events[EventIndex]; | ||||
|  | ||||
|     // Check if the parameters for the current event match this event registration | ||||
|     if (FilterEvent(Event, EventIndex)) { | ||||
|       if (HitCount < MAX_HIT-1) { | ||||
|         // Record the hit | ||||
|         Hits[++HitCount] = EventIndex; | ||||
|         MsgParams[HitCount][1] = MsgPacket[1]; | ||||
|         MsgParams[HitCount][2] = MsgPacket[2]; | ||||
|         MsgParams[HitCount][3] = MsgPacket[3]; | ||||
|       } else { | ||||
|         // ERROR: MAX_HIT is too small | ||||
|         Log_Error("Hits[] array is too small"); | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // Point to the next registered VSM | ||||
|     EventIndex = EventPtr->Link; | ||||
|   } | ||||
|  | ||||
|   // Send messages in priority order | ||||
|   for (i = HitCount; i > 0; i--) { | ||||
|     EventPtr = &Events[Hits[i]]; | ||||
|     To_VSM = EventPtr->Vsm; | ||||
|  | ||||
|     // Is the VSM being awakened prematurely from SYS_YIELD_CONTROL? | ||||
|     if (VSM_Is_Yielded(To_VSM)) { | ||||
|       EVENT_ENTRY * TimerPtr; | ||||
|  | ||||
|       // Find the wakeup timer being used | ||||
|       EventIndex = EVENT_TIMER; | ||||
|       while (EventIndex) { | ||||
|         TimerPtr = &Events[EventIndex]; | ||||
|  | ||||
|         if ((TimerPtr->Vsm == To_VSM) && (TimerPtr->Param2 & SYS_YIELD)) { | ||||
|           Unregister_Event(EVENT_TIMER, To_VSM, TimerPtr->Param1, TimerPtr->Param2); | ||||
|           break; | ||||
|         } | ||||
|         EventIndex = TimerPtr->Link; | ||||
|       }        | ||||
|     } | ||||
|  | ||||
|     // Send a message to the VSM | ||||
|     if (!(EventPtr->Param2 & SYS_YIELD)) { | ||||
|       MsgPacket[1] = MsgParams[i][1]; | ||||
|       MsgPacket[2] = MsgParams[i][2]; | ||||
|       MsgPacket[3] = MsgParams[i][3]; | ||||
|       Send_Message(From_VSM, To_VSM, MSG_EVENT); | ||||
|     } | ||||
|  | ||||
|     // Unregister one-shot events | ||||
|     if (EventPtr->Param2 & ONE_SHOT) { | ||||
|       Unregister_Event(Event, To_VSM, EventPtr->Param1, EventPtr->Param2); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Send message to Spy VSM, if present | ||||
|   if (HitCount && VSM_Ptrs[VSM_SPY]) { | ||||
|     Send_Message(From_VSM, VSM_Ptrs[VSM_SPY], MSG_EVENT); | ||||
|   } | ||||
|  | ||||
|  | ||||
|   return HitCount; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //***************************************************************************** | ||||
| // Associates a VSM with an Event and associated Parameters. | ||||
| // The System Manager maintains a table indexed by the Event.  Each entry | ||||
| // contains a Link (array index) to the next VSM registered as a handler for | ||||
| // that Event.  Entries are ordered by Priority (high to low).  Unused array | ||||
| // elements are denoted by the Vsm field == 0000. | ||||
| //***************************************************************************** | ||||
| void pascal Register_Event(EVENT Event, PRIORITY Priority, VSM Vsm, ULONG Param1, ULONG Param2) | ||||
| { UCHAR index, previous, next, Match=0; | ||||
|   register EVENT_ENTRY * EventPtr; | ||||
|  | ||||
|   if (Event > MAX_EVENT) { | ||||
|     // Illegal Event | ||||
|     Log_Error("Attempt to register invalid event 0x%04X by the %s VSM", Event, VsmNames[Get_VSM_Type(Vsm)]); | ||||
| 	return; | ||||
|   } | ||||
|  | ||||
|   // Handle special cases | ||||
|   switch (Event) { | ||||
|  | ||||
|     case EVENT_VIRTUAL_REGISTER: | ||||
|       // Param2[15:8] = low index  Param2[7:0] = high index | ||||
| 	  // If index == 0x00, then any index is valid | ||||
|       Param1 <<= 8;                             // Shift class to bits 15:8 | ||||
|       index = 0xFF;                             // Default upper index | ||||
|       if (Param2) { | ||||
|         index = (UCHAR)Param2;                  // Get upper index | ||||
|         (UCHAR)Param1 = (UCHAR)(Param2 >> 8);   // Get lower index | ||||
|       } | ||||
|       Param2 = Param1; | ||||
|       (UCHAR)Param2 = index; | ||||
|       break; | ||||
|  | ||||
|     case EVENT_IO_TRAP: | ||||
|       // 16 MSBs of Param1 are reserved | ||||
|       Param1 &= 0x0000FFFF;	 | ||||
|       // Don't allow PCI config cycles to be trapped | ||||
|       if (Param1 >= 0xCF8 && Param1 <= 0xCFF) { | ||||
|         Log_Error("Attempt to trap I/O 0xCF8-0xCFF by the %s VSM", VsmNames[Get_VSM_Type(Vsm)]); | ||||
|         return; | ||||
|       } | ||||
|       break; | ||||
|  | ||||
|     case EVENT_TIMER: | ||||
|       // Mask all except Handle and valid flags | ||||
|       Param2 &= FOR_STANDBY | ONE_SHOT | SYS_YIELD | 0xFFFF; | ||||
|       if (Param1 == 0) { | ||||
|         Priority = UNREGISTER_PRIORITY; | ||||
|       } | ||||
|       break; | ||||
|   } | ||||
|      | ||||
|   // If unregistering event(s)... | ||||
|   if (Priority >= UNREGISTER_PRIORITY) { | ||||
|      Unregister_Event(Event, Vsm, Param1, Param2); | ||||
|      return; | ||||
|   } | ||||
|  | ||||
|   index = (UCHAR)Event; | ||||
|   next = 0; | ||||
|  | ||||
|   if (Events[Event].Vsm) { | ||||
|  | ||||
|     // Ensure a VSM doesn't register for the same event twice | ||||
| 	do { | ||||
|       EventPtr = &Events[index]; | ||||
|  | ||||
|       // If it is the same VSM... | ||||
|       if (EventPtr->Vsm == Vsm) { | ||||
|  | ||||
|         switch (Event) { | ||||
|  | ||||
|           // If existing timer handle, assign new interval and/or priority | ||||
|           case EVENT_TIMER: | ||||
|             if (EventPtr->Handle == (USHORT)Param2) { | ||||
|               Match = 2; | ||||
|             } | ||||
|             break; | ||||
|  | ||||
|           case EVENT_PWM: | ||||
|             // If existing pin, change rate and/or duty cycle | ||||
|             if (EventPtr->Pin == (USHORT)Param1) { | ||||
|               Match = 3; | ||||
|             } | ||||
|             break; | ||||
|  | ||||
|           // If existing pin, accumulate attributes | ||||
|           case EVENT_GPIO: | ||||
|             if (EventPtr->Pin == Param1 && EventPtr->Priority == Priority) { | ||||
|               EventPtr->Attributes |= Param2; | ||||
|               Match = 1; | ||||
|             } | ||||
|             break; | ||||
|  | ||||
|  | ||||
|           default: | ||||
|             // If params match, then just update the event priority | ||||
|             if (EventPtr->Param1 == Param1 && EventPtr->Param2 == Param2) { | ||||
| #if SUPPORT_PRIORITY | ||||
|               // Sort list again according to priority | ||||
| #endif | ||||
|               Match = 1; | ||||
|               break; | ||||
|             } | ||||
|         }  | ||||
|       } | ||||
|  | ||||
|       // Early out | ||||
|       if (Match) { | ||||
|         break; | ||||
|       } | ||||
|       // Get link to next event | ||||
| 	  index = EventPtr->Link; | ||||
|  | ||||
| 	} while (index); | ||||
|  | ||||
|  | ||||
|  | ||||
|     if (Match == 0) { | ||||
|  | ||||
|       // Report error if no more Events[] entries | ||||
|       if (FreeEvent == 0) { | ||||
|         Log_Error("Failed attempt to register EVENT_%s[0x%08X;0x%08X] by the %s VSM", EventNames[Event], Param1, Param2, VsmNames[Get_VSM_Type(Vsm)]); | ||||
| 	    return; | ||||
|       } | ||||
|  | ||||
|       // Get an unused Events[] entry | ||||
|       index = FreeEvent; | ||||
|       FreeEvent = Events[index].Link; | ||||
|  | ||||
|       // | ||||
|       // Find the insertion point.  There are two cases: | ||||
|       // 1) The new entry is higher priority than the current 1st entry | ||||
|       // 2) The new entry belongs somewhere down the chain. | ||||
| 	  // | ||||
|       previous = next = (UCHAR)Event; | ||||
|       while (next = Events[next].Link) { | ||||
|  | ||||
|         if (Priority > Events[next].Priority) { | ||||
|           break; | ||||
|         } | ||||
|         previous = next; | ||||
|       } | ||||
|  | ||||
|       if (Priority > Events[Event].Priority) { | ||||
|         // case 1:  Need to copy 1st entry to Events[index] | ||||
| 	    Copy_Event(Event, index); | ||||
|         next = index; | ||||
|         index = (UCHAR)Event; | ||||
|  | ||||
|       } else { | ||||
|         // case 2: | ||||
|         // Insert new event into linked list | ||||
|         Events[previous].Link = index; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Create new Events[] entry | ||||
|   EventPtr = &Events[index]; | ||||
|  | ||||
|  | ||||
|   switch (Match) { | ||||
|  | ||||
|     // New registration | ||||
|     case 0: | ||||
|       EventPtr->Link     = next; | ||||
|       EventPtr->Vsm      = Vsm; | ||||
|     case 3: | ||||
|       EventPtr->Param2   = Param2; | ||||
|  | ||||
|     // Update of Priority | ||||
|     case 1: | ||||
|       EventPtr->Priority = Priority; | ||||
|  | ||||
|     // Update of Parameter (e.g. timer interval) | ||||
|     case 2: | ||||
|       EventPtr->Param1   = Param1; | ||||
|  | ||||
|   } | ||||
|  | ||||
|   // Enable the appropriate hardware | ||||
|   Enable_Event(Event, index, 1); | ||||
|  | ||||
| } | ||||
							
								
								
									
										62
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/gpio.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										62
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/gpio.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //*	Function:                                                           * | ||||
| //*     This file contains non-chipset specific GPIO code.   | ||||
|  | ||||
|  | ||||
| #include "VSA2.H" | ||||
| #include "SYSMGR.H" | ||||
| #include "PROTOS.H" | ||||
|  | ||||
|  | ||||
| extern ULONG MsgPacket[]; | ||||
| extern Hardware HardwareInfo; | ||||
|  | ||||
|  | ||||
|  | ||||
| //************************************************************************************ | ||||
| // Reports invalid GPIO pin | ||||
| //************************************************************************************ | ||||
| void Report_GPIO_Error(USHORT Pin) | ||||
| {   | ||||
|   Report_VSM_Error(ERR_HW_MISMATCH, EVENT_GPIO, Pin); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //************************************************************************************ | ||||
| // Sends the EVENT_GPIO message | ||||
| //************************************************************************************ | ||||
| void Send_GPIO_Event(USHORT Pin, USHORT Edge) | ||||
| {  | ||||
|  | ||||
|   MsgPacket[1] = Pin; | ||||
|   MsgPacket[2] = Edge; | ||||
|   Send_Event(EVENT_GPIO, 0); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										488
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/gpio5536.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										488
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/gpio5536.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,488 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //****************************************************************************** | ||||
| //*     This file contains code specific to CS5536 GPIOs | ||||
| //****************************************************************************** | ||||
|  | ||||
|  | ||||
|  | ||||
| #include "VSA2.H" | ||||
| #include "SYSMGR.H" | ||||
| #include "PROTOS.H" | ||||
| #include "VPCI.H" | ||||
| #include "PCI.H" | ||||
| #include "MDD.H" | ||||
| #include "MAPPER.H" | ||||
|  | ||||
|  | ||||
| #define POWER_BUTTON_PIN     28 | ||||
|  | ||||
| // External Functions: | ||||
| extern void Send_GPIO_Event(USHORT Pin, USHORT Edge); | ||||
| extern void Enable_PME_Event(UCHAR, UCHAR, UCHAR, USHORT); | ||||
| extern UCHAR pascal BitScanReverse(ULONG); | ||||
|  | ||||
| // External Variables: | ||||
| extern PCI_HEADER_ENTRY ISA_Hdr[]; | ||||
| extern GPIO_FUNCTION GPIO_Control; | ||||
|  | ||||
| // Local Variables: | ||||
| ULONG Enable_Mask; | ||||
| USHORT Lock_Port, Lock_Data; | ||||
| USHORT GPIO_Port; | ||||
| UCHAR  Bank=0; | ||||
| UCHAR  ShiftCount; | ||||
|  | ||||
|  | ||||
|  | ||||
| typedef struct { | ||||
|   UCHAR SelectOffset;  // Offset to filter select register | ||||
|   UCHAR FilterOffset;  // Offset to filter amount register | ||||
|   UCHAR Pin;           // Pin this filter is associated to | ||||
|   UCHAR FilterRestore; | ||||
| } FILTERS; | ||||
|  | ||||
| FILTERS FilterInfo[8] = { | ||||
|  {GPIO_FILTER_SELECT0, GPIO_FILTER_AMOUNT+0*8, 0xFF, 0}, | ||||
|  {GPIO_FILTER_SELECT1, GPIO_FILTER_AMOUNT+1*8, 0xFF, 0}, | ||||
|  {GPIO_FILTER_SELECT2, GPIO_FILTER_AMOUNT+2*8, 0xFF, 0}, | ||||
|  {GPIO_FILTER_SELECT3, GPIO_FILTER_AMOUNT+3*8, 0xFF, 0}, | ||||
|  {GPIO_FILTER_SELECT4, GPIO_FILTER_AMOUNT+4*8, 0xFF, 0}, | ||||
|  {GPIO_FILTER_SELECT5, GPIO_FILTER_AMOUNT+5*8, 0xFF, 0}, | ||||
|  {GPIO_FILTER_SELECT6, GPIO6_FILTER_AMOUNT,    28,   1}, // power button pre-defined | ||||
|  {GPIO_FILTER_SELECT7, GPIO7_FILTER_AMOUNT,    0xFF, 0}, | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //***************************************************************************** | ||||
| // Sends EVENT_GPIO messages for pins that have the specified edge status pending | ||||
| //***************************************************************************** | ||||
| void GPIO_Helper(UCHAR Edge, UCHAR PinBase) | ||||
| { ULONG PinMask; | ||||
|   UCHAR Pin; | ||||
|  | ||||
|   if (Edge == RISING_EDGE) { | ||||
|     (UCHAR)GPIO_Port = GPIO_POSEDGE_STATUS; | ||||
|   } else { | ||||
|     (UCHAR)GPIO_Port = GPIO_NEGEDGE_STATUS; | ||||
|   } | ||||
|   if (PinBase) {  | ||||
|     (UCHAR)GPIO_Port |= GPIO_HIGH_BANK_SELECT; | ||||
|   } | ||||
|  | ||||
|   // Get edge status | ||||
|   PinMask = in_32(GPIO_Port); | ||||
|  | ||||
|   // Clear the edge status | ||||
|   out_32(GPIO_Port, PinMask); | ||||
|  | ||||
|   // Ignore transitions that are not enabled | ||||
|   GPIO_Port -= GPIO_POSEDGE_STATUS; | ||||
|   GPIO_Port += GPIO_POSEDGE_ENABLE; | ||||
|   PinMask &= in_32(GPIO_Port) & 0x0000FFFFL; | ||||
|  | ||||
|   // Loop through all pending GPIO edges | ||||
|   while (PinMask) { | ||||
|  | ||||
|     // Determine next pending GPIO pin | ||||
|     Pin = BitScanReverse(PinMask); | ||||
|     PinMask &= ~(1L << Pin); | ||||
|  | ||||
|     // Send the event to the VSM(s) | ||||
|     Send_GPIO_Event(PinBase+Pin, Edge); | ||||
|   } | ||||
| } | ||||
|  | ||||
| //***************************************************************************** | ||||
| // Handles GPIO SMIs | ||||
| //***************************************************************************** | ||||
| void CS5536_GPIO_Handler(ULONG Active_GPIOs) | ||||
| { | ||||
|   // Get the current GPIO address | ||||
|   GPIO_Port = ISA_Hdr[BAR1/4].Value_LO; | ||||
|   Bank = GPIO_LOW_BANK_SELECT; | ||||
|   GPIO_Helper( RISING_EDGE,  0);  // Handle GPIO[15:00]  rising edges | ||||
|   GPIO_Helper(FALLING_EDGE,  0);  // Handle GPIO[15:00] falling edges | ||||
|   Bank = GPIO_HIGH_BANK_SELECT; | ||||
|   GPIO_Helper( RISING_EDGE, 16);  // Handle GPIO[31:16]  rising edges | ||||
|   GPIO_Helper(FALLING_EDGE, 16);  // Handle GPIO[31:16] falling edges | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //***************************************************************************** | ||||
| // Unlocks specified GPIO register(s). | ||||
| // After GPIO registers are accessed, Relock_GPIO_Regs() should be invoked. | ||||
| //***************************************************************************** | ||||
| void Unlock_GPIO_Regs(USHORT UnlockMask) | ||||
| { | ||||
|   // Get current Lock register | ||||
|   Lock_Port = ISA_Hdr[BAR1/4].Value_LO; | ||||
|   (UCHAR)Lock_Port = Bank + GPIO_LOCK_ENABLE; | ||||
|   Lock_Data = in_16(Lock_Port); | ||||
|  | ||||
|   // Unlock required registers | ||||
|   out_16(Lock_Port, Lock_Data & ~UnlockMask); | ||||
|  | ||||
| } | ||||
|  | ||||
| //***************************************************************************** | ||||
| // Restores GPIO register lock | ||||
| //***************************************************************************** | ||||
| void Relock_GPIO_Regs(void) | ||||
| { | ||||
|   out_16(Lock_Port, Lock_Data); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //***************************************************************************** | ||||
| // Writes a 32-bit value to a GPIO register | ||||
| //***************************************************************************** | ||||
| void Write_GPIO_Register(UCHAR Register, ULONG Data)  | ||||
| {  | ||||
|   // Write register | ||||
|   (UCHAR)GPIO_Port = Bank + Register; | ||||
|   out_32(GPIO_Port, Data); | ||||
|  | ||||
|   // Handle registers that are slow due to being in the Standby power domain | ||||
|   if (Bank == GPIO_HIGH_BANK_SELECT) { | ||||
|     in_32(GPIO_Port); | ||||
|   } | ||||
| } | ||||
|  | ||||
| //***************************************************************************** | ||||
| // Writes Enable_Mask to a GPIO register | ||||
| //***************************************************************************** | ||||
| void Configure_GPIO(UCHAR Reg)  | ||||
| { | ||||
|   Write_GPIO_Register(Reg, Enable_Mask); | ||||
| } | ||||
|  | ||||
|  | ||||
| //***************************************************************************** | ||||
| // Maps the specified GPIO pin to the specified GPIO Interrupt | ||||
| //***************************************************************************** | ||||
| void GPIO_Mapper(UCHAR Pin, UCHAR Irq) | ||||
| { ULONG Data; | ||||
|  | ||||
|   // Unlock GPIO register(s) | ||||
|   Unlock_GPIO_Regs(LKIE | LKOE | LKPU | LKPD); | ||||
|  | ||||
|   // Configure pin as Input | ||||
|   if (Pin != POWER_BUTTON_PIN) {  // Keeps sleep pin from generating SMI | ||||
|     Configure_GPIO(GPIO_INPUT_ENABLE); | ||||
|   } | ||||
|  | ||||
|   // Disable Output, Pullup & Pulldown | ||||
|   Data = Enable_Mask << 16; | ||||
|   Write_GPIO_Register(GPIO_OUTPUT_ENABLE,   Data); | ||||
|   Write_GPIO_Register(GPIO_PULLDOWN_ENABLE, Data); | ||||
|   Write_GPIO_Register(GPIO_PULLUP_ENABLE,   Data); | ||||
|  | ||||
|   // Restore Lock register | ||||
|   Relock_GPIO_Regs(); | ||||
|  | ||||
|  | ||||
|   // Program GPIO Mapper | ||||
|   (UCHAR)GPIO_Port = (UCHAR)(GPIO_MAPPER_X + ((Pin >> 1) & 0x0C)); | ||||
|   ShiftCount = (Pin % 8) * 4; | ||||
|   Data  = in_32(GPIO_Port); | ||||
|  | ||||
|   Data &= ~(0x0000000FL << ShiftCount); | ||||
|   Data |=  (ULONG)Irq   << ShiftCount; | ||||
|   out_32(GPIO_Port, Data); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //***************************************************************************** | ||||
| // Clears the positive & negative edge status registers for the specified GPIOs | ||||
| //***************************************************************************** | ||||
| void ClearEdgeStatus(ULONG Mask) | ||||
| { | ||||
|   Write_GPIO_Register(GPIO_POSEDGE_STATUS, Mask); | ||||
|   Write_GPIO_Register(GPIO_NEGEDGE_STATUS, Mask); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //***************************************************************************** | ||||
| // Enables/Disables generation of SMI on GPIO edge(s) for the CS5536 chipset | ||||
| //***************************************************************************** | ||||
| void CS5536_GPIO_Control(ULONG Param1, ULONG Param2, UCHAR EnableFlag) | ||||
| { ULONG Attributes; | ||||
|   UCHAR Pin, Pme, Pm1, i, PinToMatch, FilterAmount, filter_to_use; | ||||
|   ULONG Clear_Mask; | ||||
|    | ||||
|  | ||||
|   // Unpack parameters | ||||
|   Pin = (UCHAR)Param1; | ||||
|   Pme = (UCHAR)(Param1 >> 16); | ||||
|   Pm1 = (UCHAR)(Param2 >> 16); | ||||
|   Attributes = Param2 & 0xff00ffff; | ||||
|  | ||||
|   GPIO_Port = ISA_Hdr[BAR1/4].Value_LO; | ||||
|  | ||||
| //  Log_Error("GPIO %d (%d) %d %d 0x%08X 0x%08X 0x%08X\r\n",Pin,EnableFlag,Pme,Pm1,Attributes,Param1,Param2); | ||||
|   // Validate parameters | ||||
|   if (Pin >= 32) { | ||||
|     Log_Error("Invalid GPIO pin # = 0x%02X\r\n", Pin); | ||||
|     return; | ||||
|   } | ||||
|   if ((Pme >  7) && (Attributes & PME)) { | ||||
|     Log_Error("Invalid PME # = 0x%02X\r\n", Pme); | ||||
|     return; | ||||
|   } | ||||
|   if ((Pm1 > 10) && (Attributes & PM1)) { | ||||
|     Log_Error("Invalid PM1 # = 0x%02X\r\n", Pm1); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   // Select Low/High bank | ||||
|   ShiftCount = Pin; | ||||
|   Bank = GPIO_LOW_BANK_SELECT; | ||||
|   if (Pin >= 16) { | ||||
|     ShiftCount -= 16; | ||||
|     Bank = GPIO_HIGH_BANK_SELECT; | ||||
|   } | ||||
|   // Generate masks | ||||
|   Clear_Mask = Enable_Mask = 1L << ShiftCount; | ||||
|  | ||||
|   // Clear possible false edge events | ||||
|   ClearEdgeStatus(Clear_Mask); | ||||
|  | ||||
|   // If disable, set 16 MSBs of Enable_Mask | ||||
|   if (!EnableFlag) { | ||||
|     Enable_Mask <<= 16; | ||||
|   } | ||||
|  | ||||
|   // Set GPIO Interrupt/PME Mapper to generate an ASMI or PME | ||||
|   if (Attributes & PME) { | ||||
|     // Map the GPIO as a PME | ||||
|     GPIO_Mapper(Pin, (UCHAR)(Pme | 0x08)); | ||||
|   } else { | ||||
|     // Route to ASMI unless PCI interrupt is specified | ||||
|     if (Pme) { | ||||
|       // Map the GPIO to a GPIO Interrupt | ||||
|       GPIO_Mapper(Pin, (UCHAR)(Pme & 0x07)); | ||||
|     } else { | ||||
|       if (!(Attributes & NO_ASMI)) { | ||||
|         // Map the GPIO to an ASMI | ||||
|         GPIO_Mapper(Pin, (Z_IRQ_SMI & 0x07)); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|  | ||||
|  | ||||
|   // This will set the MDD MSR_SMI bit for SMI on any PM event | ||||
|   // and program the appropriate ACPI PM1_EN or GPE0_EN bit. | ||||
|   // Additionally, it will clear the corresponding ACPI PM1_STS or GPE0_STS bit. | ||||
|   Enable_PME_Event(EnableFlag, Pm1, Pme, (USHORT)Attributes); | ||||
|  | ||||
|   // If power button, don't touch any GPIO regs! | ||||
|   if (Pin == POWER_BUTTON_PIN) { | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|  | ||||
|   // Unlock GPIO registers | ||||
|   Unlock_GPIO_Regs(LKPE | LKNE | LKFE | LKEE); | ||||
|  | ||||
|   // Configure as Output ? | ||||
|   if (Attributes & OUTPUT) { | ||||
|  | ||||
|     Configure_GPIO(GPIO_OUTPUT_ENABLE); | ||||
|  | ||||
|     // Configure output pin inversion | ||||
|     if (Attributes & INVERT) { | ||||
|       Configure_GPIO(GPIO_OUTPUT_INVERT); | ||||
|     } | ||||
|  | ||||
|     // Configure open drain | ||||
|     if (Attributes & OPEN_DRAIN) { | ||||
|       Configure_GPIO(GPIO_OUTPUT_OPENDRAIN); | ||||
|     } | ||||
|  | ||||
|     // Configure AUX output selects | ||||
|     if (Attributes & AUX1) { | ||||
|       Configure_GPIO(GPIO_OUT_AUX1_SELECT); | ||||
|     } else { | ||||
|       if (Attributes & AUX2) { | ||||
|         Configure_GPIO(GPIO_OUT_AUX2_SELECT); | ||||
|       } | ||||
| 	} | ||||
|   } | ||||
|  | ||||
|  | ||||
|   // Configure as Input ? | ||||
|   if ((Attributes & INPUT) || !(Attributes & OUTPUT)) { | ||||
|     // Configure input pin inversion | ||||
|     if (Attributes & INVERT) { | ||||
|       Configure_GPIO(GPIO_INPUT_INVERT); | ||||
|     } | ||||
|  | ||||
|     if (Attributes & AUX1) { | ||||
|       Configure_GPIO(GPIO_IN_AUX1_SELECT); | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|     // Configure input for correct edge(s) | ||||
|    	switch (Attributes & BOTH_EDGES) { | ||||
|  | ||||
|       case BOTH_EDGES: | ||||
|    	  case RISING_EDGE: | ||||
|        	// Enable/Disable the RISING edge | ||||
|         Configure_GPIO(GPIO_POSEDGE_ENABLE); | ||||
|    	    if ((Attributes & BOTH_EDGES) == RISING_EDGE) { | ||||
|        	  break; | ||||
|         } | ||||
|    	    // fall through intended | ||||
|  | ||||
|       case FALLING_EDGE: | ||||
|    	    // Enable/Disable the FALLING edge | ||||
|        	Configure_GPIO(GPIO_NEGEDGE_ENABLE); | ||||
|         break; | ||||
|  | ||||
|    	  default: | ||||
|        	// If neither edge is enabled, an event is 'active' as long | ||||
|         // as the input is high (or low if inverted). | ||||
|    	    break; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|  | ||||
|   // NOTE: If pullup is enabled, pulldown is automatically disabled | ||||
|   // Configure pullup | ||||
|   if (Attributes & PULLUP) { | ||||
|     Configure_GPIO(GPIO_PULLUP_ENABLE); | ||||
|   }	else { | ||||
|     // Configure pulldown | ||||
|     if (Attributes & PULLDOWN) { | ||||
|       Configure_GPIO(GPIO_PULLDOWN_ENABLE); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|  | ||||
|   // Configure debounce filter | ||||
|   if (Attributes & DEBOUNCE) { | ||||
|     PinToMatch = (UCHAR)Pin; | ||||
|  | ||||
|     if (EnableFlag) { | ||||
|       FilterAmount = 1;	   // Units = ~30 usec | ||||
|     } else { | ||||
|       FilterAmount = 0; | ||||
|     } | ||||
|  | ||||
|     // Find a filter | ||||
|     i=0; | ||||
|     if (Attributes & FOR_STANDBY ) { | ||||
|         i=6;    // if pme 6/7 set for filter 6/7 (in standby domain) | ||||
|     } | ||||
|     filter_to_use=0xff; | ||||
|  | ||||
|     for (; i < 8; i++) { | ||||
|       if (FilterInfo[i].Pin == PinToMatch) { | ||||
|         filter_to_use=i; | ||||
|         break; | ||||
|       } | ||||
|       // see if we have found an open filter - use only for enable | ||||
|       if ((filter_to_use == 0xff) && (FilterInfo[i].Pin == 0xff) && (EnableFlag)) { | ||||
|         filter_to_use=i; | ||||
|       }  | ||||
|     } | ||||
| //    Log_Error("GPIO %d using filter %d\r\n",Pin,filter_to_use); | ||||
|     // found an matching pin for filter or an open one  | ||||
|     if (filter_to_use != 0xff) {    // found one | ||||
|         i=filter_to_use;  // use this filter | ||||
|         if (EnableFlag) { | ||||
|           // Mark filter in-use | ||||
|           FilterInfo[i].Pin = (UCHAR)Pin; | ||||
|  | ||||
|           // Save the filter select register | ||||
|           (UCHAR)GPIO_Port = FilterInfo[i].SelectOffset; | ||||
|           FilterInfo[i].FilterRestore = in_8(GPIO_Port); | ||||
|  | ||||
|           // Select the filter | ||||
|           out_8(GPIO_Port, (UCHAR)Pin); | ||||
|         } | ||||
|  | ||||
|         // Program filter Amount & Count | ||||
|         (UCHAR)GPIO_Port = FilterInfo[i].FilterOffset; | ||||
|         out_32(GPIO_Port, (ULONG)FilterAmount); | ||||
|  | ||||
|         if (!EnableFlag) { | ||||
|           // Mark filter as available | ||||
|           FilterInfo[i].Pin = 0xFF; | ||||
|  | ||||
|           // Restore the filter select register | ||||
|           (UCHAR)GPIO_Port = FilterInfo[i].SelectOffset; | ||||
|           out_8(GPIO_Port, FilterInfo[i].FilterRestore); | ||||
|         } | ||||
|         // Enable/Disable filter | ||||
|         Configure_GPIO(GPIO_IN_FILTER_ENABLE); | ||||
|     } | ||||
|     else { | ||||
|       // no filter found | ||||
|       Log_Error("No filter found for GPIO %d\r\n",Pin); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Enable/Disable GPIO as an event unless it is EVENT_PWM | ||||
|   if ((Attributes & (OUTPUT | NO_ASMI)) != (OUTPUT | NO_ASMI)) { | ||||
|     Configure_GPIO(GPIO_EVENTS_ENABLE); | ||||
|   } | ||||
|  | ||||
|  | ||||
|   // Clear possible false edge events | ||||
|   ClearEdgeStatus(Clear_Mask); | ||||
|  | ||||
|  | ||||
|   // Restore Lock register | ||||
|   Relock_GPIO_Regs(); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //***************************************************************************** | ||||
| // Initialized CS5536 GPIO logic | ||||
| //***************************************************************************** | ||||
| void CS5536_GPIO_Init(void) | ||||
| { | ||||
|  | ||||
|   // Point GPIO_Control to correct GPIO routine for CS5536 | ||||
|   GPIO_Control = CS5536_GPIO_Control; | ||||
|  | ||||
|   // Clear pending GPIOs | ||||
|   CS5536_GPIO_Handler(0); | ||||
|  | ||||
|   // Map the GPIO SMI source | ||||
|   IRQZ_Mapper(Z_IRQ_SMI, 2); | ||||
|  | ||||
| } | ||||
							
								
								
									
										645
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/handlers.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										645
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/handlers.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,645 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //***************************************************************************** | ||||
| //*     Implements the handlers for top-level SMI source | ||||
| //***************************************************************************** | ||||
|  | ||||
|  | ||||
| #include "VSA2.H" | ||||
| #include "CHIPSET.H" | ||||
| #include "PROTOS.H"  | ||||
| #include "SYSMGR.H" | ||||
| #include "VPCI.H" | ||||
| #include "PCI.H" | ||||
|  | ||||
| // External variables | ||||
| extern SmiHeader SMM_Header; | ||||
| extern SmiHeader Nested_Header; | ||||
| extern ULONG Saved_EAX, Saved_EBX, Saved_ECX; | ||||
| extern ULONG MsgPacket[]; | ||||
| extern ULONG VSM_ListHead; | ||||
| extern ULONG Virtualized_PCI_Devices; | ||||
| extern ULONG Stats_Sources; | ||||
| extern ULONG IRQ_Mask; | ||||
| extern ULONG MPCI_NB; | ||||
| extern ULONG VSM_Buffer; | ||||
| extern ULONG Nested_Flag; | ||||
| extern ULONG Video_Sources; | ||||
| extern USHORT Audio_Sources; | ||||
| extern Hardware HardwareInfo; | ||||
| extern EVENT_ENTRY Events[];  | ||||
| extern PCI_HEADER_ENTRY ISA_Hdr[]; | ||||
| extern PCI_HEADER_ENTRY HostBridge_Hdr[]; | ||||
|  | ||||
|  | ||||
| // External function prototypes | ||||
| extern void pascal Timer_Handler(USHORT); | ||||
| extern void CS5536_GPIO_Handler(ULONG); | ||||
| extern void INT_Return(void); | ||||
| extern void Send_OHCI_Event(UCHAR); | ||||
| extern void VR_Handler(SmiHeader *); | ||||
| extern void ACPI_Workaround(SmiHeader *, USHORT); | ||||
| extern void Remove_RTC_Fix(void); | ||||
| extern void set_reset_state(void); | ||||
| extern void pascal Unblock_VSM(ULONG); | ||||
| extern void pascal Return_Virtual_Value(SmiHeader *, ULONG); | ||||
| extern SmiHeader * pascal Get_Header_Params(ULONG); | ||||
| extern ULONG Get_ACPI_Status(ULONG *); | ||||
| extern USHORT Get_Timeout(ULONG, UCHAR *); | ||||
| extern USHORT CS5536_MFGPT_Handler(void); | ||||
| extern void ReInit_Descriptors(void); | ||||
| extern void Init_SysMgr(); | ||||
| extern void A20_Sync(void); | ||||
| extern void Update_VSMs_CR0(void); | ||||
|  | ||||
|  | ||||
| ULONG INT_Vectors[MAX_INT] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xF000F859}; | ||||
| ULONG VSM_Ptrs[VSM_MAX_TYPE+1]; | ||||
| ULONG Audio_IRQ = 0; | ||||
| ULONG NativeAudioStatus = 0x4F0;   // Defaults to 0040:00F0 | ||||
| UCHAR End_of_POST = 0; | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| void Broadcast_SysMgr_Msg (MSG Message, UCHAR Param1) | ||||
| { | ||||
|   MsgPacket[0] = (ULONG)Param1;  | ||||
|   MsgPacket[1] = MsgPacket[2] = 0;  | ||||
|   Broadcast_Message(Message, VSM_ANY, 0x00000000); | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Sends a message for an asynchronous event | ||||
| //*********************************************************************** | ||||
| void pascal Send_Asynchronous_Event(EVENT Event) | ||||
| {  | ||||
|   MsgPacket[1] = MsgPacket[3] = MsgPacket[4] = 00000000; | ||||
|   if (Event != EVENT_IO_TIMEOUT) { | ||||
|     MsgPacket[2] = 00000000; | ||||
|   } | ||||
|   Send_Event(Event, 0x00000000); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Sends a message for a synchronous event | ||||
| // Returns TRUE if the event was registered. | ||||
| //*********************************************************************** | ||||
| USHORT pascal Send_Synchronous_Event(EVENT Event, SmiHeader * SmiHdr) | ||||
| { ULONG Vsm; | ||||
|   USHORT EventRegistered; | ||||
|  | ||||
|   if ((USHORT)SmiHdr == 0x0000 || (USHORT)SmiHdr == (USHORT)&SMM_Header) { | ||||
|     Vsm = SysMgr_VSM; | ||||
|   } else { | ||||
|     Vsm = Current_VSM; | ||||
|   } | ||||
|   EventRegistered = Send_Event(Event, Vsm); | ||||
|   if (!EventRegistered) { | ||||
|  | ||||
|     // No VSM is registered for this event | ||||
|     // If nested event, change the VSM's state from 'Blocked' to 'Ready' | ||||
|     if (Nested_Flag) { | ||||
|       Unblock_VSM(Vsm); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return EventRegistered; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // This routine walks the VSM linked list, recording ptrs to VSMs that | ||||
| // have special requirements. | ||||
| //*********************************************************************** | ||||
| void Record_VSM_Locations(void) | ||||
| { ULONG VSM_Ptr; | ||||
|   UCHAR VSM_Type; | ||||
|  | ||||
|   for (VSM_Type=0; VSM_Type<=VSM_MAX_TYPE; VSM_Type++) { | ||||
|     VSM_Ptrs[VSM_Type] = 0x00000000; | ||||
|   } | ||||
|   VSM_Ptr = VSM_ListHead; | ||||
|  | ||||
|   while (VSM_Ptr) { | ||||
|  | ||||
|     VSM_Type = Get_VSM_Type(VSM_Ptr); | ||||
|  | ||||
|     if (VSM_Type < sizeof(VSM_Ptrs)/4) { | ||||
|       VSM_Ptrs[VSM_Type] = VSM_Ptr; | ||||
|     } | ||||
|     if (VSM_Type == VSM_RTC) { | ||||
|       Remove_RTC_Fix(); | ||||
|     } | ||||
|     VSM_Ptr = GetFlink(VSM_Ptr); | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // This routine handles software SMI events. | ||||
| //*********************************************************************** | ||||
| void pascal SMINT_Handler(USHORT Code) | ||||
| { int i; | ||||
|  | ||||
|   // Handle return from INT callback | ||||
|   if (VSM_Buffer) { | ||||
|     INT_Return(); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   switch (Code) { | ||||
|  | ||||
|     case SYS_BIOS_INIT: | ||||
|  | ||||
|       // If installing VSA from DOS, restore descriptors to default state | ||||
|       if (Saved_EBX != 0) { | ||||
|         ReInit_Descriptors(); | ||||
|       } | ||||
|  | ||||
|       // VSA Initialization | ||||
|       Init_SysMgr(); | ||||
|       if (Saved_EBX == 0) { | ||||
|         break; | ||||
|       } | ||||
|  | ||||
|     case SYS_END_OF_POST: | ||||
|       Current_VSM = 0; | ||||
|  | ||||
|       End_of_POST = 1; | ||||
|       // | ||||
|       // Take a snapshot of the interrupt vectors | ||||
|       // | ||||
|       for (i = 0; i < MAX_INT; i++) { | ||||
|         if (INT_Vectors[i] == 0) { | ||||
|           INT_Vectors[i] = read_flat((ULONG) i << 2 ); | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       // Entry point to video ROM | ||||
|       INT_Vectors[1] = 0xC0000003; | ||||
|  | ||||
|       // | ||||
|       //  The BIOS may have enabled the changed the cache setting | ||||
|       // since early init, so update each VSM's CR0 field | ||||
|       // | ||||
|       Update_VSMs_CR0(); | ||||
|  | ||||
|       // Send a phase 1 initialization message to each VSM | ||||
|       Broadcast_SysMgr_Msg(MSG_INITIALIZE, END_OF_POST_INIT); | ||||
|       break; | ||||
|  | ||||
|  | ||||
|     case SYS_REMOVE: | ||||
|       Unregister_VSM_Events(Saved_ECX); | ||||
| 	  break; | ||||
|  | ||||
|     case SYS_VSM_INSTALL: | ||||
|  | ||||
|       // EBX points to the new VSM | ||||
|       // ECX points to the old VSM | ||||
|       Unregister_VSM_Events(Saved_ECX); | ||||
|  | ||||
|       Record_VSM_Locations(); | ||||
|  | ||||
|  | ||||
|       // | ||||
|    	  // Send both phase 0 & 1 initialization messages to the new VSM | ||||
|       // | ||||
| 	  MsgPacket[0] = EARLY_INIT; | ||||
| 	  MsgPacket[1] = 1; | ||||
|       Send_Message(SysMgr_VSM, Saved_EBX, MSG_INITIALIZE); | ||||
|  | ||||
| 	  MsgPacket[0] = END_OF_POST_INIT; | ||||
| 	  MsgPacket[1] = 1; | ||||
|       Send_Message(SysMgr_VSM, Saved_EBX, MSG_INITIALIZE); | ||||
|      break; | ||||
|  | ||||
|     default: | ||||
|       // | ||||
|       // Send event to appropriate VSM | ||||
|       // | ||||
|       MsgPacket[1] = (ULONG)Code; | ||||
|       MsgPacket[2] = Saved_EBX; | ||||
|       MsgPacket[3] = Saved_ECX; | ||||
|       Send_Synchronous_Event(EVENT_SOFTWARE_SMI, 0); | ||||
|       break; | ||||
|  | ||||
|   } // end switch | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // This routine handles graphics events. | ||||
| //*********************************************************************** | ||||
| void VG_Handler(void) | ||||
| { register SmiHeader * SmiHdr; | ||||
|  | ||||
|   SmiHdr = Get_Header_Params(0); | ||||
|  | ||||
|   // Set bit 24 of MsgPacket[2] if I/O write | ||||
|   if (SmiHdr->SMI_Flags.IO_Write) { | ||||
|     MsgPacket[2] |= 0x01000000L; | ||||
|   } | ||||
|   MsgPacket[1] = Video_Sources; | ||||
|   Send_Synchronous_Event(EVENT_GRAPHICS, SmiHdr); | ||||
|  | ||||
|   // Reset video event flags | ||||
|   Video_Sources = 0; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // This routine handles A20 | ||||
| //*********************************************************************** | ||||
| void A20_Handler(void) | ||||
| {  | ||||
|  | ||||
|   A20_Sync(); | ||||
|  | ||||
|   // Send event so it will be recorded in the history buffer | ||||
|   // Send_Synchronous_Event(EVENT_A20, SMM_Header); | ||||
|  | ||||
| } | ||||
|  | ||||
| //*********************************************************************** | ||||
| // This routine handles reset | ||||
| //*********************************************************************** | ||||
| void Reset_Handler(void) | ||||
| {  | ||||
|  | ||||
|  | ||||
|   // Schedule reset routine after VSMs have processes MSG_SHUTDOWN  | ||||
|   Schedule_VSM((ULONG)((USHORT)set_reset_state)); | ||||
|  | ||||
|   // Tell each VSM to get ready for cold boot | ||||
|   // No VSMs use this message at this time, so don't broadcast message | ||||
|   // (to keep overhead down) | ||||
|   // Broadcast_SysMgr_Msg(MSG_SHUTDOWN, 0); | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
| //*********************************************************************** | ||||
| // This routine handles NMI | ||||
| //*********************************************************************** | ||||
| void NMI_Handler(void) | ||||
| { | ||||
|   Send_Asynchronous_Event(EVENT_NMI); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // This routine handles trapped PCI events. | ||||
| // The event may come from an SSMI (CPU) or an external SMI (chipset) | ||||
| //*********************************************************************** | ||||
| void PCI_Handler(void) | ||||
| { ULONG ID_Select, Data; | ||||
|   USHORT Address; | ||||
|   UCHAR Size; | ||||
|   register SmiHeader * SmiHdr; | ||||
|  | ||||
|  | ||||
|   SmiHdr = Get_Header_Params(SMI_SRC_PCI_TRAP); | ||||
|   Address = (USHORT)MsgPacket[2]; | ||||
|  | ||||
|   Size = (UCHAR)SmiHdr->data_size; | ||||
|   ID_Select = 1L << ((Address >> 11) & 0x1F); | ||||
|  | ||||
|  | ||||
|   if (SmiHdr->SMI_Flags.IO_Write) { | ||||
|  | ||||
|     // | ||||
|     // Trapped PCI header WRITE | ||||
|     // | ||||
|     Data = MsgPacket[3]; | ||||
|  | ||||
|     // Is it is a totally virtual PCI header ? | ||||
|     if (ID_Select & Virtualized_PCI_Devices) { | ||||
|       MsgPacket[3] = Virtual_PCI_Write_Handler(Address, Size, Data); | ||||
|       Address &= 0xFFFC; | ||||
|       Size = DWORD_IO; | ||||
|     } | ||||
|  | ||||
|     // Set the write flag | ||||
|     Size |= IO_WRITE; | ||||
|  | ||||
|   } else { | ||||
|  | ||||
|     // | ||||
|     // Trapped PCI header READ | ||||
|     // | ||||
|  | ||||
|     // Is it is a totally virtual PCI header ? | ||||
|     if (ID_Select & Virtualized_PCI_Devices) { | ||||
|  | ||||
|       Data = Virtual_PCI_Read_Handler(Address); | ||||
|  | ||||
|     } else { | ||||
|       Trap_PCI_IDSEL(Address, 0); | ||||
|       out_32(PCI_CONFIG_ADDRESS, 0x80000000 | Address); | ||||
|       Data = in_32(PCI_CONFIG_DATA); | ||||
|       Trap_PCI_IDSEL(Address, 1); | ||||
|     } | ||||
|     // Return virtualized PCI device value to the right environment | ||||
|     Return_Virtual_Value(SmiHdr, Data); | ||||
|     MsgPacket[3] = Data; | ||||
|   } | ||||
|  | ||||
|   // Repackage the parameters | ||||
|   MsgPacket[2] = MsgPacket[1] << 16; | ||||
|   MsgPacket[1] = 0x80000000 + (USHORT)Address; | ||||
|   (USHORT)MsgPacket[2] = Size; | ||||
|  | ||||
|   // Send EVENT_PCI_TRAP message | ||||
|   if (!Send_Synchronous_Event(EVENT_PCI_TRAP, SmiHdr)) { | ||||
|     // This PCI register was not trapped. | ||||
|     // Re-issue configuration writes to real PCI hardware devices. | ||||
|     if (Size & IO_WRITE) { | ||||
|       if (!(ID_Select & Virtualized_PCI_Devices)) { | ||||
|         USHORT PCI_Data_Reg; | ||||
|         // Disable trapping for this device | ||||
|         Trap_PCI_IDSEL(Address, 0); | ||||
|  | ||||
|         // Re-issue the configuration write to the h/w device | ||||
|         out_32(PCI_CONFIG_ADDRESS, 0x80000000 | Address); | ||||
|         PCI_Data_Reg = PCI_CONFIG_DATA + (Address & 3); | ||||
|         switch (Size & ~IO_WRITE) { | ||||
|  | ||||
|           case BYTE_IO: | ||||
|             out_8(PCI_Data_Reg, (UCHAR)Data); | ||||
|             break; | ||||
|  | ||||
|           case WORD_IO: | ||||
|             out_16(PCI_Data_Reg, (USHORT)Data); | ||||
|             break; | ||||
|  | ||||
|           case DWORD_IO: | ||||
|             out_32(PCI_Data_Reg, Data); | ||||
|             break; | ||||
|         } | ||||
|  | ||||
|         // Re-enable trapping for this device | ||||
|         Trap_PCI_IDSEL(Address, 1); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // This routine handles USB1 events. | ||||
| //*********************************************************************** | ||||
| void USB1_Handler(void) | ||||
| { | ||||
|   Send_OHCI_Event(1); | ||||
|  | ||||
| } | ||||
|  | ||||
| //*********************************************************************** | ||||
| // This routine handles USB2 events. | ||||
| //*********************************************************************** | ||||
| void USB2_Handler(void) | ||||
| { | ||||
|   Send_OHCI_Event(2); | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // This routine handles the CS5536's KEL events | ||||
| //*********************************************************************** | ||||
| void KEL_Handler(void) | ||||
| { | ||||
|   Send_OHCI_Event(1); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // This routine handles a BLOCKIO event (PIO to ATA during UDMA). | ||||
| //*********************************************************************** | ||||
| void BLOCKIO_Handler(void) | ||||
| { SmiHeader * SmiHdr; | ||||
|  | ||||
|   SmiHdr = Get_Header_Params(SMI_SRC_BLOCKIO); | ||||
|   Send_Synchronous_Event(EVENT_BLOCKIO, SmiHdr); | ||||
| } | ||||
|  | ||||
| //*********************************************************************** | ||||
| // This routine handles hits on MBus descriptors. | ||||
| //*********************************************************************** | ||||
| void Descr_Hit_Handler(void) | ||||
| { USHORT Address; | ||||
|   SmiHeader * SmiHdr; | ||||
|  | ||||
|   SmiHdr = Get_Header_Params(SMI_SRC_DESCR_HIT); | ||||
|  | ||||
|   // Ignore if one of the other sources of SSMI_FLAGS | ||||
|   if (!SmiHdr->SMI_Flags.Ext_IO_Trap && !SmiHdr->SMI_Flags.IO_Trap) { | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   Address = (USHORT)SmiHdr->IO_addr; | ||||
|  | ||||
|   // Handle virtual registers | ||||
|   if ((Address & 0xFFFC) == (HostBridge_Hdr[BAR0/4].Value_LO)) { | ||||
|     if (SmiHdr == &SMM_Header) { | ||||
|       // Handle virtual register | ||||
|       VR_Handler(SmiHdr); | ||||
|     } else { | ||||
|       Report_VSM_Error(ERR_NESTED_ACCESS, 0, 0); | ||||
|     } | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   // Handle workaround for PM Support registers | ||||
|   if ((Address & (USHORT)ISA_Hdr[BAR4/4].Mask) == (ISA_Hdr[BAR4/4].Value_LO)) { | ||||
|     ACPI_Workaround(SmiHdr, 0); | ||||
|   } | ||||
|  | ||||
|   // Handle workaround for ACPI registers | ||||
|   if ((Address & 0xFFE0) == (ISA_Hdr[BAR5/4].Value_LO)) { | ||||
|     ACPI_Workaround(SmiHdr, 1); | ||||
|   } | ||||
|   // Send the event | ||||
|   Send_Synchronous_Event(EVENT_IO_TRAP, SmiHdr); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // This routine handles statistic counter ASMIs | ||||
| //*********************************************************************** | ||||
| void StatCntr_Handler(void) | ||||
| { UCHAR StartIndex = 0; | ||||
|   USHORT Address; | ||||
|   ULONG SFlag; | ||||
|  | ||||
|  | ||||
|   while (Stats_Sources) { | ||||
|     SFlag = 1L << BitScanForward(Stats_Sources); | ||||
|  | ||||
|     Address = Get_Timeout(SFlag, &StartIndex); | ||||
|     if (Address) { | ||||
|       (USHORT)MsgPacket[2] = Address; | ||||
|       Send_Asynchronous_Event(EVENT_IO_TIMEOUT); | ||||
|     } else { | ||||
|       // Clear status bit | ||||
|       Stats_Sources &= ~SFlag; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // This routine handles the Southbridge's PIC events | ||||
| //*********************************************************************** | ||||
| void PIC_Handler(void) | ||||
| { USHORT ExpiredTimerMask, Timer; | ||||
|  | ||||
|   // Need to read PIC registers to determine if one of: | ||||
|   //   USB1, USB2, S/W Generated, RTC Alarm, Audio, PM, NAND Flash,  | ||||
|   //   SMB, KEL, UART1, UART2, MFGPT comparator, or GPIO. | ||||
|   CS5536_GPIO_Handler(0); | ||||
|  | ||||
|  | ||||
|   // Check if any MFGPT events occurred | ||||
|   ExpiredTimerMask = CS5536_MFGPT_Handler(); | ||||
|   Timer = 0; | ||||
|   while (ExpiredTimerMask) { | ||||
|     if (ExpiredTimerMask & 1) { | ||||
|       Timer_Handler(Timer); | ||||
|     } | ||||
| 	Timer++; | ||||
| 	ExpiredTimerMask >>= 1; | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // This routine handles the CS5536's ACPI events | ||||
| //*********************************************************************** | ||||
| void ACPI_Handler(void) | ||||
| { SmiHeader * SmiHdr; | ||||
|  | ||||
|   SmiHdr = Get_Header_Params(0); | ||||
|  | ||||
|   // Handle mis-aligned access to the PM1_CNT register | ||||
|   while ((UCHAR)SmiHdr->IO_addr != 0x08) { | ||||
|     (UCHAR)SmiHdr->IO_addr++; | ||||
|     (UCHAR)SmiHdr->data_size >>= 1; | ||||
|     SmiHdr->write_data >>= 8; | ||||
|   } | ||||
|   if ((UCHAR)SmiHdr->data_size == 0x07) { | ||||
|     (UCHAR)SmiHdr->data_size = WORD_IO; | ||||
|   } | ||||
|  | ||||
|  | ||||
|   Send_Synchronous_Event(EVENT_ACPI, SmiHdr); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // This routine handles the CS5536's Power Management Events | ||||
| //*********************************************************************** | ||||
| void PME_Handler(void) | ||||
| {  | ||||
|  | ||||
|   // Handle GPIOs that are routed to PM logic | ||||
|   CS5536_GPIO_Handler(0); | ||||
|  | ||||
|   // Filter any false event caused by enabling PME | ||||
|   if (Get_ACPI_Status(MsgPacket)) { | ||||
|     Send_Synchronous_Event(EVENT_PME, 0); | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // This routine handles events for which no other handler applies. | ||||
| //*********************************************************************** | ||||
| void Leftover_Handler(void) | ||||
| { | ||||
|  | ||||
|   // Report that the event was not handled. | ||||
|   Log_Error("Unhandled event"); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //************************************************************************* | ||||
| // | ||||
| //     The SMI_Sources table is used for determining the proper handler for | ||||
| // a top-level SMI source.  Note that a single handler may process multiple | ||||
| // SMI sources.   The order of entries in this table governs the order that | ||||
| // the handlers will be invoked.   This is NOT the order that the VSMs will | ||||
| // be given control.    Therefore, the order of entries is unimportant with | ||||
| // respect to controlling priority.   However, in terms of finding  a match | ||||
| // more quickly, the more frequent SMI events should  be  placed earlier in  | ||||
| // the table. | ||||
| // | ||||
| //************************************************************************* | ||||
|  | ||||
| SMI_ENTRY Handler_Table[] = { | ||||
| 	PCI_Handler,		SMI_SRC_PCI_TRAP, | ||||
|     VG_Handler,			SMI_SRC_VG, | ||||
| 	USB1_Handler,		SMI_SRC_USB1, | ||||
| 	USB2_Handler,		SMI_SRC_USB2, | ||||
| 	A20_Handler,		SMI_SRC_A20, | ||||
| 	Reset_Handler,		SMI_SRC_RESET, | ||||
| 	NMI_Handler,		SMI_SRC_NMI, | ||||
|  | ||||
|  | ||||
| 	Descr_Hit_Handler,  SMI_SRC_DESCR_HIT, | ||||
| 	PIC_Handler,		SMI_SRC_PIC, | ||||
| 	StatCntr_Handler,	SMI_SRC_STAT, | ||||
| 	KEL_Handler,		SMI_SRC_KEL, | ||||
| 	ACPI_Handler,		SMI_SRC_ACPI, | ||||
| 	PME_Handler,        SMI_SRC_PME, | ||||
| 	BLOCKIO_Handler,    SMI_SRC_BLOCKIO, | ||||
|  | ||||
| 	Leftover_Handler,	0xFFFFFFFF, | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| 						    | ||||
							
								
								
									
										193
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/history.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										193
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/history.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,193 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //*	Function:                                                           * | ||||
| //*     This file contains the code for recording event history.  | ||||
|  | ||||
|  | ||||
| #include "VSA2.H" | ||||
| #include "SYSMGR.H" | ||||
| #include "PROTOS.H" | ||||
|  | ||||
|  | ||||
| extern EVENT_ENTRY Events[]; | ||||
| extern ULONG MsgPacket[]; | ||||
|  | ||||
| extern UCHAR VSM_Filter; | ||||
|  | ||||
| #if HISTORY | ||||
| EVENT NonReportableEvents[] = { | ||||
|   EVENT_A20, | ||||
|   EVENT_GRAPHICS, | ||||
|   EVENT_ACPI_TIMER | ||||
| }; | ||||
| #define UNREPORT_COUNT (sizeof(NonReportableEvents)/sizeof(EVENT)) | ||||
|  | ||||
| // | ||||
| // Event history | ||||
| // | ||||
| EVENT_HISTORY History[HISTORY]; | ||||
| int HistoryWrap  = 0; | ||||
| int HistoryStart = 0; | ||||
| int HistoryEnd   = 0; | ||||
|  | ||||
|  | ||||
|  | ||||
| //***************************************************************************** | ||||
| // | ||||
| // Record the event history | ||||
| // | ||||
| //***************************************************************************** | ||||
| void Keep_History(EVENT Event, EVENT EventIndex) | ||||
| { int i; | ||||
|   ULONG ParamMask, Param2; | ||||
|   UCHAR VSM_Type; | ||||
|   register EVENT_ENTRY * EventPtr; | ||||
|  | ||||
|   EventPtr = &Events[EventIndex]; | ||||
|  | ||||
|   VSM_Type = Get_VSM_Type(EventPtr->Vsm); | ||||
|  | ||||
|  | ||||
|   // Filter out VSM(s) | ||||
|   if (VSM_Filter != VSM_ANY && VSM_Type != VSM_Filter) | ||||
|     return; | ||||
|  | ||||
|   // | ||||
|   // Filter events from reporting | ||||
|   // | ||||
|  | ||||
|   for (i=0; i < UNREPORT_COUNT; i++) { | ||||
|     if (Event == NonReportableEvents[i]) | ||||
| 	  return; | ||||
|   } | ||||
|  | ||||
|   // Generate mask for Param1 | ||||
|   ParamMask = 0xFFFFFFFF; | ||||
|   Param2 = EventPtr->Param2; | ||||
|   switch (Event) { | ||||
|  | ||||
|     case EVENT_PCI_TRAP: | ||||
|       // Report all PCI events together by PCI function | ||||
|       ParamMask = ~Param2; | ||||
|       break; | ||||
|  | ||||
|     case EVENT_GPIO: | ||||
|       // Get current edge | ||||
|       Param2 = EventPtr->CurrentEdge; | ||||
|       break; | ||||
|   | ||||
|     case EVENT_SOFTWARE_SMI: | ||||
|       // Don't report APM calls CPU_Busy or CPU_Idle | ||||
|       if ((EventPtr->Param1 & 0xFF00) == 0x5300) { | ||||
|         switch (EventPtr->Param1 & 0x00FF) { | ||||
|           case 0x05: | ||||
|           case 0x06: | ||||
|             return; | ||||
|         } | ||||
|         break; | ||||
|       } | ||||
|       break; | ||||
|  | ||||
|     case EVENT_VIRTUAL_REGISTER: | ||||
|       // Report all VR events together by classes | ||||
|       ParamMask = 0x0000FF00; | ||||
|       break; | ||||
|  | ||||
|   } | ||||
|  | ||||
|   // If it's the same event for the same VSM... | ||||
|   if ((History[HistoryEnd].Event == Event)  && | ||||
|       (History[HistoryEnd].Vsm   == EventPtr->Vsm) ) { | ||||
|  | ||||
|     switch (Event) { | ||||
|  | ||||
|       case EVENT_IO_TRAP: | ||||
|         if (History[HistoryEnd].Param1 != (MsgPacket[2] & 0x0000FFFFL)) { | ||||
|           break; | ||||
|         } | ||||
|  | ||||
|  | ||||
|       // Events to be recorded together if (Param1 & ParamMask) matches | ||||
|       case EVENT_PCI_TRAP: | ||||
|       case EVENT_SOFTWARE_SMI: | ||||
| 	  case EVENT_VIRTUAL_REGISTER: | ||||
|         if (History[HistoryEnd].Param1 != (MsgPacket[1] & ParamMask)) { | ||||
|           break; | ||||
|         } | ||||
|  | ||||
|  | ||||
|       default: | ||||
|         // Record together if 1st two parameters match | ||||
|         if (History[HistoryEnd].Param1 == EventPtr->Param1 && | ||||
|             History[HistoryEnd].Param2 == EventPtr->Param2 ) { | ||||
|           History[HistoryEnd].Count++; | ||||
|           Store_Timestamp(&History[HistoryEnd].TimeStamp); | ||||
|           return;    | ||||
|         } | ||||
|  | ||||
|     } // end switch | ||||
|   } | ||||
|  | ||||
|   // | ||||
|   // Report event in a new history entry. | ||||
|   // | ||||
|   // Increment HistoryEnd unless it's the 1st event | ||||
|   if (History[HistoryEnd].Vsm) { | ||||
|     HistoryEnd++; | ||||
|     if (HistoryEnd >= HISTORY) { | ||||
|       HistoryEnd = 0; | ||||
|       HistoryWrap = 1; | ||||
|     } | ||||
|  | ||||
|     // Increment HistoryStart index too if HistoryEnd has wrapped | ||||
|     if (HistoryWrap) { | ||||
|       HistoryStart++; | ||||
|       if (HistoryStart >= HISTORY) | ||||
|         HistoryStart = 0; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|  | ||||
|   History[HistoryEnd].Vsm    = EventPtr->Vsm; | ||||
|   History[HistoryEnd].Event  = Event; | ||||
|   History[HistoryEnd].Param1 = MsgPacket[1] & ParamMask; | ||||
|   History[HistoryEnd].Param2 = Param2; | ||||
|   History[HistoryEnd].Count  = 1; | ||||
|   Store_Timestamp(&History[HistoryEnd].TimeStamp); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| void Initialize_History(void) | ||||
| { | ||||
|  | ||||
|   // Initialize timestamp field of history buffer entry "previous" to 1st entry | ||||
|   Store_Timestamp(&History[HISTORY-1].TimeStamp); | ||||
|   HistoryWrap  = 0; | ||||
|   HistoryStart = 0; | ||||
|   HistoryEnd   = 0; | ||||
| } | ||||
|  | ||||
| #else | ||||
|  | ||||
| void Initialize_History(void) { } | ||||
|  | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										697
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/idt.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										697
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/idt.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,697 @@ | ||||
| ;  | ||||
| ; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| ;  | ||||
| ; This library is free software; you can redistribute it and/or modify | ||||
| ; it under the terms of the GNU Lesser General Public License as | ||||
| ; published by the Free Software Foundation; either version 2.1 of the | ||||
| ; License, or (at your option) any later version. | ||||
| ;  | ||||
| ; This code is distributed in the hope that it will be useful, | ||||
| ; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| ; Lesser General Public License for more details. | ||||
| ;  | ||||
| ; You should have received a copy of the GNU Lesser General | ||||
| ; Public License along with this library; if not, write to the | ||||
| ; Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| ; Boston, MA 02111-1307 USA  | ||||
| ;  | ||||
| ;******************************************************************************** | ||||
| ; Routines to: | ||||
| ; -set up an SMM-based IDT | ||||
| ; -save/restore of FPU state only as needed | ||||
| ;******************************************************************************** | ||||
|  | ||||
|  | ||||
|  | ||||
| include sysmgr.inc | ||||
| include vsa2.inc | ||||
| include gx2.inc | ||||
|  | ||||
| .model tiny,c | ||||
| .586p | ||||
| .CODE | ||||
|  | ||||
|  | ||||
| CR	equ	0Dh | ||||
| LF	equ	0Ah | ||||
|  | ||||
|  | ||||
| public    Saved_INTs | ||||
| public    Trap_Common | ||||
| externdef Trap_Code: 	dword | ||||
| externdef SysMgr_VSM:	dword | ||||
| externdef Current_VSM:	dword | ||||
| externdef IDT_Base:	dword | ||||
| externdef IDT_Limit:	dword | ||||
| externdef IDT_Selector:dword | ||||
| externdef pascal Parse_Capabilities: proc | ||||
| externdef pascal Read_MSR_HI:        proc | ||||
|  | ||||
| FPU_Owner	dd	0 | ||||
| FPU_State	db	108 dup (0) | ||||
| CR0_PE		equ	1 | ||||
| CR0_EM		equ	4 | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Saves the non-SMM IDT and installs VSA's exception vectors | ||||
| ;*********************************************************************** | ||||
| Install_IDT	proc | ||||
|  | ||||
| 	; Save IDT of interrupted thread | ||||
| 	mov	ecx, 1329h | ||||
| 	rdmsr | ||||
| 	mov	[IDT_Selector], eax | ||||
| 	mov	eax, IDT_SIZE-1 | ||||
| 	wrmsr | ||||
| 	 | ||||
| 	mov	cl, 39h | ||||
| 	rdmsr | ||||
| 	mov	[IDT_Base], eax | ||||
| 	mov	[IDT_Limit], edx | ||||
| 	mov	eax, [SysMgr_VSM] | ||||
| 	add	eax, OFFSET Saved_INTs | ||||
| 	mov	dx, IDT_SIZE | ||||
| 	wrmsr | ||||
| 	 | ||||
| 	 | ||||
| 	nop | ||||
| 	mov	byte ptr [$-1], 0C3h	; Patch a RET at the NOP above | ||||
|  | ||||
| 	mov	eax, [SysMgr_VSM]	; Initialize FPU owner | ||||
| 	mov	[FPU_Owner], eax | ||||
|  | ||||
| ; The following code is only necessary if SysMgr starts on a non-MB boundary. | ||||
| ;    HandlerBase = {SMM_base[31:20], CS_selector[15:0], 4'b0} | ||||
| ;	lea	di, [Saved_INTs+2]	; Patch SysMgr's CS into vector table | ||||
| ;	mov	cx, IDT_SIZE/4 | ||||
| ;	shr	eax, 4			; Compute SysMgr's CS | ||||
| ;InsertCS: | ||||
| ;	mov	[di], ax		; Store SysMgr's CS into vector table | ||||
| ;	add	di, 4 | ||||
| ;	loop	InsertCS | ||||
|  | ||||
| 	ret | ||||
| 	 | ||||
|  | ||||
| Install_IDT endp | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Restores the IDT ptr and FPU state (if modified) | ||||
| ;*********************************************************************** | ||||
| Restore_IDT	proc | ||||
|  | ||||
| 	; Restore the IDT of interrupted thread | ||||
| 	mov	ecx, 1329h | ||||
| 	mov	eax, [IDT_Selector] | ||||
| 	wrmsr | ||||
| 	mov	cl, 39h | ||||
| 	mov	eax, [IDT_Base] | ||||
| 	mov	edx, [IDT_Limit] | ||||
| 	wrmsr | ||||
| 	 | ||||
|  | ||||
| 	; The RET will be patched with a NOP if FPU usage occurs | ||||
| RestoreRET::	 | ||||
| 	ret | ||||
|  | ||||
| 	; Restore the RET at RestoreRET | ||||
| 	mov	byte ptr [RestoreRET], 0C3h | ||||
|  | ||||
| 	; Get last VSM to use FPU | ||||
| 	mov	esi, [SysMgr_VSM] | ||||
| 	xchg	[FPU_Owner], esi | ||||
|  | ||||
| 	; Set VSM's CR0.EM | ||||
| 	or	fs:(VSM_Header PTR [esi]).SysStuff.State.r_CR0, CR0_EM | ||||
|  | ||||
| 	; Save VSM's FPU state | ||||
| 	; NOTE: This can be done in real-mode | ||||
| 	fnsave	fs:(VSM_Header PTR [esi]).SysStuff.FPU_State | ||||
| 		 | ||||
| 	; Restore non-SMM FPU state | ||||
| 	; NOTE: This must be done in 32-bit protected mode | ||||
| 	mov	eax, CR0		; Enter protected mode for FPU save | ||||
| 	or	al, CR0_PE | ||||
| 	mov	CR0, eax | ||||
| 	jmp	$+2 | ||||
|  | ||||
| 	db	66h | ||||
| 	frstor	byte ptr cs:[FPU_State] | ||||
|  | ||||
| 	and	al, NOT CR0_PE		; Return to real mode | ||||
| 	mov	CR0, eax | ||||
|  | ||||
| 	ret | ||||
|  | ||||
| Restore_IDT endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Handler for Trap 7 (Device Not Available) | ||||
| ;*********************************************************************** | ||||
| Trap7	proc | ||||
|  | ||||
| 	push	eax | ||||
|  | ||||
| 	; Clear interrupted VSM's CR0.EM (so it will own the FPU)  | ||||
| 	mov	eax, CR0 | ||||
| 	and	al, NOT CR0_EM | ||||
| 	mov	CR0, eax | ||||
|  | ||||
|  | ||||
| 	; Get current owner of FPU | ||||
| 	mov	eax, cs:[FPU_Owner] | ||||
|  | ||||
| 	; Is it non-SMM thread ? | ||||
| 	cmp	eax, cs:[SysMgr_VSM] | ||||
| 	jne	Set_EM | ||||
| 	 | ||||
|  | ||||
| 	; Yes, enable FPU restore code in Restore_IDT | ||||
| 	mov	byte ptr cs:[RestoreRET], 90h | ||||
|  | ||||
| 	; Save non-SMM FPU state | ||||
| 	; NOTE: This must be done in 32-bit protected mode | ||||
| 	mov	eax, CR0		; Enter protected mode for FPU save | ||||
| 	or	al, CR0_PE | ||||
| 	mov	CR0, eax | ||||
| 	jmp	$+2 | ||||
| 	 | ||||
| 	db	66h | ||||
| 	fnsave	byte ptr cs:[FPU_State] | ||||
|  | ||||
| 	and	al, NOT CR0_PE		; Return to real mode | ||||
| 	mov	CR0, eax | ||||
|  | ||||
| 	jmp	short Record_FPU_Owner | ||||
| 	 | ||||
| 	 | ||||
| 	  | ||||
|  | ||||
| Set_EM: | ||||
| 	; Set previous owner's CR0.EM | ||||
| 	or	fs:(VSM_Header PTR [eax]).SysStuff.State.r_CR0, CR0_EM | ||||
|  | ||||
| 	; Save the FPU state of the previous owner | ||||
| 	; NOTE: This can be done in 16-bit real-mode | ||||
| 	fnsave	byte ptr fs:(VSM_Header PTR [eax]).SysStuff.FPU_State | ||||
| 	 | ||||
| 	; Set FPU flag | ||||
| 	mov	fs:(VSM_Header PTR [eax]).SysStuff.FPU_Flag, 1 | ||||
|  | ||||
|  | ||||
| Record_FPU_Owner: | ||||
| 	; Record the new owner of the FPU | ||||
| 	mov	eax, cs:[Current_VSM] | ||||
| 	mov	cs:[FPU_Owner], eax | ||||
|  | ||||
| 	; Has this VSM used the FPU previously ? | ||||
| 	cmp	fs:(VSM_Header PTR [eax]).SysStuff.FPU_Flag, 0 | ||||
| 	je	short Exit | ||||
| 	 | ||||
| 	; Yes, restore its FPU state | ||||
| 	; NOTE: This can be done in 16-bit real-mode | ||||
| 	lea	eax, (VSM_Header PTR [eax]).SysStuff.FPU_State | ||||
| 	frstor	byte ptr fs:[eax] | ||||
|  | ||||
| Exit:  	pop	eax | ||||
| 	iret			; Return to the interrupted VSM | ||||
|  | ||||
| Trap7	endp	 | ||||
| 	 | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Exception vectors (segments will be patched) | ||||
| ;*********************************************************************** | ||||
| Saved_INTs: | ||||
| 	dd	OFFSET Trap_Code + 8*0 | ||||
| 	dd	OFFSET Trap_Code + 8*1 | ||||
| 	dd	OFFSET Trap_Code + 8*2 | ||||
| 	dd	OFFSET Trap_Code + 8*3 | ||||
| 	dd	OFFSET Trap_Code + 8*4 | ||||
| 	dd	OFFSET Trap_Code + 8*5 | ||||
| 	dd	OFFSET Trap_Code + 8*6 | ||||
| 	dd	OFFSET Trap_Code + 8*7 | ||||
| 	dd	OFFSET Trap_Code + 8*8 | ||||
| 	dd	OFFSET Trap_Code + 8*9 | ||||
| 	dd	OFFSET Trap_Code + 8*0Ah | ||||
| 	dd	OFFSET Trap_Code + 8*0Bh | ||||
| 	dd	OFFSET Trap_Code + 8*0Ch | ||||
| 	dd	OFFSET Trap_Code + 8*0Dh | ||||
| 	dd	OFFSET Trap_Code + 8*0Eh | ||||
| 	dd	OFFSET Trap_Code + 8*0Fh | ||||
| IDT_SIZE	equ	($-Saved_INTs) | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Macros for performing stackless CALLs & RETs | ||||
| ;*********************************************************************** | ||||
| ROM_CALL macro Subr | ||||
| 	local RetAddr | ||||
| 	mov	dx, RetAddr		; Put return addr in BP | ||||
| 	jmp	Subr | ||||
| RetAddr: | ||||
| 	endm | ||||
|         | ||||
|  | ||||
|  | ||||
| ROM_RET	macro | ||||
| 	jmp	dx			; Return to caller | ||||
| 	endm | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; BX = Exception # | ||||
| ;*********************************************************************** | ||||
| Trap_Common: | ||||
| 	mov	cs:[TrapNum], bx | ||||
| 	mov	cs:[Reg_ECX], ecx | ||||
|  | ||||
| 	 | ||||
| 	; Disable SMIs | ||||
| 	mov	ecx, MSR_SMM_CTRL | ||||
| 	xor	eax, eax | ||||
| 	wrmsr	 | ||||
|  | ||||
| 	ROM_CALL NewLine | ||||
|  | ||||
| 	cmp	bl, LastTrap | ||||
| 	jbe	@f | ||||
| 	mov	bl, LastTrap | ||||
| @@: | ||||
| 	add	bx, bx | ||||
| 	mov	bx, cs:[bx+TrapMsgTbl] | ||||
| 	ROM_CALL String | ||||
|  | ||||
| 	lea	bx, [Msg_in] | ||||
| 	ROM_CALL String | ||||
|  | ||||
| 	; | ||||
| 	; Display the VSM which generated the exception | ||||
| 	; | ||||
| 	pop	ecx			; Get SEG:OFFSET of faulting code | ||||
| 	mov	cs:[SegOff], ecx | ||||
| 	mov	esi, cs:[Current_VSM] | ||||
| 	mov	ah, fs:(VSM_Header PTR [esi]).VSM_Type | ||||
| 	lea	si, [VSM_Table] | ||||
| 	ASSUME	SI: PTR TableItem | ||||
| 	test	ecx, 0FFFF0000h		; Is it System Manager ? | ||||
| 	jnz	ScanVSM | ||||
| 	mov	eax, cs:[SysMgr_VSM] | ||||
| 	mov	cs:[Current_VSM], eax | ||||
| 	jmp	ShowVSM | ||||
| ScanVSM: | ||||
| 	mov	al, cs:[si].Vsm		; Get VSM Type from table | ||||
| 	cmp	ah, al | ||||
| 	je	ShowVSM | ||||
| 	cmp	al, VSM_ANY		; End of table ? | ||||
| 	je	ShowVSM | ||||
| 	add	si, sizeof(TableItem)	; Advance to next table entry | ||||
| 	jmp	ScanVSM | ||||
| 	 | ||||
| ShowVSM: | ||||
| 	mov	bx, cs:[si].MsgStr | ||||
| 	ROM_CALL String | ||||
|  | ||||
| 	lea	bx, Msg_VSM		; VSM | ||||
| 	ROM_CALL String | ||||
|  | ||||
| 	ROM_CALL NewLine | ||||
| 	lea	bx, Msg_IP		; IP = xxxx | ||||
| 	ROM_CALL String | ||||
|  | ||||
| 	cmp	cs:[TrapNum], 000Dh	; Is it Trap 0Dh ? | ||||
| 	jne	ShowIP | ||||
| 	mov	ebx, cs:[Current_VSM]	; Yes, check for bad MSR address | ||||
| 	test	ecx, 0FFFF0000h		; Did SysMgr cause it ? | ||||
| 	jnz	ComputeAddr | ||||
| 	mov	ebx, cs:[SysMgr_VSM]	; Yes | ||||
| ComputeAddr: | ||||
| 	movzx	esi, cx | ||||
| 	add	esi, ebx | ||||
| 	mov	eax, dword ptr fs:[esi] | ||||
| 	cmp	al, 0Fh | ||||
| 	jne	short ShowIP | ||||
| 	cmp	ah, 30h			; WRMSR	? | ||||
| 	je	short BadMSR | ||||
| 	cmp	ah, 32h			; RDMSR ? | ||||
| 	jne	ShowIP | ||||
| BadMSR: | ||||
| 	mov	cs:[MSR_Access], ah | ||||
| 	mov	si, sp			; Show caller | ||||
| 	mov	cx, ss:[si+4] | ||||
| 	sub	cx, 3 | ||||
|  | ||||
| 	; If one of the MSR routines, show caller | ||||
| 	cmp	si, OFFSET Read_MSR_HI | ||||
| 	jb	short ShowIP | ||||
| 	cmp	si, OFFSET Parse_Capabilities | ||||
| 	jae	short ShowIP | ||||
| 	mov	cx, ss:[si+2] | ||||
| ShowIP: | ||||
|  | ||||
|  | ||||
| 	mov	ax, cx | ||||
| 	ROM_CALL Hex16 | ||||
|  | ||||
| 	mov	al, '/' | ||||
| 	out	dx, al | ||||
| 	movzx	eax, cx | ||||
| 	add	eax, cs:[Current_VSM] | ||||
| 	ROM_CALL Hex32 | ||||
| 		 | ||||
|  | ||||
| 	lea	bx, Msg_SP		; SP = xxxx | ||||
| 	ROM_CALL String | ||||
| 	mov	ax, sp | ||||
| 	ROM_CALL Hex16 | ||||
|  | ||||
| 	lea	bx, Msg_BP		; BP = xxxx | ||||
| 	ROM_CALL String | ||||
| 	mov	ax, bp | ||||
| 	ROM_CALL Hex16 | ||||
|  | ||||
| 	cmp	cs:[MSR_Access], 0	; Was it an MSR access ? | ||||
| 	je	Beep | ||||
| 	ROM_CALL NewLine		; Yes | ||||
| 	lea	bx, [Msg_MSR] | ||||
| 	ROM_CALL String | ||||
| 	lea	bx, [Msg_MSR_Wr] | ||||
| 	cmp	cs:[MSR_Access], 30h | ||||
| 	je	short ShowMSR | ||||
| 	lea	bx, [Msg_MSR_Rd] | ||||
| ShowMSR: | ||||
| 	ROM_CALL String | ||||
| 	mov	eax, cs:[Reg_ECX]	; Display invalid MSR address | ||||
| 	ROM_CALL Hex32 | ||||
|  | ||||
|  | ||||
| HI_TONE	equ	1193180/3000	; 3 KHz | ||||
| LO_TONE	equ	1193180/750	; 750 Hz | ||||
| INTERVAL	equ	100000/15	; .10 second | ||||
| BEEP_LOOPS	equ	10 | ||||
|  | ||||
| Beep: | ||||
| 	mov	bx, BEEP_LOOPS | ||||
|  	in	al, 61h | ||||
| 	or	al, 3		; connect speaker to timer 2 | ||||
| 	out	61h, al | ||||
| BeepLoop: | ||||
| 	mov	dx, HI_TONE	; Start frequency | ||||
| TwoTone: | ||||
| 	mov	al, 0B6h	; timer 2 mode set | ||||
| 	out	43h, al		; set mode | ||||
| 	mov	ax, dx | ||||
| 	out	42h, al		; set LSB of counter | ||||
| 	mov	al, ah | ||||
| 	out	42h, al		; set MSB of counter | ||||
|  | ||||
| 	mov	cx, INTERVAL	; # 15 usec intervals | ||||
| Interval: | ||||
| 	in	al, 61h		; Wait for 15 usec | ||||
| 	xor	al, ah | ||||
| 	test	al, 10h | ||||
| 	jz	Interval | ||||
| 	xor	ah, 10h | ||||
| 	loop	Interval | ||||
|  | ||||
| 	shl	dx, 1		; Divide frequency by 2 | ||||
| 	cmp	dx, LO_TONE	; End frequency | ||||
| 	jb	TwoTone | ||||
| 	dec	bx		; Decrement loop counter | ||||
| 	jnz	BeepLoop	; Start tones over | ||||
|  | ||||
|  	in	al, 61h		; Turn off speaker | ||||
| 	and	al, NOT 3 | ||||
| 	out	61h, al | ||||
|  | ||||
| Halt:	hlt | ||||
| 	jmp	Halt | ||||
| 	 | ||||
| 	 | ||||
| 	 | ||||
| ;*********************************************************************** | ||||
| ; VSM strings for display of VSM causing the exception | ||||
| ;*********************************************************************** | ||||
| TableItem struc | ||||
|   Vsm	   db	? | ||||
|   MsgStr   dw	? | ||||
| TableItem ends | ||||
|  | ||||
|  | ||||
| VSM_Table: | ||||
| 	TableItem {VSM_SYS_MGR,	Sys_Mgr_VSM} | ||||
| 	TableItem {VSM_AUDIO,	XpressAudio} | ||||
| 	TableItem {VSM_VGA,	SoftVGA} | ||||
| 	TableItem {VSM_LEGACY,	Legacy_VSM} | ||||
| 	TableItem {VSM_PM, 	PM_VSM} | ||||
| 	TableItem {VSM_OHCI,	OHCI_VSM} | ||||
| 	TableItem {VSM_i8042,	i8042_VSM} | ||||
| 	TableItem {VSM_ACPI,	ACPI_VSM} | ||||
| 	TableItem {VSM_APM,	APM_VSM} | ||||
| 	TableItem {VSM_SMB,	SMB_VSM} | ||||
| 	TableItem {VSM_BATTERY,	Battery_VSM} | ||||
| 	TableItem {VSM_RTC,	RTC_VSM} | ||||
| 	TableItem {VSM_S2D,	S2D_VSM} | ||||
| 	TableItem {VSM_SPY,	Spy_VSM} | ||||
| 	TableItem {VSM_NETWORK,	Network_VSM} | ||||
| 	TableItem {VSM_GPIO,	GPIO_VSM} | ||||
| 	TableItem {VSM_USB,	USB_VSM} | ||||
| 	TableItem {VSM_FLASH,	Flash_VSM} | ||||
| 	TableItem {VSM_INFRARED,Infrared_VSM} | ||||
| 	TableItem {VSM_THERMAL,	Thermal_VSM} | ||||
| 	TableItem {VSM_NULL, 	Null_VSM} | ||||
| 	TableItem {VSM_VIP,	VIP_VSM} | ||||
| 	TableItem {VSM_LPC,	LPC_VSM} | ||||
| 	TableItem {VSM_VUART,	VUART_VSM} | ||||
| 	TableItem {VSM_MICRO,	Micro_VSM} | ||||
| 	TableItem {VSM_USER1,	User1_VSM} | ||||
| 	TableItem {VSM_USER2,	User2_VSM} | ||||
| 	TableItem {VSM_USER3,	User3_VSM} | ||||
| 	TableItem {VSM_SUPERIO,	SuperIO_VSM} | ||||
| 	TableItem {VSM_ANY,	Unknown_VSM}		; Catch-all | ||||
|  | ||||
|  | ||||
| Msg	macro	TrapString | ||||
| 	db	TrapString | ||||
| 	db	0 | ||||
| 	endm | ||||
|  | ||||
| XpressAudio:	Msg "Audio" | ||||
| SoftVGA:	Msg "SoftVG" | ||||
| Legacy_VSM:	Msg "Legacy" | ||||
| USB_VSM:	Msg "USB" | ||||
| GPIO_VSM:	Msg "GPIO" | ||||
| ACPI_VSM:	Msg "ACPI" | ||||
| Sample_VSM:	Msg "Sample" | ||||
| APM_VSM:	Msg "APM" | ||||
| Battery_VSM:	Msg "Battery" | ||||
| PM_VSM:	Msg "PM" | ||||
| S2D_VSM:	Msg "SaveToRAM" | ||||
| Sys_Mgr_VSM:	Msg "SysMgr" | ||||
| i8042_VSM:	Msg "i8042" | ||||
| OHCI_VSM:	Msg "OHCI" | ||||
| SuperIO_VSM:	Msg "SuperIO" | ||||
| Null_VSM:	Msg "Null" | ||||
| Spy_VSM:	Msg "Spy" | ||||
| RTC_VSM:	Msg "RTC" | ||||
| SPY_VSM:	Msg "Spy" | ||||
| Network_VSM:	Msg "Network" | ||||
| Infrared_VSM:	Msg "Infrared" | ||||
| Thermal_VSM:	Msg "Thermal" | ||||
| VIP_VSM:	Msg "VIP" | ||||
| LPC_VSM:	Msg "LPC" | ||||
| User1_VSM:	Msg "User1" | ||||
| User2_VSM:	Msg "User2" | ||||
| User3_VSM:	Msg "User3" | ||||
| SMB_VSM:	Msg "SMB" | ||||
| Flash_VSM:	Msg "Flash" | ||||
| VUART_VSM:	Msg "VUART" | ||||
| Micro_VSM:	Msg "Micro" | ||||
| Unknown_VSM:	Msg "VSM???" | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Strings describing the type of exception | ||||
| ;*********************************************************************** | ||||
| TrapMsgTbl: | ||||
| 	dw	OFFSET Trap00 | ||||
| 	dw	OFFSET Trap01 | ||||
| 	dw	OFFSET Trap02 | ||||
| 	dw	OFFSET Trap03 | ||||
| 	dw	OFFSET Trap04 | ||||
| 	dw	OFFSET Trap05 | ||||
| 	dw	OFFSET Trap06 | ||||
| 	dw	OFFSET Trap07 | ||||
| 	dw	OFFSET Trap08 | ||||
| 	dw	OFFSET Trap09 | ||||
| 	dw	OFFSET Trap0A | ||||
| 	dw	OFFSET Trap0B | ||||
| 	dw	OFFSET Trap0C | ||||
| 	dw	OFFSET Trap0D | ||||
| 	dw	OFFSET Trap0E | ||||
| 	dw	OFFSET Trap0F | ||||
| 	dw	OFFSET Trap10 | ||||
| 	dw	OFFSET Trap11 | ||||
| 	dw	OFFSET Trapnn | ||||
| LastTrap equ ($-TrapMsgTbl)/2 | ||||
|  | ||||
|  | ||||
|  | ||||
| Trap00:	Msg	"Divide by Zero" | ||||
| Trap01:	Msg	"Debug" | ||||
| Trap02:	Msg	"NMI/INT 02h" | ||||
| Trap03:	Msg	"Breakpoint" | ||||
| Trap04:	Msg	"Overflow" | ||||
| Trap05:	Msg	"Bounds Check" | ||||
| Trap06:	Msg	"Invalid Opcode" | ||||
| Trap07:	Msg	"Device Not Available" | ||||
| Trap08:	Msg	"Double Fault" | ||||
| Trap09:	Msg	"Invalid TSS" | ||||
| Trap0A:	Msg	"INT 0Ah" | ||||
| Trap0B:	Msg	"Segment Not Present" | ||||
| Trap0C:	Msg	"Stack Fault" | ||||
| Trap0D:	Msg	"General Protection" | ||||
| Trap0E:	Msg	"Page Fault" | ||||
| Trap0F:	Msg	"INT 0Fh" | ||||
| Trap10:	Msg	"INT 10h" | ||||
| Trap11:	Msg	"Aligment Check" | ||||
| Trapnn:	Msg	"Trap ??" | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Miscellaneous strings | ||||
| ;*********************************************************************** | ||||
| Msg_in:        Msg " in " | ||||
| Msg_VSM:       Msg " VSM" | ||||
| Msg_SP:        Msg "  SP=" | ||||
| Msg_BP:        Msg "  BP=" | ||||
| Msg_IP:        Msg "IP=" | ||||
| Msg_MSR:       Msg "Invalid MSR " | ||||
| Msg_MSR_Rd:    Msg "read: " | ||||
| Msg_MSR_Wr:    Msg "write: " | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Stackless display routines | ||||
| ;*********************************************************************** | ||||
| NewLine: | ||||
| 	mov	al, CR | ||||
| 	out	DBG_PORT, al | ||||
| 	ROM_RET | ||||
|  | ||||
| String: | ||||
| 	mov	al, cs:[bx] | ||||
| 	or	al, al | ||||
| 	jz	StringExit | ||||
| 	out	DBG_PORT, al | ||||
| 	in	al, 80h | ||||
| 	inc	bx			; Advance ptr | ||||
| 	jmp	String | ||||
| StringExit: | ||||
| 	ROM_RET | ||||
|  | ||||
|  | ||||
| Seg_Addr: | ||||
| 	mov	si, bp | ||||
| 	rol	eax, 16 | ||||
| 	xchg	ah, al | ||||
| 	ROM_CALL Hex8 | ||||
| 	xchg	ah, al | ||||
| 	ROM_CALL Hex8 | ||||
| 	mov	al, ':' | ||||
| 	out	DBG_PORT, al | ||||
|  | ||||
| 	rol	eax, 16 | ||||
| 	xchg	ah, al | ||||
| 	ROM_CALL Hex8 | ||||
| 	xchg	ah, al | ||||
| 	ROM_CALL Hex8 | ||||
|  | ||||
| 	mov	bp, si			; Restore ret addr | ||||
| 	ROM_RET | ||||
|  | ||||
|  | ||||
| Hex32:	rol	edx, 16			; Save return address in upper EDX | ||||
|  | ||||
| 	rol	eax, 8 | ||||
| 	ROM_CALL Hex8 | ||||
| 	rol	eax, 8 | ||||
| 	ROM_CALL Hex8 | ||||
| 	rol	eax, 8 | ||||
| 	ROM_CALL Hex8 | ||||
| 	rol	eax, 8 | ||||
| 	ROM_CALL Hex8 | ||||
| 	mov	al, ' ' | ||||
| 	out	DBG_PORT, al | ||||
| 	rol	edx, 16			; Restore return address | ||||
| 	ROM_RET | ||||
|  | ||||
|  | ||||
|  | ||||
| Hex16:	rol	edx, 16			; Save return address in upper EDX | ||||
| 	xchg	ah, al | ||||
| 	ROM_CALL Hex8 | ||||
| 	xchg	ah, al | ||||
| 	ROM_CALL Hex8 | ||||
| 	rol	edx, 16			; Restore return address | ||||
| 	mov	al, ' ' | ||||
| 	out	DBG_PORT, al | ||||
| 	ROM_RET | ||||
|  | ||||
|  | ||||
| Hex8: | ||||
| 	; Display 4 MSBs | ||||
| 	mov	di, ax | ||||
| 	rol	al, 4 | ||||
| 	and	al, 0Fh | ||||
| 	add	al, '0'			; Convert to ASCII | ||||
| 	cmp	al, '9' | ||||
| 	jbe	@f | ||||
| 	add	al, 7			; 'A'-'F' | ||||
| @@:	out	DBG_PORT, al | ||||
| 	in	al, 80h | ||||
| 	mov	ax, di | ||||
|  | ||||
| 	 | ||||
| 	; Display 4 LSBs | ||||
| 	and	al, 0Fh | ||||
| 	add	al, '0'			; Convert to ASCII | ||||
| 	cmp	al, '9' | ||||
| 	jbe	Char | ||||
| 	add	al, 7			; 'A'-'F' | ||||
| Char:	out	DBG_PORT, al | ||||
| 	in	al, 80h | ||||
| 	ROM_RET | ||||
|  | ||||
| SegOff   dd	0 | ||||
| Reg_ECX  dd	0 | ||||
| TrapNum  dw	0 | ||||
| MSR_Access	db	0 | ||||
|  | ||||
|  | ||||
| 	end | ||||
|  | ||||
							
								
								
									
										37
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/image.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										37
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/image.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| ;  | ||||
| ; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| ;  | ||||
| ; This library is free software; you can redistribute it and/or modify | ||||
| ; it under the terms of the GNU Lesser General Public License as | ||||
| ; published by the Free Software Foundation; either version 2.1 of the | ||||
| ; License, or (at your option) any later version. | ||||
| ;  | ||||
| ; This code is distributed in the hope that it will be useful, | ||||
| ; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| ; Lesser General Public License for more details. | ||||
| ;  | ||||
| ; You should have received a copy of the GNU Lesser General | ||||
| ; Public License along with this library; if not, write to the | ||||
| ; Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| ; Boston, MA 02111-1307 USA  | ||||
| ;  | ||||
| ;*   Function:                                                         * | ||||
| ;*     This file contains the label for the beginning of the VSA image * | ||||
| ;*     It MUST be the last .OBJ file in the link  | ||||
|  | ||||
|  | ||||
| .model small,c | ||||
| .586 | ||||
| .CODE | ||||
|  | ||||
| public VSA_Image | ||||
|  | ||||
| TEXT	SEGMENT PARA 'CODE' | ||||
|  | ||||
| VSA_Image: | ||||
|  | ||||
| TEXT	ENDS | ||||
|  | ||||
| 	END | ||||
| 	 | ||||
							
								
								
									
										1017
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/init.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										1017
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/init.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										39
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/init.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										39
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/init.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| #define	CR	0x0D | ||||
| #define	LF	0x0A | ||||
|  | ||||
| #define	ERR_NO_FIT	(1 << 0) | ||||
| #define	ERR_NO_SYS_MGR	(1 << 1) | ||||
| #define	ERR_BAD_TYPE	(1 << 2) | ||||
| #define	ERR_SMI_STATUS	(1 << 3) | ||||
| #define	ERR_BAD_CPU		(1 << 4) | ||||
| #define	ERR_NO_CHIPSET	(1 << 5) | ||||
| #define	ERR_NOT_CPL0	(1 << 6) | ||||
| #define	ERR_VERIFY		(1 << 7) | ||||
| #define	ERR_VERSION		(1 << 8) | ||||
| #define	ERR_INTERNAL	(1 << 9) | ||||
| #define	ERR_INVALID_VSM	(1 << 10) | ||||
|  | ||||
|  | ||||
|  | ||||
| #define	DOS_LOAD		(1 << 0) | ||||
| #define	VSM_LOAD		(1 << 1) | ||||
|  | ||||
							
								
								
									
										196
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/io.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										196
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/io.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,196 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //*	 Function:                                                          * | ||||
| //*     Handles trapped and virtualized I/O   | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| #include "VSA2.H" | ||||
| #include "PROTOS.H"  | ||||
| #include "SYSMGR.H" | ||||
|   | ||||
|  | ||||
| // External variables | ||||
| extern ULONG Saved_EAX, Saved_EDI; | ||||
| extern ULONG Nested_EAX, Nested_EDI; | ||||
| extern Descriptor Saved_ES, Flat_Descriptor; | ||||
| extern SmiHeader SMM_Header; | ||||
|  | ||||
| // External routines | ||||
| extern void pascal write_flat_size(ULONG, ULONG, UCHAR); | ||||
| extern ULONG pascal Convert_To_Physical_Addr(ULONG); | ||||
|  | ||||
| #define PAGING_ENABLED 0x80000001 | ||||
|  | ||||
| #define ADDR32     1 | ||||
| #define DATA32     2 | ||||
|  | ||||
|  | ||||
| typedef struct { | ||||
|   union { | ||||
|     ULONG Ulong; | ||||
|     struct {     | ||||
|       USHORT LowAddr; | ||||
|       UCHAR MidAddr; | ||||
|       UCHAR HiAddr; | ||||
|     }; | ||||
|   }; | ||||
| } DESCR; | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Returns the physical address of the location to return the value  | ||||
| //*********************************************************************** | ||||
| ULONG pascal Get_Logical_Address(SmiHeader * SmiHdr, ULONG * CR0_Ptr) | ||||
| { UCHAR Override = 0, Size, Instruction; | ||||
|   static UCHAR SizeToIncr[16] = {0,1,0,2,0,0,0,0,0,0,0,0,0,0,0,4}; | ||||
|   ULONG EDI, Logical_Addr, Incr, Phys_Addr, Reg_Ptr; | ||||
|   register Descriptor * Callers_ES; | ||||
|   DESCR Mem_Ptr; | ||||
|  | ||||
|  | ||||
|   Size = (UCHAR)SmiHdr->data_size; | ||||
|  | ||||
|   if (SmiHdr == &SMM_Header) { | ||||
|     Reg_Ptr = SysMgr_VSM + (ULONG)((USHORT)&Saved_EAX); | ||||
|     // Get ES:EDI in case it's INSW | ||||
|     Callers_ES = &Saved_ES; | ||||
|     EDI = Saved_EDI; | ||||
|   } else { | ||||
|     // Nested_EAX is a flat ptr to EAX on the VSM's stack | ||||
| 	Reg_Ptr = Nested_EAX; | ||||
|     // Get ES:EDI in case it's INSW | ||||
|     Callers_ES = &Flat_Descriptor; | ||||
| 	EDI = Nested_EDI; | ||||
|   } | ||||
|  | ||||
|  | ||||
|   // Determine default operand and address size | ||||
|   if (Callers_ES->attr & D_BIT) { | ||||
|     Override = DATA32 | ADDR32; | ||||
|   } | ||||
|  | ||||
|  | ||||
|   // Get address of trapped code | ||||
|   Logical_Addr = SmiHdr->Current_EIP + SmiHdr->_CS.base; | ||||
|  | ||||
|   do { | ||||
|  | ||||
|      // If paging is enabled... | ||||
|     if ((SmiHdr->r_CR0 & PAGING_ENABLED) == PAGING_ENABLED){ | ||||
|       // translate logical to physical address via the page tables | ||||
|       Phys_Addr = Convert_To_Physical_Addr(Logical_Addr); | ||||
|     } else { | ||||
|       Phys_Addr = Logical_Addr; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     // Get opcode | ||||
|     Instruction = (UCHAR)read_flat(Phys_Addr); | ||||
|  | ||||
|     switch (Instruction) { | ||||
|  | ||||
|       case 0xE4:    // IN AL, <nn> | ||||
|       case 0xE5:    // IN AX, <nn> | ||||
|       case 0xEC:    // IN AL, DX | ||||
|       case 0xED:    // IN AX, DX | ||||
|         *CR0_Ptr = 0x00000000; | ||||
|         return Reg_Ptr; | ||||
| 	  | ||||
|       case 0x67:   // Address Size | ||||
|         Override ^= ADDR32; | ||||
|         break; | ||||
|  | ||||
|       case 0x66:   // Data Size | ||||
|         // Override ^= DATA32; | ||||
|       case 0xF2:   // REPNE | ||||
|       case 0xF3:   // REPE | ||||
|         break; | ||||
|  | ||||
|       case 0x6C:   // INSB | ||||
|       case 0x6D:   // INSW/INSD | ||||
|         Mem_Ptr.LowAddr = Callers_ES->base_15_0; | ||||
|         Mem_Ptr.MidAddr = Callers_ES->base_23_16; | ||||
|         Mem_Ptr.HiAddr  = Callers_ES->base_31_24; | ||||
|  | ||||
|         // (E)DI has already been inc'd/dec'd | ||||
|         Incr = SizeToIncr[Size]; | ||||
|         if (SmiHdr->EFLAGS & EFLAGS_DF) { | ||||
|           EDI += Incr; | ||||
|         } else { | ||||
|           EDI -= Incr; | ||||
| 		} | ||||
|  | ||||
|         // If 16-bit mode, mask 16 MSBs of ptr | ||||
|         if (!(Override & ADDR32)) { | ||||
|           EDI &= 0x0000FFFF; | ||||
|         } | ||||
|         Mem_Ptr.Ulong += EDI; | ||||
|         *CR0_Ptr = SmiHdr->r_CR0; | ||||
|         return Mem_Ptr.Ulong; | ||||
|  | ||||
|       default: | ||||
|         // Unexpected opcode | ||||
|         Log_Error("Unexpected opcode at 0x%08X = 0x%08X", Phys_Addr, read_flat(Phys_Addr)); | ||||
|         return 0xFFFFFFFF; | ||||
|     } | ||||
|  | ||||
|     // Increment code ptr | ||||
|     Logical_Addr++; | ||||
|  | ||||
|   } while (1); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Returns an I/O value to AL/AX/EAX or ES:(E)DI | ||||
| //*********************************************************************** | ||||
| void pascal Return_Virtual_Value(SmiHeader * SmiHdr, ULONG Data) | ||||
| { ULONG PhysicalAddr, LogicalAddr, CR0; | ||||
|   UCHAR Size; | ||||
|  | ||||
|   LogicalAddr = Get_Logical_Address(SmiHdr, &CR0); | ||||
|  | ||||
|   if (LogicalAddr == 0xFFFFFFFF) | ||||
|     return; | ||||
|  | ||||
|   Size = (UCHAR)SmiHdr->data_size; | ||||
|  | ||||
|  | ||||
|   if ((CR0 & PAGING_ENABLED) == PAGING_ENABLED){ | ||||
|     // If paging is enabled, translate logical to physical address and | ||||
|     // write one byte at a time since buffer could cross page boundary. | ||||
|     do { | ||||
|       PhysicalAddr = Convert_To_Physical_Addr(LogicalAddr++); | ||||
|       write_flat_size(PhysicalAddr, Data, BYTE_IO); | ||||
|       Data >>= 8; | ||||
|       Size >>= 1; | ||||
|     } while (Size); | ||||
|  | ||||
|   } else { | ||||
|     // Write the data to memory | ||||
|     write_flat_size(LogicalAddr, Data, Size); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										218
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/io_trap.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										218
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/io_trap.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,218 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //****************************************************************************** | ||||
| //*   Routines for setting I/O traps     | ||||
| //****************************************************************************** | ||||
|  | ||||
|  | ||||
|  | ||||
| #include "VSA2.H" | ||||
| #include "PROTOS.H" | ||||
| #include "GX2.H" | ||||
| #include "VPCI.H" | ||||
| #include "DESCR.H" | ||||
| #include "CHIPSET.H" | ||||
|  | ||||
| ULONG pascal Compute_IOD_SC(ULONG *, USHORT *, UCHAR); | ||||
|  | ||||
| // External variables: | ||||
| extern DESCRIPTOR MSRs[]; | ||||
| extern UCHAR NumMbius; | ||||
| extern MBIU_INFO MbiuInfo[MAX_MBIU]; | ||||
| extern Hardware HardwareInfo; | ||||
| extern UCHAR * VsmNames[]; | ||||
| extern ULONG Current_VSM; | ||||
|  | ||||
|  | ||||
| // Local variables: | ||||
| UCHAR MbiuSearchOrder[MAX_MBIU] = {2,1,0}; | ||||
| ULONG MbiuSkipFlags[] = {NOT_GLIU0, NOT_GLIU1, NOT_GLIU2}; | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Creates an I/O descriptor for the specified Address/Range. | ||||
| // UsePID: | ||||
| //  0 = set PID to zero (generate SMI) | ||||
| //  1 = set PID to MBIU's subtractive port | ||||
| //*********************************************************************** | ||||
| UCHAR pascal Setup_IO_Descriptor(ULONG * AddressPtr, USHORT * RangePtr, UCHAR UsePID) | ||||
| { UCHAR i, j, Index, FirstChoice, SecondChoice; | ||||
|   USHORT Range, MaxRange; | ||||
|   ULONG Address, Flags; | ||||
|   MBIU_INFO * MbiuPtr; | ||||
|   register DESCRIPTOR * Descr; | ||||
|  | ||||
|  | ||||
|   Range = * RangePtr; | ||||
|   Flags = Address = * AddressPtr; | ||||
|  | ||||
|   // Determine type(s) of I/O descriptor to use | ||||
|   FirstChoice  = IOD_BM; | ||||
|   SecondChoice = IOD_SC; | ||||
|   if (Flags & (READS_ONLY | WRITES_ONLY)) { | ||||
|     FirstChoice = IOD_SC; | ||||
|   } else { | ||||
|     // Check if we should try to use a swiss-cheese descriptor | ||||
|     if (Address & 7 || Range < 8) { | ||||
|       FirstChoice = IOD_SC; | ||||
|       SecondChoice = IOD_BM; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|  | ||||
|   // Find an appropriate descriptor | ||||
|   for (i = 0; i < NumMbius; i++) { | ||||
|     j = MbiuSearchOrder[i]; | ||||
|  | ||||
|     // Skip this MBIU ? | ||||
|     if (Flags & MbiuSkipFlags[j]) { | ||||
|       continue; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     MbiuPtr = &MbiuInfo[j]; | ||||
|     Index = Allocate_Descriptor(FirstChoice, SecondChoice, MbiuPtr->Mbiu); | ||||
|     if (Index != DESCRIPTOR_NOT_FOUND) { | ||||
|       break; | ||||
|     } | ||||
|   } | ||||
|   if (Index == DESCRIPTOR_NOT_FOUND) { | ||||
|     return Index; | ||||
|   } | ||||
|  | ||||
|   Descr = &MSRs[Index]; | ||||
|   Descr->Address = (USHORT)Address; | ||||
|  | ||||
|   // Set appropriate port | ||||
|   if (UsePID) { | ||||
|     Descr->MsrData[1] = MbiuPtr->SubtrPid; | ||||
|   } | ||||
|  | ||||
|   switch (Descr->Type) { | ||||
|  | ||||
|     case IOD_BM: | ||||
|       // Mask must not include any valid address bits | ||||
|       MaxRange = 1 << BitScanForward(Address); | ||||
|       if (Range > MaxRange) { | ||||
|         Range = MaxRange; | ||||
|       } else { | ||||
|         while (!IsPowerOfTwo(Range)) { | ||||
|           Range--;        | ||||
|         } | ||||
|       } | ||||
|       (USHORT)Descr->MsrData[1] = (USHORT)Address >> 12; | ||||
|       Descr->MsrData[0]  = ~(Range-1) | 0x000F0000; | ||||
|       Descr->MsrData[0] |= Address << 20; | ||||
|       Descr->Range = Range; | ||||
|       * AddressPtr += Range; | ||||
|       * RangePtr -= Range; | ||||
|       break; | ||||
|  | ||||
|     case IOD_SC: | ||||
|       Descr->MsrData[0] = Compute_IOD_SC(AddressPtr, RangePtr, 1); | ||||
|       Descr->Range = Range - * RangePtr; | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       return DESCRIPTOR_NOT_FOUND; | ||||
|  | ||||
|   } | ||||
|  | ||||
|   Write_MSR(Descr->MsrAddr, Descr->MsrData); | ||||
|   return Index; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Clears an I/O trap on the specified I/O Range | ||||
| //*********************************************************************** | ||||
| void pascal Clr_MBus_IO_Trap(ULONG Address, USHORT Range) | ||||
| { UCHAR Index; | ||||
|  | ||||
|   while (Range) { | ||||
|  | ||||
|     // Find an existing descriptor that matches Address | ||||
|     Index = Find_Matching_IO_Descriptor(&Address, &Range, 0); | ||||
|  | ||||
|     if (Index == DESCRIPTOR_NOT_FOUND) { | ||||
|       // Report error | ||||
|       Log_Error("Unregistration of I/O 0x%04X by the %s VSM", Address, VsmNames[Get_VSM_Type(Current_VSM)]); | ||||
|       return; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Sets an I/O trap on the specified I/O Range | ||||
| //*********************************************************************** | ||||
| void pascal Set_MBus_IO_Trap(ULONG Address, USHORT Range) | ||||
| { UCHAR Index; | ||||
|  | ||||
|  | ||||
|   // If the range is > 8 bytes and/or is not a power of 2, | ||||
|   // multiple descriptors may be required. | ||||
|   while (Range) { | ||||
|     // Find an existing descriptor that matches Address | ||||
|     Index = Find_Matching_IO_Descriptor(&Address, &Range, 2); | ||||
|  | ||||
|     if (Index == DESCRIPTOR_NOT_FOUND) { | ||||
|       // An existing descriptor does not match the range. | ||||
|       // Allocate a new descriptor | ||||
|       Index = Setup_IO_Descriptor(&Address, &Range, 0); | ||||
|       if (Index == DESCRIPTOR_NOT_FOUND) { | ||||
|         // Report resource error | ||||
|         Log_Error("No descriptors for I/O trap of 0x%04X by the %s VSM", Address, VsmNames[Get_VSM_Type(Current_VSM)]); | ||||
|         break; | ||||
|       } | ||||
|     } else { | ||||
|       // An existing descriptor was modified for the new Addr/Range | ||||
|     } | ||||
|     MSRs[Index].Flag |= IO_TRAP; | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Enable/Disable I/O trap | ||||
| //*********************************************************************** | ||||
| void pascal MBus_IO_Trap(ULONG Param1, ULONG Param2, UCHAR EnableFlag) | ||||
| { ULONG Address; | ||||
|   USHORT Range; | ||||
|  | ||||
|   // Repackage parameters | ||||
|   Address = Param2; | ||||
|   (USHORT)Address = (USHORT)Param1; | ||||
|   Range = (USHORT)Param2; | ||||
|  | ||||
|  | ||||
|   // Check for illegal combination of flags | ||||
|   if ((Address & ALL_GLIUS) == ALL_GLIUS) { | ||||
|     // Report error | ||||
|     Log_Error("Illegal combination of flags for I/O 0x%04X by the %s VSM", Address, VsmNames[Get_VSM_Type(Current_VSM)]); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   if (EnableFlag) { | ||||
|     Set_MBus_IO_Trap(Address, Range); | ||||
|   } else { | ||||
|     Clr_MBus_IO_Trap(Address, Range); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										222
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/makefile
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										222
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/makefile
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,222 @@ | ||||
|  | ||||
| # | ||||
| # Copyright (c) 2006 Advanced Micro Devices,Inc. ("AMD"). | ||||
| # | ||||
| # This library is free software; you can redistribute it and/or modify | ||||
| # it under the terms of the GNU Lesser General Public License as | ||||
| # published by the Free Software Foundation; either version 2.1 of the | ||||
| # License, or (at your option) any later version. | ||||
| # | ||||
| # This code is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| # Lesser General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU Lesser General | ||||
| # Public License along with this library; if not, write to the | ||||
| # Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| # Boston, MA 02111-1307 USA  | ||||
| # | ||||
|  | ||||
| ###################################################################### | ||||
| # | ||||
| #				Init variables | ||||
| # | ||||
| ###################################################################### | ||||
|  | ||||
| !ifndef VSA2ROOT | ||||
| VSA2ROOT	= .. | ||||
| !endif | ||||
|  | ||||
| BUILD_DIR	= $(VSA2ROOT)\build | ||||
| OBJECT		= obj | ||||
| !include $(BUILD_DIR)\setvars.mak | ||||
| .SUFFIXES: .asm .c .h .inc .map .obj .mac | ||||
|  | ||||
| INCLUDE		= $(OBJECT);$(INCLUDE) | ||||
|  | ||||
| VSMNAME	= sysmgr | ||||
|  | ||||
|  | ||||
| ###################################################################### | ||||
| # | ||||
| # 				Build Macros | ||||
| # | ||||
| ###################################################################### | ||||
|  | ||||
| INIT_ASM_OBJS	= \ | ||||
| 	$(OBJECT)\init.obj \ | ||||
| 	$(OBJECT)\cpu_init.obj \ | ||||
| 	$(OBJECT)\chip.obj \ | ||||
| 	$(OBJECT)\image.obj \ | ||||
|  | ||||
| SYSMGR_ASM_OBJS	= \ | ||||
| 	$(OBJECT)\sysmgr.obj \ | ||||
| 	$(OBJECT)\bugs.obj \ | ||||
| 	$(OBJECT)\utils.obj \ | ||||
| 	$(OBJECT)\syscalls.obj \ | ||||
| 	$(OBJECT)\smis.obj \ | ||||
| 	$(OBJECT)\port92.obj \ | ||||
| 	$(OBJECT)\sw_int.obj \ | ||||
| 	$(OBJECT)\debug.obj \ | ||||
| 	$(OBJECT)\vr_misc.obj \ | ||||
| 	$(OBJECT)\cpu.obj \ | ||||
| 	$(OBJECT)\idt.obj \ | ||||
| 	$(OBJECT)\message.obj \ | ||||
| 	$(OBJECT)\msr.obj \ | ||||
|  | ||||
| SYSMGR_C_OBJS	= \ | ||||
| 	$(OBJECT)\events.obj \ | ||||
| 	$(OBJECT)\handlers.obj \ | ||||
| 	$(OBJECT)\chipset.obj \ | ||||
| 	$(OBJECT)\gpio.obj \ | ||||
| 	$(OBJECT)\errors.obj \ | ||||
| 	$(OBJECT)\history.obj \ | ||||
| 	$(OBJECT)\io.obj \ | ||||
| 	$(OBJECT)\virt_pci.obj \ | ||||
| 	$(OBJECT)\mbus.obj \ | ||||
| 	$(OBJECT)\vsa_init.obj \ | ||||
| 	$(OBJECT)\descr.obj \ | ||||
| 	$(OBJECT)\vr.obj \ | ||||
| 	$(OBJECT)\topology.obj \ | ||||
| 	$(OBJECT)\pci_rd.obj \ | ||||
| 	$(OBJECT)\pci_wr.obj \ | ||||
| 	$(OBJECT)\cs5536.obj \ | ||||
| 	$(OBJECT)\swapsif.obj \ | ||||
| 	$(OBJECT)\unregstr.obj \ | ||||
| 	$(OBJECT)\mdd.obj \ | ||||
| 	$(OBJECT)\pci_pm.obj \ | ||||
| 	$(OBJECT)\gpio5536.obj \ | ||||
| 	$(OBJECT)\mfgpt.obj \ | ||||
| 	$(OBJECT)\mapper.obj \ | ||||
| 	$(OBJECT)\timeout.obj \ | ||||
| 	$(OBJECT)\io_trap.obj \ | ||||
| 	$(OBJECT)\mbiu.obj \ | ||||
| 	$(OBJECT)\timer.obj \ | ||||
| 	$(OBJECT)\ohci.obj \ | ||||
|  | ||||
| SYSMGR_C_CODS	= $(SYSMGR_C_SRCS:.obj=.cod) | ||||
|  | ||||
| SYSMGR_OBJS		= $(SYSMGR_ASM_OBJS) $(SYSMGR_C_OBJS) | ||||
|  | ||||
| SYSMGR_VSM		= $(OBJECT)\sysmgr.vsm | ||||
|  | ||||
| ####################################################################### | ||||
| # | ||||
| #				Targets | ||||
| # | ||||
| ####################################################################### | ||||
|  | ||||
|  | ||||
| all: $(OBJECT) setenv sysmgr.vsm vsainit.bin  | ||||
| !ifdef BUILDOBJ | ||||
| 	$(COPY) $(OBJECT)\sysmgr.vsm $(BUILDOBJ) | ||||
| 	$(COPY) $(OBJECT)\vsainit.bin $(BUILDOBJ) | ||||
| !endif | ||||
|  | ||||
| sysmgr.vsm: $(SYSMGR_OBJS) | ||||
| 	$(LN) /MAP $(LOPTS_VSM) @<<sysmgr.lnk | ||||
| 	$(SYSMGR_OBJS: =+^ | ||||
| 	) | ||||
| $(SYSMGR_VSM) | ||||
|  | ||||
| ; | ||||
| <<NOKEEP | ||||
|  | ||||
| vsainit.bin init.exe: $(INIT_ASM_OBJS) | ||||
| 	$(LN) $(LD_OPTS) /MAP $**,$(OBJECT)\init.exe,$(OBJECT)\init.map; | ||||
| 	$(X2ROM) $(OBJECT)\init.exe $(OBJECT)\vsainit.bin | ||||
| #	$(COPY) $(OBJECT)\init.rom $(OBJECT)\vsainit.bin | ||||
|  | ||||
| #This and only this clean target must exist as it is called by cleanall | ||||
| #cleanall and cleanlocal are defined in rules.mak | ||||
|  | ||||
| clean: cleanlocal | ||||
|  | ||||
| $(OBJECT): | ||||
| 	-@md $(OBJECT) | ||||
|  | ||||
| ####################################################################### | ||||
| # | ||||
| #				Dependencies | ||||
| # | ||||
| ####################################################################### | ||||
|  | ||||
| $(SYSMGR_ASM_OBJS): $(MAKEDIR)\makefile \ | ||||
| 		$(OBJECT)\sysmgr.inc \ | ||||
| 		$(OBJECT)\smimac.mac \ | ||||
| 		$(OBJECT)\vsa2.inc \ | ||||
| 		$(OBJECT)\isa.inc \ | ||||
| 		$(OBJECT)\chipset.inc \ | ||||
| 		$(OBJECT)\vr.inc \ | ||||
| 		$(OBJECT)\pci.inc \ | ||||
| 		$(OBJECT)\hce.inc \ | ||||
| 		$(OBJECT)\gx2.inc  \ | ||||
| 		$(OBJECT)\protos.inc \ | ||||
| 		$(OBJECT)\descr.inc \ | ||||
| 		$(OBJECT)\mdd.inc \ | ||||
| 		$(OBJECT)\cs5536.inc \ | ||||
|  | ||||
| $(SYSMGR_C_OBJS): $(MAKEDIR)\makefile \ | ||||
| 		$(OBJECT)\sysmgr.h \ | ||||
| 		$(OBJECT)\vsa2.h \ | ||||
| 		$(OBJECT)\isa.h \ | ||||
| 		$(OBJECT)\chipset.h \ | ||||
| 		$(OBJECT)\vr.h \ | ||||
| 		$(OBJECT)\pci.h \ | ||||
| 		$(OBJECT)\vpci.h  \ | ||||
| 		$(OBJECT)\protos.h \ | ||||
| 		$(OBJECT)\mdd.h \ | ||||
| 		$(OBJECT)\timer.h \ | ||||
| 		$(OBJECT)\mapper.h \ | ||||
| 		$(OBJECT)\gx2.h  \ | ||||
| 		$(OBJECT)\hce.h \ | ||||
| 		$(OBJECT)\acpi.h \ | ||||
| 		$(OBJECT)\cs5536.h \ | ||||
|  | ||||
| $(INIT_ASM_OBJS): $(MAKEDIR)\makefile \ | ||||
| 		$(OBJECT)\sysmgr.inc \ | ||||
| 		$(OBJECT)\smimac.mac \ | ||||
| 		$(OBJECT)\vsa2.inc \ | ||||
| 		$(OBJECT)\isa.inc \ | ||||
| 		$(OBJECT)\chipset.inc \ | ||||
| 		$(OBJECT)\vr.inc \ | ||||
| 		$(OBJECT)\pci.inc \ | ||||
| 		$(OBJECT)\init.inc \ | ||||
| 		$(OBJECT)\mdd.inc \ | ||||
| 		$(OBJECT)\gx2.inc  \ | ||||
| 		$(OBJECT)\cs5536.inc \ | ||||
|  | ||||
| ###################################################################### | ||||
| # | ||||
| #				Common Targets | ||||
| # | ||||
| ###################################################################### | ||||
| # include common targets and inference rules | ||||
| !include $(BUILD_DIR)\rules.mak | ||||
|  | ||||
| ###################################################################### | ||||
| # | ||||
| #				Inference Rules | ||||
| # | ||||
| ###################################################################### | ||||
| # Override common inference rules here | ||||
|  | ||||
| {$(INC_DIR)}.h{$(OBJECT)}.inc: | ||||
| 	$(H2) /Fa$(OBJECT)\$(@F) /nologo /Zni /C $< | ||||
|  | ||||
| {$(INC_DIR)\$(CPU)}.h{$(OBJECT)}.inc: | ||||
| 	$(H2) /Fa$(OBJECT)\$(@F) /nologo /Zni /C $< | ||||
|  | ||||
| {$(SYSMGR_SRC)}.h{$(OBJECT)}.inc: | ||||
| 	$(H2) /Fa$(OBJECT)\$(@F) /nologo /Zns /C $< | ||||
|  | ||||
| {$(SYSMGR_SRC)\$(CPU)}.h{$(OBJECT)}.inc: | ||||
| 	$(H2) /Fa$(OBJECT)\$(@F) /nologo /Zns /C $< | ||||
|  | ||||
| $(OBJECT)\hce.inc:  | ||||
| 	$(H2) /Fa$(OBJECT)\hce.inc /Znh /C $(INC_DIR)\hce.h | ||||
|  | ||||
| $(OBJECT)\protos.inc:  | ||||
| 	$(H2) /Fa$(OBJECT)\protos.inc /Zn"q" /C $(SYSMGR_SRC)\protos.h | ||||
|  | ||||
							
								
								
									
										118
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/mapper.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										118
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/mapper.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,118 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //****************************************************************************** | ||||
| //*     This file contains code specific to the IRQ Mapper   | ||||
| //****************************************************************************** | ||||
|  | ||||
| #include "VSA2.H" | ||||
| #include "SYSMGR.H" | ||||
| #include "PROTOS.H" | ||||
| #include "VPCI.H" | ||||
| #include "PCI.H" | ||||
| #include "MDD.H" | ||||
| #include "MAPPER.H" | ||||
| #include "ISA.H" | ||||
|  | ||||
| // Local Variables: | ||||
| UCHAR PCI_INTs[4] = {0,0,0,0};   // Current PCI INT mappings | ||||
| UCHAR Max_PCI_Interrupt=4; | ||||
|  | ||||
| // External Variables: | ||||
| extern ULONG MDD_Base; | ||||
| extern USHORT Saved_AX; | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| // External Functions: | ||||
| void PCI_Interrupts(void); | ||||
|  | ||||
|  | ||||
|  | ||||
| //************************************************************************************ | ||||
| // Maps an Unrestricted Source to a PIC IRQ via the IRQ Mapper logic | ||||
| //************************************************************************************ | ||||
| void pascal IRQ_Mapper(UCHAR Reg, UCHAR Source, UCHAR Irq) | ||||
| { ULONG MsrAddr, MsrData; | ||||
|   UCHAR ShiftCount; | ||||
|  | ||||
|   // 8 sources per MSR  | ||||
|   Reg += Source/8; | ||||
|  | ||||
|   MsrAddr = MDD_Base + Reg; | ||||
|  | ||||
|   // 4 bits per field | ||||
|   ShiftCount = (Source % 8) * 4; | ||||
|  | ||||
|   // Map Unrestricted Source[Source] to Irq via IRQ Mapper | ||||
|   MsrData = Read_MSR_LO(MsrAddr); | ||||
|   MsrData &= ~(0x0000000FL << ShiftCount); | ||||
|   MsrData |=  (ULONG)Irq   << ShiftCount; | ||||
|   Write_MSR_LO(MsrAddr, MsrData); | ||||
| } | ||||
|  | ||||
| //************************************************************************************ | ||||
| // Maps an Unrestricted Source Y to a PIC IRQ | ||||
| //************************************************************************************ | ||||
| void pascal IRQY_Mapper(UCHAR Y_Source, UCHAR Irq) | ||||
| {  | ||||
|   IRQ_Mapper(MSR_IRQM_YLOW, Y_Source, Irq); | ||||
| } | ||||
|  | ||||
|  | ||||
| //************************************************************************************ | ||||
| // Maps an Unrestricted Source Z to a PIC IRQ | ||||
| //************************************************************************************ | ||||
| void pascal IRQZ_Mapper(UCHAR Z_Source, UCHAR Irq) | ||||
| { | ||||
|   IRQ_Mapper(MSR_IRQM_ZLOW, Z_Source, Irq); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //************************************************************************************ | ||||
| // Implements the SYS_GENERATE_IRQ macro for CS5536 | ||||
| //************************************************************************************ | ||||
| void pascal Generate_IRQ_5536(USHORT IRQ_Mask)  | ||||
| { UCHAR Irq=0; | ||||
|   USHORT Level; | ||||
|    | ||||
|   Level = in_16(PIC1_EDGE); | ||||
|  | ||||
|   // Don't attempt to generate a level-sensitive interrupt | ||||
|   if (IRQ_Mask & Level) { | ||||
|     Log_Error("Attempt to generate a level-sensitive IRQ. Mask= 0x%04X", IRQ_Mask); | ||||
|     return; | ||||
|   }        | ||||
|  | ||||
|   while (IRQ_Mask) { | ||||
|     if (IRQ_Mask & 1) { | ||||
|       // Map the software IRQ to the requested IRQ | ||||
|       IRQY_Mapper(Y_IRQ_SW, Irq); | ||||
|  | ||||
|       // Generate an edge to the PIC | ||||
|       Write_MSR_LO(MDD_Base + MSR_SOFT_IRQ, 0L); | ||||
|       Write_MSR_LO(MDD_Base + MSR_SOFT_IRQ, 1L); | ||||
|     } | ||||
|     IRQ_Mask >>= 1; | ||||
| 	Irq++; | ||||
|   } | ||||
| } | ||||
|  | ||||
							
								
								
									
										48
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/mapper.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										48
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/mapper.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,48 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
|  | ||||
| // Unrestricted Y usage: | ||||
| #define Y_IRQ_SW	0 | ||||
| #define Y_IRQ_USB1	1 | ||||
| #define Y_IRQ_USB2	2 | ||||
| #define Y_IRQ_RTC	3 | ||||
| #define Y_IRQ_AUDIO	4 | ||||
| #define Y_IRQ_PME	5 | ||||
| #define Y_IRQ_FLASH	6 | ||||
| #define Y_IRQ_SMB	12 | ||||
| #define Y_IRQ_KEL	13 | ||||
| #define Y_IRQ_UART1	14 | ||||
| #define Y_IRQ_UART2	15 | ||||
|  | ||||
|  | ||||
|  | ||||
| // Unrestricted Z usage: | ||||
| #define Z_IRQ_MFGPT_04  0 | ||||
| #define Z_IRQ_MFGPT_15  1 | ||||
| #define Z_IRQ_MFGPT_26  2 | ||||
| #define Z_IRQ_MFGPT_37  3 | ||||
|  | ||||
| #define Z_IRQ_SMI	    8 | ||||
| #define Z_IRQ_INTA	    9 | ||||
| #define Z_IRQ_INTB	   10 | ||||
| #define Z_IRQ_INTC	   11 | ||||
| #define Z_IRQ_INTD	   12 | ||||
|  | ||||
|  | ||||
							
								
								
									
										135
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/mbiu.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										135
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/mbiu.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,135 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //*	 Function:                                                          * | ||||
| //*    Utility routines for managing MBIUs   | ||||
|  | ||||
|  | ||||
| #include "VSA2.H" | ||||
| #include "PROTOS.H" | ||||
| #include "GX2.H" | ||||
| #include "VPCI.H" | ||||
| #include "DESCR.H" | ||||
| #include "SYSMGR.H" | ||||
|  | ||||
|  | ||||
| extern void InitStatCounters(ULONG, UCHAR); | ||||
|  | ||||
|  | ||||
| // External variables: | ||||
| extern ULONG Mbiu0; | ||||
|  | ||||
| // Local variables: | ||||
| ULONG ExtendedMemoryDescr0, ExtendedMemoryDescr1 = 0; | ||||
| MBIU_INFO MbiuInfo[MAX_MBIU]; | ||||
| UCHAR NumMbius=0; | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Called once for each MBIU: | ||||
| // - Initializes statistic counters | ||||
| // - Records all available descriptors | ||||
| //*********************************************************************** | ||||
| void pascal Init_MBIU(UCHAR * CountPtr, ULONG Msr) | ||||
| { UCHAR Type, i; | ||||
|   ULONG Default[2], MsrData[2]; | ||||
|  | ||||
|  | ||||
|   // Record info about MBIU | ||||
|   MbiuInfo[NumMbius].Mbiu = Msr; | ||||
|   MbiuInfo[NumMbius].SubtrPid = Read_MSR_LO(Msr + MBD_MSR_CONFIG) << 29; | ||||
|   MbiuInfo[NumMbius].NumCounters = ((CAPABILITIES *)CountPtr)->NSTATS; | ||||
|   MbiuInfo[NumMbius].ActiveCounters = 0x00; | ||||
|   MbiuInfo[NumMbius].ClockGating = Read_MSR_LO(Msr + MBD_MSR_PM); | ||||
|  | ||||
|   // Clear SMIs on this MBIU & disable all events except HW Emulation | ||||
|   MsrData[0] = 0x0000000E; | ||||
|   MsrData[1] = 0x0000000F; | ||||
|   (USHORT)Msr = MBD_MSR_SMI; | ||||
|   Write_MSR(Msr, MsrData); | ||||
|  | ||||
|   //********************************************* | ||||
|   // Initialize Statistics MSRs | ||||
|   //********************************************* | ||||
|   InitStatCounters(Msr, ((CAPABILITIES *)CountPtr)->NSTATS); | ||||
|  | ||||
|   //********************************************* | ||||
|   // Begin with P2D_BM descriptors | ||||
|   //********************************************* | ||||
|   Type = P2D_BM; | ||||
|   (USHORT)Msr = MSR_MEM_DESCR; | ||||
|  | ||||
|   do { | ||||
|  | ||||
|     // Get number of next type of descriptor      | ||||
|     if (i = *(CountPtr++)) { | ||||
|  | ||||
|       // Get the default value for this descriptor type | ||||
|       Get_Descriptor_Default(Type, Default); | ||||
|  | ||||
|       // Loop through all descriptors of a given type | ||||
|       do { | ||||
|  | ||||
|         // If descriptor is already in use by the BIOS, skip it | ||||
|         Read_MSR(Msr, MsrData); | ||||
|         if ((MsrData[0] == Default[0]) && (MsrData[1] == Default[1])) { | ||||
|  | ||||
|           // Initialize Descriptor[] entry | ||||
|           if (Init_Descr(Type, Msr)) { | ||||
|             // Not enough table entries...abort | ||||
|             Type = 0x99; | ||||
|             break; | ||||
|           } | ||||
|  | ||||
|         } else { | ||||
|           // Descriptor is in use. | ||||
|           // If it's an extended memory descriptor, record the routing address. | ||||
|           if (Type == P2D_R) { | ||||
|             if ((Msr & ROUTING) == Mbiu0) { | ||||
|               ExtendedMemoryDescr0 = Msr; | ||||
|             } else { | ||||
|               ExtendedMemoryDescr1 = Msr; | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|         Msr++; | ||||
|       } while (--i); | ||||
|     }           | ||||
|  | ||||
|     // Check next descriptor type. | ||||
|     // If transitioning from P2D to IOD descriptors... | ||||
| 	if (++Type == IOD_BM) { | ||||
|       // change MSR offset to 0xE0 | ||||
|       (USHORT)Msr = MSR_IO_DESCR; | ||||
|     } | ||||
|   } while (Type <= IOD_SC); | ||||
|  | ||||
|   // Increment number of MBIUs | ||||
|   NumMbius++; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										758
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/mbus.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										758
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/mbus.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,758 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //****************************************************************************** | ||||
| //*    Routines related to the MBus   | ||||
| //****************************************************************************** | ||||
|  | ||||
|  | ||||
| #include "VSA2.H" | ||||
| #include "PROTOS.H" | ||||
| #include "PCI.H" | ||||
| #include "GX2.H" | ||||
| #include "VPCI.H" | ||||
| #include "CHIPSET.H" | ||||
| #include "DESCR.H" | ||||
| #include "MDD.H" | ||||
| #include "SYSMGR.H" | ||||
|  | ||||
| // Externals: | ||||
| extern void InitLogicalCounters(void); | ||||
| extern UCHAR GetPortID(ULONG); | ||||
| extern void pascal ClearMbiu(ULONG); | ||||
| extern UCHAR pascal Get_MBus_Status(ULONG, USHORT); | ||||
| extern UCHAR pascal Is_LBAR_Enabled(PCI_HEADER_ENTRY * Pci); | ||||
| extern ULONG pascal Compute_IOD_SC(ULONG *, USHORT *, UCHAR); | ||||
| extern PCI_HEADER_ENTRY * pascal Get_Structure(USHORT); | ||||
|  | ||||
| extern USHORT Class; | ||||
| extern CAPABILITIES Southbridge_MBIU; | ||||
| extern ULONG Mbiu2, MPCI_SB; | ||||
| extern ULONG ACPI_Timer_MSR; | ||||
| extern Hardware HardwareInfo; | ||||
| extern MBIU_INFO MbiuInfo[]; | ||||
| extern DESCRIPTOR MSRs[]; | ||||
|  | ||||
| // Local Variables: | ||||
| static ULONG PCI_Value; | ||||
| ULONG Mbiu0 = PORT_MBIU0; | ||||
| ULONG Mbiu1; | ||||
| ULONG LookupMbiu; | ||||
| ULONG MPCI_NB=0; | ||||
| ULONG MCP_NB =0; | ||||
| ULONG FooGlue=0; | ||||
| UCHAR MBIU1_SelfReference; | ||||
| UCHAR VG_Port; | ||||
| UCHAR MC_Port; | ||||
| CAPABILITIES Northbridge_MBIU0, Northbridge_MBIU1;  | ||||
|  | ||||
| typedef struct { | ||||
|   ULONG Routing; | ||||
|   USHORT MBus_ID; | ||||
|   UCHAR Instance; | ||||
| } SCAN_RESULTS; | ||||
|  | ||||
| #define MAX_HITS (3*8)  // Num-GLIUs * Max-Ports-per-GLIU | ||||
| SCAN_RESULTS PriorScans[MAX_HITS]; | ||||
| int j; | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Scans an MBIU for the specified MBus_ID. | ||||
| // Returns MBIU routing address (LSB = MBIU port) | ||||
| //*********************************************************************** | ||||
| ULONG pascal Scan_MBIU(ULONG Mbiu, USHORT Port_ID, UCHAR * Instance, UCHAR Shift) | ||||
| { USHORT Port; | ||||
|   ULONG RoutingMask; | ||||
|  | ||||
|   RoutingMask = 1L << Shift; | ||||
|  | ||||
|   LookupMbiu = Mbiu; | ||||
|  | ||||
|   // Adjustment for Southbridge MPCI | ||||
|   if (Port_ID == ID_MPCI && Mbiu == Mbiu2) { | ||||
|     Mbiu &= ~(RoutingMask - 1); | ||||
|   } | ||||
|  | ||||
|   // Scan MBIU's ports for specified ID | ||||
|   for (Port = 0; Port <= 7; Port++) { | ||||
|    | ||||
|     // If correct ID... | ||||
|     if (GetPortID(Mbiu) == Port_ID) { | ||||
| 	 | ||||
|       // and correct instance... | ||||
|       if (--(* Instance) == 0) { | ||||
| 	   | ||||
|         // return the routing address and port # (in 3 LSBs) | ||||
|         return (Mbiu | Port); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // Get MSR address to next device | ||||
|     Mbiu &= ~(RoutingMask - 1); | ||||
|     Mbiu +=   RoutingMask; | ||||
|  | ||||
|   } | ||||
|  | ||||
|   return 0x00000000; | ||||
| } | ||||
|  | ||||
| // Port = 1 | ||||
| // Mbiu = Southbridge = 0x51000000 | ||||
| // Port_ID = 0x47 | ||||
| // RoutingMask = 1 << 20 = 0x00100000 | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Finds an MBUS ID and returns the routing address. | ||||
| // The port number is also returned in the 3 LSBs. | ||||
| //*********************************************************************** | ||||
| ULONG pascal Find_MBus_ID(USHORT MBus_ID, UCHAR Instance) | ||||
| { ULONG DeviceAddr; | ||||
|   int i, SavedInstance=Instance; | ||||
|  | ||||
|   // Check results of previous scans for a match | ||||
|   for (i=0; i<j; i++) { | ||||
|     if (PriorScans[i].MBus_ID == MBus_ID && PriorScans[i].Instance == Instance) { | ||||
| 	  return PriorScans[i].Routing; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Filter out MBIU1 self-reference | ||||
|   if (MBus_ID == ID_MBIU) { | ||||
|     if (Instance > 2) { | ||||
|       Instance++; | ||||
|     } | ||||
|   }   | ||||
|  | ||||
| 	// MBus_ID = 0x47 | ||||
| 	// Instance = 1 | ||||
|   if (!(DeviceAddr   = Scan_MBIU(Mbiu0, MBus_ID, &Instance, 29))) { | ||||
|     if (!(DeviceAddr = Scan_MBIU(Mbiu1, MBus_ID, &Instance, 26))) { | ||||
|       if (!(DeviceAddr = Scan_MBIU(Mbiu2, MBus_ID, &Instance, 20)) && MBus_ID == ID_ATA) { | ||||
|         DeviceAddr = Scan_MBIU(Mbiu2, ID_ATA100, &Instance, 20); | ||||
|       } | ||||
|     } | ||||
|   }  | ||||
|  | ||||
|   // Clear h/w emulation events generated by scanning empty ports | ||||
|   ClearMbiu(Mbiu0); | ||||
|   ClearMbiu(Mbiu1); | ||||
|    | ||||
|   // SDG: if Mbiu2 is 0x51020000, then the folliwng call | ||||
|   // sets bit 32 (EDX[0]) in 0x51022002.  Does this actually talk  | ||||
|   // MSR 0x51000002?  If so... BUG! | ||||
|     | ||||
|   ClearMbiu(Mbiu2); | ||||
|  | ||||
|   // Record this scan for future reference | ||||
|   if (DeviceAddr && j < MAX_HITS-1) { | ||||
|     PriorScans[j].Instance = SavedInstance; | ||||
|     PriorScans[j].MBus_ID  = MBus_ID; | ||||
|     PriorScans[j].Routing  = DeviceAddr; | ||||
|     j++; | ||||
|   } | ||||
|  | ||||
|   return DeviceAddr; | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Returns the MSR address of the MPCI associated with the current device | ||||
| //*********************************************************************** | ||||
| ULONG pascal GetMSR(void) | ||||
| { | ||||
|   switch (Class) { | ||||
|    | ||||
|     case 0x0600:  // Bridge: Host | ||||
|       return MPCI_NB; | ||||
|  | ||||
|     case 0x0601:  // Bridge: ISA | ||||
|       return MPCI_SB; | ||||
|  | ||||
|     default: | ||||
|       return 0x00000000; | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Gets the PCI Latency Timer | ||||
| //*********************************************************************** | ||||
| UCHAR pascal Get_Latency(PCI_HEADER_ENTRY * Pci) | ||||
| { ULONG MsrAddr, MPCI_Ctrl[2]; | ||||
|   UCHAR LatencyTimer=Pci->LatencyTimer; | ||||
|  | ||||
|   // If bridge device, get MSR address of its MPCI | ||||
|   if (MsrAddr = GetMSR()) { | ||||
|     // Read Latency timer from MPCI_CTRL.LAT | ||||
|     Read_MSR(MsrAddr + MPCI_CTRL, MPCI_Ctrl); | ||||
|     LatencyTimer = (UCHAR)MPCI_Ctrl[1]; | ||||
|   }	 | ||||
|   return LatencyTimer; | ||||
| } | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Sets the PCI Latency timer | ||||
| //*********************************************************************** | ||||
| void pascal Set_Latency(UCHAR Latency) | ||||
| { ULONG MsrAddr=0, MPCI_Ctrl[2]; | ||||
|  | ||||
|   // If bridge device, get MSR address of its MPCI | ||||
|   if (MsrAddr = GetMSR()) { | ||||
|  | ||||
|     // Set the PCI Latency timer | ||||
|     Read_MSR(MsrAddr + MPCI_CTRL, MPCI_Ctrl); | ||||
|     (UCHAR)MPCI_Ctrl[1] = Latency; | ||||
|  | ||||
|     // LDE is only defined in Northbridge MPCI | ||||
|     if (MsrAddr == MPCI_NB) { | ||||
|       if (Latency) { | ||||
|         // Issues 118.176 & 118.197 require LDE to be set unless Latency Timer == 0 | ||||
|         (USHORT)MPCI_Ctrl[0] |=  LDE; | ||||
|       } else { | ||||
|         // Clear MPCI_CTRL[LDE] if Latency Timer = 0x00 | ||||
|         (USHORT)MPCI_Ctrl[0] &= ~LDE; | ||||
|       } | ||||
|     } | ||||
|     Write_MSR(MsrAddr + MPCI_CTRL, MPCI_Ctrl); | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Enables/Disables a trap on a PCI Address | ||||
| //*********************************************************************** | ||||
| void pascal Trap_PCI_IDSEL(USHORT PCI_Address, UCHAR EnableFlag) | ||||
| { ULONG Pbus, IDSEL_Mask; | ||||
|  | ||||
|   IDSEL_Mask = 1L << (UCHAR)(PCI_Address >> 11); | ||||
|   Pbus = Read_MSR_LO(MPCI_NB + MPCI_PBUS); | ||||
|  | ||||
|   if (EnableFlag) { | ||||
|     Pbus |=  IDSEL_Mask; | ||||
|   } else { | ||||
|     Pbus &= ~IDSEL_Mask; | ||||
|   } | ||||
|  | ||||
|   Write_MSR_LO(MPCI_NB + MPCI_PBUS, Pbus); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Initializes MBus related structures and MSRs | ||||
| // Input: | ||||
| //   IDSEL_Mask = Mask of IDSELs to be virtualized | ||||
| //*********************************************************************** | ||||
| void Init_MBus(void) | ||||
| { ULONG MsrAddr, MsrData[2]; | ||||
|  | ||||
|  | ||||
|   //********************************************* | ||||
|   // Add RCONF0-RCONF7 to available descriptor list | ||||
|   //********************************************* | ||||
|   for (MsrAddr = MSR_RCONF0; MsrAddr <= MSR_RCONF7; MsrAddr++) { | ||||
|     if (Init_Descr(GX2_RCONF, MsrAddr)) { | ||||
|       break; | ||||
| 	} | ||||
|   } | ||||
|  | ||||
|  | ||||
|   //********************************************* | ||||
|   // Initialize MBIU0 | ||||
|   //********************************************* | ||||
|   Read_MSR(Mbiu0 + MBIU_CAP, &MsrData[0]); | ||||
|   Parse_Capabilities(&MsrData[0], &Northbridge_MBIU0); | ||||
|   Init_MBIU((UCHAR *)&Northbridge_MBIU0, Mbiu0); | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|   //********************************************* | ||||
|   // Initialize MBIU1 | ||||
|   //********************************************* | ||||
|   // MBIU1 is MBIU0's subtractive port | ||||
|   Mbiu1 = MbiuInfo[0].SubtrPid; | ||||
|   // Determine MBIU1 self-reference | ||||
|   MBIU1_SelfReference = (UCHAR)Read_MSR_LO(Mbiu1 + MBIU_WHOAMI); | ||||
|  | ||||
|   Read_MSR(Mbiu1 + MBIU_CAP, &MsrData[0]); | ||||
|   Parse_Capabilities(&MsrData[0], &Northbridge_MBIU1); | ||||
|   Init_MBIU((UCHAR *)&Northbridge_MBIU1, Mbiu1); | ||||
|  | ||||
|   // Find address of MPCI_NB | ||||
|   MPCI_NB = Find_MBus_ID(ID_MPCI, 1) & 0xFFFF0000; | ||||
|  | ||||
|   // Find address of MCP | ||||
|   MCP_NB = Find_MBus_ID(ID_MCP, 1) & 0xFFFF0000; | ||||
|  | ||||
|   // Enable SMIs from the companion I/O | ||||
|   MsrAddr = MCP_NB | MBD_MSR_SMI; | ||||
|   Write_MSR_LO(MsrAddr, Read_MSR_LO(MsrAddr) & ~0x00000010L); | ||||
|  | ||||
|   PriorScans[j].Routing  = 0x00000000; | ||||
|   PriorScans[j].MBus_ID  = ID_VAIL; | ||||
|   PriorScans[j].Instance = 1; | ||||
|   j++; | ||||
|  | ||||
|   // On LX, FooGlue MSRs == MCP_NB+0x20 | ||||
|   if (HardwareInfo.CPU_ID == DEVICE_ID_LX) { | ||||
|     PriorScans[j].Routing  = MCP_NB+0x20; | ||||
|     PriorScans[j].MBus_ID  = ID_FG; | ||||
|     PriorScans[j].Instance = 1; | ||||
|     j++; | ||||
|   } | ||||
|  | ||||
|   // Find address of FooGlue | ||||
|   FooGlue = Find_MBus_ID(ID_FG, 1) & 0xFFFFFFF0; | ||||
|  | ||||
|   // Find port of Video Generator | ||||
|   VG_Port = (UCHAR)Find_MBus_ID(ID_VG, 1); | ||||
|  | ||||
|  | ||||
|   // Find port of Memory Controller | ||||
|   MC_Port = (UCHAR)Find_MBus_ID(ID_MC, 1); | ||||
|  | ||||
|  | ||||
|   // Enable MPCI error masks | ||||
|   MsrAddr = MPCI_NB | MBD_MSR_ERROR; | ||||
|   Write_MSR_LO(MsrAddr, Read_MSR_LO(MsrAddr) & ~(MARM | TARM | BMM | SYSM | PARM)); | ||||
|  | ||||
|  | ||||
|  | ||||
|   // Initialize logical timeout counters | ||||
|   InitLogicalCounters(); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Computes the MSR data corresponding to an enabled PCI BAR | ||||
| //*********************************************************************** | ||||
| void Compute_Msr_Value(register DESCRIPTOR * Descr, register PCI_HEADER_ENTRY * Pci) | ||||
| { ULONG PBase, PMask, POffset=0; | ||||
|  | ||||
|  | ||||
|   Descr->MsrData[0] = Pci->Value; | ||||
|  | ||||
|   if (Pci->Flag & IO_BAR) { | ||||
|     if (Descr->MsrAddr == ACPI_Timer_MSR) { | ||||
|       PCI_Value += 4;  // Skip over ACPI timer | ||||
|     } | ||||
|     Descr->Address = (USHORT)PCI_Value; | ||||
|   } | ||||
|  | ||||
|   switch (Descr->Type) { | ||||
|  | ||||
|     case USB_LBAR: | ||||
|       Descr->MsrData[1] |= MEM_SPACE; | ||||
|       return; | ||||
|  | ||||
|     case MDD_LBAR: | ||||
|       Descr->MsrData[1] |= Pci->Mask | LBAR_EN; | ||||
|  | ||||
|       // If Memory LBAR, set MEM_IO | ||||
|       if (!(Pci->Flag & IO_BAR)) { | ||||
|         Descr->MsrData[1] |= MEM_IO; | ||||
|       } else { | ||||
|         Descr->MsrData[1] &= 0x0000FFFF; | ||||
|         Descr->MsrData[0] &= 0x0000FFFF; | ||||
|       } | ||||
|       return; | ||||
|  | ||||
|     case MPCI_RCONF: | ||||
|       Descr->MsrData[1] = Pci->Value; | ||||
|  | ||||
|       // If I/O BAR, set SPACE bit & shift BASE & TOP | ||||
|       if (Pci->Flag & IO_BAR) { | ||||
|         Descr->MsrData[0] <<= 12;       // Move BASE to MSR[31:14] | ||||
|         Descr->MsrData[1]  += ~(Pci->Mask | 3); | ||||
|         Descr->MsrData[1] <<= 12;       // Move TOP to MSR[63:46] | ||||
|         Descr->MsrData[1]  |= 1;        // Set SPACE bit | ||||
|       }	else { | ||||
|         Descr->MsrData[1] += ~Pci->Mask & 0xFFFFF000; | ||||
|       } | ||||
|       Descr->MsrData[0] |= 1;           // Enable region | ||||
|       return; | ||||
|  | ||||
|     case EPCI: | ||||
|       return; | ||||
|  | ||||
|     case GX2_RCONF: | ||||
|       // Mark region non-cacheable and write-combined | ||||
|       Descr->MsrData[0] |= REGION_CD | REGION_EN; | ||||
|       Descr->MsrData[1] = Pci->Value + ~Pci->Mask & 0xFFFFF000; | ||||
|  | ||||
|       if (Pci->Flag & MMIO_BAR) { | ||||
|         // Memory-mapped I/O must be write-serialized to avoid deadlocks | ||||
|         // They are also marked write-burstable | ||||
|         // Descr->MsrData[0] |= REGION_WS | REGION_WT; | ||||
|       } | ||||
|       if (Pci->Flag & MEM_BAR) { | ||||
|         // Mark frame buffers write-combined | ||||
|         Descr->MsrData[0] |= REGION_WC; | ||||
|       } | ||||
|       return; | ||||
|  | ||||
|     case IOD_SC: | ||||
|       PMask = Descr->Range; | ||||
|       Descr->MsrData[0] = Compute_IOD_SC(&PCI_Value, &(USHORT)PMask, 1); | ||||
|       break; | ||||
|  | ||||
|     case IOD_BM: | ||||
|       PMask = ~(Descr->Range-1) | 0xF0000; | ||||
|       PBase = PCI_Value & PMask; | ||||
|       PCI_Value += Descr->Range; | ||||
|       break; | ||||
|  | ||||
|     case P2D_BMK: | ||||
|     case P2D_BMO: | ||||
|     case P2D_BM: | ||||
|       PMask = Pci->Mask  >> 12; | ||||
|       PBase = Pci->Value >> 12; | ||||
|       break; | ||||
|  | ||||
|     case P2D_RO: | ||||
|       // Fixup for VG alias bug | ||||
|       if (Descr->Physical) { | ||||
|         POffset = (~Pci->Value + 1) >> 12; | ||||
|       } | ||||
|     case P2D_R: | ||||
|       PMask = Pci->Value >> 12; | ||||
|       PBase = PMask + ((Descr->Range-1) >> 12); | ||||
|       break; | ||||
|  | ||||
|     // These descriptor types are not used for PCI BARs | ||||
|     case P2D_SCO: | ||||
|     case P2D_SC: | ||||
|     default: | ||||
|       Log_Error("Compute_Msr_Value() was called with an invalid descriptor type: 0x%0x", Descr->Type); | ||||
|       return; | ||||
|  | ||||
|   } // end switch() | ||||
|  | ||||
|   if (Descr->Type != IOD_SC) { | ||||
|     if (Pci->Flag & MEM_BAR) { | ||||
|       POffset = (Descr->Physical - Pci->Value) >> 12; | ||||
|     } | ||||
|     // Assemble fields into MSR value | ||||
|     MergeFields(Descr->MsrData, PMask, PBase, POffset); | ||||
|   } | ||||
|  | ||||
|   // Set PID field | ||||
|   Descr->MsrData[1] |= (ULONG)Descr->Port << 29; | ||||
|  | ||||
|   // Set Bizarro bit, if necessary | ||||
|   if (Pci->Flag & USE_BMK) { | ||||
|     Descr->MsrData[1] |= BIZARRO; | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Updates all descriptors/LBARs/RCONF associated with a PCI BAR | ||||
| //*********************************************************************** | ||||
| void pascal Update_BAR(register PCI_HEADER_ENTRY * Pci, UCHAR Enable) | ||||
| { register DESCRIPTOR * Descr; | ||||
|   UCHAR Link; | ||||
|    | ||||
|   PCI_Value = Pci->Value; | ||||
|   Link = Pci->Link; | ||||
|  | ||||
|  | ||||
|   // For each linked item, update the associated MSR | ||||
|   while (Link) { | ||||
| 							 | ||||
|     Descr = &MSRs[Link]; | ||||
|  | ||||
|     // Get link to next MSR | ||||
|     Link = Descr->Link; | ||||
|  | ||||
|     // Section 3.2.2 of PCI Spec 2.1:  A BAR of zero is not a valid address. | ||||
|     // If the BAR value is zero, the corresponding MSR will be disabled. | ||||
|     if (Enable && Pci->Value != 0) { | ||||
|  | ||||
|       // Don't update MSRs if querying resource requirements  | ||||
|       if (Pci->Value == Pci->Mask) { | ||||
|         continue; | ||||
|       } | ||||
|  | ||||
|       // BAR is being enabled | ||||
|       Compute_Msr_Value(Descr, Pci); | ||||
|  | ||||
|     } else { | ||||
|  | ||||
|       // Graphics device ignores disabling Command[1] (Issue 118.181) | ||||
|       if (Class == 0x0300) { | ||||
|         if (!(Pci->Flag & IO_BAR)) { | ||||
|           continue; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       // BAR is being disabled | ||||
|       Read_MSR(Descr->MsrAddr, Descr->MsrData); | ||||
|  | ||||
|       switch (Descr->Type) { | ||||
|  | ||||
|         case USB_LBAR: | ||||
|           Descr->MsrData[1] &= ~2; | ||||
|           break; | ||||
|  | ||||
|         case MDD_LBAR: | ||||
|           Descr->MsrData[1] &= ~LBAR_EN; | ||||
|           break; | ||||
|  | ||||
|         case EPCI: | ||||
|           break; | ||||
|  | ||||
|         case GX2_RCONF: | ||||
|           Descr->MsrData[0] &= ~REGION_EN; | ||||
|           break; | ||||
|  | ||||
|         case MPCI_RCONF: | ||||
|           Descr->MsrData[0] &= ~1; | ||||
|           break; | ||||
|  | ||||
|         case IOD_SC: | ||||
|           Descr->MsrData[0] &= ~(WEN | REN); | ||||
|           break; | ||||
|  | ||||
|         default: | ||||
|           Get_Descriptor_Default(Descr->Type, Descr->MsrData); | ||||
|           break; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // Write the MSR | ||||
|     Write_MSR(Descr->MsrAddr, Descr->MsrData); | ||||
|  | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Parses a MBD_MSR_ERROR & returns the Status register equivalent. | ||||
| // NOTE: | ||||
| //   PERR# is not implemented, so MASTER_PARITY_ERROR always reads 0. | ||||
| //*********************************************************************** | ||||
| ULONG pascal Get_Device_Status(PCI_HEADER_ENTRY * Pci) | ||||
| { ULONG MsrAddr, MsrData, Status=0; | ||||
|  | ||||
|   // Read MBD_MSR_ERROR | ||||
|   if (MsrAddr = GetMSR()) { | ||||
|     (USHORT)MsrAddr = MBD_MSR_ERROR; | ||||
|  | ||||
|     MsrData = Read_MSR_LO(MsrAddr); | ||||
|  | ||||
|     if (MsrData & (BME | TASE)) | ||||
|       Status |= SIGNALED_TARGET_ABORT;      // Status[11] | ||||
|  | ||||
|     if (MsrData & TARE) | ||||
|       Status |= RECEIVED_TARGET_ABORT;      // Status[12] | ||||
|  | ||||
|     if (MsrData & MARE) | ||||
|       Status |= RECEIVED_MASTER_ABORT;      // Status[13] | ||||
|  | ||||
|     if (MsrData & SYSE) | ||||
|       Status |= SIGNALED_SYSTEM_ERROR;      // Status[14] | ||||
|  | ||||
|     if (MsrData & PARE) | ||||
|       Status |= DETECTED_PARITY_ERROR;      // Status[15] | ||||
|   } | ||||
|   return Status; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Clears error(s) pending on a device according to the Status mask | ||||
| //*********************************************************************** | ||||
| void  pascal Clear_MBus_Error(PCI_HEADER_ENTRY * Pci, ULONG Status) | ||||
| { ULONG MsrAddr, MsrData; | ||||
|  | ||||
|   // Read MBD_MSR_ERROR | ||||
|   if (MsrAddr = GetMSR()) { | ||||
|  | ||||
|     (USHORT)MsrAddr = MBD_MSR_ERROR; | ||||
|  | ||||
|     MsrData = Read_MSR_LO(MsrAddr); | ||||
|  | ||||
|  | ||||
|     // Status[15:11] write-1-to-clear. | ||||
|     // Only clear the MSR bits corresponding to Status[15:11] | ||||
|     MsrData &= ~(TASE | BME | TARE | MARE | SYSE | PARE); | ||||
|  | ||||
|     if (Status & SIGNALED_TARGET_ABORT)     // Status[11] | ||||
|       MsrData |= TASE | BME; | ||||
|  | ||||
|     if (Status & RECEIVED_TARGET_ABORT)     // Status[12] | ||||
|       MsrData |= TARE; | ||||
|  | ||||
|     if (Status & RECEIVED_MASTER_ABORT)     // Status[13] | ||||
|       MsrData |= MARE; | ||||
|  | ||||
|     if (Status & SIGNALED_SYSTEM_ERROR)     // Status[14] | ||||
|       MsrData |= SYSE; | ||||
|  | ||||
|     if (Status & DETECTED_PARITY_ERROR)     // Status[15] | ||||
|       MsrData |= PARE; | ||||
|  | ||||
|     Write_MSR_LO(MsrAddr, MsrData); | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Enables/disables bus mastering on a GLIU device | ||||
| // Returns non-zero if no more bus-master MSRs for this device | ||||
| //*********************************************************************** | ||||
| UCHAR pascal Update_BusMaster(PCI_HEADER_ENTRY * Pci, UCHAR EnableFlag) | ||||
| { register DESCRIPTOR * Descr; | ||||
|   ULONG MsrAddr, MsrData[2]; | ||||
|   USHORT Mask; | ||||
|   UCHAR Link, Shift; | ||||
|  | ||||
|   switch (Class) { | ||||
|  | ||||
|     // Filter out devices that don't affect PAE when Command[2] is changed | ||||
|     case 0x0600:  // Bridge: Host | ||||
|     case 0x0601:  // Bridge: ISA | ||||
|     case 0x0300:  // Graphics | ||||
|     case 0x1010:  // AES | ||||
|       return 1; | ||||
|  | ||||
|     default: | ||||
|  | ||||
|       Link = Pci->Link; | ||||
|  | ||||
|       // For each linked item, update the associated MSR | ||||
|       while (Link) { | ||||
|  | ||||
|         Descr = &MSRs[Link]; | ||||
|  | ||||
|         // Get link to next MSR | ||||
|         Link = Descr->Link; | ||||
|  | ||||
|  | ||||
|         MsrAddr = Descr->MsrAddr; | ||||
|         // Each USB 2.0 device on port 2 has its own bus-master control | ||||
|         if (Descr->Type == USB_LBAR) { | ||||
|           // Modify bus-master control | ||||
|           Read_MSR(MsrAddr, MsrData); | ||||
|           (UCHAR)MsrData[1] &= ~BUS_MASTER; | ||||
|           if (EnableFlag) { | ||||
|             (UCHAR)MsrData[1] |= BUS_MASTER; | ||||
|           } | ||||
|           Write_MSR(MsrAddr, MsrData); | ||||
|           Descr->MsrData[1] = MsrData[1]; | ||||
|           return 1; | ||||
|         } | ||||
|         // Only change PAE in MBIU0 & MBIU2 | ||||
|         MsrAddr &= ROUTING; | ||||
|         if (MsrAddr == Mbiu0 || MsrAddr == Mbiu2) { | ||||
|           (USHORT)MsrAddr = MBIU_PAE; | ||||
|  | ||||
|           // Generate shift count from port # | ||||
|           Shift = 14;   // Port 0 is in 8th position (bits 15:14) | ||||
|           if (Descr->Port) { | ||||
|             Shift = (Descr->Port-1) * 2; | ||||
|           }  | ||||
|  | ||||
|           // Generate mask for PAE MSR.  2 bits/field. | ||||
|           Mask = 3 << Shift; | ||||
|  | ||||
|           // Modify bus-master control | ||||
|           Read_MSR(MsrAddr, MsrData); | ||||
|           (USHORT)MsrData[0] &= ~Mask; | ||||
|           if (EnableFlag) { | ||||
|             (USHORT)MsrData[0] |= Mask; | ||||
|           } | ||||
|           Write_MSR(MsrAddr, MsrData); | ||||
|         } | ||||
|       } | ||||
|       break; | ||||
|   } | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Supports macro SYS_MBUS_DESCRIPTOR. | ||||
| // Returns the MSR address associated with a virtualized PCI resource. | ||||
| //*********************************************************************** | ||||
| ULONG pascal Lookup_PCI(USHORT Address) | ||||
| { register PCI_HEADER_ENTRY * Pci; | ||||
|   register DESCRIPTOR * Descr; | ||||
|   UCHAR LO_Address, Index=0; | ||||
|  | ||||
|   LO_Address = (UCHAR)Address; | ||||
|  | ||||
|   // Limit search to PCI BARs and OEM registers | ||||
|   if (((LO_Address >= BAR0) && (LO_Address <= BAR5)) || (LO_Address >= 0x40)) { | ||||
|    | ||||
|     Pci = Get_Structure(Address); | ||||
|  | ||||
|     if ((USHORT)Pci > UNIMPLEMENTED_REGISTER) { | ||||
|       if (Index = Pci->Link) { | ||||
|         // For OHCI devices, return embedded PCI address | ||||
|         if (Pci->Flag & EPCI_RW ) { | ||||
|           do { | ||||
|             Descr = &MSRs[Index]; | ||||
|             if (Descr->Type == EPCI) { | ||||
|               break; | ||||
|             } | ||||
|           } while (Index = Descr->Link); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   Descr = &MSRs[Index]; | ||||
|   return Descr->MsrAddr; | ||||
| } | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Supports macro SYS_IO_DESCRIPTOR. | ||||
| // Returns the MSR address associated with an I/O address. | ||||
| //*********************************************************************** | ||||
| ULONG pascal Lookup_IO(USHORT Address) | ||||
| { USHORT Range; | ||||
|   ULONG Addr; | ||||
|   UCHAR Index=0; | ||||
|  | ||||
|   Range = 1; | ||||
|   Addr = (ULONG)Address; | ||||
|   Index = Find_Matching_IO_Descriptor(&Addr, &Range, 3); | ||||
|   return MSRs[Index].MsrAddr; | ||||
| } | ||||
							
								
								
									
										367
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/mdd.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										367
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/mdd.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,367 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //****************************************************************************** | ||||
| //*    Routines related to the MBus Diverse Device  | ||||
| //****************************************************************************** | ||||
|  | ||||
|  | ||||
| #include "VSA2.H" | ||||
| #include "SYSMGR.H" | ||||
| #include "GX2.H" | ||||
| #include "MDD.H" | ||||
| #include "PROTOS.H" | ||||
| #include "DESCR.H" | ||||
| #include "ACPI.H" | ||||
| #include "VPCI.H" | ||||
| #include "PCI.H" | ||||
| #include "ACPI.H" | ||||
| #include "CHIPSET.H" | ||||
|  | ||||
| #define A20_EN	 (A20_P_EN | A20_K_EN) | ||||
| #define INIT_EN  (INIT_K_EN | INIT_P_EN) | ||||
|  | ||||
|  | ||||
| // External function prototypes: | ||||
| void Init_MFGPT(void); | ||||
| UCHAR pascal ACPI_Trapping(USHORT); | ||||
|  | ||||
| // Local function prototypes: | ||||
| void pascal Control_MDD_SMI(USHORT, ULONG); | ||||
|  | ||||
|  | ||||
| // Local variables: | ||||
| ULONG MDD_Base; | ||||
|  | ||||
| // External variables: | ||||
| extern PCI_HEADER_ENTRY ISA_Hdr[]; | ||||
| extern Hardware HardwareInfo; | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Enables/disables KEL SMIs | ||||
| //*********************************************************************** | ||||
| void pascal Control_KEL_SMI(USHORT EnableFlag) | ||||
| { | ||||
|   Control_MDD_SMI(EnableFlag, KEL_ASMI_EN); | ||||
| } | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Enable/disable keyboard command snooping by KEL | ||||
| //*********************************************************************** | ||||
| void pascal Control_KEL_Snoop(USHORT EnableFlag) | ||||
| { ULONG MsrAddr, MsrData; | ||||
|  | ||||
|   MsrAddr = MDD_Base; | ||||
|   (USHORT)MsrAddr = MSR_KEL_CNTRL; | ||||
|   MsrData = Read_MSR_LO(MsrAddr); | ||||
|  | ||||
|   if (EnableFlag) { | ||||
|     MsrData |=  KEL_SNOOP; | ||||
|   } else { | ||||
|     MsrData &= ~KEL_SNOOP; | ||||
|   } | ||||
|   Write_MSR_LO(MsrAddr, MsrData); | ||||
|  | ||||
| } | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Initializes the MBus Diverse Device | ||||
| //*********************************************************************** | ||||
| void Init_MDD(void) | ||||
| { ULONG MsrAddr; | ||||
|   USHORT ACPI_Bar; | ||||
|   UCHAR i; | ||||
|  | ||||
|  | ||||
|   // Find address of MBus Diverse Device | ||||
|   MsrAddr = MDD_Base = Find_MBus_ID(ID_MDD, 1) & 0xFFFF0000; | ||||
|  | ||||
|   //********************************************* | ||||
|   // Record MDD's LBARs in MSRs[] | ||||
|   //********************************************* | ||||
|   for (i = MSR_LBAR_IRQ; i <= MSR_LBAR_FLSH3; i++) { | ||||
|  | ||||
|     (UCHAR)MsrAddr = i; | ||||
|  | ||||
|     if (Init_Descr(MDD_LBAR, MsrAddr)) { | ||||
|       break; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Clear PM1_STS | ||||
|   (UCHAR)MsrAddr = ISA_Hdr[BAR5/4].LBar; | ||||
|   ACPI_Bar = (USHORT)Read_MSR_LO(MsrAddr); | ||||
|   out_16(ACPI_Bar, in_16(ACPI_Bar)); | ||||
|  | ||||
|  | ||||
|   // Initialize KEL | ||||
|  | ||||
|   // Enable keyboard snooping by KEL | ||||
|   Control_KEL_Snoop(1); | ||||
|  | ||||
|   // Enable SMIs from: | ||||
|   // - A20 & Init (keyboard and port 92h) | ||||
|   // - KEL | ||||
|   // - Extended PIC Mapper | ||||
|   Control_MDD_SMI(1, A20_EN | INIT_EN | PIC_ASMI_EN | KEL_ASMI_EN); | ||||
|  | ||||
|  | ||||
|   // Initialize the MFGPT | ||||
|   Init_MFGPT(); | ||||
|  | ||||
|   // Clear any pending PIC events | ||||
|   (USHORT)MsrAddr = MBD_MSR_SMI; | ||||
|   Write_MSR_HI(MsrAddr, PIC_ASMI_EN); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Implements CS5536's F0 Special Cycles. | ||||
| // Linked to MDD's MSR_LEG_IO[31]. | ||||
| // | ||||
| // When set, a Shutdown special cycle causes a reset. When the Special | ||||
| // Cycles bit is cleared, a Shutdown special cycle is ignored.  Before  | ||||
| // updating MSR_LEG_IO,  VSA will check MSR_ERR[15] and MSR_SMI[1]. If  | ||||
| // either of these MSR bits are set, then no action is taken.  It will | ||||
| // be assumed that a debugger is in use and VSA will not interfere. | ||||
| //*********************************************************************** | ||||
| void pascal Update_Special_Cycles(USHORT EnableFlag) | ||||
| { ULONG MSR_Addr, MSR_Data; | ||||
|  | ||||
|  | ||||
|   // If either MSR_ERR[15] and MSR_SMI[1] is set, then bail. | ||||
|   if (Read_MSR_LO(MDD_Base + MBD_MSR_SMI) & 2) { | ||||
|     return; | ||||
|   } | ||||
|   if (Read_MSR_LO(MDD_Base + MBD_MSR_ERROR) & 0x8000) { | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   // Link MSR_LEG_IO[RESET_SHUT_EN] to COMMAND[3] | ||||
|   MSR_Addr = MDD_Base + MSR_LEG_IO; | ||||
|   MSR_Data = Read_MSR_LO(MSR_Addr); | ||||
|  | ||||
|   if (EnableFlag) { | ||||
|     MSR_Data |=  RESET_SHUT_EN; | ||||
|   } else { | ||||
|     MSR_Data &= ~RESET_SHUT_EN; | ||||
|   } | ||||
|  | ||||
|   Write_MSR_LO(MSR_Addr, MSR_Data); | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Enable/disable of MDD ASMI(s) | ||||
| //*********************************************************************** | ||||
| void pascal Control_MDD_SMI(USHORT EnableFlag, ULONG EnableMask) | ||||
| { ULONG MsrAddr, MsrData; | ||||
|  | ||||
|   MsrAddr = MDD_Base; | ||||
|   (USHORT)MsrAddr = MBD_MSR_SMI; | ||||
|  | ||||
|   MsrData = Read_MSR_LO(MsrAddr); | ||||
|   if (EnableFlag) { | ||||
|     MsrData |=  EnableMask; | ||||
|    } else { | ||||
|     MsrData &= ~EnableMask; | ||||
|   } | ||||
|   Write_MSR_LO(MsrAddr, MsrData); | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Clears the ACPI Status register | ||||
| // This routine fills in MsgPacket[0] = ACPI GPE0_STS | ||||
| // and MsgPacket[1] bits[15:0] = ACPI PM1_STS | ||||
| //*********************************************************************** | ||||
| USHORT Get_ACPI_Status(ULONG *msgp) | ||||
| { USHORT ACPI_Bar, PM1_Status; | ||||
|   ULONG GPE_Status; | ||||
|   UCHAR Flag; | ||||
|  | ||||
|   // Disable ACPI trapping | ||||
|   Flag = ACPI_Trapping(0); | ||||
|  | ||||
|   // Get ACPI Status | ||||
|   ACPI_Bar = ISA_Hdr[BAR5/4].Value_LO; | ||||
|  | ||||
|   (UCHAR)ACPI_Bar = GPE0_STS_OFS; | ||||
|   GPE_Status = in_32(ACPI_Bar); | ||||
|  | ||||
|   // Don't clear PIC status | ||||
|   GPE_Status &= ~1; | ||||
|  | ||||
|  | ||||
|   msgp[1] = GPE_Status; | ||||
|  | ||||
|  | ||||
|   (UCHAR)ACPI_Bar = PM1_STS_OFS; | ||||
|   PM1_Status = in_16(ACPI_Bar); | ||||
|  | ||||
|  | ||||
|   // Enable ACPI trapping | ||||
|   if (Flag) { | ||||
|     ACPI_Trapping(1); | ||||
|   } | ||||
|  | ||||
|   msgp[2] = (ULONG)PM1_Status; | ||||
|  | ||||
|   return (PM1_Status || GPE_Status); | ||||
| } | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Enable PM logic | ||||
| //*********************************************************************** | ||||
| void Enable_PME_Event(UCHAR EnableFlag, UCHAR Pm1Bit, UCHAR PmeBit, USHORT Attributes) | ||||
| { ULONG Gpe, Pm1, bmGPE0; | ||||
|   USHORT ACPI_Bar, bmPM1; | ||||
|   UCHAR Flag; | ||||
|   static UCHAR pme_instance = 0; | ||||
|   static UCHAR PM1_Instance[11] = {0,0,0,0,0,0,0,0,0,0,0}; | ||||
|   static UCHAR PME_Instance[8]  = {0,0,0,0,0,0,0,0}; | ||||
|   static ULONG GPE0_Masks[] = { // Maps PME # to GPE0 bits | ||||
|     0x00010000, | ||||
|     0x00020000, | ||||
|     0x00040000, | ||||
|     0x00080000, | ||||
|     0x00100000, | ||||
|     0x00200000, | ||||
|     0x40000000, | ||||
|     0x80000000, | ||||
|   }; | ||||
|  | ||||
|   bmPM1 = 0; | ||||
|   bmGPE0 = 0L; | ||||
|   if (Attributes & PM1) { | ||||
|     bmPM1 = 1 << Pm1Bit; | ||||
|  | ||||
|     if (EnableFlag) { | ||||
|       PM1_Instance[Pm1Bit]++; | ||||
| 	} else { | ||||
|       if (PM1_Instance[Pm1Bit]) { | ||||
|         // If there are still registrations for this PM1 bit... | ||||
|         if (--PM1_Instance[Pm1Bit]) { | ||||
|           // then don't turn disable it | ||||
|           return; | ||||
|         } | ||||
|       } else { | ||||
|         // Error:  | ||||
|         return; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   if (Attributes & GPE) { | ||||
|     bmGPE0 = GPE0_Masks[PmeBit]; | ||||
|     if (EnableFlag) { | ||||
|       PME_Instance[PmeBit]++; | ||||
| 	} else { | ||||
|       if (PME_Instance[PmeBit]) { | ||||
|         // If there are still registrations for this GEP0 bit... | ||||
|         if (--PME_Instance[PmeBit]) { | ||||
|           // then don't turn disable it | ||||
|           return; | ||||
|         } | ||||
|       } else { | ||||
|         // Error:  | ||||
|         return; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|  | ||||
|   if (!(Attributes & NO_ASMI)) { | ||||
|     // Keep a count of PME events. | ||||
|     // Once all have been de-registered, turn off PM_ASMI bit. | ||||
|     if (EnableFlag) { | ||||
|       if (Attributes & PME) { | ||||
|         pme_instance++; | ||||
|       } | ||||
|       // Enable ASMIs from Power Management logic | ||||
|       Control_MDD_SMI(EnableFlag, PM_ASMI_EN); | ||||
|     } else { | ||||
|       if (Attributes & PME) { | ||||
|         if (pme_instance != 0) { | ||||
|           if (--pme_instance == 0) { | ||||
|             // Disable ASMIs from Power Management logic | ||||
|             Control_MDD_SMI(0, PM_ASMI_EN); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // See if we want to enable the approriate bits in PM1_EN and GPE0_EN | ||||
|   // if set to NO_ENALE we don't enable (Used by ACPI as the OS controls) | ||||
|   if (!(Attributes & NO_ENABLE)) { | ||||
|     // Disable ACPI trapping | ||||
|     Flag = ACPI_Trapping(0); | ||||
|  | ||||
|     // Get ACPI base address | ||||
|     ACPI_Bar = ISA_Hdr[BAR5/4].Value_LO; | ||||
|  | ||||
|     if (bmPM1) { | ||||
|       // Must do 32-bit I/O to avoid shadow register bug (IAeng00003062) | ||||
|       (UCHAR)ACPI_Bar = 0x00; | ||||
|       Pm1 = in_32(ACPI_Bar); | ||||
|       if (EnableFlag) { | ||||
|         Pm1 |=   (ULONG)bmPM1 << 16; | ||||
|       } else { | ||||
|         Pm1 &= ~((ULONG)bmPM1 << 16); | ||||
|       } | ||||
|       out_32(ACPI_Bar, Pm1); | ||||
|  | ||||
|       // Serialize the previous I/O write | ||||
|       in_16(ACPI_Bar); | ||||
|  | ||||
|       // Clear spurious status | ||||
|       (UCHAR)ACPI_Bar = PM1_STS_OFS; | ||||
|       out_32(ACPI_Bar, (ULONG)Pm1); | ||||
|     } | ||||
|  | ||||
|     if (bmGPE0) { | ||||
|       (UCHAR)ACPI_Bar = GPE0_EN_OFS; | ||||
|       Gpe = in_32(ACPI_Bar); | ||||
|       if (EnableFlag) { | ||||
|         Gpe |=  bmGPE0; | ||||
|       } else { | ||||
|         Gpe &= ~bmGPE0; | ||||
|       } | ||||
|       out_32(ACPI_Bar, Gpe); | ||||
|       // Serialize the previous I/O write | ||||
|       in_32(ACPI_Bar); | ||||
|  | ||||
|       // Clear spurious status | ||||
|       (UCHAR)ACPI_Bar = GPE0_STS_OFS; | ||||
|       out_32(ACPI_Bar, Gpe); | ||||
|     } | ||||
|  | ||||
|     // Serialize the previous I/O write | ||||
|     in_32(ACPI_Bar); | ||||
|    | ||||
|     // Re-enable ACPI trapping | ||||
|     if (Flag) { | ||||
|       ACPI_Trapping(1); | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										226
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/mdd.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										226
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/mdd.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,226 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| // ATA | ||||
| #define MSR_LBAR_ATA			0x0008 | ||||
|  | ||||
|  | ||||
| // Diverse Integration Logic | ||||
|  | ||||
| #define MSR_MAST_CONF			0x0001 | ||||
|   #define NON_COH_RD  (1L << 12) | ||||
|   #define NON_COH_WR  (1L << 13) | ||||
|  | ||||
| #define LBAR_EN             (1 << 0) | ||||
| #define NOR_NAND            (1 << 1) | ||||
| #define MEM_IO              (1 << 2) | ||||
| #define LBAR_IO_MASK		0x0001FFF0 | ||||
| #define LBAR_MEM_MASK		0xFFFFF000 | ||||
|  | ||||
|  | ||||
| #define MSR_LBAR_IRQ			0x0008 | ||||
| #define MSR_LBAR_KEL1			0x0009 | ||||
| #define MSR_LBAR_KEL2			0x000A | ||||
| #define MSR_LBAR_SMB			0x000B | ||||
|  | ||||
| #define MSR_LBAR_GPIO			0x000C | ||||
|   #define GPIO_LOW_BANK_SELECT	0x00 | ||||
|   #define GPIO_HIGH_BANK_SELECT	0x80 | ||||
|   #define GPIO_OUTPUT_VALUE		0x00 | ||||
|   #define GPIO_OUTPUT_ENABLE	0x04 | ||||
|   #define GPIO_OUTPUT_OPENDRAIN	0x08 | ||||
|   #define GPIO_OUTPUT_INVERT	0x0C | ||||
|   #define GPIO_OUT_AUX1_SELECT	0x10 | ||||
|   #define GPIO_OUT_AUX2_SELECT  0x14 | ||||
|   #define GPIO_PULLUP_ENABLE	0x18 | ||||
|   #define GPIO_PULLDOWN_ENABLE	0x1C | ||||
|   #define GPIO_INPUT_ENABLE		0x20 | ||||
|   #define GPIO_INPUT_INVERT		0x24 | ||||
|   #define GPIO_IN_FILTER_ENABLE	0x28 | ||||
|   #define GPIO_IN_EVENTCOUNT	0x2C | ||||
|   #define GPIO_READ_BACK		0x30 | ||||
|   #define GPIO_IN_AUX1_SELECT	0x34 | ||||
|   #define GPIO_EVENTS_ENABLE	0x38 | ||||
|   #define GPIO_LOCK_ENABLE		0x3C | ||||
|     #define LKOV				(1 <  0) | ||||
|     #define LKOE				(1 <  1) | ||||
|     #define LKOD				(1 <  2) | ||||
|     #define LKOI				(1 <  3) | ||||
|     #define LKA1				(1 <  4) | ||||
|     #define LKA2				(1 <  5) | ||||
|     #define LKPU				(1 <  6) | ||||
|     #define LKPD				(1 <  7) | ||||
|     #define LKIE				(1 <  8) | ||||
|     #define LKII				(1 <  9) | ||||
|     #define LKFE				(1 < 10) | ||||
|     #define LKEE				(1 < 11) | ||||
|     #define LKIA				(1 < 12) | ||||
|     #define LKIP				(1 < 13) | ||||
|     #define LKPE				(1 < 14) | ||||
|     #define LKNE				(1 < 15) | ||||
|   #define GPIO_POSEDGE_ENABLE	0x40 | ||||
|   #define GPIO_NEGEDGE_ENABLE	0x44 | ||||
|   #define GPIO_POSEDGE_STATUS	0x48 | ||||
|   #define GPIO_NEGEDGE_STATUS	0x4C | ||||
|  | ||||
|   // GPIO IRQ Mapper | ||||
|   #define GPIO_MAPPER_X			0xE0 | ||||
|   #define GPIO_MAPPER_Y			0xE4 | ||||
|   #define GPIO_MAPPER_Z			0xE8 | ||||
|   #define GPIO_MAPPER_W			0xEC | ||||
|  | ||||
|   // Digital Filter | ||||
|   #define GPIO_FILTER_AMOUNT    0x50 | ||||
|   #define GPIO_FILTER_COUNT     0x52 | ||||
|   #define GPIO_EVENT_COUNT      0x54 | ||||
|   #define GPIO_EVENT_COMPARE    0x56 | ||||
|  | ||||
|   #define GPIO6_FILTER_AMOUNT	0xD0 | ||||
|   #define GPIO7_FILTER_AMOUNT	0xD8 | ||||
|  | ||||
|   #define GPIO_FILTER_SELECT0	0xF0 | ||||
|   #define GPIO_FILTER_SELECT1	0xF1 | ||||
|   #define GPIO_FILTER_SELECT2	0xF2 | ||||
|   #define GPIO_FILTER_SELECT3	0xF3 | ||||
|   #define GPIO_FILTER_SELECT4	0xF4 | ||||
|   #define GPIO_FILTER_SELECT5	0xF5 | ||||
|   #define GPIO_FILTER_SELECT6	0xF6 | ||||
|   #define GPIO_FILTER_SELECT7	0xF7 | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| #define MSR_LBAR_MFGPT			0x000D | ||||
|   // I/O offsets relative to MFGPT LBAR | ||||
|   #define MFGPT_CMP1			0x00 | ||||
|   #define MFGPT_CMP2			0x02 | ||||
|   #define MFGPT_COUNTER			0x04 | ||||
|   #define MFGPT_SETUP			0x06 | ||||
|  | ||||
|   #define MFGPT_OFFSET          8 | ||||
|  | ||||
| #define MSR_LBAR_ACPI			0x000E | ||||
| #define MSR_LBAR_PMS			0x000F | ||||
| #define MSR_LBAR_FLSH0 			0x0010 | ||||
| #define MSR_LBAR_FLSH1 			0x0011 | ||||
| #define MSR_LBAR_FLSH2 			0x0012 | ||||
| #define MSR_LBAR_FLSH3 			0x0013 | ||||
| #define MSR_LEG_IO	 			0x0014 | ||||
|   #define RESET_SHUT_EN  (0x80000000L) | ||||
|   #define UART1_SHIFT		(16) | ||||
|   #define UART2_SHIFT		(20) | ||||
|   #define UART_MASK			(0x07) | ||||
|   #define UART_IO_MASK		(0x03) | ||||
|   #define UART_EN			(0x04) | ||||
| #define MSR_PIN_OPTS			0x0015 | ||||
|   #define PIN_OPT_IDE		(1 << 0) | ||||
| #define MSR_SOFT_IRQ			0x0016 | ||||
| #define MSR_SOFT_RESET			0x0017 | ||||
| #define MSR_AC_DMA				0x0019 | ||||
|  | ||||
| #define MSR_KEL_CNTRL			0x001F | ||||
|   #define KEL_SNOOP			(1 << 0) | ||||
|   #define KEL_EER			(1 << 1) | ||||
|   #define KEL_PRTA_EN		(1 << 4) | ||||
|  | ||||
|  | ||||
| // IRQ Mask & Mapper (from MDD Specification) | ||||
| #define MSR_IRQM_YLOW			0x0020 | ||||
| #define MSR_IRQM_YHIGH			0x0021 | ||||
| #define MSR_IRQM_ZLOW			0x0022 | ||||
| #define MSR_IRQM_ZHIGH			0x0023 | ||||
| #define MSR_IRQM_PRIM			0x0024 | ||||
| #define MSR_IRQM_LPC			0x0025 | ||||
| #define MSR_IRQM_LXIRR			0x0026 | ||||
| #define MSR_IRQM_HXIRR			0x0027 | ||||
| #define MSR_MFGPT_IRQ			0x0028 | ||||
| #define MSR_MFGPT_NR			0x0029 | ||||
| #define MSR_MFGPT_CLR_SETUP		0x002B | ||||
|  | ||||
| #define MSR_FLOP_S3F2			0x0030 | ||||
| #define MSR_FLOP_S3F7			0x0031 | ||||
| #define MSR_FLOP_S372			0x0032 | ||||
| #define MSR_FLOP_S377			0x0033 | ||||
| #define MSR_PIC_SHADOW			0x0034 | ||||
| #define MSR_PIT_SHADOW			0x0036 | ||||
|  | ||||
| // UART's | ||||
| #define MSR_UART1_MOD			0x0038 | ||||
| #define MSR_UART1_DONG			0x0039 | ||||
| #define MSR_UART1_CONF			0x003A | ||||
| 	#define UART_SOFT_RESET			(0x01L) | ||||
| 	#define UART_DEVEN				(0x02L) | ||||
| 	#define UART_FREEZE				(0x04L) | ||||
| 	#define UART_TEST				(0x08L) | ||||
| 	#define UART_EXT_BANKS			(0x10L) | ||||
| #define MSR_UART2_MOD			0x003C | ||||
| #define MSR_UART2_DONG			0x003D | ||||
| #define MSR_UART2_CONF			0x003E | ||||
|  | ||||
| #define MSR_DMA_MAP				0x0040 | ||||
| #define MSR_DMA_SHAD0			0x0041 | ||||
| #define MSR_DMA_SHAD1			0x0042 | ||||
| #define MSR_DMA_SHAD2			0x0043 | ||||
| #define MSR_DMA_SHAD3			0x0044 | ||||
| #define MSR_DMA_SHAD4			0x0045 | ||||
| #define MSR_DMA_SHAD5			0x0046 | ||||
| #define MSR_DMA_SHAD6			0x0047 | ||||
| #define MSR_DMA_SHAD7			0x0048 | ||||
| #define MSR_DMA_MSK_SHAD		0x0049 | ||||
|  | ||||
| // LPC | ||||
| #define MSR_LPC_SIRQ			0x004E | ||||
|  | ||||
|  | ||||
|  | ||||
| // MSR_SMI | ||||
| #define HLT_ASMI_EN			(1L << 0) | ||||
| #define SHUTDOWN_ASMI_EN	(1L << 1) | ||||
| #define KEL_ASMI_EN			(1L << 2) | ||||
| #define PIC_ASMI_EN			(1L << 3) | ||||
| #define PM_ASMI_EN			(1L << 4) | ||||
| #define INIT_K_EN			(1L << 5) | ||||
| #define A20_P_EN			(1L << 6) | ||||
| #define INIT_P_EN			(1L << 7) | ||||
| #define UART1_SSMI_EN		(1L << 8) | ||||
| #define UART2_SSMI_EN		(1L << 9) | ||||
| #define RESERVED_EN    		(1L << 10) | ||||
| #define LPC_SSMI_EN			(1L << 11) | ||||
| #define DMA_SSMI_EN			(1L << 12) | ||||
| #define A20_K_EN			(1L << 13) | ||||
| #define PM2_CNT_SSMI_EN		(1L << 14) | ||||
| #define PM1_CNT_SSMI_EN		(1L << 15) | ||||
|  | ||||
| #define HLT_ASMI_STAT		(1L << 32) | ||||
| #define SHUTDOWN_ASMI_STAT	(1L << 33) | ||||
| #define KEL_ASMI_STAT		(1L << 34) | ||||
| #define PIC_ASMI_STAT		(1L << 35) | ||||
| #define PM_ASMI_STAT		(1L << 36) | ||||
| #define INIT_K_STAT			(1L << 37) | ||||
| #define A20_P_STAT			(1L << 38) | ||||
| #define INIT_P_STAT			(1L << 39) | ||||
| #define UART1_SSMI_STAT		(1L << 40) | ||||
| #define UART2_SSMI_STAT		(1L << 41) | ||||
| #define RESERVED_STAT  		(1L << 42) | ||||
| #define LPC_SSMI_STAT		(1L << 43) | ||||
| #define DMA_SSMI_STAT		(1L << 44) | ||||
| #define A20_K_STAT			(1L << 45) | ||||
| #define PM2_CNT_SSMI_STAT	(1L << 46) | ||||
| #define PM1_CNT_SSMI_STAT	(1L << 47) | ||||
|  | ||||
							
								
								
									
										393
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/message.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										393
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/message.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,393 @@ | ||||
| ;  | ||||
| ; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| ;  | ||||
| ; This library is free software; you can redistribute it and/or modify | ||||
| ; it under the terms of the GNU Lesser General Public License as | ||||
| ; published by the Free Software Foundation; either version 2.1 of the | ||||
| ; License, or (at your option) any later version. | ||||
| ;  | ||||
| ; This code is distributed in the hope that it will be useful, | ||||
| ; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| ; Lesser General Public License for more details. | ||||
| ;  | ||||
| ; You should have received a copy of the GNU Lesser General | ||||
| ; Public License along with this library; if not, write to the | ||||
| ; Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| ; Boston, MA 02111-1307 USA  | ||||
| ;  | ||||
| ;*   Function:                                                         * | ||||
| ;*     Implements message handling routines  | ||||
|  | ||||
| include SYSMGR.INC | ||||
| include VSA2.INC | ||||
|  | ||||
|  | ||||
|  | ||||
| .model tiny,c | ||||
| .586p | ||||
| .CODE | ||||
|  | ||||
| externdef SysMgr_VSM:            dword | ||||
| externdef MsgPacket:             dword | ||||
| externdef VSM_ListHead:          dword | ||||
| externdef Current_VSM:           dword | ||||
|  | ||||
| externdef Events:                EVENT_ENTRY | ||||
| externdef Sys_Exit:              proc | ||||
| externdef pascal Schedule_VSM:   proc | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; This routine is called from the System Manager to enter a message | ||||
| ; packet into a VSM's message queue. | ||||
| ; | ||||
| ; Input: | ||||
| ;   To_VSM   = Flat ptr to VSM to which message is to be sent | ||||
| ;   MsgCode  = Priority::Message | ||||
| ;   From_VSM = value to be put in Async_VSM field | ||||
| ;   MsgPacket contains the message parameters | ||||
| ;*********************************************************************** | ||||
| Send_Message proc pascal uses di si \ | ||||
| 	From_VSM:   dword, \ | ||||
| 	To_VSM:     dword, \ | ||||
| 	MsgCode:    dword | ||||
|  | ||||
| 	mov     edi, [To_VSM] | ||||
| 	cmp     edi, [SysMgr_VSM]	; Don't send messages to SysMgr | ||||
| 	je      short Exit | ||||
|  | ||||
| 	mov     eax, [MsgCode] | ||||
| 	lea     si, [MsgPacket] | ||||
| 	mov     ebx, [From_VSM] | ||||
| 	call    Insert_Msg | ||||
| Exit:	ret | ||||
|  | ||||
| Send_Message endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; This routine enters a message packet into a VSM's message queue. | ||||
| ; | ||||
| ; Input: | ||||
| ;   EAX = Priority::Message | ||||
| ;   EBX = From_VSM | ||||
| ;   EDI = To_VSM | ||||
| ;    SI = Ptr to message packet | ||||
| ;*********************************************************************** | ||||
| Insert_Msg proc  | ||||
|  | ||||
| 	cld | ||||
|  | ||||
| 	push    ebx			; Save From_VSM | ||||
|  | ||||
| 	; Get ptr to the head of the message queue | ||||
| 	movzx   ebx, fs:(VSM_Header PTR [edi]).SysStuff.Qhead | ||||
|  | ||||
| 	; Compute ptr to the next available message queue entry | ||||
| 	lea     dx, [bx+sizeof(Message)] | ||||
| 	cmp     dx, fs:(VSM_Header PTR [edi]).SysStuff.EndMsgQ | ||||
| 	jb      short Check_Q_Overflow | ||||
| 	mov     dx, OFFSET VSM_Header.SysStuff.MsgQueue | ||||
| Check_Q_Overflow: | ||||
|  | ||||
| 	; Is Qhead == Qtail ? | ||||
| 	cmp     dx, fs:(VSM_Header PTR [edi]).SysStuff.Qtail | ||||
| 	jne     short UpdateQueueHead | ||||
|  | ||||
| 	; Yes, then message queue has overflowed	 | ||||
| 	mov     [si+8], eax		; Store previous message into Param2 | ||||
| 	mov     ax, MSG_QUEUE_OVERFLOW	; Replace previous message | ||||
| 	mov     dx, bx			; Qhead = old Qhead | ||||
| UpdateQueueHead: | ||||
| 	mov     fs:(VSM_Header PTR [edi]).SysStuff.Qhead, dx | ||||
|  | ||||
| 	pop     edx			; From_VSM | ||||
| 	push    edi			; Parameter to Schedule_VSM() below | ||||
|  | ||||
| 	; Store the message into the VSM's message queue. | ||||
| 	; NOTE: This code is dependent on "#typedef Message" | ||||
| 	add     edi, ebx | ||||
| 	stosd   [edi]			; Priority::Message | ||||
|  | ||||
| 	mov     eax, edx		; From_VSM | ||||
| 	stosd   [edi] | ||||
|  | ||||
| REPEAT MAX_MSG_PARAM | ||||
| 	lodsd				; Copy parameters to message queue | ||||
| 	stosd   [edi] | ||||
| ENDM | ||||
| 	 | ||||
| 	 | ||||
| 	 | ||||
| 	; Sort messages by Priority | ||||
| if SUPPORT_PRIORITY | ||||
|  | ||||
| 	pop     ebx			; To_VSM | ||||
| 	push    ebx | ||||
| 	 | ||||
| 	push    fs:(VSM_Header PTR [ebx]).SysStuff.Qhead | ||||
| BubbleSort:	 | ||||
|  | ||||
| 	; Get ptr to latest queue entry | ||||
| 	movzx   esi, fs:(VSM_Header PTR [ebx]).SysStuff.Qhead | ||||
| 	sub     esi, sizeof(Message) | ||||
| 	cmp     si, OFFSET VSM_Header.SysStuff.MsgQueue | ||||
| 	jae     short @f | ||||
| 	mov     si, fs:(VSM_Header PTR [ebx]).SysStuff.EndMsgQ | ||||
| 	sub     si, sizeof(Message) | ||||
| @@: | ||||
| 	cmp	si, fs:(VSM_Header PTR [ebx]).SysStuff.Qtail | ||||
| 	je	Bail | ||||
|  | ||||
| 	; Get ptr to previous queue entry | ||||
| 	lea     edi, [esi-sizeof(Message)] | ||||
| 	cmp     di, OFFSET VSM_Header.SysStuff.MsgQueue | ||||
| 	jae     short @f | ||||
| 	mov     di, fs:(VSM_Header PTR [ebx]).SysStuff.EndMsgQ | ||||
| 	sub     di, sizeof(Message) | ||||
| @@: | ||||
| 	 | ||||
| 	mov     fs:(VSM_Header PTR [ebx]).SysStuff.Qhead, di | ||||
|  | ||||
| 	; Add VSM base to ptrs | ||||
| 	add     edi, ebx | ||||
| 	add     esi, ebx | ||||
| 	 | ||||
| 	; Compare their priorities	 | ||||
| 	mov     ax, fs:(Message PTR [esi]).Priority | ||||
| 	cmp     ax, fs:(Message PTR [edi]).Priority | ||||
| 	jbe     short Bail | ||||
| 	 | ||||
| 	 | ||||
| 	 | ||||
| 	; Swap the entries in the message queue | ||||
| 	mov     cx, sizeof(Message)/4	; Assumes entry is multiple of dword | ||||
| Interchange: | ||||
| 	mov     eax, fs:[edi] | ||||
| 	xchg    fs:[esi], eax | ||||
| 	stosd	[edi] | ||||
| 	add     esi, 4 | ||||
| 	loop    Interchange | ||||
|  | ||||
| 	jmp	BubbleSort | ||||
|  | ||||
|  | ||||
| Bail: | ||||
| 	pop     fs:(VSM_Header PTR [ebx]).SysStuff.Qhead | ||||
|  | ||||
| endif | ||||
| 	 | ||||
|         | ||||
| 	; Schedule the VSM to execute | ||||
| 	pop	eax | ||||
| 	cmp	eax, [SysMgr_VSM] | ||||
| 	je	short Exit | ||||
| 	push	eax | ||||
| 	call    Schedule_VSM | ||||
| Exit: | ||||
| 	ret | ||||
| 	 | ||||
|  | ||||
| Insert_Msg endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;************************************************************************ | ||||
| ; | ||||
| ; Sends a message to each VSM of type VSM_Type (or all if VSM_ANY). | ||||
| ; Called from HANDLERS.C | ||||
| ; | ||||
| ;************************************************************************ | ||||
| Broadcast_Message proc  pascal uses si di \ | ||||
| 	MsgCode:     word,	\ | ||||
| 	VSM_Type:    word,      \ | ||||
| 	From_VSM:    dword | ||||
|  | ||||
| 	mov     edi, [VSM_ListHead]	; Get ptr to list of VSMs | ||||
| VSM_Loop: | ||||
| 	or      edi, edi		; End of VSM list ? | ||||
| 	jz      Exit_Broadcast | ||||
|  | ||||
| 	mov     dx,  [VSM_Type] | ||||
| 	mov     ah, fs:(VSM_Header PTR [edi]).VSM_Type | ||||
|  | ||||
| 	cmp     dl, VSM_ANY		; Schedule all VSMs ?  | ||||
| 	je      Schedule_It | ||||
|  | ||||
| 	test    dh, (VSM_ALL_EXCEPT SHR 8) | ||||
| 	jz      CheckType | ||||
|  | ||||
| 	cmp     dl, ah			; Skip the one that matches | ||||
| 	je      Skip_VSM | ||||
| 	jmp     Schedule_It | ||||
|  | ||||
| CheckType: | ||||
| 	cmp     dl, ah			; Is it the correct VSM ? | ||||
| 	jne     Skip_VSM | ||||
|  | ||||
| Schedule_It: | ||||
|  | ||||
| 	cmp     edi, [From_VSM]		; Is it the requesting VSM ? | ||||
| 	je      Skip_VSM		; Yes, don't send to sender | ||||
|  | ||||
| 	push    edi | ||||
|  | ||||
| 	movzx   eax, [MsgCode]		; Send the message | ||||
| 	xor     ebx, ebx | ||||
| 	lea     si, [MsgPacket] | ||||
|  | ||||
| ;   EAX = Priority::Message | ||||
| ;   EBX = 00000000h (a broadcast is not a synchronous event) | ||||
| ;    SI = Ptr to message packet | ||||
| ;   EDI = Ptr to VSM header where message is to be sent | ||||
| 	call    Insert_Msg | ||||
| 	pop     edi | ||||
|  | ||||
|  | ||||
| Skip_VSM: | ||||
| 	mov     edi, fs:(VSM_Header PTR [edi]).SysStuff.Flink | ||||
| 	jmp     VSM_Loop | ||||
|  | ||||
| Exit_Broadcast: | ||||
| 	ret | ||||
|  | ||||
| Broadcast_Message endp | ||||
|  | ||||
|  | ||||
|  | ||||
| ;************************************************************************ | ||||
| ; Broadcasts a message to one or more VSMs. | ||||
| ; | ||||
| ; Input: | ||||
| ;   EBX = message code (16 MSBs) | ||||
| ;    BH = Flags | ||||
| ;    BL = VSM_Type | ||||
| ;   ECX = Param1 | ||||
| ;   ESI = Param2 | ||||
| ;   EDI = Param3 | ||||
| ;************************************************************************ | ||||
| Sys_Broadcast proc | ||||
|  | ||||
| 	mov	dx, bx			; Put VSM_Type::Flags into DX | ||||
| 	shr	ebx, 16			; Put message into BX | ||||
|  | ||||
| 	mov     eax, esi | ||||
| 	lea     si, [MsgPacket] | ||||
| 	mov	[si+0], ecx | ||||
| 	mov	[si+4], eax | ||||
| 	mov	[si+8], edi | ||||
|  | ||||
| 	; Re-schedule the broadcasting VSM | ||||
| 	; RunFlag will be changed from RUN_FLAG_ACTIVE to RUN_FLAG_READY | ||||
| 	mov     edi, [Current_VSM] | ||||
| 	push    edi | ||||
| 	call    Schedule_VSM | ||||
| 	; If RunFlag == RUN_FLAG_READY, Insert_Msg() won't schedule it again | ||||
| 	mov	fs:(VSM_Header PTR [edi]).SysStuff.RunFlag, RUN_FLAG_BLOCKED | ||||
|  | ||||
| 	; Push parameters for call to Broadcast_Message() | ||||
| 	push    bx			; Message code | ||||
| 	push    dx			; VSM type | ||||
| 	push    edi			; From_VSM | ||||
| 	 | ||||
| 	; Normally, the message is sent to the broadcasting VSM  | ||||
| 	; after all VSMs have handled the broadcasted message. | ||||
| 	; There are two exceptions to this rule: | ||||
| 	; 1) VSM_NOT_SELF   | <VSM type> | ||||
| 	; 2) VSM_ALL_EXCEPT | <self> | ||||
| 	test    dh, (VSM_NOT_SELF SHR 8) | ||||
| 	jnz     short Broadcast | ||||
|  | ||||
| 	test    dh, (VSM_ALL_EXCEPT SHR 8) | ||||
| 	jz      short SendToSelf | ||||
| 	cmp     dl, fs:(VSM_Header PTR [edi]).VSM_Type | ||||
| 	je      short Broadcast | ||||
|  | ||||
| SendToSelf: | ||||
| 	; Put callback address onto the scheduler stack | ||||
| 	mov	eax, OFFSET BroadcastCallback | ||||
| 	push	eax | ||||
| 	call    Schedule_VSM | ||||
|  | ||||
| 	mov	ax, BROADCAST_PRIORITY	; EAX = Priority::Message  | ||||
| 	shl	eax, 16 | ||||
| 	mov	ax, bx | ||||
|  | ||||
| 	mov     edi, [SysMgr_VSM]	; EDI = To_VSM | ||||
| 	mov     ebx, [Current_VSM]	; EBX = From_VSM | ||||
| 	call    Insert_Msg | ||||
|  | ||||
| Broadcast: | ||||
| 	call    Broadcast_Message | ||||
|  | ||||
| 	jmp     Sys_Exit		; Exit w/o scheduling current VSM | ||||
|  | ||||
| Sys_Broadcast endp | ||||
|  | ||||
|  | ||||
| ;************************************************************************ | ||||
| ; Control comes here when all VSMs have processed the broadcasted message. | ||||
| ; Copies the broadcasted message from SysMgr's message queue to the | ||||
| ; broadcasting VSM's message queue. | ||||
| ;************************************************************************ | ||||
| BroadcastCallback proc | ||||
| 	ASSUME  DI: PTR VSM_Header | ||||
| 	ASSUME  BX: PTR Message | ||||
|  | ||||
| 	; Point BX to parameters in SysMgr's message queue head | ||||
| 	xor     di, di | ||||
| 	mov     bx, [di].SysStuff.Qhead | ||||
| 	sub     bx, sizeof(Message) | ||||
| 	cmp     bx, OFFSET VSM_Header.SysStuff.MsgQueue | ||||
| 	jb      short BadMsgStack | ||||
| 	mov     [di].SysStuff.Qhead, bx | ||||
| 	 | ||||
| 	mov     eax, dword ptr [bx].Msg	; Get Priority::Message | ||||
| 	mov	edi, [bx].From_VSM	; To_VSM (the VSM it was originally from) | ||||
|  | ||||
| 	lea	si, [bx].Param | ||||
| 	xor     ebx, ebx		; From_VSM (asynchronous) | ||||
| 	call    Insert_Msg | ||||
| BadMsgStack:	 | ||||
| 	ret | ||||
| 	 | ||||
| 	ASSUME  BX: NOTHING | ||||
| 	ASSUME  DI: NOTHING | ||||
|  | ||||
| BroadcastCallback endp | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Passes an event to the next VSM registered for this event | ||||
| ; NOTE: This system call is now obsolete. | ||||
| ;*********************************************************************** | ||||
| Sys_PassEvent proc  | ||||
|  | ||||
| 	jmp     Sys_Exit		; Exit to VSM dispatcher | ||||
| 	 | ||||
| Sys_PassEvent endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| 	END | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										500
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/mfgpt.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										500
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/mfgpt.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,500 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //***************************************************************************** | ||||
| //*     This file contains code specific to CS5536 MFGPTs  | ||||
| //***************************************************************************** | ||||
|  | ||||
|  | ||||
| #include "VSA2.H" | ||||
| #include "SYSMGR.H" | ||||
| #include "PROTOS.H" | ||||
| #include "MDD.H" | ||||
| #include "MAPPER.H" | ||||
| #include "TIMER.H" | ||||
|  | ||||
| // External variables: | ||||
| extern ULONG MDD_Base; | ||||
|  | ||||
| // Local variables: | ||||
| USHORT MFGPT_Base=0; | ||||
| ULONG MFGPT_LBAR[2]; | ||||
|   | ||||
|  | ||||
|  | ||||
| // NOTE: Timers that use the 32KHz clock interfere with LPC DMA (see PBZ 709) | ||||
|    | ||||
|                                                                       // Clock    Prescalar  Period | ||||
| #define TIMER_SETUP (MFGPT_SCALE_1K | MFGPT_CMP1MODE | MFGPT_CLK_SEL) // 14 MHz     1024      71 us | ||||
| #define STDBY_SETUP (MFGPT_SCALE_32 | MFGPT_CMP1MODE)                 // 32 KHz       32       1 ms | ||||
| #define PWM_SETUP   (MFGPT_SCALE_32 | MFGPT_CMP1GE)                   // 32 KHz       32       1 ms | ||||
| TIMERS TimerInfo[] = { | ||||
| //  #       Z Mapper        Setup            | ||||
| // Save for OS (Linux) use   { 0,   Z_IRQ_MFGPT_04,   PWM_SETUP}, | ||||
|   { 1,   Z_IRQ_MFGPT_15,   PWM_SETUP}, | ||||
|   { 2,   Z_IRQ_MFGPT_26,   PWM_SETUP}, | ||||
|   { 3,   Z_IRQ_MFGPT_37, TIMER_SETUP}, | ||||
| // Save for OS (Linux) use  { 4,   Z_IRQ_MFGPT_04, TIMER_SETUP}, | ||||
|   { 5,   Z_IRQ_MFGPT_15, TIMER_SETUP}, | ||||
|   { 6,   Z_IRQ_MFGPT_26, STDBY_SETUP}, | ||||
|   { 7,   Z_IRQ_MFGPT_37,   PWM_SETUP}, | ||||
| }; | ||||
| #define NUM_MFGPTS     (sizeof(TimerInfo)/sizeof(TIMERS))  // Number of MFGPTs available | ||||
|  | ||||
| //************************************************************************************ | ||||
| // Saves the MFGPT LBAR setting and enables the LBAR | ||||
| //************************************************************************************ | ||||
| void Enable_MFGPT_LBAR() | ||||
| { ULONG Tmp; | ||||
|   int i; | ||||
|  | ||||
|   // Get MFGPT LBAR | ||||
|   Read_MSR(MDD_Base + MSR_LBAR_MFGPT, MFGPT_LBAR); | ||||
|  | ||||
|   // Has the MFGPT base address changed? | ||||
|   if (MFGPT_Base != (USHORT)MFGPT_LBAR[0]) { | ||||
|     // Yes, record the new base address of MFGPT | ||||
|     MFGPT_Base = (USHORT)MFGPT_LBAR[0]; | ||||
|  | ||||
|     // Update the individual timer base addresses | ||||
|     for (i = 0; i < NUM_MFGPTS; i++) { | ||||
|       TimerInfo[i].TimerBase = MFGPT_Base + TimerInfo[i].Timer*MFGPT_OFFSET; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Save the current LBAR enable | ||||
|   Tmp = MFGPT_LBAR[1]; | ||||
|  | ||||
|   // Enable the LBAR | ||||
|   MFGPT_LBAR[1] |= LBAR_EN; | ||||
|   Write_MSR(MDD_Base + MSR_LBAR_MFGPT, MFGPT_LBAR); | ||||
|   MFGPT_LBAR[1] = Tmp; | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| //************************************************************************************ | ||||
| // Restores the MFGPT LBAR | ||||
| //************************************************************************************ | ||||
| void Restore_MFGPT_LBAR() | ||||
| { | ||||
|   // Restore MFGPT LBAR | ||||
|   Write_MSR(MDD_Base + MSR_LBAR_MFGPT, MFGPT_LBAR); | ||||
| } | ||||
|  | ||||
|  | ||||
| //************************************************************************************ | ||||
| // Checks for MFGPT events | ||||
| // Returns a mask of which timer(s) have expired | ||||
| //************************************************************************************ | ||||
| USHORT CS5536_MFGPT_Handler(void) | ||||
| { USHORT Setup, Status, Accum_Status=0, i; | ||||
|   register TIMERS * TimerPtr; | ||||
|  | ||||
|   Enable_MFGPT_LBAR(); | ||||
|  | ||||
|   for (i = 0; i < NUM_MFGPTS; i++) { | ||||
|  | ||||
|     TimerPtr = &TimerInfo[i]; | ||||
|  | ||||
|     // Get timer status | ||||
|     Setup = TimerPtr->TimerBase + MFGPT_SETUP; | ||||
|     Status = in_16(Setup); | ||||
|     if (Status & MFGPT_INITED) { | ||||
|       out_16(Setup, Status); | ||||
|     } | ||||
|  | ||||
|     // Check if MFGPT is reserved for EVENT_PWM | ||||
|     if(TimerPtr->Setup == PWM_SETUP) { | ||||
|       continue; | ||||
|     } | ||||
|  | ||||
|     // If timer is enabled and expired... | ||||
|     Status &= MFGPT_ENABLE | MFGPT_COMPARE1; | ||||
|     if (Status == (MFGPT_ENABLE | MFGPT_COMPARE1)) { | ||||
|       // disable the timer | ||||
|       out_16(Setup, Status & (~MFGPT_ENABLE)); | ||||
|       // record timer event | ||||
|       Accum_Status |= TimerPtr->Mask; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Restore the MFGPT LBAR | ||||
|   Restore_MFGPT_LBAR(); | ||||
|  | ||||
|   return Accum_Status; | ||||
| } | ||||
|  | ||||
| //************************************************************************************ | ||||
| // Initializes a single MFGPT | ||||
| //************************************************************************************ | ||||
| void Init_Timer(TIMERS * TimerPtr) | ||||
| { USHORT Setup, TimerKHz; | ||||
|   ULONG MicrosPerCount; | ||||
|  | ||||
|   TimerPtr->TimerBase = MFGPT_Base + TimerPtr->Timer*MFGPT_OFFSET; | ||||
|  | ||||
|   TimerPtr->Mask = 1 << TimerPtr->Timer; | ||||
|  | ||||
|   Setup = TimerPtr->Setup; | ||||
|  | ||||
|   // Compute microseconds / tick | ||||
|   MicrosPerCount = 1000L << (Setup & 0xF); | ||||
|   TimerKHz = 32; | ||||
|   if (Setup & MFGPT_CLK_SEL) { | ||||
|     TimerKHz = 14318; | ||||
|   } | ||||
|   TimerPtr->Period = (USHORT)(MicrosPerCount / TimerKHz); | ||||
|  | ||||
|   // Initialize the timer | ||||
|   out_16(TimerPtr->TimerBase + MFGPT_SETUP, Setup); | ||||
|  | ||||
|   // NOTE: Counter resets to 0 when Counter == Comparator2 register | ||||
|   out_32(TimerPtr->TimerBase + MFGPT_CMP1,  0xFFFFFFFF); | ||||
|  | ||||
| } | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Marks a MFGPT as available | ||||
| //*********************************************************************** | ||||
| void pascal MarkTimerAvailable(USHORT Timer) | ||||
| { USHORT i; | ||||
|  | ||||
|   for (i = 0; i < NUM_MFGPTS; i++) { | ||||
|     if (TimerInfo[i].Timer == Timer) { | ||||
|       TimerInfo[i].Interval = 0x00000000; | ||||
|       return; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   Log_Error("Invalid timer: %d.", Timer); | ||||
| } | ||||
|  | ||||
|  | ||||
| //************************************************************************************ | ||||
| // Initializes the MFGPT timers to be used for EVENT_TIMER | ||||
| //************************************************************************************ | ||||
| void Init_MFGPT(void) | ||||
| { ULONG MsrAddr, IRQ_Enables; | ||||
|   USHORT i; | ||||
|   register TIMERS * TimerPtr; | ||||
|  | ||||
|   Enable_MFGPT_LBAR(); | ||||
|  | ||||
|   // Get current MFGPT IRQ mask | ||||
|   MsrAddr = MDD_Base; | ||||
|   (USHORT)MsrAddr = MSR_MFGPT_IRQ; | ||||
|   IRQ_Enables = Read_MSR_LO(MsrAddr); | ||||
|  | ||||
|   for (i = 0; i < NUM_MFGPTS; i++) { | ||||
|  | ||||
|     TimerPtr = &TimerInfo[i]; | ||||
|  | ||||
|     // Initialize a MFGPT | ||||
|     Init_Timer(TimerPtr); | ||||
|  | ||||
|     // Mark timer as available | ||||
|     MarkTimerAvailable(TimerPtr->Timer); | ||||
|  | ||||
|     // Route Compare 1 events to SMI | ||||
|     IRQZ_Mapper(TimerPtr->Mapper, 2); | ||||
|  | ||||
|     // Enable timer event | ||||
|     IRQ_Enables |= TimerPtr->Mask; | ||||
|  | ||||
|   } | ||||
|  | ||||
|  | ||||
|   // Restore the MFGPT LBAR | ||||
|   Restore_MFGPT_LBAR(); | ||||
|  | ||||
|  | ||||
|   // Enable MFGPT SMIs | ||||
|   Write_MSR_LO(MsrAddr, IRQ_Enables); | ||||
|  | ||||
| }  | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Disables a millisecond timer | ||||
| //*********************************************************************** | ||||
| void DisableMsTimer_5536(USHORT Timer) | ||||
| { USHORT Setup, i; | ||||
|  | ||||
|   Enable_MFGPT_LBAR(); | ||||
|  | ||||
|  | ||||
|   for (i = 0; i < NUM_MFGPTS; i++) { | ||||
|     if (TimerInfo[i].Timer == Timer) { | ||||
|       // Mark timer as available | ||||
|       MarkTimerAvailable(Timer); | ||||
|  | ||||
|       // Clear timer event and disable timer | ||||
|       Setup = TimerInfo[i].TimerBase + MFGPT_SETUP; | ||||
|       out_16(Setup, MFGPT_COMPARE1 | MFGPT_COMPARE2); | ||||
|       break; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Restore the MFGPT LBAR | ||||
|   Restore_MFGPT_LBAR(); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Allocates a h/w timer for the specified interval | ||||
| // Returns the timer # allocated else 0xFFFF | ||||
| //*********************************************************************** | ||||
| USHORT AllocateTimer_5536(ULONG Interval, UCHAR Attributes) | ||||
| { UCHAR i, Exact = 0, Unused=0, Compat=0, Mask; | ||||
|   register TIMERS * TimerPtr; | ||||
|  | ||||
|   // Find the MFGPT whose timebase is the best-match | ||||
|   for (i = 0; i < NUM_MFGPTS; i++) { | ||||
|     TimerPtr = &TimerInfo[i]; | ||||
|  | ||||
|     // Don't use timers reserved for EVENT_PWM | ||||
|     if (TimerPtr->Setup == PWM_SETUP) { | ||||
|       continue; | ||||
|     } | ||||
|  | ||||
|     if (Attributes & (FOR_STANDBY >> 24)) { | ||||
|       // Timers used for PM must be in the 32 KHz domain | ||||
|       if (TimerPtr->Setup & MFGPT_CLK_SEL) { | ||||
|         continue; | ||||
|       } | ||||
|     } else { | ||||
|       if (TimerPtr->Timer >= 6) { | ||||
|         // Timers 6 & 7 are reserved for PM | ||||
|         continue; | ||||
|       } | ||||
|     } | ||||
|     Mask = (UCHAR)TimerPtr->Mask; | ||||
|  | ||||
|     // Is timer unused? | ||||
|     if (TimerPtr->Interval == 0x00000000) { | ||||
|       Unused |= Mask; | ||||
| 	} | ||||
|  | ||||
|     // Is timebase a perfect match? | ||||
|     if ((Interval*1000 % TimerPtr->Period) == 0) { | ||||
|       Exact |= Mask; | ||||
|     } | ||||
|  | ||||
|     // Is timebase compatible? | ||||
|     if (Interval*1000 >= TimerPtr->Period) { | ||||
|       Compat |= Mask; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Is there an UNUSED timer whose timebase is an exact match? | ||||
|   if (!(Mask = (Unused & Exact))) { | ||||
|     // No, is there an UNUSED timer that is compatible? | ||||
|     if (!(Mask = (Unused & Compat))) { | ||||
|       // No, is there ANY timer whose timebase is an exact match? | ||||
|       if (!(Mask = Exact)) { | ||||
|         // No, is there ANY timer that is compatible? | ||||
|         if (!(Mask = Compat)) { | ||||
|           // No timers are available | ||||
|           return 0xFFFF; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Return the MFGPT index | ||||
|   Mask = 1 << BitScanReverse(Mask); | ||||
|   for (i = 0; i < NUM_MFGPTS; i++) { | ||||
|     if (TimerInfo[i].Mask == Mask) { | ||||
|       return i; | ||||
|     } | ||||
|   } | ||||
|   return 0xFFFF; | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Enables a millisecond timer | ||||
| //*********************************************************************** | ||||
| UCHAR EnableMsTimer_5536(ULONG Interval, UCHAR Attributes) | ||||
| { USHORT i, Count, TimerBase; | ||||
|   ULONG MsrAddr, IRQ_Enables, TotalCounts, Roundoff; | ||||
|   register TIMERS * TimerPtr; | ||||
|  | ||||
|   // Get current MFGPT IRQ mask | ||||
|   MsrAddr = MDD_Base; | ||||
|   (USHORT)MsrAddr = MSR_MFGPT_IRQ; | ||||
|   IRQ_Enables = Read_MSR_LO(MsrAddr); | ||||
|  | ||||
|   // Allocate a h/w timer | ||||
|   i = AllocateTimer_5536(Interval, Attributes); | ||||
|   if (i == 0xFFFF) { | ||||
|     Log_Error("Attempt to enable %d ms timer interval failed", Interval); | ||||
|     return 0; | ||||
|   } | ||||
|  | ||||
|   TimerPtr = &TimerInfo[i]; | ||||
|  | ||||
|   // A timer was allocated, is it already in use? | ||||
|   if (TimerPtr->Interval) { | ||||
|     // Yes, does it need to be reprogrammed? | ||||
|     if (Interval > TimerPtr->Interval) { | ||||
|       // No, but since the timer has already been running for an | ||||
|       // indeterminate period, the 1st interval will be shortened. | ||||
|       return (UCHAR)TimerPtr->Timer; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|  | ||||
|   if (Interval) { | ||||
|  | ||||
|     Enable_MFGPT_LBAR(); | ||||
|  | ||||
|     // Get I/O address of this timer | ||||
|     TimerBase = TimerPtr->TimerBase; | ||||
|  | ||||
|     // The MFGPT document specifies the following sequence in order | ||||
|     // to prevent any spurious resets, interrupt, or output events: | ||||
|     // - Set Counter Enable bit to 0. | ||||
|     // - Clear SMI enable in MSR_MFGPT_IRQ | ||||
|     // - Update Count as desired | ||||
|     // - When updates are completed, clear event bits | ||||
|     // - Set SMI enable in MSR_MFGPT_IRQ | ||||
|     // - Set Counter Enable bit to 1 | ||||
|  | ||||
|     // Does this timer need to be initialized again (e.g. after S3) ? | ||||
|     if (!(in_16(TimerBase + MFGPT_SETUP) & MFGPT_INITED)) { | ||||
|       // Initialize the timer | ||||
|       Init_Timer(TimerPtr); | ||||
|     } | ||||
|  | ||||
|     // Set Counter Enable to 0 | ||||
|     out_16(TimerBase + MFGPT_SETUP, 0); | ||||
|  | ||||
|     // Disable SMIs | ||||
|     Write_MSR_LO(MsrAddr, 0x00000000); | ||||
|  | ||||
|     // Scale the interval appropriately | ||||
|     Roundoff = 0; | ||||
|     if (TimerPtr->Period < 1000) { | ||||
|       Roundoff = TimerPtr->Period; | ||||
|     } | ||||
|     TotalCounts = (Interval*1000 + Roundoff)/TimerPtr->Period; | ||||
|     Count = (USHORT)TotalCounts; | ||||
|     if (TotalCounts & 0xFFFF0000) { | ||||
| 	  Count = 0xFFFF; | ||||
|     } | ||||
|  | ||||
|     // Record the timer's interval | ||||
|     TimerPtr->Interval = ((ULONG)Count * TimerPtr->Period)/1000; | ||||
|  | ||||
|     // Zero the counter | ||||
|     out_16(TimerBase + MFGPT_COUNTER, 0x0000); | ||||
|  | ||||
|     // Set Comparator1 to Count and Comparator2 to 0xFFFF | ||||
|     out_32(TimerBase + MFGPT_CMP1, 0xFFFF0000L | Count); | ||||
|  | ||||
|     // Clear timer event(s) | ||||
|     out_16(TimerBase + MFGPT_SETUP, MFGPT_COMPARE1 | MFGPT_COMPARE2); | ||||
|  | ||||
|     // Re-enable SMIs | ||||
|     Write_MSR_LO(MsrAddr, IRQ_Enables); | ||||
|  | ||||
|     // Set Counter Enable to 1 | ||||
|     out_16(TimerBase + MFGPT_SETUP, MFGPT_ENABLE); | ||||
|  | ||||
|     // Restore the MFGPT LBAR | ||||
|     Restore_MFGPT_LBAR(); | ||||
|   } | ||||
|  | ||||
|   return (UCHAR)TimerPtr->Timer; | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Configures a MFGPT as a PWM signal generator | ||||
| //*********************************************************************** | ||||
| void pascal Program_PWM(UCHAR Gpio, UCHAR Duty, USHORT Rate, UCHAR EnableFlag) | ||||
| { USHORT i, Timer; | ||||
|   register TIMERS * TimerPtr; | ||||
|  | ||||
|   // Determine the MFGPT associated with the specified GPIO | ||||
|   switch (Gpio) { | ||||
|     case 5: | ||||
|       Timer = 0; | ||||
|       break; | ||||
|     case 6: | ||||
|       Timer = 1; | ||||
|       break; | ||||
|     case 7: | ||||
|       Timer = 2; | ||||
|       break; | ||||
|     case 27: | ||||
|       Timer = 7; | ||||
|       break; | ||||
|     default: | ||||
|       Log_Error("EVENT_PWM is not supported on GPIO%d", Gpio); | ||||
|       return; | ||||
|   } | ||||
|  | ||||
|   // Program the MFGPT to the specified rate and duty cycle | ||||
|   for (i = 0; i < NUM_MFGPTS; i++) { | ||||
|  | ||||
|     TimerPtr = &TimerInfo[i]; | ||||
|  | ||||
|     if (TimerPtr->Timer == Timer) { | ||||
|  | ||||
|       // Check if MFGPT is reserved for EVENT_PWM | ||||
|       if(TimerPtr->Setup != PWM_SETUP) { | ||||
|         continue; | ||||
|       } | ||||
|  | ||||
|       // Enable the MFGPT LBAR | ||||
|       Enable_MFGPT_LBAR(); | ||||
|  | ||||
|       // Clear this timer's SETUP register in case it has been used previously as a timer | ||||
|       // Write_MSR_LO(MDD_Base + MSR_MFGPT_CLR_SETUP, TimerPtr->Mask); | ||||
|       // out_16(TimerPtr->TimerBase + MFGPT_SETUP, PWM_SETUP); | ||||
|  | ||||
|  | ||||
|       // Clamp duty cycle to 100% | ||||
|       if (Duty > 100) { | ||||
|         Duty = 100; | ||||
|       } | ||||
|  | ||||
|       // Program the Count registers | ||||
|       out_16(TimerPtr->TimerBase + MFGPT_COUNTER, 0x0000); | ||||
|       out_16(TimerPtr->TimerBase + MFGPT_CMP1, (USHORT)(((ULONG)Rate * Duty)/100)); | ||||
|       out_16(TimerPtr->TimerBase + MFGPT_CMP2,  Rate); | ||||
|  | ||||
|       // Enable the counter | ||||
|       out_16(TimerPtr->TimerBase + MFGPT_SETUP, EnableFlag ? MFGPT_ENABLE: 0); | ||||
|  | ||||
|       Restore_MFGPT_LBAR(); | ||||
|  | ||||
|       return; | ||||
| 	} | ||||
|   } | ||||
|  | ||||
|   Log_Error("EVENT_PWM on GPIO%d failed because MFGPT%d is reserved.", Gpio, Timer); | ||||
| } | ||||
|  | ||||
							
								
								
									
										348
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/msr.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										348
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/msr.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,348 @@ | ||||
| ;  | ||||
| ; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| ;  | ||||
| ; This library is free software; you can redistribute it and/or modify | ||||
| ; it under the terms of the GNU Lesser General Public License as | ||||
| ; published by the Free Software Foundation; either version 2.1 of the | ||||
| ; License, or (at your option) any later version. | ||||
| ;  | ||||
| ; This code is distributed in the hope that it will be useful, | ||||
| ; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| ; Lesser General Public License for more details. | ||||
| ;  | ||||
| ; You should have received a copy of the GNU Lesser General | ||||
| ; Public License along with this library; if not, write to the | ||||
| ; Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| ; Boston, MA 02111-1307 USA  | ||||
| ;  | ||||
| ;*   Function:                                                         * | ||||
| ;*     Routines related to MSRs.    | ||||
|  | ||||
| include VSA2.INC | ||||
| include DESCR.INC | ||||
|  | ||||
|  | ||||
| .model tiny,c | ||||
| .586p | ||||
| .CODE | ||||
|  | ||||
| extern SMM_Header: SmiHeader | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Returns the high DWORD of an MSR. | ||||
| ; Usage: HighMsrValue = Read_MSR_HI(Msr_Address); | ||||
| ;*********************************************************************** | ||||
| Read_MSR_HI proc pascal \ | ||||
| 	Msr:	dword | ||||
|  | ||||
| 	mov	ecx, [Msr] | ||||
| 	rdmsr | ||||
| 	mov	ax, dx | ||||
| 	shr	edx, 16 | ||||
| 	ret | ||||
|  | ||||
| Read_MSR_HI endp | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Writes the high DWORD of an MSR. The low DWORD is preserved. | ||||
| ; Usage: Write_MSR_HI(Msr_Address, Data); | ||||
| ;*********************************************************************** | ||||
| Write_MSR_HI proc pascal \ | ||||
| 	Msr:	dword, \ | ||||
|         Data:   dword	 | ||||
| 	 | ||||
| 	mov	ecx, [Msr] | ||||
| 	rdmsr				; Get low 32 bits | ||||
| 	mov	edx, [Data] | ||||
| 	wrmsr | ||||
| 	ret | ||||
|  | ||||
| Write_MSR_HI endp | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Returns the low DWORD of an MSR. | ||||
| ; Usage: LowMsrValue = Read_MSR_LO(Msr_Address); | ||||
| ;*********************************************************************** | ||||
| Read_MSR_LO proc pascal \ | ||||
| 	Msr:	dword | ||||
|  | ||||
| 	mov	ecx, [Msr] | ||||
| 	rdmsr | ||||
| 	mov	edx, eax | ||||
| 	shr	edx, 16 | ||||
| 	ret | ||||
|  | ||||
| Read_MSR_LO endp | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Writes the low DWORD of an MSR. The high DWORD is preserved. | ||||
| ; Usage: Write_MSR_LO(Msr_Address, Data); | ||||
| ;*********************************************************************** | ||||
| Write_MSR_LO proc pascal \ | ||||
| 	Msr:	dword, \ | ||||
|         Data:   dword	 | ||||
| 	 | ||||
| 	mov	ecx, [Msr] | ||||
| 	rdmsr				; Get high 32 bits | ||||
| 	mov	eax, [Data] | ||||
| 	wrmsr | ||||
| 	ret | ||||
|  | ||||
| Write_MSR_LO endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Returns an MSR value in a buffer. | ||||
| ; Usage: Read_MSR(ULONG Msr, ULONG * Buffer); | ||||
| ;*********************************************************************** | ||||
| Read_MSR proc pascal \ | ||||
| 	Msr:	dword, \ | ||||
| 	Buffer: PTR | ||||
| 	 | ||||
| 	mov	ecx, [Msr] | ||||
| 	rdmsr | ||||
| 	 | ||||
| 	mov	bx, [Buffer] | ||||
| 	mov	[bx+0], eax | ||||
| 	mov	[bx+4], edx | ||||
| 	ret | ||||
|  | ||||
| Read_MSR endp | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Writes an MSR. | ||||
| ; Usage: Write_MSR(ULONG Msr, ULONG * Buffer); | ||||
| ;*********************************************************************** | ||||
| Write_MSR proc pascal \ | ||||
| 	Msr:	dword, \ | ||||
| 	Buffer: PTR | ||||
| 	 | ||||
| 	mov	ecx, [Msr] | ||||
| 	mov	bx, [Buffer] | ||||
| 	mov	eax, [bx+0] | ||||
| 	mov	edx, [bx+4] | ||||
| 	wrmsr | ||||
| 	ret | ||||
|  | ||||
| Write_MSR endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Parses MSR_MBIU_CAP of an MBIU and returns descriptor counts in | ||||
| ; a byte buffer. | ||||
| ;*********************************************************************** | ||||
| Parse_Capabilities proc pascal  \ | ||||
| 	Msr:    PTR, \ | ||||
| 	Buffer: PTR | ||||
| 	 | ||||
| 	mov	bx, [Msr] | ||||
| 	mov	eax, [bx+0]		; Get 1st dword of CAPABILITIES | ||||
| 	mov	edx, [bx+4]		; Get 2nd dword of CAPABILITIES | ||||
| 	mov     bx, [Buffer] | ||||
| 	mov	cl, 6			; Number of P2D descriptors | ||||
| NxtCount: | ||||
| 	mov	ch, al | ||||
| 	and	ch, 3Fh			; 6 bits per field | ||||
| 	mov	[bx], ch | ||||
| 	inc	bx | ||||
| 	 | ||||
| 	shrd	eax, edx, 6		; Shift next field into LSBs | ||||
| 	shr	edx, 6 | ||||
| 	dec	cl	 | ||||
| 	jnz	NxtCount | ||||
|  | ||||
| 	mov	ch, al			; Get NIOD_BM | ||||
| 	and	ch, 3Fh | ||||
| 	mov	[bx+1], ch | ||||
| 	 | ||||
| 	shr	eax, 6			; Get NIOD_SC | ||||
| 	mov	ch, al | ||||
| 	and	ch, 3Fh | ||||
| 	mov	[bx+2], ch | ||||
| 	 | ||||
| 	shr	eax, 9			; Skip NCOH field | ||||
| 	mov	ch, al | ||||
| 	and	ch, 07h			; Get NPORTS | ||||
| 	mov	[bx+3], ch | ||||
|  | ||||
| 	shr	ax, 9			; Get NSTAT_CNT | ||||
| 	and	al, 07h | ||||
| 	mov	[bx+4], al	 | ||||
| 	ret | ||||
| 	 | ||||
| Parse_Capabilities endp	 | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Extract the 3 main fields from a P2D descriptor | ||||
| ;*********************************************************************** | ||||
| Parse_Descriptor proc pascal uses edi \ | ||||
| 	P2D_Type: byte, \ | ||||
| 	Source:  ptr, \ | ||||
| 	Dest:  ptr | ||||
| 	 | ||||
| 	mov	bx, [Source] | ||||
|  | ||||
| 	mov	ecx, [bx]		; Get low MSR | ||||
| 	mov	eax, ecx | ||||
| 	mov	edx, [bx+4]		; Get high MSR | ||||
|  | ||||
| 	cmp	bl, IOD_BM | ||||
| 	je	Descr_IO_BM | ||||
|  | ||||
| 	shl	ecx, 12			; Extract 1st field | ||||
| 	shrd	eax, edx, 20		; Extract 2nd field | ||||
| 	shl	eax, 12 | ||||
| 	 | ||||
| 	xor	dl, dl			; Extract 3rd field | ||||
| 	shl	edx, 12-8 | ||||
| 	mov	edi, edx		; EDI = Offset | ||||
| 	 | ||||
| 	mov	bl, [P2D_Type]		; Dispatch to correct descriptor parser | ||||
| 	cmp	bl, P2D_BM  | ||||
| 	je	Descr_BM | ||||
| 	cmp	bl, P2D_BMO | ||||
| 	je	Descr_BMO | ||||
| 	cmp	bl, P2D_BMK | ||||
| 	je	Descr_BMK | ||||
| 	cmp	bl, P2D_R | ||||
| 	je	Descr_R | ||||
| 	cmp	bl, P2D_RO | ||||
| 	je	Descr_RO | ||||
| 	jmp	Exit	 | ||||
|  | ||||
|  | ||||
| Descr_IO_BM: | ||||
| 	and	ecx, 000FFFFFh		; ECX = IMASK | ||||
| 	shrd	eax, edx, 20		; EAX = IBASE | ||||
| 	xor	edi, edi		; EDI = 00000000 | ||||
|  | ||||
| Descr_BMO:				; Assume OFFSET == 0 | ||||
| Descr_BM: | ||||
| Descr_BMK: | ||||
| 	; ECX = PMASK | ||||
| 	; EAX = PBASE | ||||
| 	and	eax, ecx		; Start = PBASE & PMASK | ||||
| 	mov	edx, eax		; End = Start + ~PMASK | ||||
| 	not	ecx | ||||
| 	add	edx, ecx | ||||
| 	jmp	StoreResult | ||||
| 	 | ||||
|  | ||||
| Descr_RO:				; Assume OFFSET == 0 | ||||
| Descr_R: | ||||
| 	; ECX = PMIN | ||||
| 	; EAX = PMAX | ||||
| 	xchg	eax, ecx		; Start = PMIN | ||||
| 	mov	edx, ecx		; End = PMAX | ||||
| 	or	dx, 0FFFh | ||||
|  | ||||
| StoreResult: | ||||
| 	mov	bx, [Dest] | ||||
| 	mov	[bx], eax		; Start | ||||
| 	mov	[bx+4], edx		; End | ||||
| 	add	edi, eax		; Physical = Start + Offset | ||||
| 	mov	[bx+8], edi | ||||
|  | ||||
| Exit:	ret | ||||
|  | ||||
|  | ||||
| Parse_Descriptor endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ;*********************************************************************** | ||||
| MergeFields proc pascal \ | ||||
| 	Dest: PTR, \ | ||||
| 	Field1: DWORD, \ | ||||
| 	Field2: DWORD, \ | ||||
| 	Field3: DWORD | ||||
|  | ||||
| 	mov	bx, [Dest] | ||||
|  | ||||
| ;//  Descr->MsrData[0]  = (PBase << 20) | (PMask & 0xFFFFF); | ||||
| ;//  Descr->MsrData[1]  = (PBase >> 12) | (POffset << 8); | ||||
| 	mov	eax, [Field2] | ||||
| 	mov	edx, eax | ||||
| 	shl	eax, 20 | ||||
| 	mov	ecx, [Field1] | ||||
| 	and	ecx, 0FFFFFh | ||||
| 	or	eax, ecx | ||||
| 	mov	[bx], eax | ||||
| 		 | ||||
| 	shr	edx, 12 | ||||
| 	mov	eax, [Field3] | ||||
| 	shl	eax, 8 | ||||
| 	or	eax, edx | ||||
| 	mov	[bx+4], eax | ||||
| 	ret | ||||
| 		 | ||||
| MergeFields endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Returns TRUE if Range is a power of 2 | ||||
| ;*********************************************************************** | ||||
| IsPowerOfTwo proc pascal \ | ||||
| 	Range: dword | ||||
|  | ||||
| 	mov	ebx, [Range] | ||||
| 	bsf	eax, ebx		; Scan LSB to MSB | ||||
| 	bsr	edx, ebx		; Scan MSB to LSB | ||||
| 	cmp	al, dl			; Same bit found ? | ||||
| 	mov	al, 0			; No, return FALSE | ||||
| 	jne	Exit | ||||
| 	mov	al, 1			; else return TRUE | ||||
| Exit:	ret | ||||
| 	 | ||||
| IsPowerOfTwo endp | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Returns index of first bit set when scanning from MSB to LSB | ||||
| ;*********************************************************************** | ||||
| BitScanReverse proc pascal \ | ||||
| 	Range: dword | ||||
|  | ||||
| 	mov	ebx, [Range] | ||||
| 	bsr	eax, ebx		; Scan MSB to LSB | ||||
| 	ret | ||||
| 		 | ||||
| BitScanReverse endp | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Returns index of first bit set when scanning from LSB to MSB | ||||
| ;*********************************************************************** | ||||
| BitScanForward proc pascal \ | ||||
| 	Range: dword | ||||
|  | ||||
| 	mov	ebx, [Range] | ||||
| 	bsf	eax, ebx		; Scan LSB to MSB | ||||
| 	ret | ||||
| 		 | ||||
| BitScanForward endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| 	end | ||||
							
								
								
									
										164
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/ohci.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										164
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/ohci.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,164 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //***************************************************************************** | ||||
| //*     Handler for EVENT_USB and EVENT_KEL | ||||
| //***************************************************************************** | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| #include "VSA2.H" | ||||
| #include "PROTOS.H"  | ||||
| #include "CHIPSET.H" | ||||
| #include "VPCI.H" | ||||
| #include "PCI.H" | ||||
| #include "HCE.H" | ||||
|  | ||||
| extern ULONG MsgPacket[]; | ||||
| extern SmiHeader SMM_Header; | ||||
| extern Hardware HardwareInfo; | ||||
| extern VIRTUAL_DEVICE * SouthBridge; | ||||
| extern void pascal write_flat_size(ULONG, ULONG, UCHAR); | ||||
|  | ||||
| USHORT OHCI_Address; | ||||
| ULONG OHCI_Command; | ||||
| ULONG HC_Status; | ||||
| #define HC ((ULONG)(&((HCOR *)0) | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Restores the OHCI COMMAND register to the original value | ||||
| //*********************************************************************** | ||||
| void Restore_OHCI_Command() | ||||
| { | ||||
|   Virtual_PCI_Write_Handler(OHCI_Address, BYTE_IO, OHCI_Command & ~MEM_SPACE); | ||||
| } | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Sends EVENT_USB or EVENT_KEL | ||||
| //*********************************************************************** | ||||
| void Send_OHCI_Event(UCHAR HC_Number) | ||||
| { USHORT Hce_Status; | ||||
|   HCE_CONTROL Hce_Control; | ||||
|   ULONG HC_Enable, HC_Address; | ||||
|   ULONG Timeout; | ||||
|   PCI_HEADER_ENTRY * OHCI_Hdr; | ||||
|  | ||||
|   // Get ptr to virtualized PCI header | ||||
|   OHCI_Hdr = *(SouthBridge+3 + HC_Number); | ||||
|   if (!OHCI_Hdr) { | ||||
|     Log_Error("Invalid HC number 0x%02X", HC_Number); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   // Get HC address from BAR0 | ||||
|   if (!(HC_Address = (OHCI_Hdr+(BAR0/4))->Value)) { | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   OHCI_Address = 0x7C00 + (((USHORT)HC_Number-1) << 8) + COMMAND; | ||||
|   // Are memory-mapped registers enabled? | ||||
|   if (!((OHCI_Hdr+(COMMAND/4))->Value & MEM_SPACE)) { | ||||
|  | ||||
|     OHCI_Command = (OHCI_Hdr+(COMMAND/4))->Value; | ||||
|     // No, temporarily enable access to them  | ||||
|     Virtual_PCI_Write_Handler(OHCI_Address, BYTE_IO, OHCI_Command | MEM_SPACE); | ||||
|  | ||||
|     // Schedule a routine to restore the original COMMAND value | ||||
|     // after the VSM has processed the EVENT_USB or EVENT_KEL. | ||||
|     Schedule_VSM((USHORT)Restore_OHCI_Command); | ||||
|   } | ||||
|  | ||||
|  | ||||
|   // Get HC's Hce_Control register | ||||
|   Hce_Control.HceUshort = (USHORT)read_flat(HC_Address + HC->HceControl))); | ||||
|  | ||||
|   // Prepare message packet | ||||
|   MsgPacket[1] = HC_Address; | ||||
|   MsgPacket[2] = HC_Number; | ||||
|   MsgPacket[3] = 0; | ||||
|  | ||||
|   // Is it an emulation event ? | ||||
|   if (Hce_Control.EmulationInterrupt) { | ||||
|  | ||||
|     // SiBZ 3069/3370: HceStatus[3] is not updated properly | ||||
|     if (SMM_Header.SMI_Flags.Ext_IO_Trap) { | ||||
|       if (SMM_Header.SMI_Flags.IO_Write) { | ||||
|  | ||||
|         Hce_Status = (USHORT)read_flat(HC_Address + HC->HceStatus))); | ||||
|         switch ((USHORT)SMM_Header.IO_addr) { | ||||
|           case 0x60: | ||||
|             Hce_Status &= ~CMD_DATA; | ||||
|             break; | ||||
|           case 0x64: | ||||
|             Hce_Status |= CMD_DATA; | ||||
|             break; | ||||
|         } | ||||
|         write_flat_size(HC_Address + HC->HceStatus)), Hce_Status, BYTE_IO); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // SiBZ 3509/3571: KEL SMIs are level instead of edge-triggered | ||||
|     MsgPacket[3] = Hce_Control.HceUshort; | ||||
|     Timeout = 1000; | ||||
|     while (Timeout--) { | ||||
|  | ||||
|       Hce_Control.HceUshort = (USHORT)read_flat(HC_Address + HC->HceControl))); | ||||
|       if (Hce_Control.IRQ1Active || Hce_Control.IRQ12Active) { | ||||
|         // Clear the active IRQ & disable emulation | ||||
|         Hce_Control.EmulationEnable = 0; | ||||
|         write_flat_size(HC_Address + HC->HceControl)), Hce_Control.HceUshort , WORD_IO); | ||||
|  | ||||
|         // Read a byte from the data port to dismiss the 8042 interrupt | ||||
|         in_8(0x60); | ||||
|  | ||||
|         // Re-enable emulation | ||||
|         Hce_Control.EmulationEnable = 1; | ||||
|         write_flat_size(HC_Address + HC->HceControl)), Hce_Control.HceUshort, WORD_IO); | ||||
|       } else { | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // Report if SiBZ 3571 workaround failed | ||||
|     if (Timeout == 0) { | ||||
|       Log_Error("IRQx_ACTIVE won't clear"); | ||||
|     } | ||||
|  | ||||
|     // Send emulation event to the i8042 VSM | ||||
|     Send_Event(EVENT_KEL, SysMgr_VSM); | ||||
|   } | ||||
|  | ||||
|   // Any unmasked events pending ? | ||||
|   HC_Status |= read_flat(HC_Address + HC->HcInterruptStatus))); | ||||
|  | ||||
|  | ||||
|   HC_Enable = read_flat(HC_Address + HC->HcInterruptEnable))); | ||||
|   if (HC_Status & HC_Enable) { | ||||
|     // SWAPSiF for PBZ 2300: | ||||
|     MsgPacket[3] = HC_Status; | ||||
|     write_flat(HC_Address + HC->HcInterruptStatus)), HC_Status); | ||||
|      | ||||
|     // Send Host Controller event to the OHCI VSM | ||||
|     Send_Event(EVENT_USB, 0x00000000); | ||||
|   } | ||||
|  | ||||
|   HC_Status = 0; | ||||
| } | ||||
							
								
								
									
										539
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/pci_pm.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										539
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/pci_pm.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,539 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //*    Routines related to PCI power management.  | ||||
|  | ||||
| #include "VSA2.H" | ||||
| #include "SYSMGR.H" | ||||
| #include "VPCI.H" | ||||
| #include "PROTOS.H" | ||||
| #include "PCI.H" | ||||
| #include "CHIPSET.H" | ||||
| #include "GX2.H" | ||||
| #include "ACPI.H" | ||||
| #include "DESCR.H" | ||||
|  | ||||
|  | ||||
|  | ||||
| #if SUPPORT_CAPABILITIES | ||||
|  | ||||
| extern DESCRIPTOR MSRs[]; | ||||
| extern PCI_HEADER_ENTRY * HdrPtr; | ||||
| extern PCI_HEADER_ENTRY * CommandPtr; | ||||
| extern UCHAR End_of_POST; | ||||
| extern ULONG OHCI1_Smi; | ||||
| extern ULONG MCP_SB; | ||||
|  | ||||
| #define OHC_IN_D3   1 | ||||
| #define EHC_IN_D3   2 | ||||
| #define UDC_IN_D3   4 | ||||
| #define UOC_IN_D3   8 | ||||
| #define ALL_IN_D3   (OHC_IN_D3 | EHC_IN_D3 | UDC_IN_D3 | UOC_IN_D3) | ||||
|  | ||||
| typedef struct {	            // All bits are Read-Only | ||||
|   union { | ||||
|     ULONG AsDword; | ||||
|     struct { | ||||
|       ULONG CompatibilityID: 8; | ||||
|       ULONG NextItemPtr:     8; | ||||
|       ULONG Version:         3; | ||||
|       ULONG PME_Clock:       1; | ||||
|       ULONG Reserved:        1; | ||||
|       ULONG DSI:             1; | ||||
|       ULONG Aux_Current:     3; | ||||
|       ULONG D1_Support:      1; | ||||
|       ULONG D2_Support:      1; | ||||
|       ULONG PME_D0:          1; | ||||
|       ULONG PME_D1:          1; | ||||
|       ULONG PME_D2:          1; | ||||
|       ULONG PME_D3_Hot:      1; | ||||
|       ULONG PME_D3_Cold:     1; | ||||
|     }; | ||||
|   }; | ||||
| } PMC; | ||||
|  | ||||
| typedef struct { | ||||
|   union { | ||||
|     ULONG AsDword; | ||||
|     struct { | ||||
|       union { | ||||
|         USHORT AsWord; | ||||
|         struct { | ||||
|           USHORT PowerState:  2;  // Read-write | ||||
|           USHORT Reserved:    6;  // Read-only | ||||
|           USHORT PME_En:      1;  // Read-write | ||||
|           USHORT Data_Select: 4;  // Read-write | ||||
|           USHORT Data_Scale:  2;  // Read-only | ||||
|           USHORT PME_Status:  1;  // Read/Write-Clear | ||||
|         }; | ||||
|       }; | ||||
|       UCHAR PMCSR_BSE;            // Bridge Support Extensions | ||||
|       UCHAR Data; | ||||
|     }; | ||||
|   }; | ||||
| } PMCR; | ||||
| // R/W Mask = 1001_1111_0000_0011 | ||||
| #define PMCR_MASK           0x9F03 | ||||
|  | ||||
|  | ||||
|  | ||||
| // Fields in USBMSROHCB, USBMSREHCB, USBMSRUDCB, USBMSRUOCB: | ||||
| typedef struct { | ||||
|   union { | ||||
|     struct { | ||||
|       ULONG Reserved:  1; | ||||
|       ULONG MEMEN:     1; | ||||
|       ULONG BMEN:      1; | ||||
|       ULONG PMEEN:     1; | ||||
|       ULONG PMESTS:    1; | ||||
|     }; | ||||
|     struct { | ||||
|       UCHAR Enables; | ||||
|       // NOTE: the next 3 fields are actually 6 bits, but the compiler | ||||
|       //       generates crappy code if defined as such | ||||
|       UCHAR FLADJ; | ||||
|       UCHAR LEGSMIEN; | ||||
|       UCHAR LEGSMISTS; | ||||
|     }; | ||||
|   }; | ||||
| } USBMSR; | ||||
|  | ||||
|  | ||||
| // Fields in 32-MSBs of GLCP's PMCLKACTIVE, PMCLKOFF, PMCLKDISABLE, PMCLK4ACK, PMCLKDISABLE: | ||||
| typedef struct { | ||||
|   union { | ||||
|     ULONG AsDword; | ||||
|     struct { | ||||
|       ULONG GL0_0:           1; | ||||
|       ULONG GL0_1:           1; | ||||
|       ULONG GLPCI_GLIU:      1; | ||||
|       ULONG GLPCI_PCI:       1; | ||||
|       ULONG GLPCI_PCIF:      1; | ||||
|       ULONG RSVD:            6; | ||||
|       ULONG ATAC_GLIU:       1; | ||||
|       ULONG ATAC_LB:         1; | ||||
|       ULONG ACC_GLIU:        1; | ||||
|       ULONG ACC_LB:          1; | ||||
|       ULONG ACC_BIT:         1; | ||||
|       ULONG DIVIL_GLIU:      1; | ||||
|       ULONG DIVIL_LB:        1; | ||||
|       ULONG DIVIL_LPC:       1; | ||||
|       ULONG DIVIL_DMA:       1; | ||||
|       ULONG DIVIL_SMB:       1; | ||||
|       ULONG DIVIL_PIT:       1; | ||||
|       ULONG DIVIL_UART1:     1; | ||||
|       ULONG DIVIL_UART2:     1; | ||||
|       ULONG DIVIL_PMC:       1; | ||||
|       ULONG DIVIL_PMC_STD:   1; | ||||
|       ULONG DIVIL_GPIO:      1; | ||||
|       ULONG DIVIL_GPIO_STD:  1; | ||||
|       ULONG DIVIL_MFGPT_32K: 1; | ||||
|       ULONG DIVIL_MFGPT_14M: 1; | ||||
|       ULONG DIVIL_32K_STD:   1; | ||||
|       ULONG GLCP_GLIU:       1; | ||||
|     }; | ||||
|   }; | ||||
|   union { | ||||
|     ULONG AsDword_HI; | ||||
|     struct { | ||||
|       ULONG GLCP_DBG:        1; | ||||
|       ULONG GLCP_PCI:        1; | ||||
|       ULONG OHC_CLK48:       1; | ||||
|       ULONG UDC_HCLK:        1; | ||||
|       ULONG EHC_HCLK:        1; | ||||
|       ULONG OHC_HCLK:        1; | ||||
|       ULONG EHC_CLK60:       1; | ||||
|       ULONG UDC_CLK60:       1; | ||||
|       ULONG USBP1_CLK60:     1; | ||||
|       ULONG USBP2_CLK60:     1; | ||||
|       ULONG USBP3_CLK60:     1; | ||||
|       ULONG USBP4_CLK60:     1; | ||||
|       ULONG OTC_HCLK:        1; | ||||
|       ULONG USB_GLIU:        1;    // aka M2A_HCLK in USB 2.0 IDS | ||||
|       ULONG USBPHYPLLEN:     1; | ||||
|     }; | ||||
|   }; | ||||
| } GLCP_CLKS; | ||||
|  | ||||
| // Local variables: | ||||
| ULONG MsrAddr, MsrData[2]; | ||||
| USBMSR * UsbMsr = (USBMSR *)&MsrData[1]; | ||||
| GLCP_CLKS Clocks; | ||||
| USHORT D3_Flag = 0; | ||||
| ULONG EHCI_BAR; | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Returns TRUE if the specified EHCI port is suspended | ||||
| // NOTE: Port is 1-based | ||||
| //*********************************************************************** | ||||
| UCHAR pascal EHCI_Port_Suspended(UCHAR Port) | ||||
| { | ||||
|   if ((UCHAR)READ_MEMORY(EHCI_BAR + 0x50 + Port*4) & 0x80) { | ||||
|     return 1; | ||||
|   } else { | ||||
|     return 0; | ||||
|   } | ||||
| } | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Reads the MSR corresponding to the current USB 2.0 function | ||||
| //*********************************************************************** | ||||
| void Get_USB_MSR(void) | ||||
| { | ||||
|   MsrAddr = OHCI1_Smi; | ||||
|   (UCHAR)MsrAddr = (HdrPtr+BAR0/4)->LBar; | ||||
|  | ||||
|   // Get current MSR value  | ||||
|   Read_MSR(MsrAddr, MsrData); | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Returns value of the EHCI Power Management register USBLEGCTLSTS | ||||
| //*********************************************************************** | ||||
| ULONG pascal Handle_EHCI_Rd(PCI_HEADER_ENTRY * Pci) | ||||
| { | ||||
|  | ||||
|   // Filter out non-EHCI functions | ||||
|   if (((HdrPtr+REVISION_ID/4)->Value & 0xFFFFFF00) == 0x0C032000) { | ||||
|  | ||||
|     // Read USBMSREHCB MSR | ||||
|     Get_USB_MSR(); | ||||
|  | ||||
|     Pci->EHCI_Errors = (UCHAR)UsbMsr->LEGSMISTS; | ||||
|  | ||||
|     // Sync PCI register with MSR (optional): | ||||
|     Pci->EHCI_SMI_Enables = (UCHAR)UsbMsr->LEGSMIEN; | ||||
|  | ||||
|   } | ||||
|   return Pci->Value; | ||||
| } | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Handles writes to the EHCI PCI registers: | ||||
| // COMMAND | ||||
| // BAR0 | ||||
| // USBLEGSUP | ||||
| // USBLEGCTLSTS  | ||||
| // FLADJ | ||||
| //*********************************************************************** | ||||
| void pascal Handle_EHCI_Wr(PCI_HEADER_ENTRY * Pci) | ||||
| { ULONG SMI_Status = SMI_ON_COMMAND; | ||||
|  | ||||
|   // Read USBMSREHCB MSR | ||||
|   Get_USB_MSR(); | ||||
|  | ||||
|   switch (Pci->Reg & 0xFC) { | ||||
|     case BAR0: | ||||
|       EHCI_BAR = Pci->Value; | ||||
|       SMI_Status = SMI_ON_BAR; | ||||
|     case COMMAND: | ||||
|       if (End_of_POST) { | ||||
|         // Set USBLEGCTLSTS[31/30] | ||||
|         (HdrPtr+9)->Value |= SMI_Status; | ||||
|       } | ||||
|       return; | ||||
|  | ||||
|     case USBLEGSUP:		// EECP | ||||
|       // If ownership changing, set USBLEGCTLSTS[29] | ||||
|       if (Pci->Value & (OS_OWNED_SEMAPHORE | BIOS_OWNED_SEMAPHORE)) { | ||||
|         // Set USBLEGCTLSTS[29] | ||||
|         (Pci+1)->Value |= SMI_ON_OC; | ||||
|       } | ||||
|       // If system software is requesting ownership... | ||||
|       if (Pci->Value & OS_OWNED_SEMAPHORE) { | ||||
|         // Clear BIOS Owned	Semaphore | ||||
|         Pci->Value &= ~BIOS_OWNED_SEMAPHORE; | ||||
|         // Clear SMI enables | ||||
|         UsbMsr->LEGSMIEN = 0x00; | ||||
|       } | ||||
|       // If BIOS is requesting ownership... | ||||
|       if (Pci->Value & BIOS_OWNED_SEMAPHORE) { | ||||
|         // Clear system software Owned Semaphore | ||||
|         Pci->Value &= ~OS_OWNED_SEMAPHORE; | ||||
|       } | ||||
|       break; | ||||
|  | ||||
|     case USBLEGCTLSTS:  // EECP+4 | ||||
|       UsbMsr->LEGSMIEN = Pci->EHCI_SMI_Enables; | ||||
|       break; | ||||
|  | ||||
|     case SRBN_REG: | ||||
|       UsbMsr->FLADJ = Pci->FLADJ; | ||||
|       break; | ||||
|   } | ||||
|  | ||||
|   // Update USBMSREHCB | ||||
|   Write_MSR(MsrAddr, MsrData); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Handles reads from a PCI Power Management register | ||||
| // Returns value of PCI register | ||||
| //*********************************************************************** | ||||
| ULONG pascal Handle_PCI_PM_Rd(PCI_HEADER_ENTRY * Pci) | ||||
| { PMCR * PMCR_Ptr; | ||||
|  | ||||
|   // Get PME status from MSR | ||||
|   Get_USB_MSR(); | ||||
|  | ||||
|   // Cast register ptr | ||||
|   PMCR_Ptr = (PMCR *)&Pci->Value; | ||||
|   PMCR_Ptr->PME_Status = UsbMsr->PMESTS ? 1: 0;  | ||||
|  | ||||
|   return Pci->Value; | ||||
| } | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Handles writes to the PCI Power Management register | ||||
| //*********************************************************************** | ||||
| void pascal Handle_PCI_PM_Wr(PCI_HEADER_ENTRY * Pci, USHORT PreviousData) | ||||
| { PMCR Delta; | ||||
|   PMCR * PMCR_Ptr; | ||||
|   PMC * PMC_Ptr; | ||||
|   USHORT Value; | ||||
|  | ||||
|   // Cast register ptrs | ||||
|   PMCR_Ptr = (PMCR *)&Pci->Value; | ||||
|   PMC_Ptr  = (PMC *)&(Pci-1)->Value; | ||||
|  | ||||
|   Value = (USHORT)Pci->Value; | ||||
|  | ||||
|   // Mask read-only bits | ||||
|   Value &= PMCR_MASK; | ||||
|  | ||||
|  | ||||
|   // Compute changes | ||||
|   Delta.AsWord = (USHORT)PreviousData ^ PMCR_Ptr->AsWord; | ||||
|  | ||||
|  | ||||
|   // Select data to be reported through the Data register | ||||
|   // Return as "not implemented" | ||||
|   PMCR_Ptr->Data       = 0;  //Power[PMCR_Ptr->Data_Select].Data; | ||||
|   PMCR_Ptr->Data_Scale = 0;  //Power[PMCR_Ptr->Data_Select].Scale; | ||||
|  | ||||
|   Get_USB_MSR(); | ||||
|  | ||||
|   // PME# status write-to-clear | ||||
|   if (PMCR_Ptr->PME_Status) { | ||||
|     UsbMsr->PMESTS = 1; | ||||
|   } | ||||
|  | ||||
|   // PME# enable | ||||
|   if (Delta.PME_En) { | ||||
|     // Check if PME# is supported  | ||||
|     if (PMC_Ptr->PME_D3_Cold || PMC_Ptr->PME_D3_Hot ||  | ||||
|         PMC_Ptr->PME_D0      || PMC_Ptr->PME_D1     || PMC_Ptr->PME_D2) { | ||||
|       if (PMCR_Ptr->PME_En) { | ||||
|         // Enable PME# assertion | ||||
|         UsbMsr->PMEEN = 1; | ||||
|       } else { | ||||
|         // Disable PME# assertion | ||||
|         UsbMsr->PMEEN = 0; | ||||
|       } | ||||
|     } else { | ||||
|       // PME# not supported | ||||
|       PMCR_Ptr->PME_En = 0; | ||||
|     } | ||||
|   } | ||||
|   // Update USBMSRxxCB | ||||
|   Write_MSR(MsrAddr, MsrData); | ||||
|  | ||||
|   // Power state | ||||
|   if (Delta.PowerState) { | ||||
|     UCHAR SupportedState=0; | ||||
| 	ULONG ClocksMsr; | ||||
|     register USHORT USB_20_D3_Flag = D3_Flag; | ||||
|  | ||||
|     ClocksMsr = MCP_SB + MCP_PMCLKOFF; | ||||
|     Read_MSR(ClocksMsr, &Clocks.AsDword); | ||||
|  | ||||
|     switch (PMCR_Ptr->PowerState) { | ||||
|       case D0_STATE: | ||||
|         // If D0 is supported... | ||||
|         if (PMC_Ptr->PME_D0) { | ||||
|           switch (HdrPtr->Device_ID) { | ||||
|             case DEVICE_ID_AMD_OHCI: | ||||
|               Clocks.OHC_HCLK  = 0; | ||||
|               Clocks.OHC_CLK48 = 0; | ||||
|               USB_20_D3_Flag &= ~OHC_IN_D3; | ||||
|               break; | ||||
|  | ||||
|             case DEVICE_ID_AMD_EHCI: | ||||
|               Clocks.EHC_HCLK  = 0; | ||||
|               Clocks.EHC_CLK60 = 0; | ||||
|               Clocks.USBP1_CLK60 = 0; | ||||
|               Clocks.USBP2_CLK60 = 0; | ||||
|               Clocks.USBP3_CLK60 = 0; | ||||
|               Clocks.USBP4_CLK60 = 0; | ||||
|               Clocks.USBPHYPLLEN = 0; | ||||
|               USB_20_D3_Flag &= ~EHC_IN_D3; | ||||
|               break; | ||||
|  | ||||
|             case DEVICE_ID_AMD_UDC: | ||||
|               Clocks.UDC_HCLK  = 0; | ||||
|               Clocks.UDC_CLK60 = 0; | ||||
|               USB_20_D3_Flag &= ~UDC_IN_D3; | ||||
|               break; | ||||
|  | ||||
|             case DEVICE_ID_AMD_OTG: | ||||
|               Clocks.OTC_HCLK  = 0; | ||||
|               USB_20_D3_Flag &= ~UOC_IN_D3; | ||||
|               break; | ||||
|           } | ||||
|           SupportedState = 1; | ||||
|         } | ||||
|         break; | ||||
|  | ||||
|       case D1_STATE: | ||||
|       case D2_STATE: | ||||
|         // D1 & D2 are not supported | ||||
|         switch (HdrPtr->Device_ID) { | ||||
|           case DEVICE_ID_AMD_OHCI: | ||||
|             USB_20_D3_Flag &= ~OHC_IN_D3; | ||||
|             break; | ||||
|  | ||||
|           case DEVICE_ID_AMD_EHCI: | ||||
|             USB_20_D3_Flag &= ~EHC_IN_D3; | ||||
|             break; | ||||
|  | ||||
|           case DEVICE_ID_AMD_UDC: | ||||
|             USB_20_D3_Flag &= ~UDC_IN_D3; | ||||
|             break; | ||||
|  | ||||
|           case DEVICE_ID_AMD_OTG: | ||||
|             USB_20_D3_Flag &= ~UOC_IN_D3; | ||||
|             break; | ||||
|         } | ||||
|         break; | ||||
|  | ||||
|       case D3_STATE:   // D3hot | ||||
|         // If D3hot is supported... | ||||
|         if (PMC_Ptr->PME_D3_Hot) { | ||||
|           switch (HdrPtr->Device_ID) { | ||||
|             case DEVICE_ID_AMD_OHCI: | ||||
|               Clocks.OHC_HCLK  = 0; | ||||
|               Clocks.OHC_CLK48 = 0; | ||||
|               USB_20_D3_Flag |= OHC_IN_D3; | ||||
|               break; | ||||
|  | ||||
|             case DEVICE_ID_AMD_EHCI: | ||||
|               Clocks.EHC_HCLK  = 0; | ||||
|               Clocks.EHC_CLK60 = 0; | ||||
|               Clocks.USBP1_CLK60 = 0; | ||||
|               Clocks.USBP2_CLK60 = 0; | ||||
|               Clocks.USBP3_CLK60 = 0; | ||||
|               Clocks.USBP4_CLK60 = 0; | ||||
|               Clocks.USBPHYPLLEN = 1; | ||||
|  | ||||
|               // In D3 *only* USBPHYPLLEN should be gated (Phy Clock switched off). | ||||
|               // This guarantees max. power saving during S1 and proper USB Remote WakeUp functionality and Resume from S1 | ||||
|               // If all EHC ports are suspended USBPHYPLLEN should not be gated, because USBPHYPLL is switched off by Phy-HW  | ||||
|               if (EHCI_Port_Suspended(1) & EHCI_Port_Suspended(2) & EHCI_Port_Suspended(3) & EHCI_Port_Suspended(4)) { | ||||
|                 Clocks.USBPHYPLLEN = 0; | ||||
|               } | ||||
|               USB_20_D3_Flag |= EHC_IN_D3; | ||||
|               break; | ||||
|  | ||||
|             case DEVICE_ID_AMD_UDC: | ||||
|               USB_20_D3_Flag |= UDC_IN_D3; | ||||
|               break; | ||||
|  | ||||
|             case DEVICE_ID_AMD_OTG: | ||||
|               USB_20_D3_Flag |= UOC_IN_D3; | ||||
|               break; | ||||
|           } | ||||
|  | ||||
|           SupportedState = 1; | ||||
|         } | ||||
|         break; | ||||
|     } // end switch (PMCR_Ptr->PowerState) | ||||
|  | ||||
|     if (SupportedState) { | ||||
|       PCI_HEADER_ENTRY * Bar; | ||||
|       DESCRIPTOR * Descr; | ||||
|       ULONG MsrData[2]; | ||||
|       UCHAR Index; | ||||
|  | ||||
|       // If going to D3, turn off P2D_BM descriptor so accesses will master-abort. | ||||
|       // Otherwise, the system hangs when the device registers are accessed since | ||||
|       // the clocks have been turned off.  Restore the descriptor when going to D0. | ||||
|       Bar = HdrPtr+BAR0/4; | ||||
|       while ((Bar->Reg >= BAR0) && (Bar->Reg <= BAR5)) { | ||||
|         if (Bar->Flag & (MMIO_BAR | MEM_BAR)) { | ||||
|  | ||||
|           // For each linked item, update the associated MSR | ||||
|           // Get the P2D_BM descriptor linked to this BAR | ||||
|           Index = Bar->Link; | ||||
|           do { | ||||
|             Descr = &MSRs[Index]; | ||||
|             if (Descr->Type == P2D_BM || Descr->Type == P2D_BMK) { | ||||
|               if (PMCR_Ptr->PowerState == D3_STATE) { | ||||
|                 Get_Descriptor_Default(Descr->Type, MsrData); | ||||
|               } else { | ||||
|                 MsrData[0] = Descr->MsrData[0]; | ||||
|                 MsrData[1] = Descr->MsrData[1]; | ||||
|               } | ||||
|               Write_MSR(Descr->MsrAddr, MsrData); | ||||
|               break; | ||||
|             } | ||||
|           } while (Index = Descr->Link); | ||||
|         } | ||||
|         if (Pci->Flag & EOL) { | ||||
|           break; | ||||
|         } | ||||
|         Bar++; | ||||
|       } | ||||
|  | ||||
|  | ||||
|  | ||||
| // PBZ 2292 - Can't turn off USB_GLIU else MSR read of USB 2.0 hangs | ||||
| #if 0 | ||||
|       // Are all USB 2.0 functions are in D3? | ||||
|       if (USB_20_D3_Flag == ALL_IN_D3) { | ||||
|         // Yes, then turn off USB_GLIU | ||||
|         Clocks.USB_GLIU = 1; | ||||
|       } else { | ||||
|         Clocks.USB_GLIU = 0; | ||||
|       } | ||||
| #endif | ||||
|       // Update D3 state for each function | ||||
|       D3_Flag = USB_20_D3_Flag; | ||||
|       // Update clock settings | ||||
|       Write_MSR(ClocksMsr, &Clocks.AsDword); | ||||
|  | ||||
|     } else { | ||||
|       PMCR Previous; | ||||
|  | ||||
|       // PCI PM Specification (page 29; Table 7): | ||||
|       // Writes of an unsupported state should discard the data | ||||
|       Previous.AsWord = PreviousData; | ||||
|       PMCR_Ptr->PowerState = Previous.PowerState; | ||||
| 	} | ||||
|   } // end if (Delta.PowerState) | ||||
|  | ||||
|   // Record current value | ||||
|   Pci->Value = PMCR_Ptr->AsDword; | ||||
| } | ||||
|  | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										177
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/pci_rd.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										177
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/pci_rd.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,177 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //***************************************************************************** | ||||
| //*     Implements reads of virtualized PCI configuration headers | ||||
| //***************************************************************************** | ||||
|  | ||||
|  | ||||
| #include "VSA2.H" | ||||
| #include "PCI.H" | ||||
| #include "VPCI.H" | ||||
| #include "PROTOS.H" | ||||
| #include "SYSMGR.H" | ||||
| #include "CHIPSET.H" | ||||
|  | ||||
|  | ||||
| // External function declarations: | ||||
| ULONG pascal Get_Device_Status(PCI_HEADER_ENTRY *); | ||||
| ULONG pascal Handle_PCI_PM_Rd(PCI_HEADER_ENTRY *); | ||||
| ULONG pascal Handle_EHCI_Rd(PCI_HEADER_ENTRY *); | ||||
| ULONG pascal Read_MSR_LO(ULONG); | ||||
| UCHAR pascal Get_Latency(PCI_HEADER_ENTRY *); | ||||
| PCI_HEADER_ENTRY * pascal Get_Structure(USHORT); | ||||
| extern Hardware HardwareInfo; | ||||
|  | ||||
|  | ||||
|  | ||||
| // External variable declarations: | ||||
| extern DESCRIPTOR MSRs[]; | ||||
| extern UCHAR Shift, AlignedReg, Function; | ||||
| extern PCI_HEADER_ENTRY * CommandPtr; | ||||
| extern ULONG ATA_Error; | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Reads an embedded PCI register | ||||
| //*********************************************************************** | ||||
| ULONG pascal Read_EPCI(UCHAR AlignedReg) | ||||
| { ULONG MsrAddr; | ||||
|  | ||||
|   MsrAddr = MSRs[CommandPtr->Link].MsrAddr; | ||||
|   if (MsrAddr) {   | ||||
|     (UCHAR)MsrAddr = AlignedReg/4; | ||||
|     return Read_MSR_LO(MsrAddr); | ||||
|   } else { | ||||
|     return 0;   | ||||
|   }   | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // | ||||
| // This routine implements reads to virtualized configuration space. | ||||
| // | ||||
| // NOTES: | ||||
| // 1) Misaligned accesses are handled.  If an access crosses a DWORD  | ||||
| //    boundary, only the bytes within the addressed DWORD are read. | ||||
| //    The remaining bytes return FFs. | ||||
| // 2) The variable Pci points to a PCI_HEADER_ENTRY entry that defines | ||||
| //    the state and characteristics of the register being read. | ||||
| //*********************************************************************** | ||||
| ULONG pascal Virtual_PCI_Read_Handler(USHORT PCI_Address) | ||||
| { ULONG Data; | ||||
|   register PCI_HEADER_ENTRY * Pci; | ||||
|  | ||||
|  | ||||
|   // Get ptr to virtualized table entry | ||||
|   Pci = Get_Structure(PCI_Address); | ||||
|  | ||||
|  | ||||
|   switch ((USHORT)Pci) { | ||||
|  | ||||
|     case UNIMPLEMENTED_FUNCTION: | ||||
|       Data = 0xFFFFFFFF; | ||||
|       break; | ||||
|  | ||||
|     case UNIMPLEMENTED_REGISTER: | ||||
|       Data = 0x00000000; | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       // Handle special cases | ||||
|       if (Pci->Flag & EPCI_R && AlignedReg < 0x40) { | ||||
|  | ||||
|         // Embedded PCI device: read its h/w PCI configuration space | ||||
|         Data = Read_EPCI(AlignedReg); | ||||
|  | ||||
|         if (AlignedReg == COMMAND) { | ||||
|           // Mark device '66 MHz capable' | ||||
|           Data |= PCI_66MHZ_CAPABLE; | ||||
|         } | ||||
|         break;     | ||||
|       } | ||||
|  | ||||
|       Data = Pci->Value; | ||||
|  | ||||
|       switch (AlignedReg) { | ||||
|  | ||||
|         case COMMAND: | ||||
|           // Get device's Status | ||||
|           Data |= Get_Device_Status(Pci); | ||||
|           break; | ||||
|  | ||||
|         case BAR0: | ||||
|         case BAR1: | ||||
|         case BAR2: | ||||
|         case BAR3: | ||||
|         case BAR4: | ||||
|         case BAR5: | ||||
|           // If I/O BAR, set bit 0 | ||||
|           if (Pci->Flag & IO_BAR) { | ||||
|             Data |= 1; | ||||
|           } | ||||
|           break; | ||||
|  | ||||
|         case CACHE_LINE: | ||||
|           Pci->LatencyTimer = Get_Latency(Pci); | ||||
|           Data = Pci->Value; | ||||
|           break; | ||||
|  | ||||
| #if SUPPORT_CAPABILITIES | ||||
|         case (PCI_PM_REG+4):  // 0x44 | ||||
|           if (Pci->Flag & PCI_PM) { | ||||
|             Data = Handle_PCI_PM_Rd(Pci); | ||||
|             break; | ||||
|           } | ||||
|  | ||||
|         case USBLEGCTLSTS: | ||||
|           if (Pci->Flag & PCI_EHCI) { | ||||
|             Data = Handle_EHCI_Rd(Pci); | ||||
|             break; | ||||
|           } | ||||
| #endif | ||||
|  | ||||
|         // Thor ATA vendor-specific registers: | ||||
|         case IDE_CFG:   // 0x40 | ||||
|         case IDE_DTC:	// 0x48 | ||||
|         case IDE_CAST:  // 0x4C | ||||
|         case IDE_ETC:   // 0x50 | ||||
|           if (Pci->LBar) { | ||||
|             ULONG MsrAddr = ATA_Error; | ||||
|  | ||||
|             (USHORT)MsrAddr = (USHORT)Pci->LBar; | ||||
|             Data = Read_MSR_LO(MsrAddr); | ||||
|           } | ||||
|           break; | ||||
|  | ||||
|       } | ||||
|   } | ||||
|  | ||||
|  | ||||
|   // Handle non-dword aligned accesses | ||||
|   Data >>= Shift; | ||||
|   Data  |= 0xFFFFFFFFL << (32-Shift); | ||||
|  | ||||
|   return Data; | ||||
| }    | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										375
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/pci_wr.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										375
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/pci_wr.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,375 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //***************************************************************************** | ||||
| //*     Implements writes of virtualized PCI configuration headers | ||||
| //***************************************************************************** | ||||
|  | ||||
|  | ||||
| #include "VSA2.H" | ||||
| #include "PCI.H" | ||||
| #include "GX2.H" | ||||
| #include "VPCI.H" | ||||
| #include "SYSMGR.H" | ||||
| #include "CHIPSET.H" | ||||
| #include "PROTOS.H" | ||||
| #include "MAPPER.H" | ||||
|  | ||||
|  | ||||
| // External function declarations: | ||||
| PCI_HEADER_ENTRY * pascal Get_Structure(USHORT); | ||||
| UCHAR pascal Update_BusMaster(PCI_HEADER_ENTRY *, UCHAR); | ||||
| void pascal Set_Latency(UCHAR); | ||||
| void pascal Clear_MBus_Error(PCI_HEADER_ENTRY *, ULONG); | ||||
| void pascal SMINT_Handler(USHORT); | ||||
| void pascal PCI_Interrupt_Steering(USHORT); | ||||
| void pascal Handle_EHCI_Wr(PCI_HEADER_ENTRY *); | ||||
| void pascal Handle_PCI_PM_Wr(PCI_HEADER_ENTRY *, USHORT); | ||||
| void pascal Update_Special_Cycles(USHORT); | ||||
| void Deallocate_Descriptor(DESCRIPTOR *); | ||||
|  | ||||
| // External variable declarations: | ||||
| extern DESCRIPTOR MSRs[]; | ||||
| extern ULONG ATA_Error; | ||||
| extern UCHAR Shift, AlignedReg, Function; | ||||
| extern PCI_HEADER_ENTRY * CommandPtr; | ||||
| extern PCI_HEADER_ENTRY * HdrPtr; | ||||
| extern VIRTUAL_DEVICE * IDSELs; | ||||
| extern Hardware HardwareInfo; | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Writes an embedded PCI register | ||||
| //*********************************************************************** | ||||
| void pascal Write_EPCI(UCHAR AlignedReg, ULONG Data) | ||||
| { ULONG MsrAddr; | ||||
|  | ||||
|   MsrAddr = MSRs[CommandPtr->Link].MsrAddr; | ||||
|   if (MsrAddr) { | ||||
|     (UCHAR)MsrAddr = AlignedReg/4; | ||||
|     Write_MSR_LO(MsrAddr, Data); | ||||
|   }	  | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // | ||||
| // Handle changes to the COMMAND register | ||||
| // | ||||
| //*********************************************************************** | ||||
| void pascal Update_Command(USHORT PreviousValue, USHORT NewValue) | ||||
| { UCHAR Changes, EnableFlag; | ||||
|   register PCI_HEADER_ENTRY * Pci; | ||||
|   ULONG OldValue; | ||||
|    | ||||
|   Changes = (UCHAR)(PreviousValue ^ NewValue); | ||||
|  | ||||
|   // | ||||
|   // Handle changes to Special Cycles | ||||
|   // | ||||
|   if (Changes & SPECIAL_CYCLES) { | ||||
|     Update_Special_Cycles((UCHAR)NewValue & SPECIAL_CYCLES); | ||||
|   } | ||||
|  | ||||
|  | ||||
|   // | ||||
|   // Handle changes to bus master & address space enables | ||||
|   // | ||||
|   if (Changes & (IO_SPACE | MEM_SPACE | BUS_MASTER)) { | ||||
|  | ||||
|     Pci = CommandPtr + 2; | ||||
|  | ||||
|     // Walk through BAR entries & enable/disable corresponding descriptors/LBARs | ||||
|     do { | ||||
|  | ||||
|       // Advance ptr to next implemented register | ||||
|       Pci++; | ||||
|  | ||||
|       // Only concerned with allocated BARs | ||||
|       if (Pci->Flag & (MMIO_BAR | MEM_BAR | IO_BAR)) { | ||||
|  | ||||
|         // Only write descriptors for BARs that have had resources allocated | ||||
|         // and have a non-zero value. | ||||
|         if ((Pci->Link) && Pci->Value) { | ||||
|  | ||||
|           // Check correct Command bit according to BAR type | ||||
|           EnableFlag = (Pci->Flag & IO_BAR) ? IO_SPACE : MEM_SPACE; | ||||
|  | ||||
|           // Handle changes to address space enable | ||||
|           if (Changes & EnableFlag) { | ||||
|             EnableFlag &= (UCHAR)NewValue; | ||||
|  | ||||
|             // Update the descriptor(s) | ||||
|             OldValue = Pci->Value; | ||||
|             Update_BAR(Pci, EnableFlag); | ||||
|             Pci->Value = OldValue; | ||||
|           } | ||||
|  | ||||
|  | ||||
|           // | ||||
|           // Handle changes to bus master enable | ||||
|           // | ||||
|           if (Changes & BUS_MASTER) { | ||||
|             EnableFlag = (UCHAR)NewValue & BUS_MASTER; | ||||
|             if (Update_BusMaster(Pci, EnableFlag)) { | ||||
|               // Early-out (e.g. bridge) | ||||
|               Changes &= ~BUS_MASTER; | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|  | ||||
|     } while (!(Pci->Flag & EOL)); | ||||
|   } | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // | ||||
| // This routine implements writes to virtualized configuration space. | ||||
| // | ||||
| // NOTES: | ||||
| // 1) Misaligned accesses are handled.  If an access crosses a DWORD  | ||||
| //    boundary, only the bytes within the addressed DWORD are written. | ||||
| // 2) The variable Pci points to a PCI_HEADER_ENTRY entry that defines | ||||
| //    the state and behavior of the accessed register. | ||||
| // | ||||
| //*********************************************************************** | ||||
| ULONG pascal Virtual_PCI_Write_Handler(USHORT PCI_Address, UCHAR Size, ULONG NewData) | ||||
| { UCHAR EnableFlag; | ||||
|   ULONG Mask, Data, PreviousData; | ||||
|   register PCI_HEADER_ENTRY * Pci; | ||||
|  | ||||
|  | ||||
|   // Get ptr to virtualized table entry | ||||
|   Pci = Get_Structure(PCI_Address); | ||||
|  | ||||
|   // Unimplemented function ? | ||||
|   if ((USHORT)Pci == UNIMPLEMENTED_FUNCTION) { | ||||
|     return NewData; | ||||
|   } | ||||
|  | ||||
|   // Unimplemented register ? | ||||
|   if ((USHORT)Pci == UNIMPLEMENTED_REGISTER) { | ||||
|     // Removing an entire PCI function ? | ||||
|     if (AlignedReg == 0x7C && NewData == 0xDEADBEEF) { | ||||
|       UCHAR i, Link; | ||||
|       DESCRIPTOR * Descr; | ||||
|  | ||||
|  | ||||
| #if SUPPORT_CAPABILITIES | ||||
|       Pci = HdrPtr + BAR0/4; | ||||
|       do { | ||||
|         Pci++; | ||||
|         // If this device is PCI PM-aware... | ||||
|         if (Pci->Flag & PCI_PM) { | ||||
|           // then set device to D3 | ||||
|           (UCHAR)PCI_Address = 0x44; | ||||
|           Virtual_PCI_Write_Handler(PCI_Address, BYTE_IO, 0x03); | ||||
|           break; | ||||
|         } | ||||
|       } while (!(Pci->Flag & EOL)); | ||||
| #endif | ||||
|       // Make function unimplemented | ||||
|       IDSELs[Function] = 0x0000; | ||||
|  | ||||
|       // Walk through all BARs and deallocate associated MSRs | ||||
|       Pci = HdrPtr + BAR0/4; | ||||
|       if (Pci->Reg != BAR0) { | ||||
|         return NewData; | ||||
|       } | ||||
|  | ||||
|       for (i = BAR0; i <= BAR5; i += 4) { | ||||
|         if (Pci->Flag & (MMIO_BAR | MEM_BAR | IO_BAR)) { | ||||
|           Link = Pci->Link; | ||||
|  | ||||
|           // For each linked item, update the associated MSR | ||||
|           while (Link) { | ||||
|             Descr = &MSRs[Link]; | ||||
|  | ||||
|             // Get link to next MSR | ||||
|             Link = Descr->Link; | ||||
|  | ||||
|             // Deallocate the descriptor & set MSR to default value | ||||
|             Deallocate_Descriptor(Descr); | ||||
|           } | ||||
|         } | ||||
|         if (Pci->Flag & EOL) { | ||||
|           break; | ||||
|         } | ||||
|         Pci++; | ||||
|       } | ||||
|     } | ||||
|     return NewData; | ||||
|   } | ||||
|  | ||||
|   // Save a copy of original value | ||||
|   PreviousData = Pci->Value; | ||||
|  | ||||
|   // | ||||
|   // Generate mask to preserve read-only fields | ||||
|   // | ||||
|   switch (Size) { | ||||
|  | ||||
|     case BYTE_IO: | ||||
|       Mask = 0x000000FF; | ||||
|       break; | ||||
|  | ||||
|     case WORD_IO: | ||||
|       Mask = 0x0000FFFF; | ||||
|       break; | ||||
|  | ||||
|     case DWORD_IO: | ||||
|       Mask = 0xFFFFFFFF; | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       Mask = 0x00000000; | ||||
|       break; | ||||
|   } | ||||
|   Mask = Pci->Mask & (Mask << Shift); | ||||
|  | ||||
|  | ||||
|   // | ||||
|   // Compute new register value | ||||
|   // - preserves R/O fields | ||||
|   // - handles misaligned accesses | ||||
|   // - handles accesses smaller than dword | ||||
|   // | ||||
|   NewData <<= Shift; | ||||
|   Data = (NewData & Mask) | (PreviousData & ~Mask); | ||||
|  | ||||
|  | ||||
|   // | ||||
|   // Record the new register value | ||||
|   // | ||||
|   Pci->Value = Data; | ||||
|  | ||||
|  | ||||
|   // Handle Write-to-Clear bits | ||||
|   if (NewData & Pci->WriteToClear) { | ||||
|     Pci->Value &= ~(NewData & Pci->WriteToClear); | ||||
|   } | ||||
|  | ||||
|  | ||||
|   // | ||||
|   // Update the MBus hardware | ||||
|   // | ||||
|   switch (AlignedReg) { | ||||
|  | ||||
|     case COMMAND: | ||||
|  | ||||
|       // Handle writes to Command register | ||||
|       if ((USHORT)PreviousData != (USHORT)Data) { | ||||
|         // If the Command register has changed, update the h/w | ||||
|         Update_Command((USHORT)PreviousData, (USHORT)Data); | ||||
|       } | ||||
|  | ||||
|       // Handle writes to Status[15:11] (write-to-clear); | ||||
|       if (NewData &= Pci->WriteToClear) { | ||||
|         // Clear status bits in device's MSR | ||||
|         Clear_MBus_Error(Pci, NewData); | ||||
|       } | ||||
|  | ||||
|       // Handle SMI on EHCI COMMAND write | ||||
|       if (Pci->Flag & PCI_EHCI) { | ||||
|         Handle_EHCI_Wr(Pci); | ||||
|         break; | ||||
|       } | ||||
|       break; | ||||
|  | ||||
|     case CACHE_LINE: | ||||
|       // PCI Spec: if an unsupported Cache Line value is written, treat as 0x00 | ||||
|       if ((UCHAR)Data ^ (UCHAR)Pci->Mask) { | ||||
|         Pci->CacheLineSize = 0x00; | ||||
|       } | ||||
|       Set_Latency((UCHAR)(Data >> 8)); | ||||
|       break; | ||||
|  | ||||
|  | ||||
|  | ||||
|     // Emulation of CS5530 software SMI mechanism | ||||
|     case SW_SMI:  // 0xD0 | ||||
|       SMINT_Handler((USHORT)Data); | ||||
|       break; | ||||
|  | ||||
|     case (PCI_PM_REG+4): // 0x44 | ||||
| #if SUPPORT_CAPABILITIES | ||||
|       if (Pci->Flag & PCI_PM) { | ||||
|         Handle_PCI_PM_Wr(Pci, (USHORT)PreviousData); | ||||
|         break; | ||||
|       } | ||||
| #endif | ||||
|     case IDE_CFG: | ||||
|         // Don't write IDE_CFG if this is a IDE-to-Flash switch | ||||
|         if (NewData == 0xDEADBEEF && Pci->LBar) { | ||||
|           return NewData; | ||||
|         } | ||||
|     case IDE_DTC:	// 0x48 | ||||
|     case IDE_CAST:  // 0x4C | ||||
|     case IDE_ETC:   // 0x50 | ||||
|       // Thor ATA vendor-specific registers: | ||||
|       if (Pci->LBar) { | ||||
|         ULONG MsrAddr = ATA_Error; | ||||
|  | ||||
|         (USHORT)MsrAddr = (USHORT)Pci->LBar; | ||||
|  | ||||
|         // Sync with the current MSR value | ||||
|         PreviousData = Read_MSR_LO(MsrAddr); | ||||
|  | ||||
|         // Update Thor ATA MSR with the new value | ||||
|         Pci->Value = (NewData & Mask) | (PreviousData & ~Mask); | ||||
|         Write_MSR_LO(MsrAddr, Pci->Value); | ||||
|         break; | ||||
|       } | ||||
|  | ||||
|  | ||||
| #if SUPPORT_CAPABILITIES | ||||
|     case BAR0: | ||||
|     case USBLEGCTLSTS: | ||||
|     case SRBN_REG: | ||||
|       if (Pci->Flag & PCI_EHCI) { | ||||
|         Handle_EHCI_Wr(Pci); | ||||
|       } | ||||
| #endif | ||||
|  | ||||
|  | ||||
|     default: | ||||
|       // Is it a BAR ? | ||||
|       if (Pci->Flag & (MMIO_BAR | MEM_BAR | IO_BAR)) { | ||||
|         // If value has changed, update the MBus descriptor | ||||
|         if (PreviousData != Data) { | ||||
|           // I/O BAR and Memory BAR ? | ||||
|           EnableFlag  = (Pci->Flag & IO_BAR) ? IO_SPACE : MEM_SPACE; | ||||
|           EnableFlag &= (UCHAR)CommandPtr->Value; | ||||
|           Update_BAR(Pci, EnableFlag); | ||||
|         } | ||||
|       } | ||||
|       break; | ||||
|  | ||||
|   } // end switch(AlignedReg) | ||||
|  | ||||
|   return Pci->Value; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										387
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/port92.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										387
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/port92.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,387 @@ | ||||
| ;  | ||||
| ; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| ;  | ||||
| ; This library is free software; you can redistribute it and/or modify | ||||
| ; it under the terms of the GNU Lesser General Public License as | ||||
| ; published by the Free Software Foundation; either version 2.1 of the | ||||
| ; License, or (at your option) any later version. | ||||
| ;  | ||||
| ; This code is distributed in the hope that it will be useful, | ||||
| ; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| ; Lesser General Public License for more details. | ||||
| ;  | ||||
| ; You should have received a copy of the GNU Lesser General | ||||
| ; Public License along with this library; if not, write to the | ||||
| ; Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| ; Boston, MA 02111-1307 USA  | ||||
| ;  | ||||
|  | ||||
| ;******************************************************************************* | ||||
| ;*     Port 92h routines   | ||||
| ;******************************************************************************* | ||||
|  | ||||
|  | ||||
| include SYSMGR.INC | ||||
| include VSA2.INC | ||||
| include GX2.INC | ||||
| include CHIPSET.INC | ||||
| include CS5536.INC | ||||
| include ISA.INC | ||||
| include PCI.INC | ||||
| include MDD.INC | ||||
| include HCE.INC | ||||
| include SMIMAC.MAC | ||||
|  | ||||
| .model tiny,c | ||||
| .586p | ||||
| .CODE | ||||
|    | ||||
|  | ||||
| externdef VSA_Exit:        proc | ||||
| externdef MDD_Base:        dword | ||||
| externdef FooGlue:         dword | ||||
| externdef OHCI1_Smi:       dword | ||||
| externdef OHCI2_Smi:       dword | ||||
| externdef Nested_Flag:     dword | ||||
| externdef Saved_EAX:       dword | ||||
| externdef Saved_EBX:       dword | ||||
| externdef Saved_ECX:       dword | ||||
| externdef Saved_EDX:       dword | ||||
| externdef Saved_ESI:       dword | ||||
| externdef Saved_EDI:       dword | ||||
| externdef Saved_EBP:       dword | ||||
| externdef Saved_ESP:       dword | ||||
| externdef IDT_Base:        dword | ||||
| externdef IDT_Limit:       dword | ||||
| externdef IDT_Selector:    dword | ||||
| externdef SMI_Sources:     dword | ||||
| externdef SMM_Header:      SmiHeader | ||||
| externdef Saved_SS:        Descriptor | ||||
| externdef Data_Descriptor: Descriptor | ||||
| externdef HardwareInfo:    Hardware | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; | ||||
| ; A20_Sync - synchronize port 92h and virtual A20 pin | ||||
| ; | ||||
| ;*********************************************************************** | ||||
| A20_Sync proc uses si edi | ||||
|  | ||||
| 	; Determine if it is a nested access to port 92h | ||||
| 	btr	word ptr [Nested_Flag], SMI_SRC_A20_INDEX | ||||
| 	jc	short Get_A20_Data        | ||||
| 	rsdc	gs, cs:[Data_Descriptor] | ||||
| Get_A20_Data: | ||||
| 	ASSUME	SI: ptr SmiHeader | ||||
| 	mov     si, OFFSET VSM_Header.SysStuff.State | ||||
| 	mov	bl, byte ptr gs:[si].write_data ; Get I/O data | ||||
| 	mov	si, gs:[si].IO_addr	; Get I/O address | ||||
| 	ASSUME  SI:NOTHING | ||||
| 	 | ||||
| 	; Set A20M in FooGlue appropriately | ||||
| 	mov	ecx, [FooGlue] | ||||
| 	add	cx, FG_A20M | ||||
| 	rdmsr | ||||
| 	and	al, NOT A20M		; A20M = 0 | ||||
| 	 | ||||
| 	and     bl, 02h                 ; Check A20M setting | ||||
| 	jnz     short Set_A20 | ||||
| 	or      al, A20M	        ; Force A20 low | ||||
| Set_A20: | ||||
|  	wrmsr | ||||
|  | ||||
| 	cmp	si, 0092h		; If port 92h, no update necessary | ||||
| 	je	short SyncHceControl | ||||
|  | ||||
| 	cmp	si, KYBD_DATA		; If not 8042 data port, ignore | ||||
| 	jne	Return | ||||
|  | ||||
| 	; Sync Port 92h to keyboard controller | ||||
| 	mov	ecx, [MDD_Base]		; Disable Port 92h trapping | ||||
| 	mov	cx, MBD_MSR_SMI | ||||
| 	rdmsr | ||||
| 	push	ax | ||||
| 	and	al, NOT A20_P_EN | ||||
| 	wrmsr | ||||
| 	 | ||||
| 	mov	al, bl			; Update Port 92h A20 state | ||||
| 	out	92h, al  | ||||
|  | ||||
| 	pop	ax			; Restore Port 92h trapping | ||||
| 	wrmsr | ||||
|  | ||||
| 	; Synchronize HceControl[A20State] with port 92h | ||||
| SyncHceControl:        | ||||
| 	mov     ecx, [OHCI1_Smi]	; Read OHCI1 h/w BAR0 | ||||
| 	test	ecx, 0FFF00000h | ||||
| 	jnz	short Get_HC_Base | ||||
| 	mov     ecx, [OHCI2_Smi]	; Use OHCI2 if OHCI1 not used | ||||
| 	test	ecx, 0FFF00000h | ||||
| 	jz	Return | ||||
| Get_HC_Base: | ||||
| 	mov     cx, 1000h + BAR0/4	; 5536 Embedded PCI MSR | ||||
| 	cmp	[HardwareInfo].Chipset_ID, DEVICE_ID_5536 | ||||
| 	je	short ReadBAR | ||||
| 	mov	cx, USBMSROHCB		; 5536 OHCI MSR | ||||
| ReadBAR: | ||||
| 	rdmsr | ||||
|  | ||||
| 	mov	bh, 0			; Clear MSR restore flag | ||||
| 	or      eax, eax		; Is BAR initialized ? | ||||
| 	jnz	short SyncA20State | ||||
| 	mov	bh, 1			; Set MSR restore flag | ||||
|  | ||||
| 	push	eax			; Save current OHCI MSR | ||||
| 	push	edx | ||||
| 	push	ecx | ||||
|  | ||||
| 	; OHCI BAR is not initialized or OHCI header is hidden. | ||||
| 	; Temporarily map the OHCI register set just above VSA | ||||
| 	; This range has been declared as OS-reserved in INT 15h E820h | ||||
| 	mov	ecx, MSR_RCONF_SMM | ||||
| 	rdmsr | ||||
| 	lea	edi, [edx+1000h] | ||||
| 	pop	ecx | ||||
| 	push	ecx | ||||
|  | ||||
| 	mov	edx, 00000000Eh | ||||
| 	mov	eax, edi | ||||
| 	wrmsr | ||||
|  | ||||
| 	mov	ecx, [MDD_Base] | ||||
| 	mov	cx, MSR_LBAR_KEL1 | ||||
| 	rdmsr | ||||
| 	push	eax			; Save current KEL LBAR | ||||
| 	push	edx | ||||
| 	push	ecx | ||||
| 	mov	eax, edi | ||||
| 	mov	edx, 0FFFFF001h | ||||
| 	wrmsr | ||||
|  | ||||
| 	; Synchronize HceControl.A20State | ||||
| SyncA20State: | ||||
| 	or      ax, OFFSET (HCOR Ptr ds:[0]).HceControl | ||||
| 	mov     dx, fs:[eax] | ||||
| 	cmp     dx, 0FFFFh		; Is Memory Space enabled ? | ||||
| 	je	short Exit | ||||
| CLEAR_A20	equ	(A20_STATE OR IRQ1_ACTIVE OR IRQ12_ACTIVE) | ||||
| 	; SWAPSiF for SiBZ 3509/3571: KEL SMIs are level instead of edge-triggered | ||||
| 	; Manifests itself as PBZ 3878: PS/2 keyboard hangs after running PCIDIAG | ||||
| 	test	dx, (IRQ1_ACTIVE OR IRQ12_ACTIVE) | ||||
| 	jz	short NoIRQ | ||||
| 	or	[SMI_Sources], SMI_SRC_KEL	; Fake another KEL SMI | ||||
| NoIRQ: | ||||
| 	and     dx, NOT CLEAR_A20	; Clear A20State | ||||
| 	test    bl, 02h | ||||
| 	jz      Update_HceControl | ||||
| 	or      dx, A20_STATE		; Set A20State | ||||
| Update_HceControl: | ||||
| 	mov     fs:[eax], dx | ||||
|  | ||||
| Exit: | ||||
| 	or	bh, bh			; Do OHCI MSRs need to be restored? | ||||
| 	je	short Return | ||||
|  | ||||
| 	pop	ecx			; Restore KEL LBAR | ||||
| 	pop	edx | ||||
| 	pop	eax | ||||
| 	wrmsr | ||||
|  | ||||
| 	pop	ecx			; Restore OHCI MSR | ||||
| 	pop	edx | ||||
| 	pop	eax | ||||
| 	wrmsr | ||||
| Return: | ||||
| 	ret | ||||
|  | ||||
| A20_Sync endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Sets the top-level RSM state to the reset state: | ||||
| ;  1) Real-mode IDT | ||||
| ;  2) Real-mode descriptors; segment regisers = 0000 | ||||
| ;  3) CS:EIP = F000:FFF0 | ||||
| ;  4) CS base = FFFF0000 | ||||
| ;  5) CS limit = 64K | ||||
| ;  6) DX = CPU ID | ||||
| ;*********************************************************************** | ||||
| set_reset_state proc   uses si | ||||
|  | ||||
| 	; Check if user code is doing a 286-style shutdown | ||||
| 	in      al, CMOS_INDEX			; Preserve CMOS index | ||||
| 	mov     ah, al | ||||
|  | ||||
| 	mov     al, 0Fh | ||||
| 	out     CMOS_INDEX, al | ||||
| 	in      al, CMOS_DATA | ||||
|  | ||||
| 	xchg    al, ah | ||||
| 	out     CMOS_INDEX, al			; Restore CMOS index | ||||
|  | ||||
| 	cmp     ah, 09H | ||||
| 	je      UserShutdown | ||||
|  | ||||
| 	cmp     ah, 05H | ||||
| 	je      UserShutdown | ||||
|  | ||||
| 	cmp     ah, 0AH | ||||
| 	je      UserShutdown | ||||
|  | ||||
| 	cmp     ah, 0FFH			; JMP if no CMOS present | ||||
| 	je      UserShutdown | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| CACHE_LINE_SIZE	equ	32 | ||||
|  | ||||
| 	; If cache is disabled, there is no way to guarantee that | ||||
| 	; the entire code sequence from DisableCKE to Pre_Fetch | ||||
| 	; will be fetched before CKE is disabled.  It was decided | ||||
| 	; we'd rather see the original POST 0xBF hang rather than | ||||
| 	; a hang in SMM. | ||||
| 	mov	ebp, [MDD_Base]			; Prepare reset MSR | ||||
| 	mov	bp, MSR_SOFT_RESET | ||||
| 	mov	eax, CR0			; Is cache disabled ? | ||||
| 	test	eax, 40000000h | ||||
| 	jnz	Reset | ||||
|  | ||||
| 	lea	si, [DisableCKE]		; Move code to start of a cache line | ||||
| 	mov	di, si | ||||
| 	and	di, NOT (CACHE_LINE_SIZE-1) | ||||
| 	mov	bx, di				; Remember where we moved it to | ||||
| 	cld | ||||
| @@:	lodsd | ||||
| 	mov	[di], eax | ||||
| 	add	di, 4 | ||||
| 	cmp	si, OFFSET Pre_Fetch | ||||
| 	jb	@b | ||||
| 	 | ||||
| 	mov	ecx, 2000001Dh			; Memory controller | ||||
| 	rdmsr | ||||
| 	or	ah, 3				; Set CKE Mask = 11b | ||||
|  | ||||
| 	jmp	Pre_Fetch | ||||
|  | ||||
|  | ||||
|  | ||||
| 	; Bug #118.226 - Some DIMMs hang at POST 0xBF on a reboot | ||||
| 	; | ||||
| 	; Need to de-assert CKE off before command signals are tri-stated. | ||||
| 	; There can be no memory accesses after the following WRMSR. | ||||
| 	; If cache is disabled, there is no way to satisfy this condition, | ||||
| 	; so some DIMMs with cache disabled is not supported with | ||||
| 	; respect to resets. | ||||
| 	db	CACHE_LINE_SIZE dup (90h) | ||||
| DisableCKE: | ||||
| 	wrmsr | ||||
|  | ||||
| 	; Reset the CPU via MDD MSR_SOFT_RESET | ||||
| Reset:	mov	ecx, ebp | ||||
| 	mov	al, 1 | ||||
| 	wrmsr | ||||
| 	jmp	$ | ||||
| Pre_Fetch: | ||||
| 	; Prefetch 4 cache lines of NOPs so there won't be any | ||||
| 	; prefetching to memory after the MC MSR is written. | ||||
| 	db	4*CACHE_LINE_SIZE dup (90h)	; 4 cache lines | ||||
| 	jmp	bx | ||||
|  | ||||
| UserShutdown: | ||||
|  | ||||
| 	mov	ecx, [FooGlue]			; Disable A20 mask | ||||
| 	add	cx, FG_A20M | ||||
| 	rdmsr | ||||
| 	and	al, NOT A20M			; A20M = 0 | ||||
| 	wrmsr | ||||
|  | ||||
| 	; Disable the cache & flush it | ||||
| 	mov     eax, CR0 | ||||
| 	or      eax, 60000000h | ||||
| 	mov     CR0, eax | ||||
| 	wbinvd | ||||
|  | ||||
| 	; Set real-mode IDT | ||||
| 	mov     [IDT_Limit], 0FFFFh		; Limit | ||||
| 	mov     [IDT_Base], 00000000h		; Base | ||||
| 	mov     [IDT_Selector], 00920000h	; Selector & Attributes | ||||
|  | ||||
|  | ||||
| 	; INIT is broken on LX 2.x and 3.0 | ||||
| 	cmp     [HardwareInfo].CPU_ID, DEVICE_ID_LX | ||||
| 	jne     short Set_INIT | ||||
| 	mov     ax, [HardwareInfo].CPU_Revision | ||||
| 	cmp     al, 30h				; Is it 3.0? | ||||
| 	jae     short FakeInit | ||||
| 	and     al, 0F0h			; Is it 2.x? | ||||
| 	cmp     al, 20h | ||||
| 	je      short FakeInit | ||||
|  | ||||
| 	call	VSA_Exit | ||||
|  | ||||
| 	; Reset via INIT MSR | ||||
| Set_INIT: | ||||
| 	mov     ecx, [FooGlue]			; Reset the CPU | ||||
| 	add	cx, FG_INIT | ||||
| 	xor	eax, eax | ||||
| 	wrmsr | ||||
| 	mov	al, INIT | ||||
| 	wrmsr | ||||
|  | ||||
| 	; Fake an INIT by setting up initial CPU state | ||||
| FakeInit: | ||||
| 	lea     si, [Saved_SS]			; Set descriptors to 64K real-mode | ||||
| 	mov     cx, 5                   	; # descriptors to fill | ||||
| 	mov     eax, 0000FFFFh			; limit_15_0 & base_15_0 | ||||
| DescrLoop: | ||||
| 	mov     [si+0], eax			; limit_15_0 & base_15_0 | ||||
| 	mov     dword ptr [si+4], 00009200h	; base_23_16, attr, limit_19_16 & base_31_24 | ||||
| 	mov     word ptr [si+8], 0000h		; selector | ||||
| 	add     si, sizeof (Descriptor)		; Advance ptr to next descriptor | ||||
| 	loop    DescrLoop | ||||
|  | ||||
|  | ||||
| 	; Set top-level SMM header to reset state | ||||
| 	mov     bx, OFFSET SMM_Header | ||||
| 	ASSUME	BX: PTR SmiHeader | ||||
| 	mov     [bx]._CS.limit,  eax | ||||
| 	mov     [bx]._CS.base,   0FFFF0000h | ||||
| 	mov     [bx]._CS.selector, 0F000h | ||||
| 	mov     [bx]._CS.attr,   92h | ||||
|  | ||||
| 	mov     [bx].Next_EIP,   0000FFF0h | ||||
| 	mov     [bx].r_CR0,      60000010h	; Real-mode; cache disabled | ||||
| 	mov     [bx].r_DR7,      00000400h | ||||
| 	mov     [bx].EFLAGS,     00000002h | ||||
| 	mov     [bx].SMI_Flags,  8001h		; CS is R/W | ||||
|  | ||||
| 	mov     [bx].SS_Flags,   DATA_ATTR | ||||
|  | ||||
| 	; Initialize general purpose register | ||||
| 	mov     [Saved_EDX], 00000540h		; CPU ID | ||||
| 	xor     eax, eax | ||||
| 	mov     [Saved_EAX], eax | ||||
| 	mov     [Saved_EBX], eax | ||||
| 	mov     [Saved_ECX], eax | ||||
| 	mov     [Saved_EDI], eax | ||||
| 	mov     [Saved_ESI], eax | ||||
| 	mov     [Saved_EBP], eax | ||||
| 	mov     [Saved_ESP], eax | ||||
|  | ||||
| 	ret | ||||
|  | ||||
| set_reset_state endp | ||||
|  | ||||
| 	end | ||||
							
								
								
									
										91
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/protos.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										91
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/protos.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,91 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| typedef unsigned short EVENT; | ||||
| typedef unsigned short MSG; | ||||
| typedef unsigned short PRIORITY; | ||||
| typedef unsigned long VSM; | ||||
| typedef void (* GPIO_FUNCTION)(unsigned long, unsigned long, unsigned char); | ||||
|  | ||||
|  | ||||
|  | ||||
| void pascal out_8(unsigned short, unsigned char); | ||||
| void pascal out_16(unsigned short, unsigned short); | ||||
| void pascal out_32(unsigned short, unsigned long); | ||||
| unsigned char  pascal in_8(unsigned short); | ||||
| unsigned short pascal in_16(unsigned short); | ||||
| unsigned long  pascal in_32(unsigned short); | ||||
|  | ||||
| void pascal Hex_8(unsigned char); | ||||
| void pascal Hex_16(unsigned short); | ||||
| void pascal Hex_32(unsigned long); | ||||
|  | ||||
|  | ||||
|  | ||||
| extern void pascal Trap_PCI_IDSEL(unsigned short, unsigned char); | ||||
| extern unsigned char pascal Init_Descr(unsigned char, unsigned long); | ||||
| extern unsigned char pascal BitScanReverse(unsigned long); | ||||
| extern unsigned char pascal BitScanForward(unsigned long); | ||||
| extern unsigned long pascal read_flat(unsigned long); | ||||
| extern unsigned long pascal Read_MSR_LO(unsigned long); | ||||
| extern unsigned long pascal Read_MSR_HI(unsigned long); | ||||
| extern unsigned long pascal Virtual_PCI_Read_Handler(unsigned short); | ||||
| extern unsigned long pascal GetFlink(unsigned long); | ||||
| extern unsigned char pascal Get_VSM_Type(unsigned long); | ||||
| extern unsigned char pascal IsPowerOfTwo(unsigned long); | ||||
| extern unsigned short pascal Send_Event(EVENT, VSM); | ||||
| extern unsigned char pascal Find_Matching_IO_Descriptor(unsigned long *, unsigned short *, unsigned char); | ||||
| extern unsigned char pascal Setup_IO_Descriptor(unsigned long *, unsigned short *, unsigned char); | ||||
| extern void pascal Init_MBIU(unsigned char *, unsigned long); | ||||
| extern void pascal Get_Descriptor_Default(unsigned char, unsigned long *); | ||||
| extern unsigned long pascal Virtual_PCI_Write_Handler(unsigned short, unsigned char, unsigned long); | ||||
| extern void pascal write_flat(unsigned long, unsigned long); | ||||
| extern void pascal Read_MSR(unsigned long, unsigned long *); | ||||
| extern void pascal Write_MSR(unsigned long, unsigned long *); | ||||
| extern void pascal Write_MSR_LO(unsigned long, unsigned long); | ||||
| extern void pascal Write_MSR_HI(unsigned long, unsigned long); | ||||
| extern void pascal Store_Timestamp(void *); | ||||
| extern void pascal Schedule_VSM(unsigned long); | ||||
| extern void pascal Report_Error(unsigned char, unsigned long, unsigned long); | ||||
| extern void pascal Report_VSM_Error(unsigned char, unsigned long, unsigned long); | ||||
| extern void pascal Send_Message(VSM, VSM, unsigned long); | ||||
| extern void pascal Broadcast_Message(MSG, unsigned short, unsigned long); | ||||
| extern void pascal Register_Event(EVENT, PRIORITY, VSM, unsigned long, unsigned long); | ||||
| extern void pascal Enable_Event(EVENT, unsigned short, unsigned char); | ||||
| extern void pascal Disable_Event(EVENT, unsigned short); | ||||
| extern void pascal Unregister_VSM_Events(VSM); | ||||
|  | ||||
| extern void pascal IRQY_Mapper(unsigned char, unsigned char); | ||||
| extern void pascal IRQZ_Mapper(unsigned char, unsigned char); | ||||
|  | ||||
|  | ||||
| extern void Keep_History(EVENT, EVENT); | ||||
| extern unsigned short pascal Unregister_Event(EVENT, VSM, unsigned long, unsigned long); | ||||
| extern unsigned short pascal Allocate_BAR(unsigned char, unsigned short, unsigned long, unsigned short, unsigned short); | ||||
|  | ||||
| extern unsigned long Current_VSM; | ||||
| extern unsigned long SysMgr_VSM; | ||||
|  | ||||
|  | ||||
| extern void Log_Error(const char *format, ...); | ||||
| extern unsigned long pascal Compute_IOD_SC(unsigned long *, unsigned short *, unsigned char); | ||||
| extern void pascal MBus_IO_Trap(unsigned long, unsigned long, unsigned char); | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										209
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/smimac.mac
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										209
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/smimac.mac
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,209 @@ | ||||
| ;  | ||||
| ; Copyright (c) 2006 Advanced Micro Devices,Inc. ("AMD"). | ||||
| ;  | ||||
| ; This library is free software; you can redistribute it and/or modify | ||||
| ; it under the terms of the GNU Lesser General Public License as | ||||
| ; published by the Free Software Foundation; either version 2.1 of the | ||||
| ; License, or (at your option) any later version. | ||||
| ;  | ||||
| ; This code is distributed in the hope that it will be useful, | ||||
| ; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| ; Lesser General Public License for more details. | ||||
| ;  | ||||
| ; You should have received a copy of the GNU Lesser General | ||||
| ; Public License along with this library; if not, write to the | ||||
| ; Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| ; Boston, MA 02111-1307 USA  | ||||
| ;  | ||||
|  | ||||
|  | ||||
| smint	macro | ||||
| 		db      0Fh, 38h | ||||
| 		endm | ||||
|  | ||||
|  | ||||
|  | ||||
| EREG	macro	Reg | ||||
| 		ifidni		<Reg>, <eax> | ||||
| 		  db		0C8h | ||||
| 		elseifidni	<Reg>, <ecx> | ||||
| 		  db		0C9h | ||||
| 		elseifidni	<Reg>, <edx> | ||||
| 		  db		0CAh | ||||
| 		elseifidni	<Reg>, <ebx> | ||||
| 		  db		0CBh | ||||
| 		elseifidni	<Reg>, <esp> | ||||
| 		  db		0CCh | ||||
| 		elseifidni	<Reg>, <ebp> | ||||
| 		  db		0CDh | ||||
| 		elseifidni	<Reg>, <esi> | ||||
| 		  db		0CEh | ||||
| 		elseifidni	<Reg>, <edi> | ||||
| 		  db		0CFh | ||||
| 		else | ||||
| 		.err | ||||
|  | ||||
| 		endif | ||||
|  | ||||
| 		endm | ||||
|  | ||||
|  | ||||
| RDSHR	macro	Reg | ||||
| 		db		0Fh, 36h | ||||
| 		EREG	Reg | ||||
| 		endm | ||||
|  | ||||
| WRSHR	macro	Reg | ||||
| 		db		0Fh, 37h | ||||
| 		EREG	Reg | ||||
| 		endm | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| MOV_EAX_CR4 macro | ||||
| 		db		0Fh, 20h, 0E0h		; mov eax, CR4 | ||||
| ENDM | ||||
|  | ||||
| MOV_CR4_EAX macro | ||||
| 		db		0Fh, 22h, 0E0h		; mov CR4, eax | ||||
| ENDM | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| SMM_Instr	macro Reg:REQ, Addr:REQ, Opcode:REQ | ||||
| 	Local Place1, Place2,  Attr, InstrLen | ||||
|  | ||||
|  | ||||
|  | ||||
| Place1: | ||||
|  | ||||
|  | ||||
| 	ifidni		<Reg>, <ES> | ||||
| 	  LFS	ax, dword ptr Addr | ||||
| 	elseifidni	<Reg>, <SS> | ||||
| 	  LFS	dx, dword ptr Addr | ||||
| 	elseifidni	<Reg>, <DS> | ||||
| 	  LFS	bx, dword ptr Addr | ||||
| 	elseifidni	<Reg>, <FS> | ||||
| 	  LFS	sp, dword ptr Addr | ||||
| 	elseifidni	<Reg>, <GS> | ||||
| 	  LFS	bp, dword ptr Addr | ||||
| 	elseifidni	<Reg>, <CS> | ||||
| 	  LFS	cx, dword ptr Addr | ||||
| 	else | ||||
| 	  .err "Error in RSDC macro" | ||||
| 	endif | ||||
|  | ||||
| Place2: | ||||
|  | ||||
| Extras = 1 | ||||
| SegOverride  INSTR <Addr>, <:> | ||||
| if SegOverride | ||||
|   Extras = Extras + 1 | ||||
| endif | ||||
|  | ||||
| AddrOverride  INSTR <Addr>, <eax> | ||||
| if AddrOverride | ||||
|   Extras = Extras + 1 | ||||
| else | ||||
|   AddrOverride  INSTR <Addr>, <EAX> | ||||
|   if AddrOverride | ||||
|     Extras = Extras + 1 | ||||
|   else | ||||
|   AddrOverride  INSTR <Addr>, <ebx> | ||||
|   if AddrOverride | ||||
|     Extras = Extras + 1 | ||||
|   else | ||||
|   AddrOverride  INSTR <Addr>, <EBX> | ||||
|   if AddrOverride | ||||
|     Extras = Extras + 1 | ||||
|   else | ||||
|   AddrOverride  INSTR <Addr>, <ecx> | ||||
|   if AddrOverride | ||||
|     Extras = Extras + 1 | ||||
|   else | ||||
|   AddrOverride  INSTR <Addr>, <ECX> | ||||
|   if AddrOverride | ||||
|     Extras = Extras + 1 | ||||
|   else | ||||
|   AddrOverride  INSTR <Addr>, <edx> | ||||
|   if AddrOverride | ||||
|     Extras = Extras + 1 | ||||
|   else | ||||
|   AddrOverride  INSTR <Addr>, <EDX> | ||||
|   if AddrOverride | ||||
|     Extras = Extras + 1 | ||||
|   else | ||||
|   AddrOverride  INSTR <Addr>, <esi> | ||||
|   if AddrOverride | ||||
|     Extras = Extras + 1 | ||||
|   else | ||||
|   AddrOverride  INSTR <Addr>, <ESI> | ||||
|   if AddrOverride | ||||
|     Extras = Extras + 1 | ||||
|   else | ||||
|   AddrOverride  INSTR <Addr>, <edi> | ||||
|   if AddrOverride | ||||
|     Extras = Extras + 1 | ||||
|   else | ||||
|   AddrOverride  INSTR <Addr>, <EDI> | ||||
|   if AddrOverride | ||||
|     Extras = Extras + 1 | ||||
|   endif | ||||
|   endif | ||||
|   endif | ||||
|   endif | ||||
|   endif | ||||
|   endif | ||||
|   endif | ||||
|   endif | ||||
|   endif | ||||
|   endif | ||||
|   endif | ||||
| endif | ||||
|  | ||||
| 	ORG Place1 + Extras | ||||
| 	db	Opcode	 | ||||
| 	ORG Place2 | ||||
|  | ||||
| 	endm | ||||
|  | ||||
| svdc	macro Addr:REQ, Reg:REQ | ||||
| 	  SMM_Instr Reg, Addr, 78h | ||||
| 	endm | ||||
|  | ||||
| rsdc	macro Reg:REQ, Addr:REQ | ||||
| 	  SMM_Instr Reg, Addr, 79h | ||||
| 	endm | ||||
|  | ||||
|  | ||||
| svldt	macro Addr:REQ | ||||
| 	  SMM_Instr <ES>, Addr, 7Ah | ||||
| 	endm | ||||
|  | ||||
|  | ||||
| rsldt	macro	Addr:REQ | ||||
| 	  SMM_Instr <ES>, Addr, 7Bh | ||||
| 	endm | ||||
|  | ||||
| svts	macro Addr:REQ | ||||
| 	  SMM_Instr <ES>, Addr, 7Ch | ||||
| 	endm | ||||
|  | ||||
|  | ||||
| rsts	macro	Addr:REQ | ||||
| 	  SMM_Instr <ES>, Addr, 7Dh | ||||
| 	endm | ||||
|  | ||||
|  | ||||
							
								
								
									
										354
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/smis.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										354
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/smis.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,354 @@ | ||||
| ;  | ||||
| ; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| ;  | ||||
| ; This library is free software; you can redistribute it and/or modify | ||||
| ; it under the terms of the GNU Lesser General Public License as | ||||
| ; published by the Free Software Foundation; either version 2.1 of the | ||||
| ; License, or (at your option) any later version. | ||||
| ;  | ||||
| ; This code is distributed in the hope that it will be useful, | ||||
| ; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| ; Lesser General Public License for more details. | ||||
| ;  | ||||
| ; You should have received a copy of the GNU Lesser General | ||||
| ; Public License along with this library; if not, write to the | ||||
| ; Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| ; Boston, MA 02111-1307 USA  | ||||
| ;  | ||||
| ;******************************************************************************** | ||||
| ;*     This file contains the code for reading the source of SMIs.  | ||||
| ;******************************************************************************** | ||||
|  | ||||
|  | ||||
| include GX2.INC | ||||
| include VSA2.INC | ||||
| include SYSMGR.INC | ||||
| include CS5536.INC | ||||
| include CHIPSET.INC | ||||
| include MDD.INC | ||||
| include PCI.INC | ||||
|  | ||||
| .model tiny,c | ||||
| .586p | ||||
| .CODE  | ||||
| ASSUME DS:_TEXT | ||||
|  | ||||
| SYNCHRONOUS equ (SMI_SRC_PCI_TRAP OR SMI_SRC_DESCR_HIT OR SMI_SRC_PM OR SMI_SRC_RESET OR SMI_SRC_BLOCKIO OR SMI_SRC_A20) | ||||
| SMI_Sources	dd	0 | ||||
| Video_Sources	dd	0 | ||||
| Audio_Sources	dw	0 | ||||
| Stats_Sources	dd	0 | ||||
| SynchEvents     dd	SYNCHRONOUS | ||||
| HiPrioritySMIs  dd	SMI_SRC_AUDIO OR SMI_SRC_USB1 OR SMI_SRC_USB2 | ||||
|  | ||||
| public    SynchEvents, HiPrioritySMIs | ||||
| public    SMI_Sources, Audio_Sources, Stats_Sources, Video_Sources | ||||
|  | ||||
| externdef pascal Hex_8:proc | ||||
| externdef pascal Hex_16:proc | ||||
| externdef pascal Hex_32:proc | ||||
| externdef pascal Generate_IRQ_5536: proc | ||||
|  | ||||
| externdef SMI_Base:     dword | ||||
| externdef Mbiu0:        dword | ||||
| externdef Mbiu1:        dword | ||||
| externdef Mbiu2:        dword | ||||
| externdef MPCI_NB:      dword  | ||||
| externdef MPCI_SB:      dword  | ||||
| externdef MDD_Base:     dword | ||||
| externdef MCP_NB:       dword | ||||
| externdef ATA_Error:    dword | ||||
| externdef OHCI1_Smi:    dword | ||||
| externdef OHCI2_Smi:    dword | ||||
| externdef HardwareInfo: Hardware | ||||
|  | ||||
|  | ||||
|  | ||||
| ;************************************************************************* | ||||
| ; Installs the SMI routine(s) appropriate to the chipset. | ||||
| ; The default routine(s) are for CS5536.   | ||||
| ;************************************************************************* | ||||
| Install_SMI_Routines proc | ||||
|  | ||||
| 	;5536 already set, do nothing. mov	[OHCI_SMI], OHCSSTAT | ||||
| Exit:	ret | ||||
|  | ||||
| Install_SMI_Routines endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;************************************************************************ | ||||
| ; Asserts/deasserts internal IRQs | ||||
| ; On Entry: | ||||
| ;  ECX = IRQ mask | ||||
| ;        16 LSBs - enable | ||||
| ;        16 MSBs - disable | ||||
| ;************************************************************************ | ||||
| Generate_IRQ proc | ||||
|  | ||||
| 	push	cx | ||||
| 	call	word ptr [IRQ_Routine] | ||||
| 	ret | ||||
|  | ||||
| IRQ_Routine:: | ||||
| 	dw	OFFSET Generate_IRQ_5536 | ||||
|  | ||||
| Generate_IRQ endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;************************************************************************* | ||||
| ; Reads & clears all SMI source registers (MSRs & Southbridge) | ||||
| ; On Exit: | ||||
| ;   EBX = SMI sources | ||||
| ;   All other registers may be destroyed | ||||
| ;************************************************************************* | ||||
| Get_SMI_Sources proc | ||||
|  | ||||
| 	mov	ebx, [SMI_Sources]	; Get SMIs that have not yet been handled | ||||
| 	call	Get_Northbridge_SMIs | ||||
| 	or	ebx, ebx		; If any NB SMIs, handle them quickly | ||||
| 	jz	short Get_SB_SMIs | ||||
| 	ret | ||||
| Get_SB_SMIs: | ||||
|  | ||||
| 	jmp	word ptr [SMI_Routine]	; Get Southbridge SMI(s) | ||||
|  | ||||
| SMI_Routine:: | ||||
| 	dw	OFFSET Get_5536_SMIs | ||||
|  | ||||
| Get_SMI_Sources endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Gets SMI sources from Northbridge | ||||
| ; On Entry: | ||||
| ;   EBX = pending SMI sources | ||||
| ; NOTES: | ||||
| ; - May set SMI source bits in EBX. | ||||
| ;*********************************************************************** | ||||
| MPCI_ERROR	equ	(MARE + TARE + PARE + BME + SYSE) | ||||
| VGA_BLANK	equ	08h | ||||
| VG_BLANK	equ	01h | ||||
| VERT_BLANK	equ	(VGA_BLANK OR VG_BLANK) | ||||
|  | ||||
| Get_Northbridge_SMIs proc | ||||
|  | ||||
| 	mov	ecx, [MPCI_NB]		; MBIU1.MPCI.0.0.0.0 | ||||
| 	mov	cx, MBD_MSR_SMI | ||||
| 	rdmsr | ||||
| 	wrmsr				; Clear the MPCI SMI event(s) | ||||
|  | ||||
| 	mov	dl, al			; Only record enabled events | ||||
| 	not	dl | ||||
| 	shr	eax, 16 | ||||
| 	and	al, dl			; Only consider unmasked events | ||||
| 	jz	short Graphics_SMIs	; Jmp if no MPCI SMI is pending	 | ||||
|  | ||||
| 	test	al, VPHE SHR 16		; Is it a virtualized PCI header ? | ||||
| 	jz	short CheckMPCI | ||||
| 	or	ebx, SMI_SRC_PCI_TRAP	; Yes, record the event | ||||
| 	 | ||||
| 	cmp	al, VPHE SHR 16		; Is VPHE the only SMI pending ? | ||||
| 	je	short Exit		; Yes, do a quick exit | ||||
|   	 | ||||
|  | ||||
| CheckMPCI:	 | ||||
| 	test	ax, MPCI_ERROR SHR 16	; Is it an MPCI error ? | ||||
| 	jz	short Graphics_SMIs | ||||
| 	or	ebx, SMI_SRC_MPCI	; Yes | ||||
|  | ||||
| 	mov	cx, MBD_MSR_ERROR	; Clear the MPCI error(s)  | ||||
| 	rdmsr | ||||
| 	wrmsr | ||||
| 	 | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| 	;******************************************* | ||||
| 	; Check for graphics SMIs | ||||
| 	;******************************************* | ||||
|  | ||||
| ; Value in Video_Sources: | ||||
| ; | ||||
| ;   Bit		            Description | ||||
| ;  -----	----------------------------------- | ||||
| ;    0		DF: SMI #1 (TBD) | ||||
| ;    1 	DF: SMI #2 (TBD) | ||||
| ;    2		GP: SMI (address or type violation) | ||||
| ;    3		reserved | ||||
| ;    4		VG: Miscellaneous Output SMI | ||||
| ;    5		VG: Input Status register SMI | ||||
| ;    6		reserved | ||||
| ;    7		VG: CRTC invalid I/O SMI | ||||
| Graphics_SMIs: | ||||
| 	; Video Generator | ||||
| 	mov	ecx, VG_SMI_MSR | ||||
| 	rdmsr | ||||
| 	wrmsr				; Clear SMI(s) | ||||
|  | ||||
| 	; Because the VG records all events that occur in the upper half of the MSR | ||||
| 	; regardless of whether or not they generate SMIs, we need to clear out the | ||||
| 	; events that aren't generating SMIs and only look for valid ones.  | ||||
| 	not eax						; NOT the SMI mask | ||||
| 	and	edx,eax					; Clear out untrapped events | ||||
|  | ||||
| 	test	dl, VERT_BLANK		; Is a vertical blank pending ? | ||||
| 	jz	short SaveVideoSources | ||||
| 	and	dl, NOT (VERT_BLANK) | ||||
| 	or	ebx, SMI_SRC_RETRACE	; Yes, record EVENT_VBLANK | ||||
| SaveVideoSources: | ||||
| 	or	[Video_Sources], edx | ||||
| 	jz	short Statistic_SMIs | ||||
| 	or	ebx, SMI_SRC_VG		; Yes, then record EVENT_GRAPHICS | ||||
|  | ||||
| 	 | ||||
| 	;******************************************* | ||||
| 	; Check for Statistic Counter SMI(s)	 | ||||
| 	;******************************************* | ||||
| Statistic_SMIs: | ||||
| 	mov	ecx, [Mbiu0]		; Check MBIU0 Statistics Counters | ||||
| 	call	Get_MBD_SMIs | ||||
| 	or	byte ptr [Stats_Sources+0], dl | ||||
|  | ||||
| 	mov	ecx, [Mbiu1]		; Check MBIU1 Statistics Counters | ||||
| 	call	Get_MBD_SMIs | ||||
| 	or	byte ptr [Stats_Sources+1], dl | ||||
| Exit: | ||||
| 	ret | ||||
|  | ||||
| Get_Northbridge_SMIs endp | ||||
|  | ||||
|  | ||||
| 	 | ||||
| 	 | ||||
| ;*********************************************************************** | ||||
| ; Checks for events in MBD_MSR_SMI: | ||||
| ;   - descriptor traps | ||||
| ;   - statistic counters | ||||
| ; On entry: ECX = base address of GLIU | ||||
| ; Returns: DL = statistic event mask | ||||
| ;*********************************************************************** | ||||
| Get_MBD_SMIs proc	 | ||||
|  | ||||
| 	mov	cx, MBD_MSR_ERROR	; Clear errors | ||||
| 	rdmsr | ||||
| 	wrmsr | ||||
|  | ||||
| 	mov	cx, MBD_MSR_SMI | ||||
| 	rdmsr | ||||
| 	 | ||||
| 	and	dl, 1Fh			; Any SMIs pending ? | ||||
| 	jz	short Exit		; No, just exit | ||||
| 	wrmsr | ||||
|  | ||||
| 	btr	dx, 0			; Is it a MBIU descriptor hit ? | ||||
| 	jnc	short StatCntrs | ||||
| 	or	ebx, SMI_SRC_DESCR_HIT	; Yes | ||||
|  | ||||
| StatCntrs: | ||||
| 	or	dl, dl			; Any hits on statistic counters ?			 | ||||
| 	jz	short Exit | ||||
| 	or	ebx, SMI_SRC_STAT	; Yes, record the event | ||||
| 	or	al, dl			; Disable further events | ||||
|  | ||||
| 	wrmsr | ||||
| 	 | ||||
| 	shr	dl, 1 | ||||
| Exit: | ||||
| 	ret | ||||
|  | ||||
| Get_MBD_SMIs endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;************************************************************************* | ||||
| ; Reads and clears CS5536 SMI source registers | ||||
| ;************************************************************************* | ||||
| Get_5536_SMIs proc | ||||
|  | ||||
| 	mov	ecx, [MDD_Base]		; Check for MDD SMIs | ||||
| 	mov	cx, MBD_MSR_SMI | ||||
| 	rdmsr | ||||
| 	wrmsr				; Clear any pending SMI(s) | ||||
| 	or	dx, dx			; Any MDD SMIs pending ? | ||||
| 	jz	short Get_MPCI_SB	; No | ||||
|  | ||||
| 	xor	eax, eax	 | ||||
| MDD_Loop: | ||||
| 	bsf	ax, dx 			; Determine next pending event | ||||
| 	jz	Exit | ||||
| 	btr	dx, ax			; Clear the status bit | ||||
| 	or	ebx, dword ptr [eax*4+MDD_Sources] | ||||
| 	jmp	short MDD_Loop | ||||
|  | ||||
|  | ||||
| 	; MDD SMI sources | ||||
| MDD_Sources: | ||||
| 	dd	0			; HLT_ASMI_STAT | ||||
| 	dd	0			; SHUTDOWN_ASMI_STAT | ||||
| 	dd	SMI_SRC_KEL		; KEL_ASMI_STAT | ||||
| 	dd	SMI_SRC_PIC		; PIC_ASMI_STAT | ||||
| 	dd	SMI_SRC_PME		; PM_ASMI_STAT | ||||
| 	dd	SMI_SRC_RESET		; INIT_K_STAT | ||||
| 	dd	SMI_SRC_A20		; A20_P_STAT | ||||
| 	dd	SMI_SRC_RESET		; INIT_P_STAT | ||||
| 	dd	0			; UART1_SSMI_STAT | ||||
| 	dd	0			; UART2_SSMI_STAT | ||||
| 	dd	0			; RESERVED_STAT | ||||
| 	dd	0			; LPC_SSMI_STAT | ||||
| 	dd	0			; DMA_SSMI_STAT | ||||
| 	dd	SMI_SRC_A20		; A20_K_STAT | ||||
| 	dd	SMI_SRC_ACPI		; PM2_CNT_SSMI_STAT | ||||
| 	dd	SMI_SRC_ACPI		; PM1_CNT_SSMI_STAT | ||||
|  | ||||
|  | ||||
|  | ||||
| Get_MPCI_SB: | ||||
| 	mov	ecx, [MPCI_SB]		; Get Southbridge MPCI events | ||||
| 	mov	cx, MBD_MSR_SMI | ||||
| 	rdmsr | ||||
| 	wrmsr				; Clear any pending SMI(s) | ||||
|  | ||||
| 	mov	ecx, [Mbiu2]		; Check for MBIU2 SMIs | ||||
| 	call	Get_MBD_SMIs | ||||
| 	or	byte ptr [Stats_Sources+2], dl | ||||
|  | ||||
| 	mov	ecx, [OHCI1_Smi]	; Check for USB #1 SMIs | ||||
| 	jcxz	short Exit | ||||
| 	rdmsr | ||||
| 	test	dl, [OHCI_SMI]		; OHCI SMI pending ? | ||||
| 	jz	short Exit		; JMP if not | ||||
| 	wrmsr				; Yes, clear the SMI | ||||
| 	or	ebx, SMI_SRC_USB1	; Record the SMI event | ||||
|  | ||||
| Exit:	ret | ||||
|  | ||||
| Get_5536_SMIs endp | ||||
|  | ||||
|  | ||||
| OHCSSTAT		equ 10h		; 5536 | ||||
| OHCI_SMI		db  OHCSSTAT	; Assume 5536; could patched by Install_SMI_Routines() if other | ||||
| 	 | ||||
|  | ||||
|  | ||||
|  | ||||
| 	end | ||||
|  | ||||
							
								
								
									
										502
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/sw_int.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										502
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/sw_int.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,502 @@ | ||||
| ;  | ||||
| ; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| ;  | ||||
| ; This library is free software; you can redistribute it and/or modify | ||||
| ; it under the terms of the GNU Lesser General Public License as | ||||
| ; published by the Free Software Foundation; either version 2.1 of the | ||||
| ; License, or (at your option) any later version. | ||||
| ;  | ||||
| ; This code is distributed in the hope that it will be useful, | ||||
| ; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| ; Lesser General Public License for more details. | ||||
| ;  | ||||
| ; You should have received a copy of the GNU Lesser General | ||||
| ; Public License along with this library; if not, write to the | ||||
| ; Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| ; Boston, MA 02111-1307 USA  | ||||
| ;  | ||||
| ;******************************************************************************** | ||||
| ;*     Implementation of BIOS callbacks | ||||
| ;******************************************************************************** | ||||
|  | ||||
|  | ||||
| include SYSMGR.INC | ||||
| include VSA2.INC | ||||
| include SMIMAC.MAC | ||||
| include GX2.INC | ||||
| include ISA.INC | ||||
|  | ||||
| .model tiny,c | ||||
| .586p | ||||
| .ALPHA | ||||
| DGROUP	GROUP _CODE, _TEXT | ||||
| _CODE	SEGMENT PUBLIC use16 'CODE' | ||||
| 	ASSUME DS:_CODE | ||||
|  | ||||
| public  VSM_Buffer | ||||
|  | ||||
| SMINT_SEGMENT		equ	0E000h		; Segment to store SMINT instruction & ISR stack | ||||
| ALLOW_SMM_SEGMENTS	equ	0		; 1 = ES segment allowed to point to SMM memory | ||||
|  | ||||
|  | ||||
| externdef pascal Report_VSM_Error: proc | ||||
| externdef pascal Schedule_VSM:     proc | ||||
| externdef Sys_Exit:                proc | ||||
| externdef pascal Hex_8:            proc | ||||
| externdef pascal Hex_16:           proc | ||||
| externdef pascal Hex_32:           proc | ||||
|  | ||||
| externdef BracketFlag:             byte | ||||
| externdef SchedulerStack:          word | ||||
| externdef INT_Vectors:             dword | ||||
| externdef Current_VSM:             dword | ||||
| externdef StartSaveArea:           dword | ||||
| externdef EndSaveArea:             dword | ||||
| externdef SysMgr_VSM:              dword | ||||
| externdef Header_Addr:             dword | ||||
| externdef SMM_Header:              SmiHeader | ||||
|  | ||||
| ;************************************************************************ | ||||
| ; Implements the SYS_STATE macro | ||||
| ; | ||||
| ; Input: | ||||
| ;    CX = Flag:  0 = Save    1 = Restore | ||||
| ;   EDI = Offset to VSM's register buffer | ||||
| ;    DS = System Manager's data segment | ||||
| ;************************************************************************ | ||||
| Sys_State proc | ||||
|  | ||||
| 	cld | ||||
| 	mov	eax, [Current_VSM]		; Create flat ptr to calling VSM | ||||
| 	add	edi, eax | ||||
|  | ||||
| 	push	eax				; Re-schedule the calling VSM | ||||
| 	call	Schedule_VSM | ||||
| 	 | ||||
|  | ||||
| 	lea	esi, [StartSaveArea] | ||||
| 	add	esi, [SysMgr_VSM] | ||||
|  | ||||
| 	jcxz	CopyState			; Save or Restore ? | ||||
|  | ||||
| 	xchg	esi, edi			; Restore | ||||
|  | ||||
| 	; Copy the non-SMM state | ||||
| CopyState: | ||||
| 	mov	ecx, OFFSET EndSaveArea | ||||
| 	sub	cx,  OFFSET StartSaveArea | ||||
| 	shr	cx, 1 | ||||
| 	 | ||||
| 	rep	movsw [edi], fs:[esi] | ||||
| 	jmp	Sys_Exit | ||||
|  | ||||
| Sys_State	endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;************************************************************************ | ||||
| ; Implements the SYS_SW_INTERRUPT macro | ||||
| ; | ||||
| ; Input: | ||||
| ;   EBX = 4 * INT number | ||||
| ;   ECX = Offset to VSM's register buffer | ||||
| ;************************************************************************ | ||||
| Sys_SW_INT proc | ||||
|  | ||||
| 	cld | ||||
| 	mov	esi, [Current_VSM] | ||||
| 	push	esi				; Re-schedule the calling VSM | ||||
| 	call	Schedule_VSM | ||||
|  | ||||
| 	cmp	bx, 4*MAX_INT			; Validate INT vector | ||||
| 	ja	Unsupported_INT | ||||
| 	mov	edx, [INT_Vectors+bx] | ||||
| 	or	edx, edx | ||||
| 	jz	Illegal_INT | ||||
|  | ||||
| 	mov	[Saved_INT], ebx		; Save current vector &  | ||||
| 	mov	edi, edx			; patch with the original vector | ||||
| 	xchg	fs:[ebx], edi | ||||
| 	mov	[Saved_Vector], edi | ||||
| 	 | ||||
| 	xor	edi, edi			; Don't allow calling VSM to execute | ||||
| 	push	edi | ||||
| 	call	Schedule_VSM | ||||
|  | ||||
| 	ASSUME	di:PTR VSM_Header		; Mark the requesting VSM blocked | ||||
| 	mov	gs:[di].SysStuff.RunFlag, RUN_FLAG_BLOCKED | ||||
|  | ||||
|  | ||||
| 	; Handle PIC masks | ||||
| 	in	al, PIC1_MASK			; Save PIC masks & set user-defined masks | ||||
| 	mov	ah, al | ||||
| 	in	al, PIC2_MASK | ||||
| 	mov	[Saved_PIC], ax | ||||
|  | ||||
| 	ASSUME	di:PTR INT_REGS | ||||
| 	mov	di, cx | ||||
| 	mov	ax, word ptr gs:[di].PIC0_Mask | ||||
| 	not	ax				; PIC masks are 0=enable | ||||
| 	cmp	ah, 0FFh			; Any PIC1 IRQs enabled ? | ||||
| 	je	short SetPIC | ||||
| 	and	al, NOT 04h			; Yes, enable IRQ2 | ||||
| SetPIC: | ||||
| 	or	al, 01h				; Always disable IRQ0 | ||||
| 	out	PIC1_MASK, al | ||||
| 	mov	al, ah | ||||
| 	out	PIC2_MASK, al | ||||
|  | ||||
| 	cmp	ax, 0FFFFh			; Are any IRQs enabled ? | ||||
| 	je	short RealMode | ||||
| 	or	gs:[di].Flags, EFLAGS_IF	; Yes, enable interrupts	 | ||||
| 	 | ||||
| 	; | ||||
| 	; Initialize real-mode state | ||||
| 	; | ||||
| RealMode: | ||||
| 	mov	ax, gs:[di].Reg_ES		; Set up ES descriptor | ||||
| 	push	OFFSET BIOS_ES | ||||
| 	call	Set_Descriptor | ||||
|  | ||||
| 	mov	ax, gs:[di].Reg_DS		; Set up DS descriptor | ||||
| 	push	OFFSET BIOS_DS | ||||
| 	call	Set_Descriptor | ||||
|  | ||||
| 	add	esi, ecx			; Create flat ptr to calling VSM's registers | ||||
| 	mov	[VSM_Buffer], esi | ||||
|  | ||||
|  | ||||
| 	ASSUME	di:PTR SmiHeader | ||||
|  | ||||
| 	lea	edi, [BIOS_Header]		; Set up CS descriptor & Next_EIP | ||||
| 	mov	word ptr [di].SS_Flags, DATA_ATTR | ||||
| 	mov	[di].SMI_Flags, SMI_FLAGS_CS_WRITABLE + SMI_FLAGS_CS_READABLE | ||||
| 	mov	word ptr [di].Next_EIP, dx	; IP | ||||
| 	shr	edx, 16				; Convert segment to linear address | ||||
| 	mov	[di]._CS.selector, dx		; CS selector | ||||
| 	shl	edx, 4 | ||||
| 	mov	[di]._CS.base,  edx		; CS descriptor | ||||
| 	mov	[di]._CS.limit, 0FFFFh | ||||
| 	mov	[di]._CS.attr, CODE_ATTR	; CS attribute | ||||
| 	mov	eax, CR0			; Preserve the CD & NW bits | ||||
| 	and	eax, 60000000h | ||||
| 	or	eax, VSM_CR0 | ||||
| 	mov	[di].r_CR0, eax | ||||
|  | ||||
| if ALLOW_SMM_SEGMENTS | ||||
|  	mov	ecx, MSR_RCONF_SMM		; Make SMM memory writeable by interrupt code | ||||
| 	rdmsr | ||||
| 	mov	[OldRCONF], al | ||||
| 	and	al, NOT REGION_WP | ||||
| 	wrmsr | ||||
| endif | ||||
|  | ||||
| 	ASSUME	DI: NOTHING | ||||
|  | ||||
|  | ||||
|  | ||||
| 	mov	ecx, 1000002Ch			; Save P2D_SC value & make UMBs R/W | ||||
| 	rdmsr | ||||
| 	mov	[ShadowMSR], dx | ||||
| 	or	dx, 0FFFFh | ||||
| 	wrmsr | ||||
|  | ||||
| 	mov	ebx, SMINT_SEGMENT		; Patch SS descriptor | ||||
| 	mov	word ptr  [BIOS_SS+8], bx | ||||
| 	shl	ebx, 4 | ||||
| 	mov	dword ptr [BIOS_SS+2], ebx | ||||
| 	mov	byte ptr  [BIOS_SS+5], DATA_ATTR | ||||
| 	add	ebx, 0FFF0h | ||||
| 	mov	[ShadowAddr], ebx | ||||
| 	mov	word ptr [BIOS_ESP], bx | ||||
|  | ||||
| 	; Build a stack frame: | ||||
| 	; SMINT_SEGMENT:FFF0   SMINT_SEGMENT:FFF6  - return addresss | ||||
| 	; SMINT_SEGMENT:FFF4   Flags | ||||
| 	; SMINT_SEGMENT:FFF6   SMINT instruction | ||||
| 	mov	eax, SMINT_SEGMENT SHL 16	; Segment | ||||
| 	lea	ax, [bx+6]			; Offset (SP+6) | ||||
| 	xchg	eax, dword ptr fs:[ebx] | ||||
| 	mov	[ShadowMemory], eax | ||||
| 	mov	eax, 380F0000h			; FLAGS & SMINT | ||||
| 	xchg	eax, fs:[ebx+4] | ||||
| 	mov	[ShadowMemory+4], eax | ||||
|  | ||||
| 	mov	eax, [Header_Addr]		; Copy top-level header address | ||||
| 	mov	[Hdr_Address], eax | ||||
|  | ||||
|  | ||||
| 	call	VSM_Registers			; Get registers for ISR | ||||
|  | ||||
|  | ||||
| 	call	Swap_States			; S wap top-level state with BIOS state | ||||
|  | ||||
| Exit:	jmp	Sys_Exit | ||||
|  | ||||
|  | ||||
|  | ||||
| Unsupported_INT: | ||||
| Illegal_INT: | ||||
|  | ||||
|  | ||||
| 	mov	ax, ERR_BAD_INTERRUPT | ||||
| 	push	ax				; Push error code | ||||
| 	shr	ebx, 2 | ||||
| 	push	ebx				; Info1 = Interrupt # | ||||
| 	push	dword ptr 0			; Info2 = 0x00000000 | ||||
| 	call	Report_VSM_Error | ||||
| 	jmp	Exit | ||||
|  | ||||
| Sys_SW_INT endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;******************************************************************************** | ||||
| ;       Returns here from INT callback | ||||
| ;******************************************************************************** | ||||
| INT_Return proc | ||||
|  | ||||
| 	mov	ebx, [Saved_INT]		; Restore the INT vector | ||||
| 	mov	edx, [Saved_Vector] | ||||
| 	mov	fs:[ebx], edx | ||||
|  | ||||
|  | ||||
| if ALLOW_SMM_SEGMENTS | ||||
|  	mov	ecx, MSR_RCONF_SMM		; Restore SMM region properties | ||||
| 	rdmsr | ||||
| 	mov	al, [OldRCONF] | ||||
| 	wrmsr | ||||
| endif | ||||
|  | ||||
| 	mov	esi, [Current_VSM]		; Mark the requesting VSM ready to run | ||||
| 	mov	fs:(VSM_Header PTR [esi]).SysStuff.RunFlag, RUN_FLAG_READY | ||||
|  | ||||
| 	call	Swap_States			; Restore the original non-SMM state | ||||
|  | ||||
| 	call	VSM_Registers			; Return register values & flags | ||||
|  | ||||
|  | ||||
| 	xor	eax, eax | ||||
| 	mov	[VSM_Buffer], eax | ||||
| 	 | ||||
| 	sub     [SchedulerStack], 4		; Pop the scheduler sentinel | ||||
|  | ||||
| 	mov	ebx, [ShadowAddr]		; Restore shadow memory | ||||
| 	mov	eax, [ShadowMemory] | ||||
| 	mov	fs:[ebx], eax | ||||
| 	mov	eax, [ShadowMemory+4] | ||||
| 	mov	fs:[ebx+4], eax | ||||
|  | ||||
| 	mov	ecx, 1000002Ch			; Restore R/W attributes of UMBs | ||||
| 	rdmsr | ||||
| 	mov	dx, [ShadowMSR] | ||||
| 	wrmsr | ||||
| 	 | ||||
| 	mov	ax, [Saved_PIC]			; Restore PIC masks | ||||
| 	out	PIC2_MASK, al | ||||
| 	mov	al, ah | ||||
| 	out	PIC1_MASK, al	 | ||||
| 	ret | ||||
|  | ||||
| INT_Return endp | ||||
|  | ||||
|  | ||||
|  | ||||
| ;************************************************************************ | ||||
| ; Swaps the top-level state with the BIOS callback state. | ||||
| ; Info to be saved: | ||||
| ;  - SMM header & pointer | ||||
| ;  - Descriptors | ||||
| ;  - GP registers | ||||
| ;  - IDT ptr | ||||
| ;  - PCI config address | ||||
| ;************************************************************************ | ||||
| Swap_States proc | ||||
|  | ||||
| 	lea	si, [StartSaveArea]		; Swap thread states | ||||
| 	lea	di, [Saved_State] | ||||
| 	mov	cx, OFFSET EndSaveArea		; Compute # dwords of state | ||||
| 	sub	cx, si | ||||
| 	shr	cx, 2 | ||||
| StateLoop: | ||||
| 	lodsd					; Exchange a dword | ||||
| 	xchg	[di], eax | ||||
| 	mov	dword ptr [si-4], eax | ||||
| 	add	di, 4 | ||||
| 	loop	StateLoop | ||||
|  | ||||
| 	lea	si, [SMM_Header]		; Now do the top-level SMM header | ||||
| 	lea	di, [BIOS_Header] | ||||
| 	mov	cl, sizeof(SmiHeader)/4 | ||||
| Hdr_Loop: | ||||
| 	lodsd | ||||
| 	xchg	[di], eax | ||||
| 	mov	[si-4], eax | ||||
| 	add	di, 4 | ||||
| 	loop	Hdr_Loop | ||||
|  | ||||
| 	ret | ||||
|  | ||||
| Swap_States endp | ||||
|  | ||||
|  | ||||
| ;************************************************************************ | ||||
| ; Swaps the VSM's registers with the local state | ||||
| ;************************************************************************ | ||||
| VSM_Registers proc | ||||
|  | ||||
| 	mov	esi, [VSM_Buffer]		; Caller's register buffer | ||||
| 	mov	ax, word ptr [BIOS_Header].EFLAGS | ||||
| 	xchg	fs:(INT_REGS PTR [esi]).Flags, ax | ||||
| 	mov	word ptr [BIOS_Header].EFLAGS, ax | ||||
| 	 | ||||
| 	lea	bx, [Reg_Table] | ||||
| 	mov	cx, (End_Reg_Table-Reg_Table)/2 | ||||
| Reg_Loop: | ||||
| 	mov	di, [bx]			; Get offset of register | ||||
| 	mov	eax, [di]			; Swap with register structure | ||||
| 	xchg	eax, fs:[esi] | ||||
| 	mov	[di], eax | ||||
| 	add	bx, 2				; Increment ptrs | ||||
| 	add	esi, 4 | ||||
| 	loop	Reg_Loop | ||||
|  | ||||
| 	ret | ||||
|  | ||||
| ; This table translates between a INT_REGS structure and the PUSHA/POPA ordering | ||||
| Reg_Table: | ||||
| 	dw	OFFSET BIOS_EAX | ||||
| 	dw	OFFSET BIOS_EBX | ||||
| 	dw	OFFSET BIOS_ECX | ||||
| 	dw	OFFSET BIOS_EDX | ||||
| 	dw	OFFSET BIOS_EBP | ||||
| 	dw	OFFSET BIOS_ESI | ||||
| 	dw	OFFSET BIOS_EDI | ||||
| End_Reg_Table: | ||||
|  | ||||
| VSM_Registers endp | ||||
|  | ||||
|  | ||||
| ;************************************************************************ | ||||
| ; Sets a descriptor to a real-mode descriptor | ||||
| ; Input: | ||||
| ;   AX = selector | ||||
| ;        If selector = 0x0000, a 4 GB descriptor (big-real) is used | ||||
| ;        If selector = 0xFFFF, the calling VSM's base/limit is used | ||||
| ;   DI = ptr to descriptor | ||||
| ;************************************************************************ | ||||
| Set_Descriptor proc pascal uses di \ | ||||
| 	DescrPtr: PTR Descriptor | ||||
|  | ||||
| 	ASSUME	di: PTR Descriptor | ||||
| 	mov	di, [DescrPtr] | ||||
|  | ||||
| 	mov	ebx, 0FFFFh			; 64K limit | ||||
|  | ||||
| 	or	ax, ax				; Selector = 0000h? | ||||
| 	jnz	short SetSelector | ||||
| 	mov	ebx, 008FFFFFh			; Yes, then use 4 GB limit (big-real mode) | ||||
| SetSelector: | ||||
|  | ||||
| 	movzx	eax, ax	 | ||||
| 	mov	[di].selector, ax | ||||
| 	shl	eax, 4 | ||||
|  | ||||
|  | ||||
| if ALLOW_SMM_SEGMENTS | ||||
| 	; If ES == 0xFFFF, use VSM's base | ||||
| 	cmp	ax, bx | ||||
| 	jne	short Set_Limit | ||||
| 	mov	eax, [Current_VSM]		; No, use VSM's base & limit | ||||
| 	mov	bx, ax | ||||
| 	shr	bx, 4 | ||||
| 	mov	[di].selector, bx | ||||
| 	mov	ebx, (VSM_Header PTR fs:[eax]).DS_Limit | ||||
| endif | ||||
|  | ||||
| Set_Limit: | ||||
| 	; EAX = base | ||||
| 	; EBX = limit | ||||
| 	mov	[di].limit_15_0, bx		; Store 24-bit limit | ||||
| 	shr	ebx, 16 | ||||
| 	mov	[di].limit_19_16, bl | ||||
|  | ||||
| 	mov	[di].base_15_0, ax		; Store	32-bit base | ||||
| 	shr	eax, 16 | ||||
| 	mov	[di].base_23_16, al | ||||
| 	mov	[di].base_31_24, ah | ||||
| 	ret | ||||
|  | ||||
| 	ASSUME	di: NOTHING | ||||
|  | ||||
| Set_Descriptor endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|    		align	4 | ||||
| Saved_State: | ||||
| ;****************************************************************************** | ||||
| ; The following must match the structure at StartSaveArea in SYSMGR.ASM | ||||
| BIOS_PCI	dd	80000000h | ||||
| BIOS_EDI	dd	0 | ||||
| BIOS_ESI	dd	0 | ||||
| BIOS_EBP	dd	0 | ||||
| 		dd	0			; ESP (not used) | ||||
| BIOS_EBX	dd	0 | ||||
| BIOS_EDX	dd	0 | ||||
| BIOS_ECX	dd	0 | ||||
| BIOS_EAX	dd	0 | ||||
|  | ||||
| BIOS_ESP	dd	0 | ||||
|  | ||||
| BIOS_SS		Descriptor {0FFFFh, 0, 0, DATA_ATTR, 0, 0, 0} | ||||
| BIOS_DS		Descriptor {0FFFFh, 0, 0, DATA_ATTR, 0, 0, 0} | ||||
| BIOS_ES		Descriptor {0FFFFh, 0, 0, DATA_ATTR, 0, 0, 0} | ||||
| BIOS_FS		Descriptor {0FFFFh, 0, 0, DATA_ATTR, 0, 0, 0} | ||||
| BIOS_GS		Descriptor {0FFFFh, 0, 0, DATA_ATTR, 0, 0, 0} | ||||
|  | ||||
| Hdr_Address	dd	0 | ||||
|  | ||||
| IDT_Selector	dd	00920000h | ||||
| IDT_Base	dd	00000000h | ||||
| IDT_Limit	dd	0000FFFFh | ||||
|  | ||||
| 	   | ||||
| 		dw	0			; Pad | ||||
| 		 | ||||
| ;****************************************************************************** | ||||
| SMM_CONTROL	equ EXTL_SMI_EN + INTL_SMI_EN + SMM_INST_EN + NEST_SMI_EN | ||||
|  | ||||
| BIOS_Header	SmiHeader {,SMM_CONTROL,,,,,,,,,VSM_CR0, VSM_EFLAGS, VSM_DR7} | ||||
|  | ||||
| ShadowMemory	dd	0, 0 | ||||
| ShadowAddr	dd	0 | ||||
| ShadowMSR	dw	0 | ||||
|  | ||||
| VSM_Buffer	dd	0 | ||||
|  | ||||
|  | ||||
| Saved_PIC	dw	0 | ||||
| Saved_INT	dd	0 | ||||
| Saved_Vector	dd	0 | ||||
| OldRCONF	db	0 | ||||
|  | ||||
| _CODE	ENDS | ||||
|  | ||||
|  | ||||
| 	END | ||||
							
								
								
									
										316
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/swapsif.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										316
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/swapsif.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,316 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //***************************************************************************** | ||||
| //*    SWAPSiFs routines | ||||
| //***************************************************************************** | ||||
|  | ||||
|  | ||||
|  | ||||
| #include "VSA2.H" | ||||
| #include "SYSMGR.H" | ||||
| #include "PROTOS.H" | ||||
| #include "VPCI.H" | ||||
| #include "PCI.H" | ||||
|  | ||||
|  | ||||
| // External Functions: | ||||
| extern void pascal Return_Virtual_Value(SmiHeader *, ULONG); | ||||
|  | ||||
|  | ||||
| // External Variables: | ||||
| extern PCI_HEADER_ENTRY ISA_Hdr[]; | ||||
| extern DESCRIPTOR MSRs[]; | ||||
|  | ||||
|  | ||||
|  | ||||
| #define ACPI_FLAGS (0) | ||||
| #define ACPI_RANGE 0x20 | ||||
| #define PMS_RANGE  0x80 | ||||
| #define PMS_FLAGS  (NOT_GLIU1) | ||||
|  | ||||
| ULONG ACPI_Timer_MSR; | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Enables/disables trapping of PMS or ACPI registers | ||||
| //*********************************************************************** | ||||
| UCHAR pascal PM_Trapping(USHORT EnableFlag, USHORT Bar) | ||||
| { ULONG DescrDefault[2]; | ||||
|   UCHAR Link, i=0; | ||||
|   register DESCRIPTOR * Descr; | ||||
|  | ||||
|   // For each linked item, update the associated MSR | ||||
|   Link = ISA_Hdr[Bar/4].Link; | ||||
|   while (Link) {   | ||||
|     Descr = &MSRs[Link]; | ||||
|  | ||||
|     // Get link to next MSR | ||||
|     Link = Descr->Link; | ||||
|  | ||||
|     // Ignore this MSR if not an I/O trap | ||||
|     if ((Descr->Flag & IO_TRAP) != IO_TRAP) { | ||||
|       continue; | ||||
|     } | ||||
|  | ||||
|     if (EnableFlag) { | ||||
|       // Restore descriptor to original value (re-enable trapping) | ||||
| 	  Write_MSR(Descr->MsrAddr, Descr->MsrData); | ||||
| 	} else { | ||||
|       i++; | ||||
|       // Set descriptor to default (disable trapping) | ||||
|       Get_Descriptor_Default(Descr->Type, DescrDefault); | ||||
| 	  Write_MSR(Descr->MsrAddr, DescrDefault); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return i; | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Enables/disables trapping of PM Support registers | ||||
| //*********************************************************************** | ||||
| UCHAR pascal PMS_Trapping(USHORT EnableFlag) | ||||
| { | ||||
|   return PM_Trapping(EnableFlag, BAR4); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Enables/disables trapping of ACPI registers | ||||
| //*********************************************************************** | ||||
| UCHAR pascal ACPI_Trapping(USHORT EnableFlag) | ||||
| { | ||||
|   return PM_Trapping(EnableFlag, BAR5); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Workaround for ACPI issues with A3 parts: | ||||
| // 1) Hang on byte accesses to ACPI registers 0x00-0x03  | ||||
| // 2) Improper sharing of shadow register | ||||
| // Flag: | ||||
| //  = 0 if PM Support registers | ||||
| //  = 1 if ACPI registers | ||||
| //*********************************************************************** | ||||
| void ACPI_Workaround(SmiHeader * SmiHdr, USHORT Flag) | ||||
| { USHORT Address; | ||||
|   UCHAR Alignment, Size; | ||||
|   ULONG WriteToClearMask, Mask, Data, SrcData; | ||||
|   static ULONG WriteToClearMasks[] = { | ||||
|     0xFFFF0000,		// 00 PM1_STS | ||||
|     0xFFFFFFFF,		// 04 PM1_EN | ||||
|     0xFFFFFDFF,		// 08 PM1_CNT | ||||
|     0xFFFFFFFF,		// 0C PM2_CNT | ||||
|     0xFFFFFFFF,		// 10 PM_TMR | ||||
|     0xFFFFFFFF,		// 14 Reserved | ||||
|     0x00000000,		// 18 GPE0_STS | ||||
|     0xFFFFFFFF,		// 1C GPE0_EN | ||||
|   }; | ||||
|  | ||||
|  | ||||
|   // Get info about the I/O from the SMM header | ||||
|   Data = SmiHdr->write_data; | ||||
|   Address = SmiHdr->IO_addr; | ||||
|   Size = (UCHAR)SmiHdr->data_size; | ||||
|  | ||||
|   Alignment = (UCHAR)((Address & 3) << 3); | ||||
|   // Make Address dword-aligned | ||||
|   Address &= ~3; | ||||
|  | ||||
|   if (Flag) { | ||||
|  | ||||
|     // Get write-to-clear mask for ACPI registers | ||||
|     WriteToClearMask = WriteToClearMasks[(Address & 0x1F) >> 2]; | ||||
|  | ||||
|     // Disable I/O trapping | ||||
|     ACPI_Trapping(0); | ||||
|  | ||||
|   } else { | ||||
|  | ||||
|     // Get write-to-clear mask for PM Support registers | ||||
| 	switch ((UCHAR)Address) { | ||||
|  | ||||
|       case 0x00: | ||||
|         WriteToClearMask = 0xFFFF7FFF; | ||||
|         break; | ||||
|  | ||||
|       case 0x54: | ||||
|         WriteToClearMask = 0xFFFF0000; | ||||
|         break; | ||||
|  | ||||
|       default: | ||||
|         WriteToClearMask = 0xFFFFFFFF; | ||||
|         break; | ||||
| 	} | ||||
|     // Disable I/O trapping | ||||
|     PMS_Trapping(0); | ||||
|  | ||||
|   } | ||||
|  | ||||
|  | ||||
|   // Read initial value | ||||
|   SrcData = in_32(Address); | ||||
|   | ||||
|   if (SmiHdr->SMI_Flags.IO_Write) {   | ||||
|     // I/O WRITE | ||||
|  | ||||
|     // Get mask appropriate to I/O size | ||||
|     switch (Size) { | ||||
|       case BYTE_IO: | ||||
|         Mask = 0x000000FF; | ||||
|         break; | ||||
|  | ||||
|       case WORD_IO: | ||||
|         Mask = 0x0000FFFF; | ||||
|         break; | ||||
|  | ||||
|       case DWORD_IO: | ||||
|         Mask = 0xFFFFFFFF; | ||||
| 		break; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     Data  &= Mask; | ||||
|     Data <<= Alignment; | ||||
|     SrcData &= ~(Mask << Alignment); | ||||
|  | ||||
|     // Write final data out; Don't rewrite write-to-clear bits | ||||
|     Data |= (SrcData & WriteToClearMask); | ||||
|     out_32(Address, Data); | ||||
|  | ||||
|   } else { | ||||
|  | ||||
|     // I/O READ | ||||
| 	Data = (SrcData >> Alignment); | ||||
|  | ||||
|     // Return value to the right environment                      | ||||
|     Return_Virtual_Value(SmiHdr, Data); | ||||
|   } | ||||
|  | ||||
|   // Re-enable I/O trapping | ||||
|   if (Flag) { | ||||
|     ACPI_Trapping(1); | ||||
|   } else { | ||||
|     PMS_Trapping(1); | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // An I/O BAR for devices in the MDD (e.g. PMS and ACPI) doesn't require | ||||
| // a GLIU descriptor since the MDD is the subtractive decode. Therefore, | ||||
| // if these registers are trapped, they are not linked to the BARs. | ||||
| // This function adds the linkages so when the BAR is changed, the  | ||||
| // descriptor(s) generating the I/O trap are also changed. | ||||
| // NOTES: | ||||
| // 1) The descriptors must be linked in order of increasing address. | ||||
| //    Increasing address does not imply increasing MSRs[] index, so the | ||||
| //    search index starts over at 1 on an address hit.  | ||||
| // 2) This function must handle the case where the BAR is of one size but | ||||
| //    the trapped range is another (either longer or shorter).  | ||||
| //*********************************************************************** | ||||
| void pascal FixupLinkages(USHORT Bar) | ||||
| { USHORT IO_Address; | ||||
|   UCHAR First = 0, Previous=0, Index; | ||||
|   register DESCRIPTOR * Descr; | ||||
|   | ||||
|   IO_Address = ISA_Hdr[Bar/4].Value_LO; | ||||
|  | ||||
|   // Walk through all the descriptors  | ||||
|   for (Index=1; Index<MAX_DESCR ; Index++ ) { | ||||
|     Descr = &MSRs[Index]; | ||||
|  | ||||
|     // Only examine descriptors used for I/O traps | ||||
|     if ((Descr->Flag & (AVAILABLE | IO_TRAP)) != IO_TRAP) { | ||||
|       continue; | ||||
|     } | ||||
|     // Does this descriptor map the region covered by the BAR? | ||||
|     if (Descr->Address == IO_Address) { | ||||
|       // Yes | ||||
|       if (Previous) { | ||||
|         // Link it | ||||
|         MSRs[Previous].Link = Index; | ||||
|       } else { | ||||
|         First = Index; | ||||
|       } | ||||
|       Previous = Index; | ||||
|  | ||||
|       // Mark it unavailable so we don't 'hit' again | ||||
|       Descr->Flag &= ~AVAILABLE; | ||||
|  | ||||
|       // Advance the address | ||||
|       IO_Address += (USHORT)Descr->Range; | ||||
|  | ||||
|       // Skip the ACPI timer register | ||||
|       if (Bar == BAR5) { | ||||
|         switch (IO_Address & (ACPI_RANGE-1)) { | ||||
|           case 0x10: | ||||
|             (UCHAR)IO_Address += 4; | ||||
|             break; | ||||
|           case 0x18: | ||||
|             // Record descriptor that skips ACPI timer | ||||
|             ACPI_Timer_MSR = Descr->MsrAddr; | ||||
|             break; | ||||
|         } | ||||
|       } | ||||
|       // Re-start search at beginning of MSR array | ||||
|       Index = 1; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   if (First) { | ||||
|     // Re-link the 'expanded' list to the BAR's linkages   | ||||
|     MSRs[Previous].Link = ISA_Hdr[Bar/4].Link; | ||||
|     ISA_Hdr[Bar/4].Link = First; | ||||
|   }	else { | ||||
|     Log_Error("No links found by FixupLinkages()"); | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Installs the trapping for ACPI and PMS register SWAPSiF | ||||
| //*********************************************************************** | ||||
| void ACPI_PMS_SWAPSiF(void) | ||||
| {  USHORT IO_Address; | ||||
|  | ||||
|   // Trap PMC registers (F0 BAR4) | ||||
|   IO_Address = ISA_Hdr[BAR4/4].IO_Base; | ||||
|   if (IO_Address) { | ||||
|     Register_Event(EVENT_IO_TRAP, 0, SysMgr_VSM, IO_Address, PMS_FLAGS | PMS_RANGE); | ||||
|     // Link the descriptors used for trapping the PMS registers | ||||
|     FixupLinkages(BAR4); | ||||
|   } | ||||
|  | ||||
|   // Trap ACPI registers (F0 BAR5) | ||||
|   IO_Address = ISA_Hdr[BAR5/4].IO_Base; | ||||
|   if (IO_Address) { | ||||
|     Register_Event(EVENT_IO_TRAP, 0, SysMgr_VSM, IO_Address,      ACPI_FLAGS | 0x10); | ||||
|     // Skip the ACPI Timer register | ||||
|     Register_Event(EVENT_IO_TRAP, 0, SysMgr_VSM, IO_Address+0x14, ACPI_FLAGS | 0x0C); | ||||
|     // Link the descriptors used for trapping the ACPI registers | ||||
|     FixupLinkages(BAR5); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										772
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/syscalls.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										772
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/syscalls.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,772 @@ | ||||
| ;  | ||||
| ; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| ;  | ||||
| ; This library is free software; you can redistribute it and/or modify | ||||
| ; it under the terms of the GNU Lesser General Public License as | ||||
| ; published by the Free Software Foundation; either version 2.1 of the | ||||
| ; License, or (at your option) any later version. | ||||
| ;  | ||||
| ; This code is distributed in the hope that it will be useful, | ||||
| ; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| ; Lesser General Public License for more details. | ||||
| ;  | ||||
| ; You should have received a copy of the GNU Lesser General | ||||
| ; Public License along with this library; if not, write to the | ||||
| ; Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| ; Boston, MA 02111-1307 USA  | ||||
| ;  | ||||
| ;******************************************************************************* | ||||
| ;*     Implements several system calls   | ||||
| ;******************************************************************************* | ||||
|  | ||||
|  | ||||
| include SYSMGR.INC | ||||
| include VSA2.INC | ||||
| include PCI.INC | ||||
| include SMIMAC.MAC | ||||
| include CHIPSET.INC | ||||
| include VR.INC | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| .model tiny,c | ||||
| .586p | ||||
| .CODE | ||||
|  | ||||
| public SysCall_Table | ||||
| public ReturnULONG | ||||
|  | ||||
|  | ||||
| externdef Sys_SW_INT:                   proc | ||||
| externdef Sys_Broadcast:                proc | ||||
| externdef Sys_PassEvent:                proc | ||||
| externdef Sys_State:                    proc | ||||
| externdef EmptyMsgQueue:                proc | ||||
| externdef ExitSysCall:                  proc | ||||
| externdef Dispatcher:                   proc | ||||
| externdef Sys_Exit:                     proc | ||||
| externdef Record_VSM_Locations:         proc | ||||
| externdef pascal Lookup_PCI:            proc | ||||
| externdef pascal Lookup_IO:             proc | ||||
| externdef pascal Find_MBus_ID:          proc | ||||
| externdef pascal Send_Event:            proc | ||||
| externdef pascal Schedule_VSM:          proc | ||||
| externdef pascal Allocate_BAR:          proc | ||||
| externdef pascal Register_Event:        proc | ||||
| externdef pascal Report_VSM_Error:      proc | ||||
| externdef pascal Allocate_Resource:     proc | ||||
| externdef pascal Set_Address_Decode:    proc | ||||
| externdef pascal Enable_PCI_Trapping:   proc | ||||
| externdef pascal Unregister_VSM_Events: proc | ||||
| externdef pascal IRQY_Mapper:           proc | ||||
| externdef pascal Return_Virtual_Value:  proc | ||||
|  | ||||
| externdef SysMgr_VSM:            dword | ||||
| externdef VSM_ListHead:          dword | ||||
| externdef Current_VSM:           dword | ||||
| externdef MsgPacket:             dword | ||||
| externdef SMI_Base:              dword | ||||
| externdef IRQ_Base:              dword | ||||
| externdef VSM_Ptrs:              dword | ||||
| externdef Events:                EVENT_ENTRY | ||||
| externdef HardwareInfo:          Hardware | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| 	align	2 | ||||
| SysCall_Table: | ||||
| 	dw	OFFSET Sys_Register	; 00 - SYS_CODE_EVENT | ||||
| 	dw	OFFSET Sys_Yield	; 01 - SYS_CODE_YIELD | ||||
| 	dw	OFFSET Sys_SW_INT	; 02 - SYS_CODE_SW_INT | ||||
| 	dw	OFFSET Sys_PassEvent	; 03 - SYS_CODE_PASS_EVENT | ||||
| 	dw	OFFSET Sys_Unload       ; 04 - SYS_CODE_UNLOAD | ||||
| 	dw	OFFSET Sys_Registers	; 05 - SYS_CODE_REGISTER | ||||
| 	dw	OFFSET Sys_RdWrPCI	; 06 - SYS_CODE_PCI_ACCESS | ||||
| 	dw	OFFSET Sys_SetVirtual	; 07 - SYS_CODE_SET_VIRTUAL | ||||
| 	dw	OFFSET Sys_GetVirtual	; 08 - SYS_CODE_GET_VIRTUAL | ||||
| 	dw	OFFSET Sys_Broadcast	; 09 - SYS_CODE_BROADCAST | ||||
| 	dw	OFFSET Sys_State	; 0A - SYS_CODE_STATE | ||||
| 	dw	OFFSET Sys_Report_Error ; 0B - SYS_CODE_ERROR | ||||
| 	dw	OFFSET Sys_Resource     ; 0C - SYS_CODE_RESOURCE | ||||
| 	dw	OFFSET Sys_Decode	; 0D - SYS_CODE_DECODE | ||||
| 	dw	OFFSET Sys_GetDescr	; 0E - SYS_CODE_DESCRIPTOR | ||||
| 	dw	OFFSET Sys_Lookup	; 0F - SYS_CODE_LOOKUP | ||||
| 	dw	OFFSET Sys_IRQ_Mapper	; 10 - SYS_CODE_IRQ_MAPPER | ||||
| 	dw	OFFSET Sys_Result     	; 11 - SYS_CODE_RESULT | ||||
| 	dw	OFFSET Sys_Duplicate    ; 12 - SYS_CODE_DUPLICATE | ||||
| 	dw	OFFSET EmptyMsgQueue    ; 13 - SYS_CODE_EXIT | ||||
|  | ||||
|  | ||||
| ;************************************************************************ | ||||
| ; Implements the WRITE_PCI_NO_TRAP macros | ||||
| ; | ||||
| ; On Entry: | ||||
| ;   SI = data size (bit 7 = 1 if I/O write); | ||||
| ;  EBX = PCI configuration address | ||||
| ;  ECX = data (if write) | ||||
| ;************************************************************************ | ||||
| Sys_RdWrPCI proc | ||||
|  | ||||
| 	push    ebx			; Save PCI address | ||||
| 	push    ecx			; Save data | ||||
| 	 | ||||
| 	; Disable trapping of PCI address | ||||
| 	push    bx			; PCI_Address | ||||
| 	push	word ptr 0000 | ||||
| 	call    Enable_PCI_Trapping | ||||
|  | ||||
| 	movzx   bp, al			; Save previous trap setting | ||||
|  | ||||
| 	pop     ecx			; Restore data | ||||
| 	pop     ebx			; Restore PCI address | ||||
|  | ||||
| 	; Write the PCI address | ||||
| 	mov     dx, PCI_CONFIG_ADDRESS | ||||
| 	mov     eax, ebx | ||||
| 	out     dx, eax | ||||
| 	add     dl, 4 | ||||
| 	and     al, 3 | ||||
| 	add     dl, al | ||||
|  | ||||
| 	btr     si, 7			; Read or write ? | ||||
| 	jc      PCI_Write		; Jmp if write | ||||
|          | ||||
| 	cmp     si, BYTE_IO		; Byte, Word, or Dword ? | ||||
| 	je      Read_Byte | ||||
| 	cmp     si, WORD_IO | ||||
| 	je      Read_Word | ||||
|  | ||||
|  | ||||
| Read_Dword: | ||||
| 	db      66h			; Force next instruction to be IN EAX,DX | ||||
| Read_Word: | ||||
| 	in      ax, dx | ||||
| 	jmp     short ReturnValue | ||||
|  | ||||
|  | ||||
| Read_Byte: | ||||
| 	in      al, dx | ||||
| ReturnValue: | ||||
|  | ||||
| 	push    eax			; Save return value | ||||
|  | ||||
| 	call    Restore_Trapping	; Re-enable PCI trapping | ||||
|  | ||||
| 	pop     ax			; Restore return value | ||||
| 	pop     dx		 | ||||
|  | ||||
| ReturnULONG:: | ||||
| 	mov     bx, word ptr gs:(VSM_Header).SysStuff.SavedESP | ||||
| 	mov	word ptr gs:[bx+8*4], ax | ||||
| 	mov	word ptr gs:[bx+6*4], dx | ||||
| 	jmp	ExitSysCall | ||||
| 	 | ||||
|  | ||||
|  | ||||
| ;************************************************************************ | ||||
| PCI_Write: | ||||
|  | ||||
| 	mov     eax, ecx		; Get data to be written | ||||
|    	cmp     si, WORD_IO		; Byte, Word, or Dword ? | ||||
| 	je      short Write_Word | ||||
| 	cmp     si, DWORD_IO | ||||
| 	je      short Write_Dword | ||||
| 	cmp     si, BYTE_IO | ||||
| 	jne     short Ignore		; Ignore if error in parameter | ||||
|  | ||||
| Write_Byte: | ||||
| 	out     dx, al | ||||
| 	jmp     short Restore_PCI_Trap | ||||
|  | ||||
|  | ||||
| Write_Dword: | ||||
| 	db      66h			; Force next instruction to be OUT DX,EAX | ||||
| Write_Word: | ||||
| 	out     dx, ax | ||||
|  | ||||
| Restore_PCI_Trap: | ||||
| 	call    Restore_Trapping	; Re-enable PCI trapping | ||||
|  | ||||
| Ignore: | ||||
| 	jmp     ExitSysCall | ||||
|  | ||||
|  | ||||
| Sys_RdWrPCI endp | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Restores PCI trapping | ||||
| ; On entry: | ||||
| ;   BP = 1 means re-enable PCI trapping | ||||
| ;*********************************************************************** | ||||
| Restore_Trapping proc | ||||
|  | ||||
| 	; Is trapping to be re-enabled ? | ||||
| 	cmp     bp, 1 | ||||
| 	jne     short Exit | ||||
|  | ||||
| 	; Yes, restore PCI trapping on this address | ||||
| 	; Enable_PCI_Trapping(PCI_Address, EnableFlag); | ||||
| 	push    bx			; PCI address | ||||
| 	push    bp			; EnableFlag | ||||
| 	call    Enable_PCI_Trapping | ||||
| Exit:	ret | ||||
|  | ||||
| Restore_Trapping endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; | ||||
| ; Register an event to the calling VSM | ||||
| ; | ||||
| ; On entry: | ||||
| ;   EBX = Event::Priority | ||||
| ;   ECX = Parameter 1 | ||||
| ;   EDI = Parameter 2 | ||||
| ;*********************************************************************** | ||||
| Sys_Register proc | ||||
|  | ||||
| 	; Register_Event(Event, Priority, VSM, Param1, Param2); | ||||
| 	push    ebx			; Event::Priority | ||||
| 	push    [Current_VSM]		; VSM ptr | ||||
| 	push    ecx			; Param1 | ||||
| 	push    edi 			; Param2 | ||||
| 	call    Register_Event | ||||
| 	jmp     ExitSysCall | ||||
|  | ||||
| Sys_Register endp | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Input: | ||||
| ;   BX = Virtual register index | ||||
| ; Output: | ||||
| ;   AX = returned data | ||||
| ;*********************************************************************** | ||||
| Sys_GetVirtual proc | ||||
|  | ||||
| 	xor     cx, cx			; Data = 0000 | ||||
| 	xor     di, di			; 0 = read | ||||
| 	jmp     VirtualCommon | ||||
|  | ||||
| Sys_GetVirtual endp | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Input: | ||||
| ;   BX = Virtual register index | ||||
| ;   CX = Data | ||||
| ;*********************************************************************** | ||||
| Sys_SetVirtual proc | ||||
|  | ||||
| 	call    Handle_PM | ||||
| 	 | ||||
| 	mov     di, 1			; 1 = write | ||||
| VirtualCommon:: | ||||
| 	cmp     bh, VRC_KEYBOARD	; Allow VRC_KEYBOARD to pass 32-bits | ||||
| 	je      Reschedule | ||||
| 	movzx   ecx, cx | ||||
| Reschedule:		 | ||||
| 	mov     edx, [Current_VSM]	; Re-schedule calling VSM | ||||
| 	push    edx | ||||
| 	call    Schedule_VSM | ||||
|  | ||||
| 	call    VirtualRegisterEvent | ||||
|  | ||||
| 	mov     ax, 0FFFFh		; Value of an undefined virtual register | ||||
| 	mov     bx, word ptr gs:(VSM_Header).SysStuff.SavedESP | ||||
| 	mov	word ptr gs:[bx+8*4], ax | ||||
| 	jmp	Dispatcher | ||||
| 	 | ||||
| 	 | ||||
|  | ||||
|  | ||||
| Sys_SetVirtual endp | ||||
|  | ||||
|  | ||||
| Handle_PM proc | ||||
|  | ||||
| if 0;SUPPORT_PM	; requires 78 bytes | ||||
| 	; If OHCI VSM is sending a USB event to KBD VSM, send an EVENT_IO_TRAP | ||||
| 	; to the PM VSM so system will exit DOZE mode. | ||||
| 	cmp     bh, VRC_KEYBOARD | ||||
| 	jne     short Exit | ||||
| 	mov     eax, [VSM_Ptrs+4*VSM_PM]; Is PM installed ? | ||||
| 	or      eax, eax | ||||
| 	jz      short Exit | ||||
| 	 | ||||
| 	 | ||||
| 	; Is PM VSM registered for the I/O trap ? | ||||
| 	mov	al, EVENT_IO_TRAP | ||||
| FindPM:	 | ||||
| 	mov	ah, sizeof(EVENT_ENTRY) | ||||
| 	mul	ah | ||||
| 	mov	si, ax | ||||
| 	mov	eax, (EVENT_ENTRY PTR [Events+si]).Vsm | ||||
| 	or	eax, eax | ||||
| 	jz	short Exit | ||||
| 	cmp	eax, edi		; Is it the PM VSM ? | ||||
| 	jne	short Next_VSM | ||||
| 	cmp	(EVENT_ENTRY PTR [Events+si]).Param1, 0060h | ||||
| 	je	short PM_Is_Dozing | ||||
| Next_VSM:	 | ||||
| 	mov	al, (EVENT_ENTRY PTR [Events+si]).Link | ||||
| 	or	al, al | ||||
| 	jnz	FindPM | ||||
| 	jmp	short Exit | ||||
| 	 | ||||
| 	 | ||||
| PM_Is_Dozing: | ||||
| 	push    bx			; Yes, save virtual register info | ||||
| 	push    cx | ||||
|  | ||||
| 	mov     eax, MSG_EVENT		; Send the PM VSM an EVENT_IO_TRAP[0x60] message | ||||
| 	mov     ebx, [SysMgr_VSM] | ||||
| 	lea     si, [PM_Packet] | ||||
| 	call    Insert_Msg | ||||
|  | ||||
| 	pop     cx			; Restore virtual register info | ||||
| 	pop     bx | ||||
|  | ||||
| endif | ||||
|  | ||||
| Exit:	ret | ||||
|  | ||||
| PM_Packet dd	 EVENT_IO_TRAP, 0, 0060h | ||||
|  | ||||
| Handle_PM endp | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Sends an EVENT_VIRTUAL_REGISTER to VSM(s) | ||||
| ; On entry: | ||||
| ;  BX = Class::Index | ||||
| ;  CX = write data | ||||
| ;  DI = 0 (read) or 1 (write) | ||||
| ; EDX = From_VSM | ||||
| ;*********************************************************************** | ||||
| VirtualRegisterEvent proc | ||||
|  | ||||
| 	lea     si, [MsgPacket]		; Fill the message packet | ||||
| 	movzx   eax, bx | ||||
| 	mov     [si+1*4], eax		; MsgPacket[1] : virtual register index | ||||
| 	mov     ax, di | ||||
| 	mov     [si+2*4], eax		; MsgPacket[2] : 0=read   1=write | ||||
| 	mov     [si+3*4], ecx 	 	; MsgPacket[3] : write data | ||||
|  | ||||
| 	mov     ax, EVENT_VIRTUAL_REGISTER ; No, so it's a VR access | ||||
| 	push    ax			; Event | ||||
| 	push    edx			; From_VSM | ||||
| 	call    Send_Event | ||||
| 	ret | ||||
| 	 | ||||
| VirtualRegisterEvent endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Implements the SYS_UNLOAD_VSM macro | ||||
| ;*********************************************************************** | ||||
| Sys_Unload proc | ||||
|  | ||||
| 	; Find prior VSM to current VSM | ||||
| 	mov     eax, [Current_VSM] | ||||
| 	or	eax, eax | ||||
| 	jz	short Exit	 | ||||
| 	 | ||||
| 	; Remove current VSM from linked list | ||||
| 	mov     ebx, (VSM_Header PTR fs:[eax]).SysStuff.Blink | ||||
| 	mov     ecx, (VSM_Header PTR fs:[eax]).SysStuff.Flink | ||||
| 	or	ebx, ebx		; Is there a previous VSM ? | ||||
| 	jnz	short IsBackLink | ||||
| 	mov	[VSM_ListHead], ecx	; No, update VSM_ListHead with VSM at Flink  | ||||
| 	jmp	short FixupBlink | ||||
| IsBackLink: | ||||
| 	mov     (VSM_Header PTR fs:[ebx]).SysStuff.Flink, ecx | ||||
| FixupBlink: | ||||
| 	or	ecx, ecx | ||||
| 	jz	short Unregister | ||||
| 	mov     (VSM_Header PTR fs:[ecx]).SysStuff.Blink, ebx | ||||
|  | ||||
| 	; Unregister events registered to this VSM | ||||
| Unregister: | ||||
| 	push    eax | ||||
| 	call	Unregister_VSM_Events | ||||
|  | ||||
| 	call    Record_VSM_Locations | ||||
| Exit:	jmp     Sys_Exit		; Exit to SysMgr | ||||
|  | ||||
| Sys_Unload endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Implements the SYS_ALLOCATE_RESOURCE macro | ||||
| ; Input: | ||||
| ;   BL  - Resource type | ||||
| ;   Other registers - various parameters | ||||
| ;*********************************************************************** | ||||
| Sys_Resource  proc | ||||
|  | ||||
| 	; Only BAR types are implemented at this time | ||||
| 	cmp	bl, RESOURCE_MEMORY | ||||
| 	je	short BAR_Resource | ||||
| 	cmp	bl, RESOURCE_MMIO | ||||
| 	je	short BAR_Resource | ||||
| 	cmp	bl, RESOURCE_IO | ||||
| 	je	short BAR_Resource | ||||
| 	cmp	bl, RESOURCE_SCIO | ||||
| 	je	short BAR_Resource | ||||
|  | ||||
| 	; Not a BAR resource	 | ||||
| 	push    bx			; Resource | ||||
| 	push    ecx			; Param | ||||
|   	call    Allocate_Resource | ||||
| 	jmp	ExitSysCall | ||||
| 	 | ||||
| 	 | ||||
| BAR_Resource: | ||||
| 	push	bx			; BAR type | ||||
| 	push	si			; BAR offset | ||||
| 	push	ecx			; Range | ||||
|  | ||||
| 	ror	edi, 16 | ||||
| 	push	di			; MBus_ID | ||||
| 	ror	edi, 16 | ||||
| 	push	di			; PCI Device_ID | ||||
| 	call    Allocate_BAR | ||||
|  | ||||
| 	jmp	ReturnULONG | ||||
|  | ||||
| Sys_Resource  endp | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Implements the SYS_REPORT_ERROR macro | ||||
| ;  DI = Error code | ||||
| ; EBX = Info1 | ||||
| ; ECX = Info2 | ||||
| ;*********************************************************************** | ||||
| Sys_Report_Error proc | ||||
|  | ||||
| 	push    di | ||||
| 	push    ebx | ||||
| 	push    ecx | ||||
| 	call    Report_VSM_Error | ||||
|  | ||||
| 	jmp     ExitSysCall | ||||
|  | ||||
|  | ||||
| Sys_Report_Error endp | ||||
|  | ||||
|  | ||||
| YIELD_HANDLE   equ  (ONE_SHOT OR SYS_YIELD OR 0000BEEFh) | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Implements the SYS_YIELD macro | ||||
| ; | ||||
| ; Input: | ||||
| ;   ECX = milliseconds to suspend the VSM | ||||
| ;*********************************************************************** | ||||
| Sys_Yield proc | ||||
|  | ||||
| 	mov     eax, [Current_VSM]      ; VSM that is yielding control | ||||
| 	mov     fs:(VSM_Header PTR [eax]).SysStuff.RunFlag, RUN_FLAG_WAITING | ||||
| 	 | ||||
| 	push    word ptr EVENT_TIMER    ; Event | ||||
| 	push    word ptr 0000           ; Priority | ||||
| 	push    eax			; Vsm | ||||
| 	push    ecx                     ; Param1 (ms) | ||||
| 	push    dword ptr YIELD_HANDLE  ; Param2 (handle) | ||||
| 	call    Register_Event | ||||
| 	 | ||||
| 	jmp     Sys_Exit		; Exit to SysMgr. Don't return to VSM | ||||
|  | ||||
| Sys_Yield endp | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; This system call is obsolete | ||||
| ; Input: | ||||
| ;   BH = 0 for Set, 1 for Get | ||||
| ;   BL = register definition | ||||
| ;  ECX = data if Set | ||||
| ;*********************************************************************** | ||||
| Sys_Registers proc | ||||
|  | ||||
| 	jmp     ExitSysCall | ||||
|  | ||||
| Sys_Registers endp | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Implements the SYS_MAP_IRQ macro | ||||
| ; Maps IRQ source to specified IRQ | ||||
| ; Input: | ||||
| ;   BL = Unrestricted Y source (0x00-0x0F) | ||||
| ;   CL = IRQ setting | ||||
| ;*********************************************************************** | ||||
| Sys_IRQ_Mapper proc | ||||
|  | ||||
| 	push    bx | ||||
| 	push    cx | ||||
| 	call    IRQY_Mapper | ||||
| 	jmp     ExitSysCall | ||||
|  | ||||
| Sys_IRQ_Mapper endp | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Input: | ||||
| ;   BX = Address | ||||
| ;   CX = Decode flag | ||||
| ;*********************************************************************** | ||||
| Sys_Decode proc | ||||
|  | ||||
| 	push    bx			; Address | ||||
| 	push    cx			; Decode (POSITIVE_DECODE or SUBTRACTIVE_DECODE) | ||||
| 	call    Set_Address_Decode | ||||
|  | ||||
| 	jmp     ExitSysCall | ||||
|  | ||||
| Sys_Decode endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Implements the SYS_MBUS_DESCRIPTOR & SYS_IO_DESCRIPTOR macros | ||||
| ; | ||||
| ; On entry: | ||||
| ;   BX = Address | ||||
| ;   CX = 0 if PCI else I/O | ||||
| ; Returns: | ||||
| ;  MSR address of corresponding resource | ||||
| ;*********************************************************************** | ||||
| Sys_GetDescr proc | ||||
|  | ||||
| 	jcxz	PCI | ||||
|  | ||||
|         ; MSR_Address = Lookup_IO(Address); | ||||
| 	push	bx | ||||
| 	call	Lookup_IO | ||||
|  | ||||
| 	mov	bl, 2			; Restore IO_Flag | ||||
| 	jmp	Common | ||||
| 	 | ||||
|         ; MSR_Address = Lookup_PCI(Address); | ||||
| PCI:	push	bx | ||||
| 	call	Lookup_PCI | ||||
|  | ||||
| 	xor	bx, bx | ||||
| Common:	 | ||||
| 	mov	cx, dx			; Was resource found ? | ||||
| 	shl	ecx, 16 | ||||
| 	mov	cx, ax | ||||
| 	xor	eax, eax		; EDX:EAX = 00000000:00000000 | ||||
| 	xor	edx, edx | ||||
| 	jecxz	ReturnMSRInfo | ||||
|  | ||||
| 	rdmsr				; Yes, read MSR | ||||
|  | ||||
| 	test	bl, 2			; Set MSR to default ? | ||||
| 	jz	ReturnMSRInfo | ||||
| 	push	edx			; Yes, save current value | ||||
| 	push	eax | ||||
|  | ||||
| 	test	eax, 000F0000h		; IOD_BM or IOD_SC ? | ||||
| 	mov	eax, 00000000h		; Default for IOD_SC | ||||
| 	mov	edx, eax | ||||
| 	jz	SetDefault | ||||
| 	mov	eax, 0FFF00000h		; Default for IOD_BM | ||||
| 	mov	edx, 0000000FFh | ||||
| SetDefault: | ||||
| 	wrmsr				; Set MSR to default value | ||||
|  | ||||
| 	pop	eax			; Restore original MSR value | ||||
| 	pop	edx | ||||
|  | ||||
| 	; Return MSR address in ECX and MSR value in EDX:EAX | ||||
| ReturnMSRInfo: | ||||
| 	mov     bx, word ptr gs:(VSM_Header).SysStuff.SavedESP | ||||
| 	mov	gs:[bx+7*4], ecx	; Return MSR address in ECX | ||||
| 	mov	gs:[bx+8*4], eax	; Return MSR value in EDX:EAX | ||||
| 	mov	gs:[bx+6*4], edx | ||||
| 	jmp	ExitSysCall | ||||
|  | ||||
| Sys_GetDescr endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Implements the SYS_LOOKUP_DEVICE macro | ||||
| ; | ||||
| ; On entry: | ||||
| ;   BX = MBus Device_ID | ||||
| ;   CX = Instance | ||||
| ; Returns: | ||||
| ;  DX:AX = MSR routing address to MBus device | ||||
| ;*********************************************************************** | ||||
| Sys_Lookup proc | ||||
|  | ||||
| 	; Find_MBus_ID(USHORT MBus_ID, UCHAR Instance); | ||||
| 	push	bx | ||||
| 	push	cx | ||||
| 	call	Find_MBus_ID | ||||
| 	xor     ax, ax | ||||
|  | ||||
| 	jmp	ReturnULONG | ||||
|  | ||||
| Sys_Lookup endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Implements the SYS_RETURN_RESULT macro | ||||
| ; Returns a byte/word/dword result to the correct context. | ||||
| ; Input: | ||||
| ;   EBX = Result to be returned | ||||
| ;*********************************************************************** | ||||
| Sys_Result proc | ||||
|  | ||||
| 	push	OFFSET VSM_Header.SysStuff.State | ||||
| 	push    ebx			; Value | ||||
| 	call    Return_Virtual_Value | ||||
|  | ||||
| 	jmp     ExitSysCall | ||||
|  | ||||
| Sys_Result endp | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Implements the SYS_DUPLICATE_VSM macro | ||||
| ; On entry: BX = memory model | ||||
| ;                 Legend:    (C=copy of parent VSM) (N=new copy) | ||||
| ;                    CS    DS    SS | ||||
| ;                0:  N     N     N | ||||
| ;                1:  C     N     N | ||||
| ;*********************************************************************** | ||||
| Sys_Duplicate proc | ||||
|  | ||||
| ;	mov	[MemoryModel], bx   ; Ignore parameter for new | ||||
| 	 | ||||
| 	; Find end of VSMs in memory | ||||
| 	mov	esi, [Current_VSM] | ||||
| 	mov	ebx, esi | ||||
| FindLastVSM: | ||||
| 	mov	edi, ebx | ||||
| 	mov	ebx, (VSM_Header PTR fs:[ebx]).SysStuff.Flink | ||||
| 	or	ebx, ebx | ||||
| 	jnz	FindLastVSM | ||||
|  | ||||
| 	; EDI points to last VSM in memory.  Find end of last VSM. | ||||
| 	mov	edx, edi | ||||
| 	add	edi, (VSM_Header PTR fs:[edi]).DS_Limit | ||||
|  | ||||
|  | ||||
| 	; Copy this VSM's image | ||||
| 	mov	ecx, (VSM_Header PTR fs:[esi]).DS_Limit | ||||
| 	cmp	[MemoryModel], 0	; Use same Code segment ? | ||||
| 	je	short CopyImage | ||||
| 	mov	ecx, sizeof(VSM_Header) + VSM_STACK_SIZE | ||||
| CopyImage:		 | ||||
| 	push	edi | ||||
| 	push	esi | ||||
| 	push	ecx | ||||
| 	shr	ecx, 2			; Convert BYTE count to DWORDs | ||||
| 	rep	movsd [edi], es:[esi] | ||||
| 	pop	ecx | ||||
| 	pop	esi | ||||
| 	pop	edi | ||||
|  | ||||
| 	; Patch descriptors | ||||
| 	mov	(VSM_Header PTR fs:[edi])._DS.base_15_0, di | ||||
| 	mov	(VSM_Header PTR fs:[edi])._SS.base_15_0, di | ||||
| 	mov	eax, edi | ||||
| 	shr	eax, 16 | ||||
| 	mov	(VSM_Header PTR fs:[edi])._DS.base_31_24, ah | ||||
| 	mov	(VSM_Header PTR fs:[edi])._DS.base_23_16, al | ||||
| 	mov	(VSM_Header PTR fs:[edi])._SS.base_31_24, ah | ||||
| 	mov	(VSM_Header PTR fs:[edi])._SS.base_23_16, al | ||||
|  | ||||
| 	mov	(VSM_Header PTR fs:[edi])._DS.limit_15_0, cx | ||||
| 	mov	(VSM_Header PTR fs:[edi])._SS.limit_15_0, cx | ||||
| ;	Required for segments > 64K	 | ||||
| ;	shr	ecx, 16 | ||||
| ;	mov	(VSM_Header PTR fs:[edi])._DS.limit_19_16, cl | ||||
| ;	mov	(VSM_Header PTR fs:[edi])._SS.limit_19_16, cl | ||||
|  | ||||
|  | ||||
| 	cmp	[MemoryModel], 0	; Use same Code segment ? | ||||
| 	jne	short LinkNewVSM | ||||
| 	mov	(VSM_Header PTR fs:[edi]).SysStuff.State._CS.base, edi | ||||
|  | ||||
| LinkNewVSM:	 | ||||
| 	; Link the new VSM into the VSM list | ||||
| 	mov	(VSM_Header PTR fs:[edx]).SysStuff.Flink, edi | ||||
| 	mov	(VSM_Header PTR fs:[edi]).SysStuff.Blink, edx | ||||
| 	mov	(VSM_Header PTR fs:[edi]).SysStuff.Flink, 0 | ||||
|  | ||||
| 	; Init EIP | ||||
| 	movzx	eax, (VSM_Header PTR fs:[edi]).EntryPoint | ||||
| 	mov	(VSM_Header PTR fs:[edi]).SysStuff.State.Next_EIP, eax | ||||
|  | ||||
| 	; Init ESP & create the initial stack frame | ||||
| 	mov	eax, (VSM_Header PTR fs:[edi]).DS_Limit | ||||
| 	sub	ax, VSM_STACK_FRAME | ||||
| 	mov	(VSM_Header PTR fs:[edi]).SysStuff.SavedESP, eax | ||||
|  | ||||
| 	; Schedule the new VSM | ||||
| 	push    edi | ||||
| 	call    Schedule_VSM | ||||
|  | ||||
| 	jmp     ExitSysCall | ||||
| 	ret			; Gets rid of assembler warning | ||||
|  | ||||
| ; Warning: don't make MemoryModel a variable on the stack | ||||
| ; The JMP ExitSysCall bypasses the LEAVE instruction and BP is trashed | ||||
| MemoryModel	dw	0 | ||||
|  | ||||
| Sys_Duplicate endp | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Returns TRUE if the VSM is currently yielded | ||||
| ;*********************************************************************** | ||||
| VSM_Is_Yielded proc Vsm: dword | ||||
|  | ||||
| 	mov     ebx, [Vsm] | ||||
| 	mov     al, 0			; return FALSE | ||||
| 	cmp     fs:(VSM_Header PTR [ebx]).SysStuff.RunFlag, RUN_FLAG_WAITING | ||||
| 	jne     short Exit | ||||
| 	mov     al, 1			; return TRUE | ||||
| Exit: | ||||
| 	ret | ||||
|  | ||||
| VSM_Is_Yielded endp | ||||
|  | ||||
|  | ||||
| 	END | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										804
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/sysmgr.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										804
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/sysmgr.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,804 @@ | ||||
| ;  | ||||
| ; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| ;  | ||||
| ; This library is free software; you can redistribute it and/or modify | ||||
| ; it under the terms of the GNU Lesser General Public License as | ||||
| ; published by the Free Software Foundation; either version 2.1 of the | ||||
| ; License, or (at your option) any later version. | ||||
| ;  | ||||
| ; This code is distributed in the hope that it will be useful, | ||||
| ; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| ; Lesser General Public License for more details. | ||||
| ;  | ||||
| ; You should have received a copy of the GNU Lesser General | ||||
| ; Public License along with this library; if not, write to the | ||||
| ; Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| ; Boston, MA 02111-1307 USA  | ||||
| ;  | ||||
| ;*   Function:                                                         * | ||||
| ;*     This file contains the entry point to the SMM code.             * | ||||
| ;*     This code performs the following:                               * | ||||
| ;*       1) saves the processor state                                  * | ||||
| ;*       2) reads the top-level SMI source register(s)                 * | ||||
| ;*       3) issues message(s) to the appropriate VSM(s)                * | ||||
| ;*       4) dispatches to VSM(s) until all messages are handled        * | ||||
| ;*       5) restores the processor state  | ||||
|  | ||||
| include SYSMGR.INC | ||||
| include VSA2.INC | ||||
| include PCI.INC | ||||
| include SMIMAC.MAC | ||||
| include CHIPSET.INC | ||||
| include CS5536.INC | ||||
| include GX2.INC | ||||
|  | ||||
| .model tiny,c | ||||
| .586p | ||||
|  | ||||
| .ALPHA | ||||
| DGROUP	GROUP _CODE, _TEXT | ||||
| _CODE	SEGMENT PUBLIC use16 'CODE' | ||||
| 	ASSUME DS:_CODE | ||||
|  | ||||
|  | ||||
| BRACKETS  equ	0 | ||||
|  | ||||
| public    SysMgr_Entry | ||||
| public    Nested_SMI | ||||
| public    Saved_EAX, Saved_AX | ||||
| public    Saved_EBX, Saved_ECX, Saved_EDX, Saved_PCI | ||||
| public    Saved_ESI, Saved_EDI, Saved_EBP, Saved_ESP | ||||
| public    Saved_SS,  Saved_ES,  Saved_DS,  Saved_FS, Saved_GS | ||||
| public    IDT_Selector, IDT_Base, IDT_Limit | ||||
| public    VSMs_EAX | ||||
| public    Nested_PCI, Nested_EDI, Nested_EAX, Nested_ES | ||||
| public    StartSaveArea, EndSaveArea | ||||
| public    SchedulerStack | ||||
| public    Sys_Exit | ||||
| public    VSM_ListHead | ||||
| public    SMM_Header | ||||
| public    SysMgr_VSM | ||||
| public    Data_Descriptor | ||||
| public    Flat_Descriptor | ||||
| public    Current_VSM | ||||
| public    Nested_Flag | ||||
| public    HardwareInfo | ||||
| public    SMI_Base | ||||
| public    IRQ_Base, IRQ_Mask | ||||
| public    Header_Addr | ||||
| public    BracketFlag | ||||
| public    ExitSysCall | ||||
| public    EmptyMsgQueue | ||||
| public    Dispatcher | ||||
| public    Trap_Code | ||||
|  | ||||
| externdef Trap_Common:        proc | ||||
| externdef Trap7:              proc | ||||
| externdef Get_SMI_Sources:    proc | ||||
| externdef VSA_Entry:          proc | ||||
| externdef VSA_Exit:           proc | ||||
| externdef Show_SMI_Source:    proc | ||||
| externdef Generate_IRQ:       proc | ||||
| externdef pascal Hex_8:       proc | ||||
| externdef pascal Hex_16:      proc | ||||
| externdef pascal Hex_32:      proc | ||||
| externdef pascal SMINT_Handler:proc | ||||
|  | ||||
| externdef INT_Vectors:        dword | ||||
| externdef SMI_Sources:        dword | ||||
| externdef SynchEvents:        dword | ||||
| externdef HiPrioritySMIs:     dword | ||||
| externdef MSRs:               dword | ||||
|  | ||||
| externdef SysCall_Table:      word | ||||
|  | ||||
| externdef NumDescriptors:     byte | ||||
| externdef Events:             byte | ||||
| externdef MSRs:               byte | ||||
| externdef _end:	       byte | ||||
| externdef edata:              byte | ||||
|  | ||||
| externdef Handler_Table:      SMI_ENTRY | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ; NOTE: "#define EXTRA_SAVE" in SYSMGR.H must match the number of bytes | ||||
| ;        of state (over and above the registers) that is saved by the | ||||
| ;        following two macros: | ||||
| SAVE_STATE macro | ||||
| 	pushad				; Save general purpose registers | ||||
| 	mov	dx, PCI_CONFIG_ADDRESS 	; Save PCI Configuration Address | ||||
| 	in	eax, dx | ||||
| 	push	eax | ||||
|  | ||||
| 	endm | ||||
|  | ||||
|   | ||||
| RESTORE_STATE macro | ||||
| 	pop	eax			; PCI Configuration Address | ||||
| 	mov	dx, PCI_CONFIG_ADDRESS | ||||
| 	out	dx, eax | ||||
| 	popad				; Restore general purpose registers | ||||
|  | ||||
| 	endm | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| Start: | ||||
| ; NOTE: The VSA II installer patches a "JMP SysMgr_Entry" over the signature field | ||||
| 	dd	VSM_SIGNATURE		; VSM signature | ||||
| 	db	VSM_SYS_MGR		; VSM type | ||||
| 	db	0FFh			; Any CPU | ||||
| 	dw	DEVICE_ID_5536		; VSA for CS5536 | ||||
| 	dw	VSA_VERSION		; System Manager version  | ||||
| 	dd	OFFSET edata		; Size of System Manager | ||||
| 	dw	OFFSET SysMgr_Entry	; EntryPoint | ||||
| 	dd	OFFSET _end		; DS Limit | ||||
| 	dw	0007h			; Requirements: 4096-byte boundary | ||||
|  	dw	VSA_VERSION		; VSA version | ||||
|  | ||||
| Stack_Descriptor: | ||||
|  	Descriptor {_end,   0000h, 00h, DATA_ATTR, 00h, 00h, 0000h} | ||||
| Data_Descriptor: | ||||
|  	Descriptor {_end,   0000h, 00h, DATA_ATTR, 00h, 00h, 0000h} | ||||
|  | ||||
| Flat_Descriptor: | ||||
| 	Descriptor {0FFFFh, 0000h, 00h, DATA_ATTR, 8Fh, 00h, 0000h} | ||||
|  | ||||
|  | ||||
| 		dw	0		; .AlignSystem | ||||
| SMM_Header	SmiHeader {}		; .State | ||||
| VSM_ListHead	dd	0		; .Flink (ptr to 1st VSM; zero if no VSMs) | ||||
|  | ||||
| Trap	macro  Trap_Num | ||||
| 	ORG	Trap_Code + (Trap_Num * 8) | ||||
| 	mov	bx, Trap_Num | ||||
| 	jmp	Trap_Common | ||||
| 	endm | ||||
|  | ||||
| 	ORG	sizeof(VSM_Header) | ||||
| 	align	16 | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Exception vectors | ||||
| ;*********************************************************************** | ||||
| Trap_Code: | ||||
| 	Trap	0 | ||||
| 	Trap	1 | ||||
| 	Trap	2 | ||||
| 	Trap	3 | ||||
| 	Trap	4 | ||||
| 	Trap	5 | ||||
| 	Trap	6 | ||||
|  | ||||
| 	ORG	Trap_Code + (7 * 8) | ||||
| 	jmp	Trap7 | ||||
|  | ||||
| 	Trap	8 | ||||
| 	Trap	9 | ||||
| 	Trap	0Ah | ||||
| 	Trap	0Bh | ||||
| 	Trap	0Ch | ||||
| 	Trap	0Dh | ||||
| 	Trap	0Eh | ||||
| 	Trap	0Fh | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ;       Non-nested VSA entry point                                     * | ||||
| ;*********************************************************************** | ||||
| SysMgr_Entry: | ||||
|  | ||||
| 	; | ||||
| 	; Save state of interrupted task & initialize VSA environment | ||||
| 	; | ||||
| 	svdc	cs:[Saved_DS], ds	; Save DS descriptor & set to SysMgr segment | ||||
| 	rsdc	ds, cs:[Data_Descriptor] | ||||
| 	ASSUME  DS:_CODE | ||||
|  | ||||
| 	svdc	[Saved_ES], es		; Save ES descriptor | ||||
| 	svdc	[Saved_FS], fs		; Save FS descriptor	 | ||||
| 	svdc	[Saved_GS], gs		; Save GS descriptor | ||||
|  | ||||
| 	svdc	[Saved_SS], ss		; Save SS descriptor & set to SysMgr segment | ||||
| 	rsdc    ss, [Stack_Descriptor] | ||||
| 	mov     [Saved_ESP], esp	; Save ESP & set up SysMgr stack | ||||
| 	mov     esp, OFFSET SysMgrStack | ||||
|  | ||||
| 	SAVE_STATE			; Save the general purpose registers on SysMgr's stack | ||||
|  | ||||
|  | ||||
| 	rdtsc				; Get start time of this SMI | ||||
| 	mov     (VSM_Header PTR ds:[0]).SysStuff.StartTime, eax | ||||
| 	mov     (VSM_Header PTR ds:[4]).SysStuff.StartTime, edx | ||||
|  | ||||
| 	rsdc	fs, [Flat_Descriptor]	; Set FS descriptor to a 4 GB flat segment | ||||
| 	rsdc	es, [Flat_Descriptor]	; Set ES descriptor to a 4 GB flat segment | ||||
|  | ||||
| if BRACKETS | ||||
| 	cmp	[BracketFlag], 0 | ||||
| 	je	short NoBracket | ||||
| 	mov	dx, DBG_PORT | ||||
| 	mov	al, '[' | ||||
| 	out	dx, al | ||||
| 	 | ||||
| NoBracket: | ||||
| endif | ||||
|  | ||||
|  | ||||
| 	call	VSA_Entry		; Perform VSA entry setup | ||||
|  | ||||
| 	xor	eax, eax | ||||
| 	mov	[Nested_Flag], eax | ||||
|  | ||||
| 	; | ||||
| 	; Check for SMINT | ||||
| 	; | ||||
| 	test	[SMM_Header].SMI_Flags, 1000b | ||||
| 	jz	short Main_SMI_Loop  | ||||
|  | ||||
| 	push	word ptr [Saved_EAX] | ||||
| 	call	SMINT_Handler | ||||
| 	jmp	Dispatcher | ||||
| 	 | ||||
| ;*********************************************************************** | ||||
| ;*********************************************************************** | ||||
| ;*********************************************************************** | ||||
| ;                                                                      * | ||||
| ;	Main SMI Loop                                                  * | ||||
| ;                                                                      * | ||||
| ;   1) Read the top-level SMI sources.                                 * | ||||
| ;   2) If no SMIs are pending, exit SMM.                               * | ||||
| ;   3) Call an SMI handler for each pending SMI source.                * | ||||
| ;   4) Dispatch to VSMs that have non-empty message queues.            * | ||||
| ;   5) Rinse and repeat.                                               * | ||||
| ;                                                                      * | ||||
| ;*********************************************************************** | ||||
| ;*********************************************************************** | ||||
| ;*********************************************************************** | ||||
| Main_SMI_Loop: | ||||
|  | ||||
| 	call	Get_SMI_Sources		; Get source(s) of external SMIs | ||||
| 	test	ebx, ebx		; If no SMIs pending, exit SMM | ||||
| 	jz	SMI_Resume | ||||
|  | ||||
|  | ||||
| 	; | ||||
| 	; Invoke the handler for each pending SMI source | ||||
| 	; | ||||
| 	mov	[SMI_Sources], ebx | ||||
| RunHandlers: | ||||
| 	lea	di, Handler_Table - sizeof (SMI_ENTRY) | ||||
| NextHandler: | ||||
| 	add	di, sizeof (SMI_ENTRY)	; Advance ptr to next handler entry | ||||
|  | ||||
| 	mov	eax, (SMI_ENTRY PTR [di]).SMI_Mask | ||||
| 	and	eax, [SMI_Sources]	; Sources = TopLevelSources & Handler_Table.SMI_Mask | ||||
| 	jz	NextHandler | ||||
|  | ||||
| 	push	eax			; call Handler_Table.Handler(Sources) | ||||
| 	call	(SMI_ENTRY PTR [di]).Handler | ||||
| 	pop	eax | ||||
|  | ||||
| 	not	eax			; TopLevelSources &= ~Sources; | ||||
| 	and	[SMI_Sources], eax | ||||
| 	jnz	NextHandler		; if (!TopLevelSources) break; | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| 	; | ||||
| 	; Dispatch to the VSM on top of the scheduler's stack | ||||
| 	; | ||||
| Dispatcher: | ||||
| 	mov	si, [SchedulerStack]	; Get scheduler's ptr | ||||
| 	mov	ebx, [si]		; Pop next VSM | ||||
| 	sub	si, 4 | ||||
|  | ||||
| 	test	ebx, 0FFFF0000h		; Is it a VSM ? | ||||
| 	jnz	RunTask | ||||
| 	test	bx, bx			; Callback routine ? | ||||
| 	je	Main_SMI_Loop | ||||
| 	mov	[SchedulerStack], si	; Yes, update scheduler ptr | ||||
| 	call	bx			; Go to callback routine | ||||
| 	jmp	Dispatcher | ||||
|         | ||||
|         | ||||
| RunTask: | ||||
| 	mov	[SchedulerStack], si	; Save scheduler's ptr | ||||
| 	mov	[Current_VSM], ebx	; Save ptr to the current VSM | ||||
| ExecuteTask:	 | ||||
| 	; | ||||
| 	; Point SMHR to the VSM's SMM header. | ||||
| 	; | ||||
| 	lea	eax, (VSM_Header PTR [ebx+sizeof(SmiHeader)]).SysStuff.State | ||||
| 	mov	ecx, MSR_SMM_HDR | ||||
| 	wrmsr | ||||
| 	; | ||||
| 	; Restore the VSM's state | ||||
| 	; | ||||
| 	rsdc	ds, fs:(VSM_Header PTR [ebx])._DS | ||||
| 	 | ||||
| 	xor	edi, edi | ||||
| 	ASSUME	di:PTR VSM_Header | ||||
| 	rsdc	gs, [di]._DS | ||||
| 	rsdc	ss, [di]._SS		; Restore VSM's SS:SP | ||||
| 	lea	bx, [di].SysStuff | ||||
| 	ASSUME	bx:PTR System | ||||
| 	mov	sp, word ptr [bx].SavedESP | ||||
|  | ||||
|  | ||||
| 	; | ||||
| 	; Update statistics | ||||
| 	; | ||||
| 	rdtsc				; Record start time of the VSM | ||||
| 	mov	[bx+0].StartTime, eax | ||||
| 	add	[bx+0].NumSMIs, 1	; Increment SMI count | ||||
| 	adc	[bx+4].NumSMIs, edi | ||||
|  | ||||
| 	; | ||||
| 	; Mark VSM active unless it is sleeping | ||||
| 	; | ||||
| 	mov	al, RUN_FLAG_ACTIVE | ||||
| SetRunFlag: | ||||
| 	xchg	[bx].RunFlag, al | ||||
| 	cmp	al, RUN_FLAG_SLEEPING | ||||
| 	je	SetRunFlag | ||||
|  | ||||
| 	RESTORE_STATE			; No, restore registers | ||||
| 	 | ||||
| 	rsm				; Resume to the VSM | ||||
|  | ||||
|  | ||||
| 	ASSUME	DI: NOTHING | ||||
| 	ASSUME	BX: NOTHING | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ;      Restore state & resume to non-SMM code                          * | ||||
| ;*********************************************************************** | ||||
| 	align	16 | ||||
| SMI_Resume: | ||||
|  | ||||
|  | ||||
| 	; Generate internal IRQ(s) | ||||
| 	xor	ecx, ecx | ||||
| 	xchg	ecx, [IRQ_Mask] | ||||
| 	jecxz	NoIRQ | ||||
| 	call	Generate_IRQ | ||||
| NoIRQ: | ||||
|  | ||||
|  | ||||
| 	call	VSA_Exit		; Perform VSA exit | ||||
| 	jc	Main_SMI_Loop | ||||
| 			  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| 	; Increment count of SMIs | ||||
| 	mov     si, OFFSET VSM_Header.SysStuff | ||||
| 	ASSUME	SI: PTR System | ||||
| 	xor	ecx, ecx | ||||
| 	add	[si+0].NumSMIs, 1 | ||||
| 	adc	[si+4].NumSMIs, ecx | ||||
|  | ||||
| 	; Compute total clocks for this SMI | ||||
| 	rdtsc | ||||
| 	sub	eax, [si+0].StartTime | ||||
| 	; Accumulate total clocks spent executing VSA code | ||||
| 	add	[si+0].Clocks, eax | ||||
| 	adc	[si+4].Clocks, ecx | ||||
|  | ||||
| 	ASSUME  SI:NOTHING | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| if BRACKETS | ||||
| 	cmp	[BracketFlag], 0 | ||||
| 	je	@f | ||||
| 	mov	dx, DBG_PORT | ||||
| 	mov	al, ']' | ||||
| 	out	dx, al | ||||
| @@: | ||||
| endif | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ;         Restore the state of the interrupted task                    * | ||||
| ;*********************************************************************** | ||||
| 	RESTORE_STATE			; Restore GP registers & PCI addr | ||||
|  | ||||
| 	mov	esp, [Saved_ESP]	; Restore ESP | ||||
| 	rsdc	ss,  [Saved_SS]		; Restore descriptors | ||||
| 	rsdc	es,  [Saved_ES] | ||||
| 	rsdc	fs,  [Saved_FS] | ||||
| 	rsdc	gs,  [Saved_GS] | ||||
| 	rsdc	ds,  [Saved_DS]		; Must be restored last | ||||
| 	rsm				; Resume to non-SMM thread | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; An SMI has occurred that is not a system call:                       * | ||||
| ;                                                                      * | ||||
| ; If synchronous SMI:                                                  * | ||||
| ;    - Save the state of the interrupted VSM                           * | ||||
| ;    - Reschedule the interrupted VSM                                  * | ||||
| ;    - Execute SMI handlers                                            * | ||||
| ; If asynchronous SMI:                                                 * | ||||
| ;    - If event is not high priority or VSM is marked no-preempt,      * | ||||
| ;      return to interrupted VSM immediately.                          * | ||||
| ;    - Otherwise, execute SMI handlers                                 * | ||||
| ;*********************************************************************** | ||||
| 	align	16 | ||||
| NotSysCall: | ||||
|  | ||||
| 	; | ||||
| 	; Save VSM's state and set up SysMgr stack | ||||
| 	; | ||||
| 	SAVE_STATE			; Save the VSM's state | ||||
| 	mov     word ptr gs:(VSM_Header).SysStuff.SavedESP, sp | ||||
|  | ||||
| 	rsdc    ss, [Stack_Descriptor]	; Setup System Manager's stack | ||||
| 	lea	sp, [StartSaveArea] | ||||
|  | ||||
|  | ||||
| 	call	Get_SMI_Sources		; Get source(s) of nested SMIs | ||||
|  | ||||
| 	mov	[SMI_Sources], ebx	; Record the pending SMI sources | ||||
| 	test	ebx, [SynchEvents]	; Is nested SMI a syncronous event ? | ||||
| 	jz	short AsyncSMI | ||||
|  | ||||
| 	; | ||||
| 	; The SMI is synchronous (I/O or virtualized PCI trap) | ||||
| 	; | ||||
| 	and	ebx, [SynchEvents]	; Record the nested SMI source | ||||
| 	or	[Nested_Flag], ebx | ||||
|  | ||||
| 	; It's a trapped or virtualized PCI. | ||||
| 	; Record some info about the event. | ||||
| 	svdc	[Nested_ES], gs		; Save GS descriptor | ||||
| 	mov	esi, gs:(VSM_Header).SysStuff.SavedESP | ||||
| 	mov	eax, gs:[si+0]		; Get VSM's PCI address | ||||
| 	mov	edi, gs:[si+4]		; Get VSM's EDI | ||||
| 	mov	[Nested_PCI], eax	; Required by PCI_Handler | ||||
| 	mov	[Nested_EDI], edi	; Required if INS | ||||
| 	add	esi, VSM_STACK_FRAME - 4 | ||||
| 	add	esi, [Current_VSM]	; Ptr to EAX on VSM's stack | ||||
| 	mov	[Nested_EAX], esi | ||||
|  | ||||
| ServiceNow: | ||||
|  | ||||
| 	mov	gs:(VSM_Header).SysStuff.RunFlag, RUN_FLAG_READY | ||||
| Reschedule:	 | ||||
| 	add	[SchedulerStack], 4	; Re-schedule the interrupted VSM | ||||
|  | ||||
| 	mov	ebp, [SMI_Sources]	; Needed by RunHandlers | ||||
|  | ||||
| 	; Update the clock count used by the VSM | ||||
| 	rdtsc | ||||
| 	sub	eax, gs:(VSM_Header).SysStuff.StartTime | ||||
| 	xor	edx, edx | ||||
| 	add	gs:(VSM_Header).SysStuff.Clocks+0, eax | ||||
| 	adc	gs:(VSM_Header).SysStuff.Clocks+4, edx | ||||
|  | ||||
| 	jmp	RunHandlers | ||||
|  | ||||
|  | ||||
| 	; | ||||
| 	; The SMI is asynchronous | ||||
| 	; | ||||
| AsyncSMI: | ||||
| 	or	ebx, ebx		; If null SMI, just return to VSM | ||||
| 	jz	short NoPreempt | ||||
|  | ||||
| 	cmp	gs:(VSM_Header).SysStuff.RunFlag, RUN_FLAG_SLEEPING | ||||
| 	je	Reschedule | ||||
|  | ||||
| 	jmp	ServiceNow	 | ||||
|  | ||||
| 	; Is this a high priority SMI ? | ||||
| ;	test	ebx, [HiPrioritySMIs] | ||||
| ;	jnz	short ServiceNow	; Yes, execute SMI handlers | ||||
|  | ||||
|  | ||||
| 	; | ||||
| 	; Resumes to a VSM from an low-priority asynchronous SMI | ||||
| 	; | ||||
| NoPreempt: | ||||
| 	; | ||||
| 	; Resumes to a VSM from a system call | ||||
| 	; | ||||
| ExitSysCall:				; Return to caller | ||||
| 	rsdc	ss, gs:(VSM_Header)._SS | ||||
| 	mov     sp, word ptr gs:(VSM_Header).SysStuff.SavedESP | ||||
| 	rsdc    ds, gs:(VSM_Header)._DS | ||||
| 	RESTORE_STATE | ||||
| 	rsm | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; The current VSM has emptied its message queue.  It will not be       * | ||||
| ; executed again until a new message is entered into its queue.        * | ||||
| ; NOTE: SysMgr will be using the last VSM's stack.                     * | ||||
| ;*********************************************************************** | ||||
| EmptyMsgQueue: | ||||
|  | ||||
|  | ||||
| 	mov	gs:(VSM_Header).SysStuff.RunFlag, RUN_FLAG_INACTIVE | ||||
| 	jmp	short UpdateClocks | ||||
|  | ||||
| Sys_Exit: | ||||
| 	; System calls should not count as an SMI | ||||
| 	sub	gs:(VSM_Header).SysStuff.NumSMIs+0, 1	; Decrement number of SMIs | ||||
| 	sbb	gs:(VSM_Header).SysStuff.NumSMIs+4, 0 | ||||
| UpdateClocks: | ||||
|  | ||||
|  | ||||
| 	; Update the clock count used by the VSM | ||||
| 	rdtsc | ||||
| 	sub	eax, gs:(VSM_Header).SysStuff.StartTime | ||||
| 	xor	edx, edx | ||||
| 	add	gs:(VSM_Header).SysStuff.Clocks+0, eax | ||||
| 	adc	gs:(VSM_Header).SysStuff.Clocks+4, edx | ||||
|  | ||||
| 	jmp	Dispatcher | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; Schedules a VSM to execute | ||||
| ;*********************************************************************** | ||||
| Schedule_VSM proc pascal uses bx \ | ||||
| 	Vsm: DWORD | ||||
|  | ||||
| 	mov     eax, [Vsm] | ||||
| 	test	eax, 0FFFF0000h		; Is it a callback ? | ||||
| 	jz	Schedule | ||||
|  | ||||
| 	; Mark VSM ready, if not already on scheduler's stack	 | ||||
| 	mov	bl, RUN_FLAG_READY	 | ||||
| 	xchg	bl, fs:(VSM_Header PTR [eax]).SysStuff.RunFlag | ||||
| ;	cmp	bl, RUN_FLAG_READY | ||||
| ;	je      short Exit | ||||
|  | ||||
| Schedule: | ||||
| 	mov     bx, [SchedulerStack]	; Get scheduler's ptr | ||||
| 	add     bx, 4		    	; Push the VSM | ||||
| 	mov     [bx], eax | ||||
| 	mov     [SchedulerStack], bx	; Update scheduler's ptr  | ||||
| Exit:	ret | ||||
|  | ||||
| Schedule_VSM endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ;*********************************************************************** | ||||
| ;*********************************************************************** | ||||
| ;*                                                                     * | ||||
| ;*                    Nested SMI Entry Point                           * | ||||
| ;*                                                                     * | ||||
| ;*  A nested SMI can occur for one of four reasons:                    * | ||||
| ;*  1) A system call                                                   * | ||||
| ;*  2) An asynchronous event (timer, GPIO, etc.)                       * | ||||
| ;*  3) A trapped I/O from a VSM (virtual register, PCI access)         * | ||||
| ;*  4) Return from a BIOS callback                                     * | ||||
| ;*                                                                     * | ||||
| ;*********************************************************************** | ||||
| ;*********************************************************************** | ||||
| ;*********************************************************************** | ||||
| 	align	16 | ||||
| Nested_SMI: | ||||
|  | ||||
| 	; Set DS descriptor to System Manager's | ||||
| 	rsdc	ds, cs:[Data_Descriptor] | ||||
|  | ||||
|  | ||||
| 	; Is it a system call (SMINT) ? | ||||
| 	test	byte ptr gs:(VSM_Header).SysStuff.State.SMI_Flags, 1000b | ||||
| 	jz	NotSysCall | ||||
|  | ||||
| ;************************************************************************* | ||||
| ;************************************************************************* | ||||
| ;************************************************************************* | ||||
| ;                                                                        * | ||||
| ;       SMI is a system call                                             * | ||||
| ;                                                                        * | ||||
| ; The VSM's registers are saved on the VSM's stack.                      * | ||||
| ; DS: and SS:SP are initialized to SysMgr's environment.                 * | ||||
| ;                                                                        * | ||||
| ; On Entry:                                                              * | ||||
| ;   AX = System call code                                                * | ||||
| ;   Other registers, depending on the system call                        * | ||||
| ;                                                                        * | ||||
| ;************************************************************************* | ||||
| ;************************************************************************* | ||||
| ;************************************************************************* | ||||
| SystemCall: | ||||
| 	cmp	ax, SYS_CODE_EXIT	; Check for valid system code | ||||
| 	ja 	short IllegalSysCall	; If invalid, record an error | ||||
|  | ||||
|  | ||||
| 	mov	[VSMs_EAX], eax | ||||
| 	SAVE_STATE			; Save the VSM's state | ||||
| 	mov     word ptr gs:(VSM_Header).SysStuff.SavedESP, sp | ||||
|  | ||||
| 	; Setup System Manager's stack | ||||
| 	rsdc    ss, [Stack_Descriptor] | ||||
| 	lea	sp, [StartSaveArea] | ||||
|  | ||||
| 	; Dispatch to system call routine | ||||
| 	movzx	eax, word ptr [VSMs_EAX] | ||||
| 	jmp	[SysCall_Table + eax*2] | ||||
|  | ||||
|  | ||||
| 	 | ||||
|  | ||||
| ;*********************************************************************** | ||||
| ; An illegal system call was detected | ||||
| ;*********************************************************************** | ||||
| IllegalSysCall: | ||||
| 	; Is it ResumeFromRAM ? | ||||
| 	cmp	ax, SYS_RESUME_FROM_RAM | ||||
| 	je	ResumeFromRAM | ||||
|  | ||||
| 	mov	di, ERR_UNDEF_SYS_CALL | ||||
| 	mov	ebx, eax		; Info1 = system call code | ||||
| 	mov	ecx, [Current_VSM]	; Info2 = offending VSM | ||||
| 	mov	ax, SYS_CODE_ERROR	; Fake a SYS_CODE_ERROR | ||||
| 	jmp	SystemCall | ||||
|  | ||||
|  | ||||
|  | ||||
| ;*********************************************************************** | ||||
| 	; BIOS is resuming after a Save-to-RAM: | ||||
| 	; 1) Re-init VSA state | ||||
| 	; 2) Re-schedule the suspended VSM | ||||
| 	; 3) Go to VSM dispatcher | ||||
| ;*********************************************************************** | ||||
| ResumeFromRAM: | ||||
| 	rsdc    fs, [Flat_Descriptor]	; Set FS to a 4 GB flat segment | ||||
| 	rsdc    es, [Flat_Descriptor]	; Set ES to a 4 GB flat segment | ||||
|  | ||||
| 	mov     ebx, [Current_VSM] | ||||
| 	mov	ax, fs:(VSM_Header PTR [ebx]).SysStuff.ResumeVector | ||||
| 	mov	fs:(VSM_Header PTR [ebx]).SysStuff.State.Next_IP, ax | ||||
| 	mov     fs:(VSM_Header PTR [ebx]).SysStuff.RunFlag, RUN_FLAG_READY	 | ||||
| 	jmp     ExecuteTask | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| 		align	4 | ||||
| Current_VSM	dd	0 | ||||
| HardwareInfo	Hardware { } | ||||
| BracketFlag	db	0 | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;************************************************************************************* | ||||
| ; | ||||
| ; IMPLEMENTATION NOTES: | ||||
| ; | ||||
| ;  - The scheduler's stack and System Manager's stack grow toward each other. | ||||
| ; | ||||
| ;  - The variables at StartSaveArea are grouped together because they, along with | ||||
| ;    the SMM header, represent the entire state of the interrupted task.  This is | ||||
| ;    important since this state must be saved & restored across a BIOS callback. | ||||
| ; | ||||
| ;************************************************************************************* | ||||
| 		align	2 | ||||
| SchedulerStack dw	OFFSET Scheduled_VSMs | ||||
|  | ||||
| 		align	4 | ||||
| Scheduled_VSMs	dd	0			; Marks bottom of scheduler's stack | ||||
|  | ||||
|  | ||||
|  | ||||
| 		ORG	SYSMGRS_STACK | ||||
| StartSaveArea: | ||||
| Saved_PCI	dd	? | ||||
|  | ||||
| ; NOTE: the following 8 variables must be in the correct order for PUSHAD/POPAD | ||||
| Saved_EDI	dd	? | ||||
| Saved_ESI	dd	? | ||||
| Saved_EBP	dd	? | ||||
| 		dd	?			; ESP (not used) | ||||
| Saved_EBX	dd	? | ||||
| Saved_EDX	dd	? | ||||
| Saved_ECX	dd	? | ||||
| Saved_AX: | ||||
| Saved_EAX	dd	? | ||||
| SysMgrStack:					; <==== System Manager's stack begins here | ||||
|  | ||||
| Saved_ESP	dd	OFFSET SysMgrStack	; DO NOT MOVE !!! | ||||
|  | ||||
|  | ||||
| ; | ||||
| ; NOTE: The SET_REGISTER, GET_REGISTER, GET_DESCRIPTOR, & SET_DESCRIPTOR | ||||
| ;       macros assume these are in this exact location and order: | ||||
| Saved_SS	Descriptor { } | ||||
| Saved_DS	Descriptor { } | ||||
| Saved_ES	Descriptor { } | ||||
| Saved_FS	Descriptor { } | ||||
| Saved_GS	Descriptor { } | ||||
|  | ||||
| Header_Addr	dd	0			; Ptr to end of SMM header | ||||
|  | ||||
| IDT_Selector	dd	0			; Saved IDT state | ||||
| IDT_Base	dd	0 | ||||
| IDT_Limit	dd	0		 | ||||
|  | ||||
|  | ||||
|  | ||||
| 		dw	0			; Pad | ||||
| EndSaveArea	label	byte | ||||
| ; | ||||
| ; This table contains System Manager structures accesses by INIT.EXE and INFO.EXE. | ||||
| ; Must match the InfoStuff structure in VSA2.H | ||||
| ; | ||||
| 		ORG	SPECIAL_LOC | ||||
|  | ||||
| 		dw	OFFSET Events | ||||
| 		dw	OFFSET MSRs | ||||
| 		dw	OFFSET INT_Vectors | ||||
| 		dw	OFFSET HardwareInfo | ||||
| IRQ_Base	dd	0			; Memory-mapped location of Internal IRQs | ||||
| IRQ_Mask	dd	0			; Mask of IRQs to be generated | ||||
| ; NOTE: The following fields are not referenced by VSMs. | ||||
| ;       They are in this structure so INIT.ASM can initialize them. | ||||
| SysMgr_VSM	dd	0			; Logical address of System Manager | ||||
| SMI_Base	dd	0			; Memory-mapped location of SMI sources | ||||
| 		dw	OFFSET Header_Addr	; Offset of SysMgr.SysStuff.State | ||||
| 		dw	OFFSET StartSaveArea	; Initial value of SysMgr.SysStuff.SavedESP | ||||
| 		dw	OFFSET MSRs | ||||
| 		dw	OFFSET NumDescriptors | ||||
|  | ||||
| Nested_EAX	dd	0			; Flat ptr to interrupted VSM's EAX | ||||
| Nested_EDI	dd	0			; Value of interrupted VSM's EDI | ||||
| Nested_PCI	dd	0			; PCI config address of interrupted VSM | ||||
| Nested_Flag	dd	0 | ||||
|  | ||||
| VSMs_EAX	dd	0 | ||||
| Nested_ES	Descriptor {} | ||||
|  | ||||
|  | ||||
| _CODE	ENDS | ||||
|  		 | ||||
| 	END	Start | ||||
|  | ||||
							
								
								
									
										207
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/sysmgr.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										207
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/sysmgr.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,207 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
|  | ||||
|  | ||||
| // Build flags for various optional features | ||||
| #define HISTORY		0	// History support (value determines size of history buffer; 0=disabled) | ||||
| #define CHECKED_BUILD		1	// Perform internal sanity checks | ||||
|  | ||||
| #define SUPPORT_CAPABILITIES	1	// Enables support for PCI capabilities list | ||||
| #define SUPPORT_PRIORITY	0	// Enables message priority logic | ||||
| #define SUPPORT_FS2		1	// Enables MBIU1 descriptors so FS2 sees same map as GX2 | ||||
|  | ||||
| #define USB_FIX		0	// 0=none 1=old 2=new | ||||
| #define MAX_INT		0x1B	// Maximum INT vector supported for BIOS callbacks | ||||
|  | ||||
|  | ||||
| #define SYS_YIELD		0x40000000L	 // Must be >= bit 24 | ||||
|  | ||||
| #define DBG_PORT		0x84 | ||||
| #define VSA_POST		0x84		// I/O port for VSA POST codes | ||||
|  | ||||
| #define EXTRA_SAVE		4		// State saved other than registers | ||||
| #define VSM_STACK_FRAME	(8*4+EXTRA_SAVE)// PUSHAD + EXTRA_SAVE | ||||
|  | ||||
| #define SPECIAL_LOC		0xA80		// Determines depth of SysMgr's stack | ||||
| #define STACK_OFFSET		0x94	// Should be: EndSaveArea - StartSaveArea | ||||
| #define SYSMGRS_STACK		(SPECIAL_LOC-STACK_OFFSET) | ||||
|  | ||||
| #define MAX_REGISTRATIONS	100		// # entries in Events[] | ||||
|  | ||||
| // VSM specific definitions | ||||
| #define CODE_ATTR		0x9B | ||||
| #define DATA_ATTR		0x93 | ||||
| #define VSM_CR0		0x00000014 | ||||
| #define VSM_EFLAGS		0x00000002 | ||||
| #define VSM_DR7		0x00000400 | ||||
| #define VSM_STACK_SIZE		0x300		// Size of allocated stack in bytes | ||||
| #define BIOS_STACK_SIZE	0x100 | ||||
|  | ||||
| // VSM States | ||||
| #define RUN_FLAG_INACTIVE	0x00		// VSM is idle | ||||
| #define RUN_FLAG_SLEEPING	0x55		// VSM is in Standby/Suspend | ||||
| #define RUN_FLAG_ACTIVE	0xAA		// VSM is running or scheduled to run | ||||
| #define RUN_FLAG_WAITING	0xEE		// VSM has yielded control | ||||
| #define RUN_FLAG_BLOCKED	0xBB		// VSM is blocked | ||||
| #define RUN_FLAG_READY		0x77		// VSM is ready to execute | ||||
|  | ||||
|  | ||||
| // System calls | ||||
| #define SYS_CODE_EVENT		0x0000		// Event registration | ||||
| #define SYS_CODE_YIELD		0x0001		// VSM is yielding control | ||||
| #define SYS_CODE_SW_INT	0x0002		// Software Interrupt (INT xx) | ||||
| #define SYS_CODE_PASS_EVENT	0x0003		// VSM did not handle an event | ||||
| #define SYS_CODE_UNLOAD	0x0004		// Unload VSM | ||||
| #define SYS_CODE_REGISTER	0x0005		// Get/Set special registers | ||||
| #define SYS_CODE_PCI_ACCESS	0x0006		// Access a PCI dword with trapping disabled | ||||
| #define SYS_CODE_SET_VIRTUAL	0x0007		// Set virtual register | ||||
| #define SYS_CODE_GET_VIRTUAL	0x0008		// Get virtual register | ||||
| #define SYS_CODE_BROADCAST	0x0009		// Broadcast a message to one or more VSMs | ||||
| #define SYS_CODE_STATE		0x000A		// Save/Restore non-SMM state | ||||
| #define SYS_CODE_ERROR		0x000B		// Report error | ||||
| #define SYS_CODE_RESOURCE	0x000C		// Reserve resource | ||||
| #define SYS_CODE_DECODE	0x000D		// Set resource to be subtractive/positive decode | ||||
| #define SYS_CODE_DESCRIPTOR	0x000E		// Get descriptor of virtualized PCI BAR | ||||
| #define SYS_CODE_LOOKUP	0x000F		// Lookup routing for MBus device | ||||
| #define SYS_CODE_IRQ_MAPPER	0x0010		// Set IRQ mapping (CS5535 only) | ||||
| #define SYS_CODE_RESULT	0x0011		// Return virtualized result | ||||
| #define SYS_CODE_DUPLICATE	0x0012		// Duplicate a VSM | ||||
| #define SYS_CODE_EXIT		0x0013		// Exit to System Manager | ||||
|  | ||||
| #define GET_REG		0x80 | ||||
| #define SET_REG		0x81 | ||||
| #define GET_HDR		0x82 | ||||
| #define SET_HDR		0x83 | ||||
| #define GET_DESCR		0x84 | ||||
| #define SET_DESCR		0x85 | ||||
|  | ||||
|  | ||||
| // Fields in SMM header flag | ||||
| #define SMI_FLAGS_CS_WRITABLE	0x0001		// "Cw" bit  CS is writable | ||||
| #define SMI_FLAGS_OUTPUT       0x0002		// "I" bit   I/O indicator | ||||
| #define SMI_FLAGS_REP          0x0004		// "P" bit   REP indicator | ||||
| #define SMI_FLAGS_SMINT        0x0008		// "S" bit	 SMI occured due to a SMINT | ||||
| #define SMI_FLAGS_HALT         0x0010		// "H" bit   SMI occured during CPU halt | ||||
| #define SMI_FLAGS_MEMORY       0x0020		// "M" bit   0=I/O, 1=memory | ||||
| #define SMI_FLAGS_EXT	        0x0040		// "X" bit   External SMI source | ||||
| #define SMI_FLAGS_VGA          0x0080		// "V" bit   VGA emulation source | ||||
| #define SMI_FLAGS_NESTED       0x0100		// "N" bit   Nested SMI | ||||
| #define SMI_FLAGS_CS_READABLE  0x8000		// "Cr" bit  CS is writable | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| typedef void (* SMI_Handler)(void); | ||||
|  | ||||
| typedef struct { | ||||
|   SMI_Handler Handler; | ||||
|   unsigned long SMI_Mask; | ||||
| } SMI_ENTRY; | ||||
|  | ||||
|  | ||||
|  | ||||
| typedef struct { | ||||
|   unsigned long   Vsm; | ||||
|  | ||||
|   union { | ||||
|     struct { | ||||
|       unsigned long Param1; | ||||
|       unsigned long Param2; | ||||
|       unsigned long Param3; | ||||
| 	}; | ||||
| 	struct {		// Timers | ||||
|       unsigned long Interval; | ||||
|       unsigned short Handle; | ||||
|       unsigned char Timer; | ||||
|       unsigned char Attr; | ||||
|       unsigned long RemainingInterval; | ||||
|     }; | ||||
| 	struct {		// GPIOs | ||||
| 	  unsigned short Pin; | ||||
| 	  unsigned short Pme; | ||||
| 	  unsigned short Attributes; | ||||
| 	  unsigned short Pm1; | ||||
| 	  unsigned long CurrentEdge; | ||||
|     }; | ||||
| 	struct {		// PCI header | ||||
| 	  unsigned short PCI_Addr; | ||||
| 	  unsigned short Unused; | ||||
| 	  unsigned short PCI_Mask; | ||||
| 	  unsigned short Flags; | ||||
|     }; | ||||
| 	struct {		// I/O trap & timeout | ||||
| 	  unsigned short IO_Base; | ||||
| 	  unsigned short IO_Timeout; | ||||
| 	  unsigned short IO_Range; | ||||
|     }; | ||||
| 	struct {		// Virtual Register | ||||
|       unsigned long ClassLow; | ||||
|       unsigned long ClassHigh; | ||||
|     }; | ||||
|  | ||||
|   }; | ||||
|  | ||||
|   unsigned long Timestamp[2]; | ||||
|   unsigned char Index; | ||||
|   unsigned char Link; | ||||
|   unsigned short Priority; | ||||
| } EVENT_ENTRY; | ||||
|  | ||||
| typedef struct { | ||||
|   unsigned long Vsm; | ||||
|   unsigned long Event; | ||||
|   unsigned long Param1; | ||||
|   unsigned long Param2; | ||||
|   unsigned long Count; | ||||
|   unsigned long TimeStamp[2]; | ||||
| } EVENT_HISTORY; | ||||
|  | ||||
|  | ||||
| typedef struct { | ||||
|   unsigned short History_Array; | ||||
|   int * History_Start; | ||||
|   int * History_End; | ||||
|   int * History_Wrap; | ||||
|   unsigned short HistoryEntries; | ||||
| } HISTORY_INFO; | ||||
|    | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| // | ||||
| // An instance of this structure is found in the System Manager at offset SPECIAL_LOC | ||||
| // | ||||
| typedef struct { | ||||
|   unsigned short Events;		// Events array | ||||
|   unsigned short Descriptors;		// MBus Descriptors array | ||||
|   unsigned short Vectors;		// INT vectors | ||||
|   unsigned short HardwareInfo;		// Hardware structure | ||||
|   unsigned long  IRQ_Base;		// Used by SYS_GENERATE_IRQ | ||||
|   unsigned long  IRQ_Mask;		// Used by SYS_GENERATE_IRQ | ||||
|   unsigned long  SysMgr_VSM;		// Used in SysMgr only | ||||
|   unsigned long  SMI_Base;		// Used in SysMgr only | ||||
|   unsigned short Header_Addr;		// Used in SysMgr only | ||||
|   unsigned short SysMgr_Stack;		// Used in SysMgr only | ||||
|   unsigned short MSRs;			// Used for DOS_BUILD | ||||
|   unsigned short NumDescrs;		// Used for DOS_BUILD | ||||
| } InfoStuff; | ||||
							
								
								
									
										729
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/timeout.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										729
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/timeout.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,729 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //****************************************************************************** | ||||
| //*    - Handles I/O inactivity counters    | ||||
| //****************************************************************************** | ||||
|  | ||||
|  | ||||
|  | ||||
| #include "VSA2.H" | ||||
| #include "PROTOS.H" | ||||
| #include "GX2.H" | ||||
| #include "VPCI.H" | ||||
| #include "DESCR.H" | ||||
| #include "CS5536.H" | ||||
|  | ||||
| // External prototypes: | ||||
| void Deallocate_Descriptor(DESCRIPTOR *); | ||||
|  | ||||
|  | ||||
| // External variables: | ||||
| extern ULONG LookupMbiu; | ||||
| extern ULONG ClocksPerMs; | ||||
| extern DESCRIPTOR MSRs[]; | ||||
| extern UCHAR NumDescriptors; | ||||
| extern ULONG Mbiu2; | ||||
| extern UCHAR NumMbius; | ||||
| extern MBIU_INFO MbiuInfo[MAX_MBIU]; | ||||
| extern ULONG MbiuSkipFlags[]; | ||||
| extern Hardware HardwareInfo; | ||||
|  | ||||
| #define NUM_PHYSICAL_COUNTERS   7		// Number of physical statistic counters | ||||
| #define NUM_LOGICAL_COUNTERS   20		// Number of logical statistic counters | ||||
| #define NUM_LINKED_DESCRIPTORS  3		// Number of descriptors per logical counter | ||||
|  | ||||
| // Local variables: | ||||
| UCHAR NumPhysCounters= 0; | ||||
|  | ||||
| typedef struct { | ||||
|   ULONG  MsrAddr;			// MSR address of STATISTICS_CNT | ||||
|   ULONG  Prescaler; | ||||
|   ULONG  Mask;				// IOD_MASK field | ||||
|   ULONG  SFlags; | ||||
|   USHORT StandbyFlag; | ||||
|   USHORT Timeout; | ||||
|   USHORT MbiuNumber; | ||||
| } PHYSICAL_COUNTERS; | ||||
|  | ||||
|  | ||||
| typedef struct { | ||||
|   ULONG  Mask; | ||||
|   USHORT Address; | ||||
|   USHORT DeviceID; | ||||
|   USHORT Timeout; | ||||
|   UCHAR  PhysIndex;         // Index to physical counter | ||||
|   UCHAR  DescrIndex[NUM_LINKED_DESCRIPTORS];     // Indices to descriptors | ||||
| } LOGICAL_COUNTERS; | ||||
|  | ||||
| PHYSICAL_COUNTERS PhysCounter[NUM_PHYSICAL_COUNTERS]; | ||||
| LOGICAL_COUNTERS  LogCounter[NUM_LOGICAL_COUNTERS]; | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Initializes a logical timeout counter | ||||
| //*********************************************************************** | ||||
| void InitLogicalCounter(LOGICAL_COUNTERS * LogicalPtr) | ||||
| { int i; | ||||
|  | ||||
|   LogicalPtr->Mask = 0x00000000; | ||||
|   for (i = 0; i < NUM_LINKED_DESCRIPTORS; i++) { | ||||
|     LogicalPtr->DescrIndex[i] = 0xFF; | ||||
|   }   | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Deallocates a logical counter. | ||||
| // Deallocates all descriptors associated with a logical counter, | ||||
| // unless the descriptor is also being used for an I/O trap. | ||||
| //*********************************************************************** | ||||
| void DeallocateLogicalCounter(LOGICAL_COUNTERS * LogicalPtr) | ||||
| { int i, j; | ||||
|  | ||||
|  | ||||
|   for (i = 0; i < NUM_LINKED_DESCRIPTORS; i++) { | ||||
|     // Get index of I/O descriptor used for this logical counter | ||||
|     j = LogicalPtr->DescrIndex[i]; | ||||
| 	if (j == 0xFF) { | ||||
|       // No more linked descriptors | ||||
|       break; | ||||
|     } | ||||
|  | ||||
|     // If not used for I/O trap or virtualized PCI BAR | ||||
|     if (!(MSRs[j].Flag & IO_TRAP) && !(MSRs[j].Owner)) { | ||||
|       Deallocate_Descriptor(&MSRs[j]); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Deallocate logical counter   | ||||
|   InitLogicalCounter(LogicalPtr); | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Initializes the logical timeout counter structures | ||||
| //*********************************************************************** | ||||
| void InitLogicalCounters(void)  | ||||
| { int i; | ||||
|   register LOGICAL_COUNTERS * LogicalPtr; | ||||
|  | ||||
|   // Initialize logical counters | ||||
|   LogicalPtr = &LogCounter[0]; | ||||
|   for (i=0; i < NUM_LOGICAL_COUNTERS; i++) { | ||||
|     InitLogicalCounter(LogicalPtr++); | ||||
|   } | ||||
| } | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Initializes the physical timeout counter structures & MSRs | ||||
| // Called from Init_MBIU(). | ||||
| //*********************************************************************** | ||||
| void InitStatCounters(ULONG Msr, UCHAR NumStatCntrs)  | ||||
| { int i; | ||||
|   ULONG MsrData[2], SFlags; | ||||
|   register PHYSICAL_COUNTERS * PhysPtr; | ||||
|   static UCHAR Shift=0; | ||||
|  | ||||
|   // Initialize physical counters | ||||
|   MsrData[0] = MsrData[1] = 0x00000000; | ||||
|   (USHORT)Msr = MSR_STATISTICS_CNT; | ||||
|   SFlags = 1L << Shift; | ||||
|  | ||||
|   // Prepare shift count for next MBIU  | ||||
|   Shift += 8; | ||||
|   for (i = 0; i < NumStatCntrs; i++) { | ||||
|  | ||||
|     // Initialize the statistic MSR | ||||
|     Write_MSR(Msr+0, MsrData);  // MSR_STATISTICS_CNT | ||||
|     Write_MSR(Msr+1, MsrData);  // MSR_STATISTICS_MASK | ||||
|     Write_MSR(Msr+2, MsrData);  // MSR_STATISTICS_ACTION | ||||
|  | ||||
|     // Initialize next physical counter | ||||
|     if (NumPhysCounters < NUM_PHYSICAL_COUNTERS) { | ||||
|  | ||||
|       PhysPtr = &PhysCounter[NumPhysCounters]; | ||||
|       PhysPtr->MbiuNumber = NumMbius; | ||||
|       PhysPtr->MsrAddr = Msr; | ||||
|       PhysPtr->Mask = 0x00000000; | ||||
|       PhysPtr->StandbyFlag = 0; | ||||
|       PhysPtr->SFlags = SFlags; | ||||
|       SFlags <<= 1; | ||||
|  | ||||
|       // Determine 16-bit prescaler | ||||
|       if ((Msr & ROUTING) == Mbiu2) { | ||||
|         // Clock to Southbridge statistic counters is 66 MHz. | ||||
| 	    PhysPtr->Prescaler = 66000L/8; | ||||
|       } else { | ||||
|         // Clock to Northbridge statistic counters is DRAM clock. | ||||
| 	    PhysPtr->Prescaler = HardwareInfo.DRAM_MHz * 1000L/8; | ||||
|         // If memory is DDR, DRAM clock is running at 1/2 MBUS frequency | ||||
|         if (!(Read_MSR_LO(0x4C000014) & 0x400)) { | ||||
|           // so adjust the prescaler | ||||
|           PhysPtr->Prescaler >>= 1; | ||||
|         } | ||||
|       } | ||||
|       // Shift into PREDIV field | ||||
|       PhysPtr->Prescaler <<= 8; | ||||
|       // Set counter attributes | ||||
|       (UCHAR)PhysPtr->Prescaler = (ALWAYS_DEC | HIT_LDEN | ZERO_SMI); | ||||
|  | ||||
|       // Increment number of statistics counters. | ||||
|       NumPhysCounters++;    | ||||
|  | ||||
|     } else { | ||||
|       Log_Error("The PhysCounter structure has fewer entries than # of h/w counters"); | ||||
|       // Continue initializing, but don't record MSR in array | ||||
|     } | ||||
|  | ||||
|     // Advance to next statistic MSR | ||||
|     Msr += 4; | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Finds the Address corresponding to a bit set in MBD_MSR_SMI. | ||||
| // Clears the next set bit in the EventMask variable. | ||||
| //*********************************************************************** | ||||
| USHORT Get_Timeout(ULONG SFlag, UCHAR * StartIndex) | ||||
| { UCHAR i, j; | ||||
|   USHORT Address = 0x0000; | ||||
|   register PHYSICAL_COUNTERS * PhysPtr; | ||||
|   register LOGICAL_COUNTERS * LogicalPtr; | ||||
|  | ||||
|   // Find the correct logical counter & return the associated address | ||||
|   LogicalPtr = &LogCounter[* StartIndex]; | ||||
|   for (i = * StartIndex; i < NUM_LOGICAL_COUNTERS; i++) { | ||||
|     // Is logical counter in use ? | ||||
|     if (LogicalPtr->Mask != 0x00000000) { | ||||
|  | ||||
|       // Get physical counter to which it is linked | ||||
|       j = LogicalPtr->PhysIndex; | ||||
| 	  PhysPtr = &PhysCounter[j]; | ||||
|  | ||||
|       // Is this counter generating an event ? | ||||
|       if (PhysPtr->SFlags & SFlag) { | ||||
|  | ||||
|         // Yes, return either the DeviceID or the Inactive Address | ||||
|         Address = LogicalPtr->DeviceID; | ||||
|         if (!Address) { | ||||
|           Address = LogicalPtr->Address; | ||||
|         } | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|     LogicalPtr++; | ||||
|   } | ||||
|  | ||||
|   // Return logical index | ||||
|   * StartIndex = i+1; | ||||
|  | ||||
|   return Address; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Enables/Disables SMIs for a statistic counter | ||||
| //*********************************************************************** | ||||
| void pascal StatCntrSMI(ULONG MsrAddr, UCHAR EnableFlag) | ||||
| { ULONG MsrData[2], Mask; | ||||
|   int j; | ||||
|  | ||||
|   MsrData[0] = MsrData[1] = 0x00000000; | ||||
|   if (!EnableFlag) { | ||||
|     Write_MSR(MsrAddr, MsrData); | ||||
|     Write_MSR(MsrAddr+2, MsrData); | ||||
|   }   | ||||
|  | ||||
|   j = ((UCHAR)MsrAddr - MSR_STATISTICS_CNT) / 4; | ||||
|   j++;  // HW Emulation is bit 0 | ||||
|  | ||||
|  | ||||
|   (USHORT)MsrAddr = MBD_MSR_SMI; | ||||
|  | ||||
|   Read_MSR(MsrAddr, MsrData); | ||||
|   Mask = 1L << j; | ||||
|   if (EnableFlag) { | ||||
|     MsrData[0]  &= ~Mask; | ||||
|   } else { | ||||
|     MsrData[0]  |=  Mask; | ||||
|   } | ||||
|   Write_MSR(MsrAddr, MsrData); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Sets the IOD_MASK field of STATISTIC_MASK | ||||
| //*********************************************************************** | ||||
| void pascal Set_IOD_MASK(PHYSICAL_COUNTERS * PhysPtr)  | ||||
| { | ||||
|   Write_MSR_HI(PhysPtr->MsrAddr | 1, PhysPtr->Mask); | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Disables an inactivity timer for the specified parameters. | ||||
| // Param1: | ||||
| //    31:16 = Timeout in seconds | ||||
| //    15:00 = I/O Base | ||||
| // Param2: | ||||
| //    31:16 = Flags (ONE_SHOT, WRITES_ONLY, READS_ONLY) | ||||
| //    15:00 = I/O Range | ||||
| //*********************************************************************** | ||||
| void pascal Clr_MBus_IO_Timeout(ULONG Param1, ULONG Param2) | ||||
| { int i; | ||||
|   USHORT Address, Range, Timeout; | ||||
|   MBIU_INFO * MbiuPtr; | ||||
|   register PHYSICAL_COUNTERS * PhysPtr; | ||||
|   register LOGICAL_COUNTERS * LogicalPtr; | ||||
|  | ||||
|   // Unpack parameters | ||||
|   Range = (USHORT)Param2; | ||||
|   Address = (USHORT)Param1; | ||||
|   Timeout = (USHORT)(Param1 >> 16); | ||||
|  | ||||
|   // Find the corresponding logical counter | ||||
|   LogicalPtr = &LogCounter[0]; | ||||
|   for (i = 0; i < NUM_LOGICAL_COUNTERS; i++) { | ||||
|     if (LogicalPtr->Address == Address) { | ||||
| 	  break; | ||||
| 	} | ||||
|     LogicalPtr++; | ||||
|   } | ||||
|  | ||||
|   if (i >= NUM_LOGICAL_COUNTERS) { | ||||
|     // ERROR: VSM is unregistering a non-existent timeout. | ||||
|     Report_VSM_Error(ERR_UNREGISTRATION, Address, 0); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   // Get physical counter corresponding to this logical counter | ||||
|   PhysPtr = &PhysCounter[LogicalPtr->PhysIndex]; | ||||
|  | ||||
|   // Clear IOD_MASK in the corresponding physical counter | ||||
|   PhysPtr->Mask &= ~LogicalPtr->Mask; | ||||
|   Set_IOD_MASK(PhysPtr); | ||||
|  | ||||
|   // Decrement timer count on this MBIU | ||||
|   MbiuPtr = &MbiuInfo[PhysPtr->MbiuNumber]; | ||||
|   if (MbiuPtr->ActiveCounters) { | ||||
|     MbiuPtr->ActiveCounters--; | ||||
|   } | ||||
|  | ||||
|  | ||||
|   // If no more timeouts for this physical counter... | ||||
|   if (PhysPtr->Mask == 0x00000000) { | ||||
|     PhysPtr->StandbyFlag = 0; | ||||
|  | ||||
|     // Disable the statistics counter | ||||
|     StatCntrSMI(PhysPtr->MsrAddr, 0); | ||||
|  | ||||
|  | ||||
|     if (MbiuPtr->ActiveCounters == 0) { | ||||
|       // Restore clock gating on this MBIU | ||||
|       if (MbiuPtr->ActiveCounters == 0) { | ||||
|         Write_MSR_LO(MbiuPtr->Mbiu + MBD_MSR_PM, MbiuPtr->ClockGating); | ||||
|       } | ||||
| 	} | ||||
|   }	else { | ||||
|     if (MbiuPtr->ActiveCounters == 0) { | ||||
|       Log_Error("MbiuInfo->ActiveCounters is out of sync"); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Deallocate descriptor(s) | ||||
|   DeallocateLogicalCounter(LogicalPtr); | ||||
|  | ||||
| } | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Enables an inactivity timer for the specified I/O Range | ||||
| // Param1: | ||||
| //    31:16 = Timeout in seconds | ||||
| //    15:00 = I/O Base | ||||
| // Param2: | ||||
| //    31:16 = Flags (NOT_GLIUx, ONE_SHOT, WRITES_ONLY, READS_ONLY) | ||||
| //    15:00 = I/O Range | ||||
| //*********************************************************************** | ||||
| void pascal Set_MBus_IO_Timeout(USHORT Address, USHORT Timeout, USHORT Range, USHORT Attr, USHORT DeviceID) | ||||
| { ULONG MsrAddr, MsrData[2], Addr, Candidate, Flags; | ||||
|   UCHAR i, j, k; | ||||
|   MBIU_INFO * MbiuPtr; | ||||
|   register DESCRIPTOR * Descr; | ||||
|   register PHYSICAL_COUNTERS * PhysPtr; | ||||
|   register LOGICAL_COUNTERS * LogicalPtr; | ||||
|  | ||||
|   Flags = (ULONG)Attr << 16; | ||||
|  | ||||
|   // Find an available logical counter | ||||
|   LogicalPtr = &LogCounter[0]; | ||||
|   for (i=0; i < NUM_LOGICAL_COUNTERS; i++) { | ||||
|     if (LogicalPtr->Mask == 0x00000000) { | ||||
| 	  break; | ||||
| 	} | ||||
|     LogicalPtr++; | ||||
|   } | ||||
|  | ||||
|   if (i >= NUM_LOGICAL_COUNTERS) { | ||||
|     Log_Error("The LogCounter structure is not large enough"); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|  | ||||
|   // Record info about this timeout | ||||
|   LogicalPtr->Address = Address; | ||||
|   LogicalPtr->DeviceID = DeviceID; | ||||
|   LogicalPtr->Timeout = Timeout; | ||||
|  | ||||
|  | ||||
|   // Set Flags:NOT_GLIUx for GLIUs with no available counters | ||||
|   for (k=0; k < NumMbius; k++) { | ||||
|  | ||||
|     // Skip this MBIU ? | ||||
|     if (Flags & MbiuSkipFlags[k]) { | ||||
|       continue; | ||||
|     } | ||||
|     MbiuPtr = &MbiuInfo[k]; | ||||
|     j = MbiuPtr->NumCounters; | ||||
|  | ||||
|     //   | ||||
|     PhysPtr = &PhysCounter[0]; | ||||
|     for (i=0; i < NumPhysCounters; i++) { | ||||
|       // Is this counter on the current GLIU ? | ||||
|       if ((MbiuPtr->Mbiu & ROUTING) == (PhysPtr->MsrAddr & ROUTING)) { | ||||
|         // Is it available ? | ||||
|         if (PhysPtr->Mask) { | ||||
|           // No, is it the last counter on this GLIU ? | ||||
|           if (--j == 0) { | ||||
|             // Yes, then exclude from search | ||||
|             Flags |= MbiuSkipFlags[k]; | ||||
|             break; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|       PhysPtr++; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Allocate descriptor(s) for address range | ||||
|   Addr = Flags;		   // Set Addr = Flags::Address | ||||
|   (USHORT)Addr = Address; | ||||
|   k = 0; | ||||
|   while (Range) { | ||||
|  | ||||
|     // Find existing descriptor(s) that match Address | ||||
|     j = Find_Matching_IO_Descriptor(&Addr, &Range, 1); | ||||
|     if (j == DESCRIPTOR_NOT_FOUND) { | ||||
|       // No compatible descriptor exists, so create one | ||||
|       // and route it to the subtractive port. | ||||
|       j = Setup_IO_Descriptor(&Addr, &Range, 1); | ||||
|       if (j == DESCRIPTOR_NOT_FOUND) { | ||||
|         // Error: No free descriptors | ||||
|         k = 0xFF; | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     Descr = &MSRs[j]; | ||||
|  | ||||
|     // Record the descriptor index | ||||
|     LogicalPtr->DescrIndex[k] = j; | ||||
|  | ||||
|     if (k++ == 0) { | ||||
|       // Record 1st descriptor | ||||
|       MsrAddr = Descr->MsrAddr; | ||||
|     } else { | ||||
|       // Check that all descriptors are on same MBIU | ||||
| 	  if ((MsrAddr & ROUTING) != (Descr->MsrAddr & ROUTING)) { | ||||
|         // No free descriptors on same MBIU | ||||
|         k = 0xFF; | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|     // Add the new descriptor to IOD_MASK | ||||
|     LogicalPtr->Mask |= 1L << ((UCHAR)Descr->MsrAddr - MSR_IO_DESCR); | ||||
|   } | ||||
|  | ||||
|  | ||||
|   // If no descriptor found... | ||||
|   if (k == 0xFF) { | ||||
|     // ERROR: Not enough descriptors to handle request | ||||
|     Report_VSM_Error(ERR_NO_MORE_DESCRIPTORS, Address, 0); | ||||
|  | ||||
|     // Deallocate descriptor(s) and logical counter | ||||
|     DeallocateLogicalCounter(LogicalPtr); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   // Find an appropriate hardware statistic counter | ||||
|   Candidate = 0; | ||||
|   for (i=0; i < NumPhysCounters; i++) { | ||||
|  | ||||
|     PhysPtr = &PhysCounter[i]; | ||||
|  | ||||
|     // Physical counter must be on the same MBIU as the I/O descriptor | ||||
|     if ((PhysPtr->MsrAddr & ROUTING) != (Descr->MsrAddr & ROUTING)) { | ||||
|       continue; | ||||
|     } | ||||
|  | ||||
|     if (PhysPtr->Timeout == Timeout) { | ||||
|       // If same timeout, the leverage same counter | ||||
|       break; | ||||
|     } | ||||
|  | ||||
|     // Is this counter being used for Standby inactivity detection ? | ||||
|     if (PhysPtr->StandbyFlag) { | ||||
|       // Yes, is the request for Standby ? | ||||
|       if (Flags & FOR_STANDBY) { | ||||
|         // Yes, then must use the same physical counter | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // Mark physical counter as a candidate | ||||
|     Candidate |= 1L << i; | ||||
|   } | ||||
|  | ||||
|   // If an existing counter can't be leveraged, find a new one | ||||
|   if (i >= NumPhysCounters) { | ||||
|     // Among the candidates, find an unused counter | ||||
|     for (i=0; i < NumPhysCounters; i++) { | ||||
|       if (Candidate & (1L << i)) { | ||||
|         PhysPtr = &PhysCounter[i]; | ||||
|         if (!(PhysPtr->Mask)) { | ||||
|           break; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // If physical counter is found, link it to the descriptor | ||||
|   if (i < NumPhysCounters) { | ||||
|  | ||||
|     // Increment timer count on this MBIU | ||||
|     MbiuPtr = &MbiuInfo[PhysPtr->MbiuNumber]; | ||||
|     MbiuPtr->ActiveCounters++; | ||||
|     // Turn off clock gating on this MBIU | ||||
|     Write_MSR_LO(MbiuPtr->Mbiu + MBD_MSR_PM, Read_MSR_LO(MbiuPtr->Mbiu + MBD_MSR_PM) & 0xFFFFFFF0); | ||||
|  | ||||
|     // Record physical counter used for the logical counter | ||||
|     LogicalPtr->PhysIndex = i; | ||||
|  | ||||
|     // Mark descriptor as used for I/O timeout | ||||
|     Descr->Flag |= IO_TIMEOUT; | ||||
|  | ||||
|     // Record info about this timer | ||||
|     PhysPtr->Timeout = Timeout; | ||||
|     PhysPtr->Mask |= LogicalPtr->Mask; | ||||
|  | ||||
|     // Set flag if counter is being used for Standby inactivity detection | ||||
|     if (Flags & FOR_STANDBY) { | ||||
|       PhysPtr->StandbyFlag = 1; | ||||
|     } | ||||
|  | ||||
|     // Set STATISTIC_CNT[LOAD_VAL] | ||||
|     MsrAddr = PhysPtr->MsrAddr; | ||||
|     MsrData[0] = MsrData[1] = Timeout * 8*1000L; | ||||
|     Write_MSR(MsrAddr, MsrData); | ||||
|  | ||||
|     // Link counter to the descriptor | ||||
|     Set_IOD_MASK(PhysPtr); | ||||
|  | ||||
|     // Set STATISTIC_ACTION[PREDIV] | ||||
|     // Set Prescaler to decrement Count every ms | ||||
|     Write_MSR_LO(MsrAddr+2, PhysPtr->Prescaler); | ||||
|  | ||||
|  | ||||
|     // Enable the statistics counter in MBD_MSR_SMI | ||||
|     StatCntrSMI(MsrAddr, 1); | ||||
|  | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|  | ||||
|   // ERROR: Not enough statistics counter to handle request | ||||
|   Report_VSM_Error(ERR_NO_MORE_DESCRIPTORS, (ULONG)Address, NumPhysCounters); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| typedef struct { | ||||
|   union { | ||||
|     ULONG dword; | ||||
|     struct { | ||||
|       USHORT IO_Base; | ||||
|       USHORT Timeout; | ||||
|     }; | ||||
|   }; | ||||
| } TIMEOUT_P1; | ||||
|  | ||||
| typedef struct { | ||||
|   union { | ||||
|     ULONG Flags; | ||||
|     struct { | ||||
|       union { | ||||
|         USHORT Range; | ||||
|         UCHAR Instance; | ||||
|       }; | ||||
|       USHORT Attributes; | ||||
|     }; | ||||
|   }; | ||||
| } TIMEOUT_P2; | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Enables/disables an inactivity timer for an I/O Range or GLIU device. | ||||
| // Param1: | ||||
| //    31:16 = Timeout in seconds | ||||
| //    15:00 = I/O Base | ||||
| //          = GLIU DeviceID if Flags[GLIU_ID] is set | ||||
| // Param2: | ||||
| //    31:16 = Flags | ||||
| //    15:00 = Length of I/O range | ||||
| //          = Instance if Flags[GLIU_ID] is set | ||||
| // EnableFlag: | ||||
| //        0 = disable | ||||
| //        1 = enable | ||||
| //*********************************************************************** | ||||
| void pascal MBus_IO_Timeout(ULONG Param1, ULONG Param2, UCHAR EnableFlag)  | ||||
| { UCHAR Port, ByteEnables, i, Hit; | ||||
|   USHORT Address, DeviceID = 0x0000; | ||||
|   ULONG MsrAddr; | ||||
|   register DESCRIPTOR * Descr; | ||||
|   TIMEOUT_P1 p1; | ||||
|   TIMEOUT_P2 p2; | ||||
|  | ||||
|  | ||||
|   // Force use of descriptors in Southbridge | ||||
|   if (!(Param2 & FOR_STANDBY)) { | ||||
|     Param2 |= NOT_GLIU0 | NOT_GLIU1; | ||||
|   } | ||||
|  | ||||
|   p1.dword = Param1; | ||||
|   p2.Flags = Param2; | ||||
|  | ||||
|   if (p2.Flags & GLIU_ID) { | ||||
|     p2.Flags &= ~GLIU_ID; | ||||
|  | ||||
|     DeviceID = p1.IO_Base; | ||||
|  | ||||
|     // Don't allow stupid requests | ||||
|     switch (DeviceID) { | ||||
|       case ID_MBIU: | ||||
|       case ID_MDD: | ||||
|       case ID_MCP: | ||||
|       case ID_VAIL: | ||||
|         // Log an error | ||||
|         Report_VSM_Error(ERR_BAD_PARAMETER, EVENT_IO_TIMEOUT, Param1); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     // Find specified instance of the requested device | ||||
|     MsrAddr = Find_MBus_ID(DeviceID, p2.Instance); | ||||
|     Port = (UCHAR)MsrAddr; | ||||
|  | ||||
|     if (!MsrAddr) { | ||||
|       // Log an error | ||||
|       Report_VSM_Error(ERR_HW_MISMATCH, EVENT_IO_TIMEOUT, Param2); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     MsrAddr = LookupMbiu & ROUTING;   // LookupMbiu was set by Find_MBus_ID() | ||||
|  | ||||
|     // Find all descriptors on this MBIU/Port | ||||
|     Hit = 0; | ||||
|     for (i = 1; i < NumDescriptors; i++) { | ||||
|  | ||||
|       Descr = &MSRs[i]; | ||||
|  | ||||
|       // Is descriptor routing to a device ? | ||||
|       Address = Descr->Address; | ||||
|       if (Address == 0x0000) { | ||||
|         continue; | ||||
|       } | ||||
|       // Is descriptor on correct MBIU ? | ||||
|       if (MsrAddr != (Descr->MsrAddr & ROUTING)) { | ||||
|         continue; | ||||
|       } | ||||
|       // Is descriptor routing to the requested device ? | ||||
|       if (Port == (Descr->MsrData[1] >> 29)) { | ||||
|  | ||||
|         // Yes, determine start address of descriptor | ||||
|         switch (Descr->Type) { | ||||
|           case IOD_SC: | ||||
|             // Determine start address of IOD_SC descriptor | ||||
|             ByteEnables = (UCHAR)(Descr->MsrData[0] >> 24); | ||||
|             while (ByteEnables) { | ||||
|               if (ByteEnables & 1) { | ||||
|                 break; | ||||
|               } else { | ||||
|                 Address++; | ||||
|               } | ||||
|               ByteEnables >>= 1; | ||||
|             } | ||||
|             // Fall through intended | ||||
|  | ||||
|           case IOD_BM: | ||||
|              // Recursive call | ||||
|             p1.IO_Base = Address; | ||||
|             p2.Range = 1; | ||||
|             MBus_IO_Timeout(p1.dword, p2.Flags, EnableFlag); | ||||
|             Hit = 1; | ||||
|             break; | ||||
|  | ||||
|           default: | ||||
|             break; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     if (Hit || DeviceID != ID_VG) { | ||||
|       DeviceID = 0x0000; | ||||
|       return; | ||||
|     } | ||||
|     // Monitor external video card activity | ||||
|     p1.IO_Base = 0x03C0; | ||||
|     p2.Range = 32; | ||||
|   } | ||||
|  | ||||
|   // Check for illegal combination of flags | ||||
|   if ((p2.Flags & ALL_GLIUS) == ALL_GLIUS) { | ||||
|     // ERROR: Illegal combination of EVENT_IO_TIMEOUT flags | ||||
|     Report_VSM_Error(ERR_BAD_PARAMETER, EVENT_IO_TIMEOUT, p2.Flags); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   if (EnableFlag) { | ||||
|     Set_MBus_IO_Timeout(p1.IO_Base, p1.Timeout, p2.Range, p2.Attributes, DeviceID); | ||||
|   } else { | ||||
|     Clr_MBus_IO_Timeout(p1.dword, p2.Flags); | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
							
								
								
									
										183
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/timer.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										183
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/timer.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,183 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //***************************************************************************** | ||||
| //*    Routines related to timer management.   | ||||
| //***************************************************************************** | ||||
|  | ||||
|  | ||||
| #include "VSA2.H" | ||||
| #include "CHIPSET.H" | ||||
| #include "SYSMGR.H" | ||||
| #include "PROTOS.H" | ||||
| #include "TIMER.H" | ||||
|  | ||||
| typedef   unsigned char (* TIMER_ON)(ULONG, UCHAR); | ||||
| typedef   void (* TIMER_OFF)(unsigned short); | ||||
|  | ||||
|  | ||||
| // External prototypes: | ||||
| extern UCHAR EnableMsTimer_5536(ULONG, UCHAR); | ||||
| extern USHORT DisableMsTimer_5536(USHORT); | ||||
| extern void pascal MarkTimerAvailable(USHORT); | ||||
|  | ||||
|  | ||||
| // External variables: | ||||
| extern ULONG MsgPacket[]; | ||||
| extern EVENT_ENTRY Events[]; | ||||
| extern ULONG ClocksPerMs; | ||||
| extern Hardware HardwareInfo; | ||||
| extern TIMERS TimerInfo[]; | ||||
|  | ||||
|  | ||||
| // Local variables: | ||||
| TIMER_ON  EnableTimer; | ||||
| TIMER_OFF DisableTimer; | ||||
| USHORT ActiveTimer; | ||||
| ULONG ActiveInterval; | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Performs initialization related to timers | ||||
| //*********************************************************************** | ||||
| void InitTimers(void) | ||||
| { | ||||
|  | ||||
|   switch (HardwareInfo.Chipset_ID) { | ||||
|  | ||||
|     case DEVICE_ID_5536: | ||||
|       EnableTimer = EnableMsTimer_5536; | ||||
|       DisableTimer = DisableMsTimer_5536; | ||||
|       break; | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // This routine handles timer ticks. | ||||
| //*********************************************************************** | ||||
| USHORT FilterTimer(EVENT_ENTRY * EventPtr, EVENT EventIndex)  | ||||
| { USHORT ReturnValue=0; | ||||
|   ULONG Vsm; | ||||
|   static EVENT NextToExpire; | ||||
|  | ||||
|   Vsm = EventPtr->Vsm; | ||||
|  | ||||
|  | ||||
|   // If 1st registered timer, initialize 'next interval' variables | ||||
|   if (EventIndex == EVENT_TIMER) { | ||||
|     NextToExpire = 0; | ||||
|   } | ||||
|  | ||||
|   // Only decrement timers associated with the expired h/w timer | ||||
|   if (EventPtr->Timer == ActiveTimer) { | ||||
|  | ||||
|     // Has this timer expired ? | ||||
|     if (ActiveInterval >= EventPtr->RemainingInterval) { | ||||
|  | ||||
|       // Yes, reset the VSM's remaining interval | ||||
|       EventPtr->RemainingInterval = EventPtr->Interval; | ||||
|  | ||||
|       // Fill message packet       | ||||
|       MsgPacket[1] = EventPtr->Interval; | ||||
|       MsgPacket[2] = EventPtr->Handle; | ||||
|  | ||||
|       // Was timer due to a SYS_YIELD ? | ||||
|       if (EventPtr->Param2 & SYS_YIELD) { | ||||
|         // Yes, schedule the slumbering VSM | ||||
|         Schedule_VSM(Vsm); | ||||
|       } | ||||
|  | ||||
|       // Return its Events[] index | ||||
|       ReturnValue = EventIndex; | ||||
|     } else { | ||||
|       // Decrement RemainingInterval by the expired timer interval | ||||
|       EventPtr->RemainingInterval -= ActiveInterval; | ||||
|     } | ||||
|  | ||||
|     // Find the next interval on the current h/w timer to expire | ||||
|     if (EventPtr->RemainingInterval < Events[NextToExpire].RemainingInterval) { | ||||
|       // Ignore one-shots that just expired | ||||
|       if (ReturnValue != EventIndex || !(EventPtr->Param2 & ONE_SHOT)) { | ||||
|         NextToExpire = EventIndex; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // If no more timers, then set timer h/w to next interval | ||||
|   if (!EventPtr->Link) { | ||||
|     // Set the timer h/w to the next interval to expire | ||||
|     if (Events[NextToExpire].Vsm) { | ||||
|       Enable_Event(EVENT_TIMER, NextToExpire, 2); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return ReturnValue; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // This routine decrements all software timers.  If a software timer has | ||||
| // expired, it sends an event message to the VSM.   The time to the next | ||||
| // scheduled event and invokes Enable_Event() to restart the timer. | ||||
| // | ||||
| //*********************************************************************** | ||||
| void pascal Timer_Handler(USHORT TimerNumber) | ||||
| { | ||||
|   // Record the active timer | ||||
|   ActiveTimer = TimerNumber; | ||||
|   ActiveInterval = TimerInfo[ActiveTimer].Interval; | ||||
|  | ||||
|   // Mark this timer as available | ||||
|   MarkTimerAvailable(TimerNumber); | ||||
|  | ||||
|   // Send the timer event | ||||
|   Send_Event(EVENT_TIMER, 0x00000000); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| //***************************************************************************** | ||||
| // Enables a millisecond timer to the specified interval | ||||
| // | ||||
| // EnableFlag | ||||
| //   0 = disable | ||||
| //   1 = new registration | ||||
| //   2 = reprogram timer to new interval | ||||
| //***************************************************************************** | ||||
| void MillisecondTimer(UCHAR EnableFlag, EVENT_ENTRY * EventPtr) | ||||
| { | ||||
|   if (EnableFlag == 0) { | ||||
|  | ||||
|     // Disable the h/w timer | ||||
|     DisableTimer(EventPtr->Timer); | ||||
|  | ||||
|   } else { | ||||
|  | ||||
|     // Program a hardware timer | ||||
|     EventPtr->Timer = (UCHAR)EnableTimer(EventPtr->RemainingInterval, EventPtr->Attr); | ||||
|      | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
							
								
								
									
										51
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/timer.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										51
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/timer.h
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
|  | ||||
| typedef struct { | ||||
|   UCHAR  Timer;        // Timer number | ||||
|   UCHAR  Mapper;       // Unrestricted Z field  | ||||
|   USHORT Setup;        // Scale factor & clock select | ||||
|   USHORT Period;       // microseconds/count | ||||
|   ULONG  Interval;     // Current interval in milliseconds | ||||
|   USHORT Mask;         // Bit mask | ||||
|   USHORT TimerBase;    // I/O base | ||||
| } TIMERS; | ||||
|  | ||||
|  | ||||
| #define MFGPT_ENABLE     0x8000 | ||||
| #define MFGPT_COMPARE2   0x4000 | ||||
| #define MFGPT_COMPARE1   0x2000 | ||||
| #define MFGPT_INITED     0x1000 | ||||
| #define MFGPT_STOP_EN    0x0800 | ||||
| #define MFGPT_EXT_EN     0x0400 | ||||
| #define MFGPT_CMP2MODE   0x0300 | ||||
| #define MFGPT_CMP2GE     0x0200 | ||||
| #define MFGPT_CMP1MODE   0x00C0 | ||||
| #define MFGPT_CMP1GE     0x0080 | ||||
| #define MFGPT_REV_EN     0x0020 | ||||
| #define MFGPT_CLK_SEL    0x0010 | ||||
| #define MFGPT_SCALE_32   0x0005 | ||||
| #define MFGPT_SCALE_1K   0x000A | ||||
| #define MFGPT_SCALE_2K   0x000B | ||||
| #define MFGPT_SCALE_4K   0x000C | ||||
| #define MFGPT_SCALE_8K   0x000D | ||||
| #define MFGPT_SCALE_16K  0x000E | ||||
| #define MFGPT_SCALE_32K  0x000F | ||||
|  | ||||
							
								
								
									
										348
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/topology.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										348
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/topology.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,348 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //***************************************************************************** | ||||
| //*     Implements tables that determine the virtualized PCI topology | ||||
| //*     and register definitions.  | ||||
| //***************************************************************************** | ||||
|  | ||||
| #include "VSA2.H" | ||||
| #include "VPCI.H" | ||||
| #include "PCI.H" | ||||
| #include "CHIPSET.H" | ||||
| #include "CS5536.H" | ||||
| #include "SYSMGR.H" | ||||
| #include "MDD.H" | ||||
| #include "MAPPER.H" | ||||
|  | ||||
| //*********************************************************************** | ||||
| //                  Notes on Virtualized PCI Header Tables | ||||
| // | ||||
| // 1) The PCI_HEADER_ENTRY structure must contain at a minimum: | ||||
| //    - Vendor & Device IDs | ||||
| //    - Command/Status | ||||
| //    - RevisionID/ClassCode | ||||
| //    - CacheLine/LatencyTimer/HeaderType/BIST | ||||
| // 2) The Flag field of the last (and only last) entry must have EOL set. | ||||
| // 3) The Mask field contains a 1 in each bit position that is R/W, | ||||
| //    except for bits 11-15 of the Status register.  In this case, a set | ||||
| //    bit means that this feature is reportable. | ||||
| // 4) Memory BARs require a minimum of 4 KB alignment. | ||||
| // 5) Registers up to and including BAR0 must be present and in ascending order | ||||
| //*********************************************************************** | ||||
|  | ||||
| // Write-to-Clear Status bits | ||||
| #define WC_STATUS_BITS	((ULONG)(SIGNALED_TARGET_ABORT | RECEIVED_TARGET_ABORT | RECEIVED_MASTER_ABORT | \ | ||||
| 							 SIGNALED_SYSTEM_ERROR | DETECTED_PARITY_ERROR )) | ||||
|  | ||||
|  | ||||
| #define DEVSEL_TIMING        (DEVSEL_MEDIUM) | ||||
| // Defaults | ||||
| #define DEF_STATUS           (PCI_66MHZ_CAPABLE | DEVSEL_TIMING | BACK2BACK_CAPABLE) | ||||
| #define DEF_MASK             (FAST_BACK_TO_BACK | PARITY_RESPONSE) | ||||
|  | ||||
| // Northbridge | ||||
| #define NB_STATUS            (DEF_STATUS  | BUS_MASTER) & ~(BACK2BACK_CAPABLE) | ||||
| #define NB_MASK              (DEF_MASK    | BUS_MASTER | IO_SPACE) & \ | ||||
| 						    ~(SERR_ENABLE | PARITY_RESPONSE | SIGNALED_SYSTEM_ERROR | FAST_BACK_TO_BACK) | ||||
|  | ||||
| // Southbridge | ||||
| #define SB_MASK              (DEF_MASK    | SPECIAL_CYCLES) | ||||
| #define SB_STATUS            (DEF_STATUS) | ||||
|  | ||||
| // Graphics | ||||
| #define GFX_STATUS           (DEF_STATUS) & ~(BACK2BACK_CAPABLE) | ||||
| #define GFX_MASK             (DEF_MASK | BUS_MASTER) & \ | ||||
|                             ~(SERR_ENABLE | PARITY_RESPONSE | SIGNALED_SYSTEM_ERROR | FAST_BACK_TO_BACK) | ||||
|  | ||||
| // AES | ||||
| #define AES_STATUS           (DEF_STATUS) | ||||
| #define AES_MASK             (GFX_MASK) | ||||
|  | ||||
| // Bus Masters | ||||
| #define BM_STATUS            (DEF_STATUS)  | ||||
| #define BM_MASK              (DEF_MASK | BUS_MASTER) | ||||
|  | ||||
| // OHCI Controllers | ||||
| #define OHCI_MASK            (BM_MASK | IO_SPACE | PARITY_RESPONSE) | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| //                Virtualized Northbridge PCI Device | ||||
| //*********************************************************************** | ||||
| PCI_HEADER_ENTRY HostBridge_Hdr[] = { | ||||
|   //  Reg         Flag     Value         Mask | ||||
|   {   0x00,       0x00, 0x20801022,   0x00000000}, | ||||
|   {   COMMAND,    0x00,  NB_STATUS,      NB_MASK,0,0,WC_STATUS_BITS}, | ||||
|   {   0x08,       0x00, 0x06000000,   0x00000000},  // Bridge: Host | ||||
|   {   0x0C,       0x00, 0x00800008,   0x0000F808}, | ||||
|   {   BAR0,       0x00, 0x00000000,   0x00000000},  // Virtual registers  | ||||
|   {   BAR1,       0x00, 0x00000000,   0x00000000},  // CPU PM functionality | ||||
|   {   0x58,        EOL, 0x00000000,   0xFFFFFFFF},  // Regression testing | ||||
| }; | ||||
|  | ||||
|  | ||||
| PCI_HEADER_ENTRY Graphics_Hdr[] = { | ||||
|   //  Reg         Flag     Value         Mask | ||||
|   {   0x00,       0x00, 0x20811022,   0x00000000}, | ||||
|   {   COMMAND,    0x00, GFX_STATUS,     GFX_MASK,0,0,WC_STATUS_BITS}, | ||||
|   {   0x08,       0x00, 0x03000000,   0x00000000},  // Display: VGA-compatible | ||||
|   {   0x0C,       0x00, 0x00000008,   0x00000008}, | ||||
|   {   BAR0,       0x00, 0x00000000,   0x00000000},  // Graphics memory | ||||
|   {   BAR1,       0x00, 0x00000000,   0x00000000},  // GP | ||||
|   {   BAR2,       0x00, 0x00000000,   0x00000000},  // VG | ||||
|   {   BAR3,       0x00, 0x00000000,   0x00000000},  // DF | ||||
|   {   BAR4,       0x00, 0x00000000,   0x00000000},  // VIP  (LX only) | ||||
|   {   0x3C,       0x00, 0x00000000,   0x00000000},  // LX only | ||||
|   {   OEM_BAR0,   0x00, 0x00000000,   0x00000000},  // VG | ||||
|   {   OEM_BAR1,   0x00, 0x00000000,   0x00000000},  // VG | ||||
|   {   OEM_BAR2,   0x00, 0x00000000,   0x00000000},  // A0000-AFFFF or A0000-BFFFF if no MONO | ||||
|   {   OEM_BAR3,    EOL, 0x00000000,   0x00000000},  // B8000-BFFFF only if MONO present | ||||
| }; | ||||
|  | ||||
| PCI_HEADER_ENTRY AES_Hdr[] = { | ||||
|   //  Reg         Flag     Value         Mask | ||||
|   {   0x00,       0x00, 0x20821022,   0x00000000}, | ||||
|   {   COMMAND,    0x00, AES_STATUS,     AES_MASK,0,0,WC_STATUS_BITS}, | ||||
|   {   0x08,       0x00, 0x10100000,   0x00000000},  // Encryption: entertainment | ||||
|   {   0x0C,       0x00, 0x00000008,   0x00000008}, | ||||
|   {   BAR0,       0x00, 0x00000000,   0x00000000},  //  | ||||
|   {   0x3C,        EOL, 0x00000100,   0x000000FF},  // INTA | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| //                Virtualized Southbridge PCI Device | ||||
| //*********************************************************************** | ||||
|  | ||||
| PCI_HEADER_ENTRY ISA_Hdr[] = { | ||||
|   //  Reg         Flag     Value         Mask | ||||
|   {   0x00,       0x00, 0x20901022,   0x00000000}, | ||||
|   {   COMMAND,    0x00,  SB_STATUS,      SB_MASK,0,0,WC_STATUS_BITS}, | ||||
|   {   0x08,       0x00, 0x06010000,   0x00000000},  // Bridge: ISA | ||||
|   {   0x0C,       0x00, 0x00800008,   0x0000F808}, | ||||
|   {   BAR0,       0x00, 0x00000000,   0x00000008, MSR_LBAR_SMB  },  //   8 byte I/O BAR	(SMB) | ||||
|   {   BAR1,       0x00, 0x00000000,   0x00000100, MSR_LBAR_GPIO },  // 256 byte I/O BAR (GPIO) | ||||
|   {   BAR2,       0x00, 0x00000000,   0x00000040, MSR_LBAR_MFGPT},  //  64 byte I/O BAR (MFGPT) | ||||
|   {   BAR3,       0x00, 0x00000000,   0x00000020, MSR_LBAR_IRQ  },  //  32 byte I/O BAR (IRQ) | ||||
|   {   BAR4,       0x00, 0x00000000,   0x00000080, MSR_LBAR_PMS  },  // 128 byte I/O BAR (PMS) | ||||
|   {   BAR5,       0x00, 0x00000000,   0x00000040, MSR_LBAR_ACPI },  //  64 byte I/O BAR (ACPI) | ||||
|   {   0xD0,        EOL, 0x00000000,   0x0000FFFF},  // Software SMI | ||||
| }; | ||||
|  | ||||
| PCI_HEADER_ENTRY Flash_Hdr[] = { | ||||
|   //  Reg         Flag     Value         Mask | ||||
|   {   0x00,       0x00, 0x20911022,   0x00000000}, | ||||
|   {   COMMAND,    0x00, DEF_STATUS,     DEF_MASK,0,0,WC_STATUS_BITS}, | ||||
|   {   0x08,       0x00, 0x05010000,   0x00000000},  // Memory controller: Flash | ||||
|   {   0x0C,       0x00, 0x00000008,   0x00000008}, | ||||
|   {   BAR0,       0x00, 0x00000000,   0x00000000, MSR_LBAR_FLSH0},  // Flash0 | ||||
|   {   BAR1,       0x00, 0x00000000,   0x00000000, MSR_LBAR_FLSH1},  // Flash1 | ||||
|   {   BAR2,       0x00, 0x00000000,   0x00000000, MSR_LBAR_FLSH2},  // Flash2 | ||||
|   {   BAR3,       0x00, 0x00000000,   0x00000000, MSR_LBAR_FLSH3},  // Flash3 | ||||
|   {   0x3C,       0x00, 0x00000100 | Y_IRQ_FLASH,     0x000000FF},  // INTA | ||||
|   {   0x40,        EOL, 0x00000000,   0xFFFFFFFF},  // IDE-Flash switch | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
| PCI_HEADER_ENTRY Audio_Hdr[] = { | ||||
|   //  Reg         Flag     Value         Mask | ||||
|   {   0x00,       0x00, 0x20931022,   0x00000000}, | ||||
|   {   COMMAND,    0x00,  BM_STATUS,      BM_MASK,0,0,WC_STATUS_BITS}, | ||||
|   {   0x08,       0x00, 0x04010000,   0x00000000},  // Multimedia: Audio | ||||
|   {   0x0C,       0x00, 0x00000008,   0x00000008}, | ||||
|   {   BAR0,       0x00, 0x00000000,   0x00000000},  // 128 byte I/O BAR | ||||
|   {   0x3C,        EOL, 0x00000200 | Y_IRQ_AUDIO, 0x000000FF}	// INTB | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| #define USB20_INT           (0x00000400 | Y_IRQ_USB2)   // INTD | ||||
| #if SUPPORT_CAPABILITIES   | ||||
|   #define USB20_CMD         (DEVSEL_TIMING | PCI_66MHZ_CAPABLE | CAPABILITIES_LIST) | ||||
| #else | ||||
|   #define USB20_CMD         (DEVSEL_TIMING | PCI_66MHZ_CAPABLE) | ||||
| #endif | ||||
| #define USB20_MASK          (BM_MASK  & ~(SERR_ENABLE | PARITY_RESPONSE | SIGNALED_SYSTEM_ERROR | FAST_BACK_TO_BACK | BACK2BACK_CAPABLE)) | ||||
|  | ||||
| #define OTG_CMD             USB20_CMD | ||||
| #define OTG_MASK            (USB20_MASK & ~BUS_MASTER) | ||||
|  | ||||
|  | ||||
|  | ||||
| PCI_HEADER_ENTRY OHC_Hdr[] = { | ||||
|   //  Reg         Flag     Value         Mask | ||||
|   {   0x00,       0x00, 0x20941022,   0x00000000}, | ||||
|   {   COMMAND,    0x00,  USB20_CMD,   USB20_MASK,0,0,WC_STATUS_BITS}, | ||||
|   {   0x08,       0x00, 0x0C031000,   0x00000000},  // Serial Bus: USB : OHCI | ||||
|   {   0x0C,       0x00, 0x00000008,   0x00000008}, | ||||
|   {   BAR0,    USE_BMK, 0x00000000,   0x00001000, USBMSROHCB}, | ||||
| #if SUPPORT_CAPABILITIES   | ||||
|   {   0x34,       0x00, PCI_PM_REG,   0x00000000},  // Capabilities pointer | ||||
|   {  PCI_PM_REG,  0x00, 0xC8020001,   0x00000000},  // PCI Power Management | ||||
|   {  PCI_PM_REG+4,PCI_PM, 0x00000000,   0x00008103}, | ||||
| #endif | ||||
|   {   0x3C,        EOL,  USB20_INT,   0x000000FF}, | ||||
| }; | ||||
|  | ||||
|  | ||||
| PCI_HEADER_ENTRY EHC_Hdr[] = { | ||||
|   //  Reg         Flag     Value         Mask | ||||
|   {   0x00,       0x00, 0x20951022,   0x00000000}, | ||||
|   {   COMMAND,PCI_EHCI,  USB20_CMD,   USB20_MASK,0,0,WC_STATUS_BITS}, | ||||
|   {   0x08,       0x00, 0x0C032000,   0x00000000},  // Serial Bus: USB : EHCI | ||||
|   {   0x0C,       0x00, 0x00000008,   0x00000008}, | ||||
|   {   BAR0,   PCI_EHCI, 0x00000000,   0x00001000, USBMSREHCB}, | ||||
| #if SUPPORT_CAPABILITIES   | ||||
|   {   0x34,       0x00, PCI_PM_REG,   0x00000000},  // Capabilities pointer | ||||
|   {PCI_PM_REG,    0x00, 0xC8020001,   0x00000000},  // PCI Power Management | ||||
|   {PCI_PM_REG+4,PCI_PM, 0x00000000,   0x00008103}, | ||||
| #endif | ||||
|   {   EECP,   PCI_EHCI, 0x00000001,   0x01010000},  // USBLEGSUP     section 2.1.7 of EHCI spec | ||||
|   {   EECP+4, PCI_EHCI, 0x00000000,   0x0000E03F,0,0,0xE0000000},  // USBLEGCTLSTS  section 2.1.8 of EHCI spec | ||||
|   {  SRBN_REG,PCI_EHCI, 0x00000020,   0x00003F00},  // FLADJ/SBRN | ||||
|   {   0x3C,        EOL,  USB20_INT,   0x000000FF}, | ||||
| }; | ||||
|  | ||||
|  | ||||
| PCI_HEADER_ENTRY UDC_Hdr[] = { | ||||
|   //  Reg         Flag     Value         Mask | ||||
|   {   0x00,       0x00, 0x20961022,   0x00000000}, | ||||
|   {   COMMAND,    0x00,  USB20_CMD,   USB20_MASK,0,0,WC_STATUS_BITS}, | ||||
|   {   0x08,       0x00, 0x0C03FE00,   0x00000000},  // Serial Bus: USB : device | ||||
|   {   0x0C,       0x00, 0x00000008,   0x00000008}, | ||||
|   {   BAR0,       0x00, 0x00000000,   0x00002000, USBMSRUDCB}, | ||||
| #if SUPPORT_CAPABILITIES   | ||||
|   {   0x34,       0x00, PCI_PM_REG,   0x00000000},  // Capabilities pointer | ||||
|   {PCI_PM_REG,    0x00, 0xC8020001,   0x00000000},  // PCI Power Management | ||||
|   {PCI_PM_REG+4,PCI_PM, 0x00000000,   0x00008103}, | ||||
| #endif | ||||
|   {   0x3C,        EOL,  USB20_INT,   0x000000FF}, | ||||
| }; | ||||
|  | ||||
|  | ||||
| PCI_HEADER_ENTRY OTG_Hdr[] = { | ||||
|   //  Reg         Flag     Value         Mask | ||||
|   {   0x00,       0x00, 0x20971022,   0x00000000}, | ||||
|   {   COMMAND,    0x00,    OTG_CMD,     OTG_MASK,0,0,WC_STATUS_BITS}, | ||||
|   {   0x08,       0x00, 0x0C038000,   0x00000000},  // Serial Bus: USB : No specific interface | ||||
|   {   0x0C,       0x00, 0x00000008,   0x00000008}, | ||||
|   {   BAR0,       0x00, 0x00000000,   0x00001000, USBMSRUOCB}, | ||||
| #if SUPPORT_CAPABILITIES   | ||||
|   {   0x34,       0x00, PCI_PM_REG,   0x00000000},  // Capabilities pointer | ||||
|   {PCI_PM_REG,    0x00, 0xC8020001,   0x00000000},  // PCI Power Management | ||||
|   {PCI_PM_REG+4,PCI_PM, 0x00000000,   0x00008103}, | ||||
| #endif | ||||
|   {   0x3C,        EOL,  USB20_INT,   0x000000FF}, | ||||
| }; | ||||
|  | ||||
|  | ||||
| #define THOR_MASK   (BM_MASK | IO_SPACE) | ||||
| PCI_HEADER_ENTRY Thor_Hdr[] = { | ||||
|   //  Reg         Flag     Value         Mask | ||||
|   {   0x00,       0x00, 0x209A1022,   0x00000000}, | ||||
|   {   COMMAND,    0x00,  BM_STATUS,    THOR_MASK,0,0,WC_STATUS_BITS}, | ||||
|   {   0x08,       0x00, 0x01018000,   0x00000000},  // Mass Storage: IDE | ||||
|   {   0x0C,       0x00, 0x0000F808,   0x00000008}, | ||||
|   {   BAR4,       0x00, 0x00000000,   0x00000000, MSR_LBAR_ATA},  // 16 byte I/O BAR | ||||
| // The following 4 registers must be contiguous: | ||||
|   {   IDE_CFG,    0x00, 0x00000000,   0x0003FFFF, 0x10},  | ||||
|   {   IDE_DTC,    0x00, 0xA8A80000,   0xFFFF0000, 0x12},  | ||||
|   {   IDE_CAST,   0x00, 0xFF0000F0,   0xFF0000F0, 0x13},  | ||||
|   {   IDE_ETC,    0x00, 0x03030000,   0xC7C70000, 0x14}, | ||||
|   {   IDE_PM,      EOL, 0x00000000,   0x00000003, 0x15}, | ||||
| }; | ||||
|  | ||||
|  | ||||
| PCI_HEADER_ENTRY * Virtual_5536[] = { | ||||
|    ISA_Hdr,          // F0  ISA bridge | ||||
|    Flash_Hdr,        // F1  Flash | ||||
|    Thor_Hdr,         // F2  ATA | ||||
|    Audio_Hdr,        // F3  AC97 | ||||
|    OHC_Hdr,          // F4  OHCI | ||||
|    EHC_Hdr,          // F5  EHCI | ||||
|    UDC_Hdr,          // F6  UDC | ||||
|    OTG_Hdr,          // F7  OTG | ||||
| }; | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // The following tables determine the virtualized PCI topology | ||||
| //*********************************************************************** | ||||
| PCI_HEADER_ENTRY * NorthBridge[] = { | ||||
|    HostBridge_Hdr,   // F0  Host bridge | ||||
|    0,                // F1  Graphics (enabled via softvg) | ||||
|    AES_Hdr,          // F2  Encryption | ||||
|    0,                // F3 | ||||
|    0,                // F4 | ||||
|    0,                // F5 | ||||
|    0,                // F6 | ||||
|    0                 // F7 | ||||
| }; | ||||
|  | ||||
|  | ||||
| // Pointer to the virtualized Southbridge table | ||||
| VIRTUAL_DEVICE * SouthBridge; | ||||
|  | ||||
|  | ||||
|  | ||||
| // NOTE: SouthBridge will be inserted into the following table  | ||||
| //       at the same DEVSEL as the hardware header.       | ||||
| VIRTUAL_DEVICE * Virtual_Devices[32] = { | ||||
|                     // IDSEL Dev#    Address          Description | ||||
|                     // ----- -----  ----------   --------------------- | ||||
|    0,               //  N/A   0 | ||||
|    NorthBridge,     //  11    1     0x80000800   HostBridge + Graphics | ||||
|    0,               //  12    2 | ||||
|    0,               //  13    3 | ||||
|    0,               //  14    4 | ||||
|    0,               //  15    5 | ||||
|    0,               //  16    6 | ||||
|    0,               //  17    7 | ||||
|    0,               //  18    8 | ||||
|    0,               //  19    9 | ||||
|    0,               //  20   10 | ||||
|    0,               //  21   11 | ||||
|    0,               //  22   12 | ||||
|    0,               //  23   13 | ||||
|    0,               //  24   14 | ||||
|    0,               //  25   15     0x80007800   CS5535 & CS5536 | ||||
|    0,               //  26   16 | ||||
|    0,               //  27   17 | ||||
|    0,               //  28   18     0x80009000   CS5530 | ||||
|    0,               //  29   19     0x80009800   CS5530 OHCI | ||||
|    0,               //  30   20 | ||||
|    0,               //  31   21 | ||||
|    0,               //  N/A  22 | ||||
|    0,               //  N/A  23 | ||||
|    0,               //  N/A  24 | ||||
|    0,               //  N/A  25 | ||||
|    0,               //  N/A  26 | ||||
|    0,               //  N/A  27 | ||||
|    0,               //  N/A  28 | ||||
|    0,               //  N/A  29 | ||||
|    0,               //  N/A  30 | ||||
|    0,               //  N/A  31 | ||||
| }; | ||||
|  | ||||
|  | ||||
							
								
								
									
										338
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/unregstr.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										338
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/unregstr.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,338 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA  | ||||
| */ | ||||
|  | ||||
| //****************************************************************************** | ||||
| //*     This file contains the code that unregisters events | ||||
| //****************************************************************************** | ||||
|  | ||||
|  | ||||
|  | ||||
| #include "VSA2.H" | ||||
| #include "SYSMGR.H" | ||||
| #include "PROTOS.H" | ||||
|  | ||||
|  | ||||
|  | ||||
| // Externals: | ||||
| extern void pascal Clr_MBus_IO_Trap(ULONG Address, USHORT Range); | ||||
| extern UCHAR * VsmNames[]; | ||||
| extern UCHAR * EventNames[]; | ||||
| extern UCHAR FreeEvent; | ||||
| extern EVENT_ENTRY Events[MAX_REGISTRATIONS]; | ||||
|  | ||||
|  | ||||
| //***************************************************************************** | ||||
| // Copies an Events[] entry | ||||
| //***************************************************************************** | ||||
| extern void pascal Copy_Event(USHORT From, USHORT To); | ||||
|  | ||||
| //***************************************************************************** | ||||
| // Retires an Events[] entry to the free list | ||||
| //***************************************************************************** | ||||
| void pascal Retire_Events_Entry(EVENT Event, USHORT match, USHORT previous) | ||||
| { USHORT i; | ||||
|  | ||||
|   // Remove Events[match] from the linked list. | ||||
|   i = Events[match].Link; | ||||
|   if (previous) { | ||||
|     Events[previous].Link = (UCHAR)i; | ||||
|     i = match; | ||||
|   } else { | ||||
|     // The first entry in the linked list is being removed. | ||||
|     Copy_Event(i, Event); | ||||
|   } | ||||
|  | ||||
|   // Mark the entry as available. | ||||
|   Events[i].Vsm = 0x00000000; | ||||
|   if (i) { | ||||
|     // Put Events[] entry on free list | ||||
|     Events[i].Link = FreeEvent; | ||||
|     FreeEvent = (UCHAR)i; | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
| //***************************************************************************** | ||||
| // Unregisters a PCI trap | ||||
| //***************************************************************************** | ||||
| USHORT pascal Unregister_PCI_Trap(VSM Vsm, USHORT PCI_Addr, USHORT PCI_Mask) | ||||
| { USHORT EventIndex, IDSEL_Count=0, previous=0, match=0; | ||||
|   register EVENT_ENTRY * EventPtr; | ||||
|  | ||||
|  | ||||
|   // The entire event chain must be traversed to find out how | ||||
|   // many registrations are trapping this IDSEL.  If only this | ||||
|   // one, then the IDSEL in the MPCI_PBUS MSR will be cleared. | ||||
|   EventIndex = EVENT_PCI_TRAP; | ||||
|   while (Events[EventIndex].Vsm) { | ||||
|     EventPtr = &Events[EventIndex]; | ||||
|  | ||||
|     // Check if IDSEL matches | ||||
|     if ((EventPtr->PCI_Addr & 0xF800) == (PCI_Addr & 0xF800)) { | ||||
|  | ||||
|       IDSEL_Count++; | ||||
|  | ||||
|       // If it is the requested VSM... | ||||
|       if (EventPtr->Vsm == Vsm) { | ||||
|         // and the PCI Address/Mask match... | ||||
|         if (EventPtr->PCI_Addr == PCI_Addr && EventPtr->PCI_Mask == PCI_Mask) { | ||||
|           // Record the EventIndex to be removed | ||||
|           match = EventIndex; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // Record index immediately before the matching Events[] entry | ||||
|     if (!match) { | ||||
|       previous = EventIndex; | ||||
|     } | ||||
|  | ||||
|     // Get the next entry in the linked list | ||||
|     EventIndex = EventPtr->Link; | ||||
|  | ||||
|   }  // end while | ||||
|  | ||||
|  | ||||
|   // If this is the only registration for this IDSEL... | ||||
|   if (IDSEL_Count == 1) { | ||||
|     // disable trapping this IDSEL | ||||
|     Disable_Event(EVENT_PCI_TRAP, match); | ||||
|   } | ||||
|  | ||||
|   // Retire the Events[] entry | ||||
|   Retire_Events_Entry(EVENT_PCI_TRAP, match, previous); | ||||
|  | ||||
|   return match; | ||||
| } | ||||
|  | ||||
|  | ||||
| //***************************************************************************** | ||||
| //   Disassociates an event from a VSM.  This may occur as a result of a | ||||
| //   VSM performing the UNREGISTER_EVENT() macro, or if a VSM is being | ||||
| //   removed or replaced. | ||||
| //***************************************************************************** | ||||
| // RESOURCE_COUNT: | ||||
| // 1) Must be power of 2 since the Mod (%) operator is used | ||||
| // 2) A minimum of 32 (# GPIOs) | ||||
| // 3) A maximum of 256 | ||||
| #define RESOURCE_COUNT 128 | ||||
| USHORT pascal Unregister_Event(EVENT Event, VSM Vsm, ULONG Param1, ULONG Param2) | ||||
| { USHORT EventIndex, i, j=4, k=0, previous=0, match=0; | ||||
|   static UCHAR HW_Resource[RESOURCE_COUNT]; | ||||
|   UCHAR IO_Base, IO_Range; | ||||
|   ULONG Mask1=0x00000000, Mask2=0x00000000; | ||||
|   register EVENT_ENTRY * EventPtr; | ||||
|  | ||||
|  | ||||
|  | ||||
|   // Determine which parameters must match | ||||
|   switch (Event) { | ||||
|  | ||||
|     case EVENT_TIMER: | ||||
|       // Only require Handle to match | ||||
|       Mask2 = 0x0000FFFF; | ||||
|       j = 8;      // # h/w timers | ||||
|       break; | ||||
|  | ||||
|     case EVENT_PWM: | ||||
|     case EVENT_PME: | ||||
|     case EVENT_GPIO: | ||||
|       // Only require pin to match | ||||
|       Mask1 = 0x0000FFFF; | ||||
|       j = 32;     // max # GPIO pins | ||||
|       break; | ||||
|  | ||||
|     case EVENT_IO_TRAP: | ||||
|       j = RESOURCE_COUNT; | ||||
|       // Only require I/O addresses within range to match | ||||
|       Mask1 = 0x00010000 - RESOURCE_COUNT; | ||||
|       break; | ||||
|  | ||||
|     case EVENT_PCI_TRAP: | ||||
|       match = Unregister_PCI_Trap(Vsm, (USHORT)Param1, (USHORT)Param2); | ||||
|       return match; | ||||
|  | ||||
|     case EVENT_IO_TIMEOUT: | ||||
|       // Require Param1 to match | ||||
|       Mask1 = 0xFFFFFFFF; | ||||
|       break; | ||||
|   } | ||||
|  | ||||
|   // Zero the h/w resource usage counters | ||||
|   for (i=0; i<j; i++) { | ||||
|     HW_Resource[i] = 0; | ||||
|   } | ||||
|   j = 0; | ||||
|  | ||||
|   // The entire event chain must be traversed to find out how | ||||
|   // many registrations are using the resource.  If more than | ||||
|   // one, then the hardware will not be disabled. | ||||
|   EventIndex = Event; | ||||
|   while (Events[EventIndex].Vsm) { | ||||
|     EventPtr = &Events[EventIndex]; | ||||
|     switch (Event) { | ||||
|       case EVENT_TIMER: | ||||
|         j = (USHORT)EventPtr->Timer; | ||||
|         break; | ||||
|  | ||||
|       case EVENT_PWM: | ||||
|       case EVENT_PME: | ||||
|       case EVENT_GPIO: | ||||
|         j = (USHORT)EventPtr->Pin; | ||||
|         break; | ||||
|     } | ||||
|  | ||||
|     // Check if parameters match | ||||
|     if ((EventPtr->Param1 & Mask1) == (Param1 & Mask1) && | ||||
|         (EventPtr->Param2 & Mask2) == (Param2 & Mask2)) { | ||||
|  | ||||
|       if (Event == EVENT_IO_TRAP) { | ||||
|         // Accumulate usage count for each I/O location in range | ||||
|         IO_Base  = (UCHAR)EventPtr->IO_Base; | ||||
|         IO_Range = (UCHAR)EventPtr->IO_Range; | ||||
|         for (i = 0; i < IO_Range; i++) { | ||||
|           k = (UCHAR)(i + IO_Base) % RESOURCE_COUNT; | ||||
|           HW_Resource[k]++; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       // If it is the requested VSM... | ||||
|       if (EventPtr->Vsm == Vsm) { | ||||
|  | ||||
|         // Record which h/w resource is being disabled | ||||
|         switch (Event) { | ||||
|           case EVENT_IO_TRAP: | ||||
|             if (match) { | ||||
|               // There are overlapping I/O ranges in the same VSM | ||||
|               if ((EventPtr->IO_Base != (USHORT)Param1) || | ||||
|                   (EventPtr->IO_Range != (USHORT)Param2)) { | ||||
|                 // This is not the one being removed | ||||
|                 break; | ||||
|               } | ||||
|             } | ||||
|           case EVENT_PWM: | ||||
|           case EVENT_PME: | ||||
|           case EVENT_GPIO: | ||||
|           case EVENT_TIMER: | ||||
|             k = j; | ||||
|           default: | ||||
|             // Record the EventIndex to be removed | ||||
|             if (!match) { | ||||
|               match = EventIndex; | ||||
|             } | ||||
|             break; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // Record entry previous to 'match' | ||||
|     if (!match) { | ||||
|       previous = EventIndex; | ||||
|     } | ||||
|  | ||||
|     // Increment resource usage count | ||||
|     if (Event != EVENT_IO_TRAP) { | ||||
|       HW_Resource[j]++; | ||||
|     } | ||||
|  | ||||
|     // Link to the next entry in the list. | ||||
|     EventIndex = EventPtr->Link; | ||||
|  | ||||
|   }  // end while | ||||
|  | ||||
|  | ||||
|   if (match) { | ||||
|  | ||||
|     switch (Event) { | ||||
|       USHORT Range; | ||||
|  | ||||
|       case EVENT_IO_TRAP: | ||||
|         Range=0x0000; | ||||
|         EventPtr = &Events[match]; | ||||
|         Param1 |= Param2 & 0xFFFF0000; | ||||
|         for (j = 0; j < (UCHAR)Param2; j++) { | ||||
|           k = (UCHAR)((j + EventPtr->Param1) % RESOURCE_COUNT); | ||||
|           if (HW_Resource[k] > 1) { | ||||
|             if (Range) { | ||||
|               // Found end of a range used exclusively by this VSM | ||||
|               Clr_MBus_IO_Trap(Param1, Range); | ||||
|               Param1 += Range; | ||||
|               Range = 0; | ||||
|             } else { | ||||
|               (USHORT)Param1++; | ||||
|             } | ||||
|           } else { | ||||
|             Range++; | ||||
|           } | ||||
|         } | ||||
|         if (Range) { | ||||
|           Clr_MBus_IO_Trap(Param1, Range); | ||||
|         } | ||||
|         break; | ||||
|  | ||||
|       default: | ||||
|         // If only one registration is using the h/w resource, disable it | ||||
|         if (HW_Resource[k] == 1) { | ||||
|       case EVENT_IO_TIMEOUT:          // Statistic counter logic keeps track of usage | ||||
|           Disable_Event(Event, match); | ||||
|         } | ||||
|       case EVENT_SOFTWARE_SMI: | ||||
|         break; | ||||
|     } | ||||
|  | ||||
|     // Retire the Events[] entry | ||||
|     Retire_Events_Entry(Event, match, previous); | ||||
|    | ||||
|   } else { | ||||
|  | ||||
|     // A VSM attempted to unregister a event that it is not registered for | ||||
|     Log_Error("Attempt to unregister EVENT_%s[0x%08X;0x%08X] by the %s VSM", EventNames[Event], Param1, Param2, VsmNames[Get_VSM_Type(Vsm)]); | ||||
|   } | ||||
|  | ||||
|   return match; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //***************************************************************************** | ||||
| // Removes all events registered to a VSM. | ||||
| //***************************************************************************** | ||||
| void pascal Unregister_VSM_Events(VSM Vsm) | ||||
| { register EVENT Event; | ||||
|   register EVENT_ENTRY * EventPtr; | ||||
|     | ||||
|   // Unregister all events registered to this VSM | ||||
|   for (Event=1; Event <= MAX_EVENT; Event++) { | ||||
|     EventPtr = &Events[Event]; | ||||
|     while (EventPtr->Vsm) { | ||||
|  | ||||
| 	  if (EventPtr->Vsm == Vsm) { | ||||
|         if (Unregister_Event(Event, Vsm, EventPtr->Param1, EventPtr->Param2)) { | ||||
|           // Start over on this event since there might be others for this VSM. | ||||
|           Event--; | ||||
|           break; | ||||
|         }         | ||||
|       } | ||||
|       EventPtr = &Events[EventPtr->Link]; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
							
								
								
									
										642
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/utils.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										642
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/utils.asm
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,642 @@ | ||||
| ;  | ||||
| ; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| ;  | ||||
| ; This library is free software; you can redistribute it and/or modify | ||||
| ; it under the terms of the GNU Lesser General Public License as | ||||
| ; published by the Free Software Foundation; either version 2.1 of the | ||||
| ; License, or (at your option) any later version. | ||||
| ;  | ||||
| ; This code is distributed in the hope that it will be useful, | ||||
| ; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| ; Lesser General Public License for more details. | ||||
| ;  | ||||
| ; You should have received a copy of the GNU Lesser General | ||||
| ; Public License along with this library; if not, write to the | ||||
| ; Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| ; Boston, MA 02111-1307 USA  | ||||
| ;  | ||||
| ;******************************************************************************* | ||||
| ;*     Miscellaneous utility routines | ||||
| ;******************************************************************************* | ||||
|  | ||||
|  | ||||
| include SYSMGR.INC | ||||
| include VSA2.INC | ||||
| include PCI.INC | ||||
| include GX2.INC | ||||
|  | ||||
| .model tiny,c | ||||
| .586p | ||||
| .CODE | ||||
|  | ||||
| externdef SchedulerStack:   word | ||||
| externdef SysMgr_VSM:       dword | ||||
| externdef Saved_PCI:	    dword | ||||
| externdef Nested_PCI:       dword | ||||
| externdef MsgPacket:        dword | ||||
| externdef ClocksPerMs:      dword | ||||
| externdef StartSaveArea:    dword | ||||
| externdef Header_Addr:      dword | ||||
| externdef Nested_Flag:      dword | ||||
| externdef VSM_Ptrs:         dword | ||||
| externdef Events:           EVENT_ENTRY | ||||
|  | ||||
| 	 | ||||
|  | ||||
|  | ||||
| ;************************************************************************ | ||||
| ; | ||||
| ; 8 bit I/O routines | ||||
| ; | ||||
| ;************************************************************************ | ||||
|  | ||||
| in_8 proc  pascal \ | ||||
| 	io_port: word | ||||
|  | ||||
| 	mov	dx, [io_port] | ||||
| 	in 	al, dx | ||||
| 	ret | ||||
|     | ||||
| in_8 endp | ||||
|  | ||||
|  | ||||
| out_8	proc pascal \ | ||||
| 	io_port: word, \ | ||||
| 	io_data: byte | ||||
|  | ||||
| 	mov	dx, [io_port] | ||||
| 	mov	al, [io_data] | ||||
| 	out	dx, al | ||||
| 	ret | ||||
|  | ||||
| out_8	endp | ||||
|  | ||||
| ;************************************************************************ | ||||
| ; | ||||
| ; 16 bit I/O routines | ||||
| ; | ||||
| ;************************************************************************ | ||||
|  | ||||
| in_16 proc  pascal \ | ||||
| 	io_port: word | ||||
|  | ||||
| 	mov	dx, [io_port] | ||||
| 	in 	ax, dx | ||||
| 	ret | ||||
|     | ||||
| in_16 endp | ||||
|  | ||||
|  | ||||
| out_16	proc pascal \ | ||||
| 	io_port: word, \ | ||||
| 	io_data: word | ||||
|  | ||||
| 	mov	dx, [io_port] | ||||
| 	mov	ax, [io_data] | ||||
| 	out	dx, ax | ||||
| 	ret | ||||
|  | ||||
| out_16	endp | ||||
|  | ||||
|  | ||||
| ;************************************************************************ | ||||
| ; | ||||
| ; 32 bit I/O routines | ||||
| ; | ||||
| ;************************************************************************ | ||||
|  | ||||
| in_32 proc  pascal \ | ||||
| 	io_port: word | ||||
|  | ||||
| 	mov	dx, [io_port] | ||||
| 	in 	eax, dx | ||||
| 	mov	edx, eax | ||||
| 	shr	edx, 16 | ||||
| 	ret | ||||
|     | ||||
| in_32 endp | ||||
|  | ||||
|  | ||||
| out_32	proc pascal \ | ||||
| 	io_port: word, \ | ||||
| 	io_data: dword | ||||
|  | ||||
| 	mov	dx, [io_port] | ||||
| 	mov	eax, [io_data] | ||||
| 	out	dx, eax | ||||
| 	ret | ||||
|  | ||||
| out_32	endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;************************************************************************ | ||||
| ; | ||||
| ; Input: | ||||
| ;   Ptr to a VSM header | ||||
| ; | ||||
| ; Output: | ||||
| ;   Ptr to the next VSM in the chain | ||||
| ; | ||||
| ;************************************************************************ | ||||
| GetFlink proc pascal, \ | ||||
| 	VSM_Ptr: dword | ||||
|  | ||||
| 	mov	ebx, [VSM_Ptr] | ||||
| 	mov	eax, (VSM_Header PTR fs:[ebx]).SysStuff.Flink | ||||
| 	mov	edx, eax | ||||
| 	shr	edx, 16 | ||||
| 	ret | ||||
|  | ||||
| GetFlink endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;************************************************************************ | ||||
| ; Writes a BYTE, WORD, DWORD to a 32-bit address | ||||
| ;************************************************************************ | ||||
| write_flat_size proc pascal \ | ||||
| 	Address: dword, \ | ||||
| 	Data:    dword, \ | ||||
| 	Len:     byte | ||||
|  | ||||
| 	mov	ebx, [Address] | ||||
| 	mov	eax, [Data] | ||||
| 	mov	cl,  [Len] | ||||
| 	cld | ||||
| 	cmp	cl, BYTE_IO | ||||
| 	jne	short CheckWord | ||||
| 	mov	fs:[ebx], al | ||||
| 	jmp	short Exit | ||||
| 	 | ||||
| CheckWord:	 | ||||
| 	cmp	cl, WORD_IO | ||||
| 	je	short WriteWord | ||||
| WriteDword: | ||||
| 	db	66H | ||||
| WriteWord: | ||||
| 	mov	fs:[ebx], ax | ||||
| Exit:	ret | ||||
|  | ||||
| write_flat_size endp | ||||
|  | ||||
| ;************************************************************************ | ||||
| ; Writes a DWORD to a 32-bit address | ||||
| ;************************************************************************ | ||||
| write_flat proc pascal \ | ||||
| 	Address: dword, \ | ||||
| 	Data:    dword | ||||
|  | ||||
| 	mov	ebx, [Address] | ||||
| 	mov	eax, [Data] | ||||
| 	mov	fs:[ebx], eax | ||||
| 	ret | ||||
|  | ||||
| write_flat endp | ||||
|  | ||||
| ;************************************************************************ | ||||
| ; Reads a DWORD from a 32-bit address | ||||
| ;************************************************************************ | ||||
| read_flat proc pascal \ | ||||
| 	Address: dword | ||||
|  | ||||
| 	mov	ebx, [Address] | ||||
| 	mov	eax, fs:[ebx] | ||||
| 	mov	edx, eax | ||||
| 	shr	edx, 16 | ||||
| 	ret | ||||
|  | ||||
| read_flat endp | ||||
|  | ||||
|  | ||||
|  | ||||
| ;************************************************************************ | ||||
| ; | ||||
| ; Copies the parameters for a synchronous event from the appropriate SMI | ||||
| ; header to the MsgPacket array. | ||||
| ; NOTE: This routine should only be called from a Synchronous SMI handler. | ||||
| ; | ||||
| ; On exit: | ||||
| ;   MsgPacket[1]:  15:0  - Flags field from SMM header | ||||
| ;   MsgPacket[2]:  15:0  - I/O address (or PCI address) from SMM header | ||||
| ;		   31:16 - Data Size field from SMM header | ||||
| ;   MsgPacket[3]:  Data (if I/O write) | ||||
| ; | ||||
| ;   Returns ptr to appropriate SMM header. | ||||
| ; | ||||
| ;************************************************************************ | ||||
| Get_Header_Params proc pascal \ | ||||
| 	SMI_Event: dword | ||||
|  | ||||
| 	mov     bx, OFFSET VSM_Header.SysStuff.State | ||||
| 	 | ||||
| 	ASSUME	BX: PTR SmiHeader | ||||
|  | ||||
| 	mov	eax, [SMI_Event]	; Is it a nested event ? | ||||
| 	test	[Nested_Flag], eax | ||||
| 	je	Copy_Params	 | ||||
|  | ||||
| 	not	eax			; Yes, clear the event | ||||
| 	and	[Nested_Flag], eax | ||||
|  | ||||
| 	push	si			; Copy VSM's header to local buffer | ||||
| 	mov	si, bx | ||||
|  | ||||
| 	lea	bx, [Nested_Header] | ||||
| 	push	bx | ||||
| 	mov	cx, sizeof(SmiHeader)/4 | ||||
| 	cld | ||||
| CopyHdr: | ||||
| 	lodsd	gs:[si] | ||||
| 	mov	dword ptr [bx], eax | ||||
| 	add	bx, 4 | ||||
| 	loop	CopyHdr	 | ||||
|  | ||||
| 	pop	bx | ||||
| 	pop	si | ||||
| 	 | ||||
| 	 | ||||
| 	 | ||||
| 	; Copy parameters from SMM header to MsgPacket[] | ||||
| Copy_Params: | ||||
| 	 | ||||
| 	movzx	eax, [bx].SMI_Flags | ||||
| 	mov	[MsgPacket+4*1], eax	; MsgPacket[1] | ||||
|  | ||||
|  | ||||
| 	; Is it a PCI trap ? | ||||
| 	mov	eax, dword ptr [bx].IO_addr | ||||
| 	mov	dx, ax | ||||
| 	and	dl, NOT 3 | ||||
| 	cmp	dx, PCI_CONFIG_DATA | ||||
| 	jne	short StoreAddr | ||||
| 	 | ||||
| 	; Yes, get PCI address from appropriate context | ||||
| 	mov	cl, al			; Get 2 LSBs of PCI address | ||||
| 	and	cl, 3 | ||||
| 	mov	ax, word ptr [Nested_PCI] | ||||
| 	cmp	bx, OFFSET [Nested_Header] | ||||
| 	je	short Get_PCI | ||||
|  | ||||
| 	mov	ax, word ptr [Saved_PCI] | ||||
| Get_PCI: | ||||
| 	or	al, cl | ||||
| StoreAddr: | ||||
| 	mov	[MsgPacket+4*2], eax	; MsgPacket[2] | ||||
|  | ||||
|  | ||||
| 	; Get write data | ||||
| 	mov	ecx, [bx].write_data | ||||
| 	shr	eax, 16			; Put I/O size into AL | ||||
| 	cmp	al, DWORD_IO		; Dword I/O ? | ||||
| 	je	short StoreData | ||||
| 	movzx	ecx, cx | ||||
| 	cmp	al, WORD_IO		; Word I/O ? | ||||
| 	je	short StoreData | ||||
| 	xor	ch, ch			; Byte I/O | ||||
| 	 | ||||
| StoreData:	 | ||||
| 	mov	[MsgPacket+4*3], ecx	; MsgPacket[3] | ||||
|  | ||||
| 	mov	ax, bx			; Return ptr to header | ||||
| 	ret | ||||
|  | ||||
| Nested_Header	SmiHeader {} | ||||
|  | ||||
|  | ||||
| Get_Header_Params endp | ||||
| 	 | ||||
| 	ASSUME	BX: NOTHING | ||||
| 	 | ||||
|  | ||||
| ;************************************************************************ | ||||
| ; Returns the # milliseconds elapsed on a timer. | ||||
| ;************************************************************************ | ||||
| ElapsedSoFar proc  StartTime: PTR | ||||
| 	 | ||||
| 	rdtsc				; Get current timestamp | ||||
|  | ||||
| 	mov	bx, [StartTime]		; Subtract timer's start time | ||||
| 	sub	eax, [bx+0] | ||||
| 	sbb	edx, [bx+4] | ||||
|  | ||||
| 	idiv	[ClocksPerMs]		; Convert delta to milliseconds | ||||
| 	mov	edx, eax | ||||
| 	shr	edx, 16 | ||||
| 	ret | ||||
| 	 | ||||
| ElapsedSoFar endp | ||||
|  | ||||
|  | ||||
|  | ||||
| ;************************************************************************ | ||||
| ; Returns the timestamp counter in the passed buffer | ||||
| ;************************************************************************ | ||||
| Store_Timestamp proc pascal \ | ||||
| 	TimeStamp:  PTR | ||||
|  | ||||
| 	rdtsc | ||||
| 	mov	bx, [TimeStamp] | ||||
| 	mov	[bx+0], eax | ||||
| 	mov	[bx+4], edx | ||||
| 	ret | ||||
|  | ||||
| Store_Timestamp endp | ||||
|  | ||||
|  | ||||
|  | ||||
| ;************************************************************************ | ||||
| ; Returns the type of the VSM pointed to by the Vsm parameter | ||||
| ;************************************************************************ | ||||
| Get_VSM_Type proc pascal \ | ||||
|   	Vsm:dword | ||||
|  | ||||
| 	mov	ebx, [Vsm] | ||||
| 	mov	al, fs:(VSM_Header PTR [ebx]).VSM_Type | ||||
| 	ret | ||||
|  | ||||
| Get_VSM_Type endp | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ;************************************************************************ | ||||
| ; Translates a logical address to a physical address via the page tables | ||||
| ; NOTES: | ||||
| ;  - This routine should only be called if paging is enabled. | ||||
| ;  - All page & segment protection has already occurred. | ||||
| ;************************************************************************ | ||||
|  | ||||
| PAGE_ATTR	equ	0FFFh | ||||
| CR4_PSE_BIT	equ	0010h | ||||
| PDIR_PS_BIT	equ	0080h | ||||
| OFFSET_4M	equ	0003FFFFFh | ||||
| PAGEBASE_4M	equ	0FFC00000h | ||||
|  | ||||
| Convert_To_Physical_Addr proc pascal \ | ||||
| 	Logical: dword | ||||
|  | ||||
| 	; Start by checking for 4MB page possibility | ||||
| 	mov	eax, CR4 | ||||
| 	test	ax, CR4_PSE_BIT | ||||
| 	jz	short page4K | ||||
|  | ||||
| 	mov	ebx, CR3		; Get ptr to page directory base | ||||
| 	and	ebx, 0FFFFFC00h		; Mask attribute bits | ||||
|  | ||||
| 	mov	edx, [Logical]		; Get address to translate | ||||
| 	shr	edx, 22			; Get page directory index | ||||
|  | ||||
| 	; See if this directory entry points to a 4MB page | ||||
| 	mov	ebx, fs:[ebx+edx*4] | ||||
|  | ||||
| 	test	bx, PDIR_PS_BIT | ||||
| 	jz	short page4K | ||||
|  | ||||
| 	and	ebx, PAGEBASE_4M	; Get the page base offset | ||||
|  | ||||
| 	mov	eax, [Logical]		; Get address to translate | ||||
| 	and	eax, OFFSET_4M		; Peel off the directory index | ||||
|  | ||||
| 	or	eax, ebx		; Combine the base and offset | ||||
|  | ||||
| 	jmp	short Exit | ||||
|  | ||||
|  | ||||
| page4K: | ||||
| 	mov	ebx, CR3		; Get ptr to page directory base | ||||
| 	and	ebx, 0FFFFFC00h		; Mask attribute bits | ||||
|  | ||||
| 	mov	eax, [Logical]		; Get address to translate | ||||
| 	 | ||||
| 	movzx	ecx, ax			; Extract page offset | ||||
| 	and	cx, PAGE_ATTR		; (contains offset into 4K page) | ||||
| 	 | ||||
| 	shr	eax, 12			; Remove page offset | ||||
| 	mov	edx, eax | ||||
| 	 | ||||
| 	shr	edx, 10			; Get page directory offset | ||||
|  | ||||
| 	mov	ebx, fs:[ebx+edx*4] | ||||
| 	and	bx, NOT PAGE_ATTR 	; Remove page directory attributes | ||||
|  | ||||
| 	and	eax, 03FFh		; Extract page table offset  | ||||
| 	mov	eax, fs:[ebx+eax*4] | ||||
| 	and	ax, NOT PAGE_ATTR 	; Remove page attributes | ||||
| 	 | ||||
| 	add	eax, ecx		; Add page offset | ||||
|  | ||||
| Exit:	mov	edx, eax		; Return translated addr in DX:AX | ||||
| 	shr	edx, 16	 | ||||
| 	ret | ||||
| 	 | ||||
| Convert_To_Physical_Addr endp | ||||
|  | ||||
|  | ||||
| ;************************************************************************ | ||||
| ; Marks a 'Blocked' VSM to 'Ready' | ||||
| ;************************************************************************ | ||||
| Unblock_VSM proc pascal Vsm: dword | ||||
|  | ||||
| 	mov	ebx, [Vsm] | ||||
| 	mov	fs:(VSM_Header PTR [ebx]).SysStuff.RunFlag, RUN_FLAG_READY | ||||
| 	ret | ||||
|  | ||||
| Unblock_VSM endp | ||||
|  | ||||
| ;MEJ | ||||
| ;************************************************************************ | ||||
| ; This routine determines if an event should wake the system. | ||||
| ; If so, the PMCore VSM's RunFlag is changed from 'Sleeping' to 'Ready'. | ||||
| ; There currently are two cases: | ||||
| ; 1) A timer for either the APM or PMCore VSM | ||||
| ; 2) A press of the sleep button while in Legacy PM mode | ||||
| ; | ||||
| ; Returns TRUE if the event is a wake event. | ||||
| ;************************************************************************ | ||||
| ;IsWakeEvent proc pascal \ | ||||
| ;  	Vsm:	DWORD | ||||
| ; | ||||
| ;	mov	ebx, [Vsm] | ||||
| ; | ||||
| ;	; Is event for a PM-related VSM ? | ||||
| ;	cmp	fs:(VSM_Header PTR [ebx]).VSM_Type, VSM_PM | ||||
| ;	je	short PossibleWakeEvent | ||||
| ;	cmp	fs:(VSM_Header PTR [ebx]).VSM_Type, VSM_APM | ||||
| ;	jne	short NotWakeEvent | ||||
| ; | ||||
| ;	; Yes, mark PM VSM 'Ready' if it is 'Sleeping' | ||||
| ;PossibleWakeEvent: | ||||
| ;	mov	ebx, [VSM_Ptrs+4*VSM_PM] | ||||
| ;	mov	al, fs:(VSM_Header PTR [ebx]).SysStuff.RunFlag | ||||
| ;	cmp	al, RUN_FLAG_SLEEPING | ||||
| ;	jne	short NotWakeEvent | ||||
| ;	mov	fs:(VSM_Header PTR [ebx]).SysStuff.RunFlag, RUN_FLAG_READY | ||||
| ;	jmp	Exit | ||||
| ;	 | ||||
| ; | ||||
| ;NotWakeEvent:	 | ||||
| ;	xor	al, al | ||||
| ;	 | ||||
| ;Exit:	ret | ||||
| ; | ||||
| ;IsWakeEvent endp | ||||
|  | ||||
|  | ||||
|  | ||||
| ;************************************************************************ | ||||
| ; Returns the flat address to the VSM performing a system call | ||||
| ; Used for reporting errors in a system call. | ||||
| ;************************************************************************ | ||||
| Get_SysCall_Address proc pascal \ | ||||
| 	Vsm: dword, \ | ||||
| 	Depth: byte | ||||
|  | ||||
| 	mov     eax, [Vsm] | ||||
|  | ||||
| 	cmp	eax, [SysMgr_VSM] | ||||
| 	jne	short Get_VSM_Addr | ||||
|  | ||||
| if CHECKED_BUILD | ||||
|  | ||||
| 	mov	dx, sp			; Save BP & SP | ||||
| 	shl	edx, 16 | ||||
| 	mov	dx, bp | ||||
|  | ||||
| 	mov	cl, [Depth] | ||||
| 	add	cl, 2			; Include stack frames for this routine's & Error_Report() | ||||
| PopStackFrame: | ||||
| 	mov	bx, sp | ||||
| 	leave				; Pop a stack frame | ||||
| 	cmp	sp, OFFSET StartSaveArea | ||||
| 	jae	short Bail | ||||
| 	cmp	sp, [SchedulerStack] | ||||
| 	jb	short Bail | ||||
| 	 | ||||
| 	 | ||||
| 	dec	cl | ||||
| 	jnz	PopStackFrame | ||||
| 	jmp	short GetFault | ||||
|  | ||||
|  | ||||
| Bail:	mov	sp, bx | ||||
| GetFault: | ||||
| 	mov	bx, sp			; Get return address to faulting CALL | ||||
| 	movzx	ebx, word ptr [bx] | ||||
| 	sub     bx, 3			; Account for CALL sys_xxxxx | ||||
| 	 | ||||
| 	mov	bp, dx			; Restore BP & SP | ||||
| 	shr	edx, 16 | ||||
| 	mov	sp, dx | ||||
| else | ||||
| 	xor	ebx, ebx		; Don't attempt to determine address | ||||
| endif	 | ||||
| 	jmp	short Result	 | ||||
|  | ||||
| Get_VSM_Addr: | ||||
|  | ||||
| 	ASSUME	BX: PTR word | ||||
|  | ||||
| 	; There are 3 cases: | ||||
| 	; 1) A system call. | ||||
| 	; 2) In-line assembly (e.g. direct I/O virtual register) | ||||
| 	; 3) A subroutine call to offending I/O | ||||
| 	mov	bx, word ptr gs:(VSM_Header).SysStuff.State.Next_EIP | ||||
| 	cmp	gs:[bx-2], 380Fh	; Was it from a SMINT (system call) | ||||
| 	je	short Sys_Call | ||||
|  | ||||
| 	mov	dx, gs:[bx]		; Get next two bytes of VSM's code | ||||
| 	 | ||||
| 	dec	bx			; In case it is in-line assembly | ||||
| 	; If the next two instructions are LEAVE & RET, then it is a  | ||||
| 	; subroutine. Report the caller's address. | ||||
| 	cmp	dl, 0C9h		; Is the next instruction a LEAVE ? | ||||
| 	jne	short Result		; No, must be in-line assembly | ||||
| 	and	dh, NOT 1		; Yes, is the next one a struction a RET ? | ||||
| 	cmp	dh, 0C2h | ||||
| 	jne	short Result		; No, must be in-line assembly | ||||
| Sys_Call: | ||||
| 	mov	bx, word ptr gs:(VSM_Header).SysStuff.SavedESP | ||||
| 	mov	bx, gs:[bx+3*4]		; Get caller's BP | ||||
| 	movzx   ebx, gs:[bx+2]		; Get SP at time of CALL sys_xxxx | ||||
| 	sub     bx, 3			; Account for CALL sys_xxxxx | ||||
| Result: | ||||
| 	add     eax, ebx | ||||
|  | ||||
| 	mov	edx, eax | ||||
| 	shr	edx, 16 | ||||
|  | ||||
| 	ret | ||||
|  | ||||
| Get_SysCall_Address endp | ||||
|  | ||||
|  | ||||
|  | ||||
| ;************************************************************************ | ||||
| ; Returns the 8 MSBs of the DEVID field of the Device Capabilities MSR | ||||
| ;************************************************************************ | ||||
| GetPortID proc 	MBD_Addr: dword | ||||
|  | ||||
| 	mov	ecx, [MBD_Addr] | ||||
| 	mov	cx, MBD_MSR_CAP | ||||
| 	rdmsr | ||||
| 	shr	eax, ID_SHIFT | ||||
| 	xor	ah, ah | ||||
| 	ret | ||||
|  | ||||
| GetPortID endp | ||||
|  | ||||
|  | ||||
| ;************************************************************************ | ||||
| ; Clears pending h/w emulation events in an GeodeLink device | ||||
| ;************************************************************************ | ||||
| ClearMbiu proc pascal Mbiu: dword | ||||
|  | ||||
| 	mov	ecx, [Mbiu] | ||||
| 	or	ecx, ecx | ||||
| 	jz	short Exit | ||||
| 	mov	cx, MBD_MSR_SMI | ||||
| 	rdmsr | ||||
| 	mov	dl, 1 | ||||
| 	wrmsr | ||||
| 	mov	cx, MBD_MSR_ERROR | ||||
| 	rdmsr | ||||
| 	wrmsr | ||||
|  | ||||
| Exit:	ret | ||||
| 	 | ||||
| ClearMbiu endp | ||||
|  | ||||
|  | ||||
|  | ||||
| ;************************************************************************ | ||||
| ; Trims a P2D_R descriptor by Range | ||||
| ;************************************************************************ | ||||
| Trim_P2D_R proc pascal uses esi \ | ||||
| 	MsrAddr: dword, \ | ||||
| 	Range: dword, \ | ||||
| 	MsrData: PTR | ||||
|  | ||||
| 	mov	ecx, [MsrAddr]		; Get current MSR value | ||||
| 	rdmsr | ||||
|  | ||||
| 	mov	ebx, [Range]		; Adjust by Range bytes | ||||
| 	mov	esi, ebx | ||||
| 	shr	esi, (12+12) | ||||
| 	shl	ebx, (20-12) | ||||
| 	sub	eax, ebx | ||||
| 	sbb	edx, esi | ||||
| 	wrmsr | ||||
|  | ||||
| 	mov	bx, [MsrData]		; Return modified MSR | ||||
| 	mov	dword ptr [bx+0], eax | ||||
| 	mov	dword ptr [bx+4], edx | ||||
| 	ret | ||||
| 	 | ||||
| Trim_P2D_R endp | ||||
|  | ||||
| 	end | ||||
							
								
								
									
										885
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/virt_pci.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										885
									
								
								firmware/coreboot/3rdparty/blobs/cpu/amd/geode_lx/gplvsa_ii/sysmgr/virt_pci.c
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,885 @@ | ||||
| /* | ||||
| * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). | ||||
| * | ||||
| * This library is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as | ||||
| * published by the Free Software Foundation; either version 2.1 of the | ||||
| * License, or (at your option) any later version. | ||||
| * | ||||
| * This code is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| * Lesser General Public License for more details. | ||||
|  | ||||
| * You should have received a copy of the GNU Lesser General | ||||
| * Public License along with this library; if not, write to the | ||||
| * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
| * Boston, MA 02111-1307 USA | ||||
| */ | ||||
|  | ||||
| //****************************************************************************** | ||||
| //*     Utility routines related to virtualized PCI config headers | ||||
| //****************************************************************************** | ||||
|  | ||||
|  | ||||
|  | ||||
| #include "VSA2.H" | ||||
| #include "PCI.H" | ||||
| #include "GX2.H" | ||||
| #include "VPCI.H" | ||||
| #include "SYSMGR.H" | ||||
| #include "CHIPSET.H" | ||||
| #include "PROTOS.H" | ||||
| #include "DESCR.H" | ||||
| #include "MDD.H" | ||||
|  | ||||
|  | ||||
| // External function declarations: | ||||
| extern void pascal Parse_Descriptor(UCHAR, ULONG *, ULONG *); | ||||
| extern void pascal Trim_P2D_R(ULONG, ULONG, ULONG *); | ||||
|  | ||||
|  | ||||
| // External variable declarations: | ||||
| extern UCHAR DynamicVSALoad; | ||||
| extern UCHAR MC_Port, VG_Port; | ||||
| extern UCHAR MBIU1_SelfReference; | ||||
| extern UCHAR End_of_POST; | ||||
| extern ULONG MDD_Base; | ||||
| extern ULONG Mbiu0, Mbiu1, Mbiu2; | ||||
| extern ULONG MPCI_NB, MPCI_SB; | ||||
| extern DESCRIPTOR MSRs[]; | ||||
| extern ULONG ExtendedMemoryDescr0, ExtendedMemoryDescr1; | ||||
| extern Hardware HardwareInfo; | ||||
| extern VIRTUAL_DEVICE   * Virtual_Devices[]; | ||||
| extern VIRTUAL_DEVICE   * SouthBridge; | ||||
| extern PCI_HEADER_ENTRY * NorthBridge[]; | ||||
| extern PCI_HEADER_ENTRY * Virtual_5536[]; | ||||
| extern PCI_HEADER_ENTRY Graphics_Hdr[]; | ||||
| extern PCI_HEADER_ENTRY HostBridge_Hdr[]; | ||||
| extern PCI_HEADER_ENTRY AES_Hdr[]; | ||||
| extern PCI_HEADER_ENTRY ISA_Hdr[]; | ||||
| extern PCI_HEADER_ENTRY Thor_Hdr[]; | ||||
| extern PCI_HEADER_ENTRY Audio_Hdr[]; | ||||
| extern PCI_HEADER_ENTRY Flash_Hdr[]; | ||||
|  | ||||
|  | ||||
| // Local variable declarations: | ||||
| PCI_HEADER_ENTRY * CommandPtr, * HdrPtr; | ||||
| PCI_HEADER_ENTRY Dummy_Hdr[] = { | ||||
|   {0x00, 0x00, 0xFFFFFFFF, 0x00000000}, | ||||
|   {0x00, 0x00, 0xFFFFFFFF, 0x00000000}, | ||||
|   {0x00, 0x00, 0xFFFFFFFF, 0x00000000}, | ||||
|   {0x00,  EOL, 0xFFFFFFFF, 0x00000000}, | ||||
| }; | ||||
| VIRTUAL_DEVICE * IDSELs; | ||||
| VIRTUAL_PTR * VirtDevPtr; | ||||
| USHORT DeviceID; | ||||
| USHORT Class; | ||||
| UCHAR BaseClass; | ||||
| UCHAR Shift, AlignedReg, Function; | ||||
| ULONG Virtualized_PCI_Devices=0; | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Given a ptr to a virtual PCI header, finds Register | ||||
| //*********************************************************************** | ||||
| PCI_HEADER_ENTRY * pascal Find_Register(PCI_HEADER_ENTRY * Pci, UCHAR Register) | ||||
| { | ||||
|   // Keep a ptr to the Vendor ID register | ||||
|   HdrPtr = Pci; | ||||
|   DeviceID = HdrPtr->Device_ID; | ||||
|  | ||||
|   // Keep a ptr to the Command register | ||||
|   CommandPtr = Pci + COMMAND/4; | ||||
|  | ||||
|   // Record the device Class | ||||
|   BaseClass = (HdrPtr+REVISION_ID/4)->BaseClass; | ||||
|   Class = (HdrPtr+REVISION_ID/4)->Class; | ||||
|  | ||||
|   // Scan the table for the specified register entry | ||||
|   do { | ||||
|     if (Pci->Reg == Register) { | ||||
|       return Pci; | ||||
|     } | ||||
|   } while (!((Pci++)->Flag & EOL)); | ||||
|  | ||||
|  | ||||
|   // If CommandPtr is used, avoid generating an exception | ||||
|   CommandPtr = Dummy_Hdr; | ||||
|  | ||||
|   // Register is not in the table | ||||
|   return (PCI_HEADER_ENTRY *) UNIMPLEMENTED_REGISTER; | ||||
| } | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Parses PCI_Address & returns a pointer to the corresponding entry in a | ||||
| // virtual header table. | ||||
| // Computes global variables: | ||||
| //   AlignedReg, Function, Shift, HdrPtr, CommandPtr, & DeviceID | ||||
| //*********************************************************************** | ||||
| PCI_HEADER_ENTRY * pascal Get_Structure(USHORT PCI_Address) | ||||
| { register PCI_HEADER_ENTRY * Pci; | ||||
|   UCHAR Reg; | ||||
|  | ||||
|   // Compute Function # | ||||
|   Function = (UCHAR)(PCI_Address >> 8) & 0x07; | ||||
|  | ||||
|   // Get register offset | ||||
|   Reg = (UCHAR) PCI_Address; | ||||
|  | ||||
|   // Compute DWORD aligned register offset | ||||
|   AlignedReg = Reg & ~3; | ||||
|  | ||||
|   // Compute shift count | ||||
|   Shift = (Reg & 3) << 3; | ||||
|  | ||||
|   // Subsystem Vendor ID & Subsystem ID are same as Vendor ID & Device ID | ||||
|   if (AlignedReg == SUBSYSTEM_VENDOR_ID) { | ||||
|     AlignedReg = VENDOR_ID; | ||||
|   } | ||||
|  | ||||
|  | ||||
|   // Return value if function not implemented | ||||
|   Pci = (PCI_HEADER_ENTRY *) UNIMPLEMENTED_FUNCTION; | ||||
|  | ||||
|   // Is this IDSEL virtualized ? | ||||
|   if (IDSELs = *(VirtDevPtr+(PCI_Address >> 11))) { | ||||
|  | ||||
|     // Get ptr to this function (0000 if not implemented) | ||||
|     if (Pci = IDSELs[Function]) { | ||||
|       Pci = Find_Register(Pci, AlignedReg); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return Pci; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Trims the MSRs that map extended memory by RangeRequest bytes | ||||
| //*********************************************************************** | ||||
| ULONG Trim_Extended_Memory(ULONG RangeRequest) | ||||
| { ULONG Fields[3], Ext_Mem[2], Msr; | ||||
|  | ||||
|   // Trim the MPCI Region 1 configuration | ||||
|   Msr = MPCI_NB + MPCI_R1; | ||||
|   Read_MSR(Msr, Ext_Mem); | ||||
|   if (DynamicVSALoad) { | ||||
|     RangeRequest = 0; | ||||
|   } | ||||
|   Ext_Mem[1] -= RangeRequest; | ||||
|   Write_MSR(Msr, Ext_Mem); | ||||
|  | ||||
|   // Adjust RCONF_DEFAULT[SYSTOP] | ||||
|   Read_MSR(MSR_RCONF_DEFAULT, Ext_Mem); | ||||
|   Ext_Mem[0] -= RangeRequest >> 4; | ||||
|   Write_MSR(MSR_RCONF_DEFAULT, Ext_Mem); | ||||
|  | ||||
|  | ||||
|   // Trim extended memory in GLIUs 0 & 1 | ||||
|   Trim_P2D_R(ExtendedMemoryDescr0, RangeRequest, Ext_Mem); | ||||
|   Trim_P2D_R(ExtendedMemoryDescr1, RangeRequest, Ext_Mem); | ||||
|  | ||||
|   // Copy Start/End to new descriptor | ||||
|   Parse_Descriptor(P2D_R, Ext_Mem, Fields); | ||||
|   return (Fields[1] + 1); | ||||
| } | ||||
|  | ||||
|  | ||||
| typedef struct { | ||||
|   UCHAR StartType; | ||||
|   UCHAR EndType; | ||||
|   UCHAR Port; | ||||
|   ULONG Msr; | ||||
| } ROUTING_INFO; | ||||
| #define MAX_ROUTE   5 | ||||
| ROUTING_INFO Routing[MAX_ROUTE]; | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Allocates a Region Configuration Register | ||||
| //*********************************************************************** | ||||
| ROUTING_INFO * pascal Allocate_RCONF(ULONG DevAddress, ROUTING_INFO * RoutingPtr) | ||||
| { | ||||
|  | ||||
|   // Allocate a region configuration register | ||||
|   // If in Southbridge... | ||||
|   if ((DevAddress & MPCI_SB) == MPCI_SB) { | ||||
|     // then use SB MPCI R0-R15 | ||||
|     RoutingPtr->StartType = MPCI_RCONF; | ||||
|     RoutingPtr->Msr = MPCI_SB; | ||||
|   } else { | ||||
|     // else use GX2 RCONF0-RCONF7 | ||||
|     RoutingPtr->StartType = GX2_RCONF; | ||||
|   } | ||||
|   RoutingPtr++; | ||||
|   return RoutingPtr; | ||||
| } | ||||
|  | ||||
| //*********************************************************************** | ||||
| //   This routines creates an association between the virtualized PCI BAR | ||||
| // (specified by BaseAddr and Device_ID) and an MBus device (specified by | ||||
| // Geode_ID).  The Resource parameter specifies the type  of BAR (Memory, | ||||
| // Memory-mapped I/O, or I/O) and the size of the region by RangeRequest. | ||||
| //*********************************************************************** | ||||
| USHORT pascal Allocate_BAR(UCHAR Resource, USHORT BaseAddr, ULONG RangeRequest, \ | ||||
|                            USHORT Geode_ID, USHORT Device_ID) | ||||
| { ULONG DevAddress, Mbiu, Physical=0; | ||||
|   UCHAR LSB, MSB; | ||||
|   UCHAR Instance=1; | ||||
|   UCHAR Index, StartType, EndType; | ||||
|   UCHAR * LinkPtr; | ||||
|   USHORT DevNum, Function, PCI_Address; | ||||
|   register ROUTING_INFO * RoutingPtr; | ||||
|   register PCI_HEADER_ENTRY * Pci; | ||||
|   register VIRTUAL_DEVICE * VirtDev; | ||||
|   register DESCRIPTOR * Descr; | ||||
|   int i; | ||||
|  | ||||
|   // Validate parameters | ||||
|   switch (Resource) { | ||||
|     case RESOURCE_MEMORY: | ||||
|     case RESOURCE_MMIO: | ||||
|     case RESOURCE_SCIO: | ||||
|     case RESOURCE_IO: | ||||
|       break; | ||||
|     default: | ||||
|       Log_Error("Invalid value for parameter Resource: 0x%02X", Resource); | ||||
| 	  return 0x0000; | ||||
|   } | ||||
|  | ||||
|   // Ensure RangeRequest meets PCI & MBus requirements | ||||
|   LSB = BitScanForward(RangeRequest); | ||||
|   MSB = BitScanReverse(RangeRequest); | ||||
|  | ||||
|   if (Resource == RESOURCE_MEMORY || Resource == RESOURCE_MMIO) { | ||||
|     // Memory BARs must be at least 4 KB because of granularity of descriptors | ||||
|     if (RangeRequest < 4096) { | ||||
|       MSB = LSB = 12; | ||||
|     } | ||||
|   } | ||||
|   // If RangeRequest is not a power of 2... | ||||
|   if (LSB != MSB) { | ||||
|     // Round size of BAR to next higher power of 2 | ||||
|     MSB++; | ||||
|   } | ||||
|  | ||||
|  | ||||
|   // Do some massaging based on Device ID | ||||
|   switch (Device_ID) { | ||||
|  | ||||
|     // Graphics header is invisible until SoftVG is enabled. | ||||
|     case DEVICE_ID_GFX2: | ||||
|     case DEVICE_ID_GFX3: | ||||
|       NorthBridge[1] = Graphics_Hdr; | ||||
|       break; | ||||
|   } | ||||
|  | ||||
|   // | ||||
|   // Determine the PCI Address by scanning the PCI tables for Device_ID | ||||
|   // | ||||
|   for (DevNum = 1; DevNum <= 21; DevNum++) { | ||||
|     if (VirtDev = *(VirtDevPtr+DevNum)) { | ||||
|       // For each defined function... | ||||
|       for (Function = 0; Function <= 7; Function++) { | ||||
|         if (Pci = *VirtDev++) { | ||||
|           // Do the Device IDs match ? | ||||
|           if (Pci->Device_ID == Device_ID) { | ||||
|             // Handle the 2nd instance of 5536's OHCI | ||||
|             if ((Geode_ID == ID_OHCI) && ((Pci+BAR0/4)->Flag & (IO_BAR | MEM_BAR | MMIO_BAR))) { | ||||
|               continue; | ||||
|             } | ||||
|             break; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|       // If Device ID match is found... | ||||
|       if (Function < 8) { | ||||
|         // Compute the PCI address | ||||
|         PCI_Address = (DevNum << 11) + (Function << 8) + (UCHAR)BaseAddr; | ||||
|  | ||||
|         Pci = Find_Register(Pci, (UCHAR)BaseAddr); | ||||
|  | ||||
|         // Check for errors | ||||
|         if ((USHORT)Pci > UNIMPLEMENTED_REGISTER) { | ||||
|           // Has this BAR already been allocated ? | ||||
|           if (Pci->Flag & (IO_BAR | MEM_BAR | MMIO_BAR)) { | ||||
|             // Yes, log an error | ||||
|             Log_Error("Resource has already been allocated for PCI address 0x%X", PCI_Address); | ||||
|           } | ||||
|         } | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|  | ||||
|   // Device_ID was not found in virtual PCI tables | ||||
|   if (DevNum > 21) { | ||||
|     Log_Error("DeviceID 0x%04X was not found", Device_ID); | ||||
|     return 0x0000; | ||||
|   } | ||||
|  | ||||
|   // Record Mask for BAR | ||||
|   Pci->Mask = ~((1L << MSB)-1); | ||||
|  | ||||
|  | ||||
|   // Initialize routing structure | ||||
|   RoutingPtr = &Routing[0]; | ||||
|   for (i=0; i<MAX_ROUTE; i++) { | ||||
|     RoutingPtr->StartType = 0x00; | ||||
|     RoutingPtr->EndType   = 0x00; | ||||
|     RoutingPtr->Port = 0x00; | ||||
|     RoutingPtr->Msr  = 0x00000000; | ||||
|     RoutingPtr++; | ||||
|   } | ||||
|   RoutingPtr = &Routing[0]; | ||||
|  | ||||
|  | ||||
|   // Handle special cases | ||||
|   switch (Geode_ID) { | ||||
|  | ||||
|     // SMI generation on access (no physical device, e.g. virtual registers) | ||||
|     case 0x0000: | ||||
|       DevAddress = 0x00000000; | ||||
|       break; | ||||
|  | ||||
|     // Routing address of some devices has already been determined | ||||
|     case ID_MDD: | ||||
|       DevAddress = MDD_Base; | ||||
|       break; | ||||
|  | ||||
|     // Handle the 2nd instance of 5536's OHCI | ||||
|     case ID_OHCI: | ||||
|       if (Function == 4) { | ||||
|         Instance = 2; | ||||
|       } | ||||
|  | ||||
|     default: | ||||
|       // Search for the requested Geode_ID | ||||
|       DevAddress = Find_MBus_ID(Geode_ID, Instance); | ||||
|       if (!DevAddress) { | ||||
|         Log_Error("Geode ID 0x%04X was not found for Device ID 0x%04X", Geode_ID, Device_ID); | ||||
|         return 0x0000; | ||||
|       } | ||||
|       break; | ||||
|  | ||||
|   } | ||||
|  | ||||
|   // If an LBAR is required, allocate it | ||||
|   if (Pci->LBar) { | ||||
|     RoutingPtr->StartType = MDD_LBAR; | ||||
|     RoutingPtr->Msr = MDD_Base; | ||||
|     switch (Geode_ID) { | ||||
|       case ID_USB_20: | ||||
|         // OHCI needs an LBAR in the MDD | ||||
|         if ((HdrPtr+REVISION_ID/4)->Interface == 0x10) { | ||||
|           (UCHAR)RoutingPtr->Msr = MSR_LBAR_KEL1; | ||||
|           RoutingPtr++; | ||||
|         } | ||||
|         RoutingPtr->StartType = USB_LBAR; | ||||
|  | ||||
|       case ID_ATA: | ||||
|         RoutingPtr->Msr = DevAddress; | ||||
|         break; | ||||
|     } | ||||
|     (UCHAR)RoutingPtr->Msr = Pci->LBar; | ||||
|     RoutingPtr++; | ||||
|   } | ||||
|  | ||||
|   // Get an available descriptor appropriate to the type of BAR | ||||
|   switch (Resource) { | ||||
|  | ||||
|     // Physical Memory | ||||
|     case RESOURCE_MEMORY: | ||||
|  | ||||
|       // Mark it as a memory BAR | ||||
|       Pci->Flag |= MEM_BAR; | ||||
|  | ||||
|       RoutingPtr->StartType = P2D_BMO; | ||||
|       RoutingPtr->EndType = P2D_RO; | ||||
|       RoutingPtr->Msr = Mbiu0; | ||||
|  | ||||
|       // Legacy VGA frame buffers don't require physical memory | ||||
|       if ((UCHAR)BaseAddr > BAR5) { | ||||
|         ULONG RegionEnables, RegionProperties[2]; | ||||
|  | ||||
| #define OFF_PROPS  (REGION_WS)	// Frame buffer properties to be disabled | ||||
| #define OFF_PROPERTIES ((OFF_PROPS<<24) | (OFF_PROPS<<16) | (OFF_PROPS<<8) | (OFF_PROPS)) | ||||
| #define ON_PROPS   (0)	        // Frame buffer properties to be enabled | ||||
| #define ON_PROPERTIES  (( ON_PROPS<<24) | ( ON_PROPS<<16) | ( ON_PROPS<<8) | ( ON_PROPS)) | ||||
|  | ||||
|         // Set MPCI Fixed Region Enables and disable write-serialize | ||||
|         Read_MSR(MSR_RCONF_A0_BF, RegionProperties); | ||||
|  | ||||
|         Physical = 0xA0000; | ||||
|         RegionEnables = 0x00; | ||||
|  | ||||
|         switch (RangeRequest) { | ||||
|  | ||||
|           case 128L*1024: | ||||
|             RegionEnables = 0xFF;	// A0000-BFFFF | ||||
|             RegionProperties[1] &= ~OFF_PROPERTIES; | ||||
|             RegionProperties[1] |=   ON_PROPERTIES; | ||||
|  | ||||
|           case  64L*1024: | ||||
|             RegionEnables |= 0x0F;	// A0000-AFFFF | ||||
|             RegionProperties[0] &= ~OFF_PROPERTIES; | ||||
|             RegionProperties[0] |=   ON_PROPERTIES; | ||||
|             break; | ||||
|  | ||||
|           case  32L*1024: | ||||
|             RegionEnables = 0xC0;	// B8000-BFFFF | ||||
|             RegionProperties[1] &= ~(OFF_PROPERTIES & 0xFFFF0000); | ||||
|             RegionProperties[1] |=  (ON_PROPERTIES  & 0xFFFF0000); | ||||
|             Physical = 0xB8000; | ||||
|             break; | ||||
|  | ||||
|         } | ||||
|  | ||||
|         // Set Vail Region Properties (0x180B) | ||||
|         Write_MSR(MSR_RCONF_A0_BF, RegionProperties); | ||||
|  | ||||
|         // Set MPCI Fixed Region Enables (0x2014) | ||||
|         Write_MSR_LO(MPCI_NB + MPCI_REN, Read_MSR_LO(MPCI_NB + MPCI_REN) | RegionEnables); | ||||
|  | ||||
|         // Allocate P2D_BM | ||||
|         switch (Device_ID) { | ||||
|           case DEVICE_ID_GFX2: | ||||
|           case DEVICE_ID_GFX3: | ||||
|             RoutingPtr->StartType = P2D_BM; | ||||
|             break; | ||||
|         } | ||||
|         RoutingPtr++; | ||||
|  | ||||
|       } else { | ||||
|  | ||||
|         // Trim required memory from the end of extended memory | ||||
|         Physical = Trim_Extended_Memory(RangeRequest); | ||||
|         DevAddress = Find_MBus_ID(ID_MC, 1); | ||||
|  | ||||
|         // Allocate a Region Configuration Register | ||||
|         RoutingPtr++; | ||||
|         RoutingPtr = Allocate_RCONF(DevAddress, RoutingPtr); | ||||
|       } | ||||
|       break; | ||||
|  | ||||
|  | ||||
|     // Memory-mapped I/O | ||||
|     case RESOURCE_MMIO: | ||||
|       // Mark it as a memory-mapped BAR | ||||
|       Pci->Flag |= MMIO_BAR; | ||||
|  | ||||
|       switch (Geode_ID) { | ||||
|  | ||||
|         // Subtractive ports; no MBIU descriptor is necessary | ||||
|         case ID_MPCI: | ||||
|         case ID_MDD: | ||||
|           break; | ||||
|  | ||||
|         case ID_USB_20: | ||||
|         case ID_OHCI: | ||||
|           // Allocate a P2D_BMK descriptor in MBIU2 | ||||
|           RoutingPtr->StartType = P2D_BMK; | ||||
|           if (!(Pci->Flag & USE_BMK)) { | ||||
|             RoutingPtr->EndType = P2D_BM; | ||||
|           } | ||||
|           RoutingPtr->Msr = Mbiu2; | ||||
|           RoutingPtr->Port = (UCHAR)DevAddress; | ||||
|           RoutingPtr++; | ||||
|  | ||||
|           if (Pci->Flag & EPCI_RW) { | ||||
|             // Allocate the appropriate mailbox address | ||||
|             RoutingPtr->StartType = EPCI; | ||||
|             RoutingPtr->Msr = DevAddress & ROUTING; | ||||
|             RoutingPtr++; | ||||
|           } | ||||
|           break; | ||||
|  | ||||
|         case ID_VG: | ||||
|           RoutingPtr->StartType = P2D_RO; | ||||
|           RoutingPtr++; | ||||
|           // Fix for VG alias bug: POFFSET field should be set to -PBASE | ||||
|           // See Compute_Msr_Value() | ||||
|           Physical = 1; | ||||
|           break; | ||||
|  | ||||
|         case ID_AES: | ||||
|           RoutingPtr->StartType = P2D_R; | ||||
|           RoutingPtr++; | ||||
|           break; | ||||
|  | ||||
|         default: | ||||
|           RoutingPtr->StartType = P2D_BM; | ||||
|           RoutingPtr->EndType = P2D_RO; | ||||
|           RoutingPtr++; | ||||
|           break; | ||||
|       } | ||||
|  | ||||
|       // Allocate a Region Configuration Register | ||||
|       RoutingPtr = Allocate_RCONF(DevAddress, RoutingPtr); | ||||
|       break; | ||||
|  | ||||
|  | ||||
|     // I/O Space | ||||
|     case RESOURCE_SCIO: | ||||
|       RoutingPtr->StartType = IOD_SC; | ||||
|       RoutingPtr++; | ||||
|  | ||||
|     case RESOURCE_IO: | ||||
|       // Mark it as an I/O BAR | ||||
|       Pci->Flag |= IO_BAR; | ||||
|  | ||||
|       switch (Geode_ID) { | ||||
|         // Subtractive ports; no MBIU descriptor is necessary | ||||
|         case ID_MPCI: | ||||
|         case ID_MDD: | ||||
|           break; | ||||
|  | ||||
|         default: | ||||
|           if (Resource != RESOURCE_SCIO) { | ||||
|             RoutingPtr->StartType = IOD_BM; | ||||
|             RoutingPtr->EndType = IOD_SC; | ||||
|             RoutingPtr++; | ||||
|           } | ||||
|           break; | ||||
|       } | ||||
|  | ||||
|       // If device is in the Southbridge... | ||||
|       if ((DevAddress & MPCI_SB) == MPCI_SB) { | ||||
|         // allocate a Region Configuration Register | ||||
|         RoutingPtr = Allocate_RCONF(DevAddress, RoutingPtr); | ||||
|       } | ||||
|  | ||||
|       // PCI Spec requires I/O BAR a minimum of 4 bytes | ||||
|       Pci->Mask &= 0xFFFFFFFC; | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       Log_Error("Unknown resource requested: 0x%X", Resource); | ||||
|       return 0x0000; | ||||
|   } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|   // | ||||
|   // Get device's PCI Revision ID | ||||
|   // | ||||
|   switch (Device_ID) { | ||||
|  | ||||
|     // Revision of some devices is already determined | ||||
|     case DEVICE_ID_OHCI: | ||||
|     case DEVICE_ID_5536: | ||||
|     case DEVICE_ID_GX2: | ||||
|     case DEVICE_ID_LX: | ||||
|       break; | ||||
|  | ||||
|     // Graphic's Revision ID comes from GP, not VG or DF | ||||
|     case DEVICE_ID_GFX2: | ||||
|     case DEVICE_ID_GFX3: | ||||
|       if (Geode_ID != ID_GP) { | ||||
|         break; | ||||
|       } | ||||
|  | ||||
|     default: | ||||
|       // Read MBD_MSR_CAP | ||||
|       Mbiu = DevAddress; | ||||
|       (USHORT)Mbiu = MBD_MSR_CAP; | ||||
|  | ||||
|       // Insert Revision ID into header | ||||
|       (HdrPtr+REVISION_ID/4)->Revision_ID = (UCHAR)Read_MSR_LO(Mbiu); | ||||
|       break; | ||||
|   } | ||||
|  | ||||
|   // Compute number of MSRs needed to support this BAR | ||||
|   i = (UCHAR)(RoutingPtr - &Routing[0]); | ||||
|  | ||||
|   if (i >= MAX_ROUTE) { | ||||
|     Log_Error("Allocate_BAR- routing failed on PCI address 0x%X", PCI_Address); | ||||
|   } | ||||
|  | ||||
|   // | ||||
|   // Allocate the required MSRs | ||||
|   // | ||||
|   RoutingPtr = &Routing[0]; | ||||
|   LinkPtr = &Pci->Link; | ||||
|  | ||||
|   while (i) { | ||||
|  | ||||
|     // Force use of P2D_RO to prevent ROVER from complaining about overlapped | ||||
|     // physical addresses when the frame buffer length is not a power of 2. | ||||
|     if (Pci == &Graphics_Hdr[BAR0/4]) { | ||||
|       if(RoutingPtr->Msr == Mbiu0) { | ||||
|         RoutingPtr->StartType = P2D_RO; | ||||
|       } | ||||
|     } | ||||
|     StartType = RoutingPtr->StartType; | ||||
|     EndType = RoutingPtr->EndType; | ||||
|  | ||||
|     // If 2nd choice is not specified, force it to 1st choice | ||||
|     if (EndType == 0x00) { | ||||
|       EndType = StartType; | ||||
|     } | ||||
|     // Has the correct MBIU been determined ? | ||||
|     if (RoutingPtr->Msr == 0x00000000) { | ||||
|       // Determine the MBIU as follows: | ||||
|       // - If the 2nd routing field == 0, then it's MBIU0 | ||||
|       // - If the 1st three routing fields match MBIU2, then it's MBIU2 | ||||
|       // - Otherwise it's MBIU1 | ||||
|       if ((DevAddress & (7L << 26)) == 0) { | ||||
|         Mbiu = Mbiu0; | ||||
|       } else { | ||||
|         if ((DevAddress & 0xFF800000) == (Mbiu2 & 0xFF800000)) { | ||||
|           Mbiu = Mbiu2; | ||||
|         } else { | ||||
|           Mbiu = Mbiu1; | ||||
|         } | ||||
|       } | ||||
|       RoutingPtr->Msr = Mbiu; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     if (StartType) { | ||||
|  | ||||
|       Index = Allocate_Descriptor(StartType, EndType, RoutingPtr->Msr); | ||||
|  | ||||
|       if (Index == DESCRIPTOR_NOT_FOUND) { | ||||
|  | ||||
|         // If SMI generation, then any MBIU may be used | ||||
|         if (!Geode_ID) { | ||||
|           // Try MBIU1 | ||||
|           Mbiu = Mbiu1; | ||||
|           Index = Allocate_Descriptor(StartType, EndType, Mbiu); | ||||
|           if (Index == DESCRIPTOR_NOT_FOUND) { | ||||
|             if (Mbiu = Mbiu2) { | ||||
|               Index = Allocate_Descriptor(StartType, EndType, Mbiu); | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     if (Index == DESCRIPTOR_NOT_FOUND) { | ||||
|       UCHAR Mbiu=9; | ||||
|  | ||||
|       if (RoutingPtr->Msr == Mbiu0) Mbiu = 0; | ||||
|       else if (RoutingPtr->Msr == Mbiu1) Mbiu = 1; | ||||
|       else if (RoutingPtr->Msr == Mbiu2) Mbiu = 2; | ||||
|       Log_Error("MSR allocation failed for GeodeID=%02X/DeviceID=%04X/BAR%x/MBIU%1x", \ | ||||
|                  (UCHAR)Geode_ID, Device_ID, (USHORT)((BaseAddr-BAR0)/4), Mbiu); | ||||
|       goto NextMSR; | ||||
|     } | ||||
|  | ||||
|     // Record info about the descriptor | ||||
|     Descr = &MSRs[Index]; | ||||
|     Descr->Owner = PCI_Address; | ||||
|     Descr->Range = RangeRequest; | ||||
|     Descr->Physical = Physical; | ||||
|  | ||||
|  | ||||
|     if (RoutingPtr->Port == 0) { | ||||
|       RoutingPtr->Port = (UCHAR)DevAddress; | ||||
|     } | ||||
|     Descr->Port = RoutingPtr->Port; | ||||
|  | ||||
|     // If embedded PCI device, record PCI mailbox MSR to Command register | ||||
|     if (StartType == EPCI) { | ||||
|       CommandPtr->Link = Index; | ||||
|     } | ||||
|  | ||||
|     // Link to previous MSRs[] (or Pci->Link) | ||||
|     * LinkPtr = Index; | ||||
|  | ||||
|     // Update link pointer | ||||
|     LinkPtr = &Descr->Link; | ||||
|  | ||||
|  | ||||
|     // Is an additional swiss-cheese descriptor necessary ? | ||||
|     if (Descr->Type == IOD_SC && RangeRequest > 8) { | ||||
|       RangeRequest -= 8; | ||||
|       continue; | ||||
|     } | ||||
|  | ||||
|     // If the device is on GLIU0, then allocate a descriptor on GLIU1 | ||||
|     // to route FS2 transactions to GLIU0. | ||||
|     if (RoutingPtr->Msr == Mbiu0 && RoutingPtr->StartType < GX2_RCONF ) { | ||||
|       // Don't allocate MBUI1 descriptor for virtual register BAR | ||||
|       if (Geode_ID) { | ||||
|         switch (RoutingPtr->StartType) { | ||||
|  | ||||
|           case IOD_SC: | ||||
|             RoutingPtr->StartType = IOD_BM; | ||||
|             RoutingPtr->EndType = IOD_SC; | ||||
|             RangeRequest = 1L << MSB; | ||||
|             break; | ||||
|  | ||||
|           case P2D_RO: | ||||
|             if (Pci == &Graphics_Hdr[BAR0/4]) { | ||||
|               RoutingPtr->StartType = P2D_R; | ||||
|               break; | ||||
|             } else { | ||||
|               RoutingPtr->StartType = P2D_BM; | ||||
|             } | ||||
|  | ||||
|           default: | ||||
|             RangeRequest = 1L << MSB; | ||||
|             break; | ||||
|         } | ||||
|  | ||||
|         // Use only 1 descriptor for northbound VG transactions | ||||
|         if (RangeRequest == 16 && Geode_ID == ID_VG) { | ||||
|           static UCHAR VG_FS2_Flag=0; | ||||
|  | ||||
|           if (VG_FS2_Flag) { | ||||
|             break; | ||||
|           } else { | ||||
|             VG_FS2_Flag = 1; | ||||
|             RangeRequest = 32; | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         RoutingPtr->Msr = Mbiu1; | ||||
|         RoutingPtr->Port = MBIU1_SelfReference; | ||||
|         continue; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // Advance ptr to next MSR | ||||
| NextMSR: | ||||
|     RoutingPtr++; | ||||
|     i--; | ||||
|   }	 // end while | ||||
|  | ||||
|  | ||||
|  | ||||
|   // Make appropriate Command register bit R/W | ||||
|   if (Pci->Flag & IO_BAR) { | ||||
|     CommandPtr->Mask |= IO_SPACE; | ||||
|   } else { | ||||
|     CommandPtr->Mask |= MEM_SPACE; | ||||
|   } | ||||
|  | ||||
|   return PCI_Address; | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // | ||||
| // Perform early POST initialization of virtualized PCI config space | ||||
| // | ||||
| //*********************************************************************** | ||||
| void VirtualPCI_EarlyInit(void) | ||||
| { USHORT i; | ||||
|   ULONG PCI_Address; | ||||
|   ULONG MsrAddr; | ||||
|   VIRTUAL_PTR DevicePtr; | ||||
|   PCI_HEADER_ENTRY * Pci; | ||||
|  | ||||
|  | ||||
|   // Initialize ptr to virtualized PCI topology | ||||
|   VirtDevPtr = &Virtual_Devices[0]; | ||||
|  | ||||
|  | ||||
|   // Virtualize CS5536's configuration space, if present, | ||||
|   // at the same device number as the h/w header. | ||||
|   i = (UCHAR)((USHORT)HardwareInfo.Chipset_Base >> 11); | ||||
|   switch (HardwareInfo.Chipset_ID) { | ||||
|  | ||||
|     case DEVICE_ID_5536: | ||||
|       Virtual_Devices[i] = Virtual_5536; | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       return; | ||||
|   } | ||||
|  | ||||
|   SouthBridge = Virtual_Devices[i]; | ||||
|  | ||||
|   // Compute mask of IDSELs that are to be virtualized | ||||
|   for (i = 1; i <= 21; i++) { | ||||
|     // If IDSEL is virtualized, set enable mask | ||||
|     DevicePtr = * (VirtDevPtr+i); | ||||
|     if (DevicePtr) { | ||||
|  | ||||
|       // Record IDSEL to trap | ||||
|       Virtualized_PCI_Devices |= (1L << i); | ||||
|  | ||||
|       // Register System Manager for this IDSEL | ||||
|       PCI_Address = ((ULONG)i << 11); | ||||
|       Register_Event(EVENT_PCI_TRAP, MAX_PRIORITY, SysMgr_VSM, PCI_Address, 0x07FF); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Enable virtual PCI headers | ||||
|   MsrAddr = MPCI_NB + MBD_MSR_SMI; | ||||
|   Write_MSR_LO(MsrAddr, Read_MSR_LO(MsrAddr) & ~VPHM); | ||||
|  | ||||
|  | ||||
|   // Store CPU's Device & Revision IDs in Host Bridge's PCI header | ||||
|   HostBridge_Hdr[0].Device_ID = HardwareInfo.CPU_ID; | ||||
|   HostBridge_Hdr[2].Revision_ID = (UCHAR)HardwareInfo.CPU_Revision; | ||||
|  | ||||
|  | ||||
|   // AES header (F2) BAR | ||||
|   Allocate_BAR(RESOURCE_MMIO, BAR0, 16*1024, ID_AES, AES_Hdr[0].Device_ID); | ||||
|  | ||||
|   // Implement Interrupt Pin/Line registers in LX graphic header | ||||
|   if (Pci = Find_Register(Graphics_Hdr, INTERRUPT_LINE)) { | ||||
|     // Make Interrupt Line read-write | ||||
|     (UCHAR)Pci->Mask = 0xFF; | ||||
|     // Set Interrupt Pin to INTA# | ||||
|     Pci->Interrupt_Pin = 0x01; | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
| //*********************************************************************** | ||||
| // Routine to support INFO getting PCI<->MSR linkages | ||||
| //*********************************************************************** | ||||
| ULONG pascal Get_MSR_Linkage(USHORT PCI_Address) | ||||
| { PCI_HEADER_ENTRY * Pci; | ||||
|   ULONG MsrAddr; | ||||
|   static UCHAR Link=0x00; | ||||
|   static DESCRIPTOR * Descr; | ||||
|   static USHORT LastPCI = 0x0000; | ||||
|  | ||||
|   if (PCI_Address != LastPCI) { | ||||
|     LastPCI = PCI_Address; | ||||
|     Pci = Get_Structure(PCI_Address); | ||||
|  | ||||
|     switch ((USHORT)Pci) { | ||||
|  | ||||
|       case UNIMPLEMENTED_FUNCTION: | ||||
|       case UNIMPLEMENTED_REGISTER: | ||||
|         Link = 0x00; | ||||
|         break; | ||||
|  | ||||
|       default: | ||||
|         Link = Pci->Link; | ||||
|         break; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   Descr = &MSRs[Link]; | ||||
|  | ||||
|   // Get link to next descriptor | ||||
|   Link = Descr->Link; | ||||
|  | ||||
|   if (!(MsrAddr = Descr->MsrAddr)) { | ||||
|     LastPCI = 0x0000; | ||||
|   } | ||||
|  | ||||
|   return MsrAddr; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user
	 David Hendricks
					David Hendricks