Initial commit
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				Build Kernel / Build all affected Kernels (push) Has been cancelled
				
			
		
			
				
	
				Build all core packages / Build all core packages for selected target (push) Has been cancelled
				
			
		
			
				
	
				Build and Push prebuilt tools container / Build and Push all prebuilt containers (push) Has been cancelled
				
			
		
			
				
	
				Build Toolchains / Build Toolchains for each target (push) Has been cancelled
				
			
		
			
				
	
				Build host tools / Build host tools for linux and macos based systems (push) Has been cancelled
				
			
		
			
				
	
				Coverity scan build / Coverity x86/64 build (push) Has been cancelled
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	Build Kernel / Build all affected Kernels (push) Has been cancelled
				
			Build all core packages / Build all core packages for selected target (push) Has been cancelled
				
			Build and Push prebuilt tools container / Build and Push all prebuilt containers (push) Has been cancelled
				
			Build Toolchains / Build Toolchains for each target (push) Has been cancelled
				
			Build host tools / Build host tools for linux and macos based systems (push) Has been cancelled
				
			Coverity scan build / Coverity x86/64 build (push) Has been cancelled
				
			This commit is contained in:
		
							
								
								
									
										74
									
								
								target/linux/bmips/image/lzma-loader/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								target/linux/bmips/image/lzma-loader/Makefile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | ||||
| # SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| # | ||||
| # Copyright (C) 2020 Álvaro Fernández Rojas <noltari@gmail.com> | ||||
| # Copyright (C) 2014 Jonas Gorski <jogo@openwrt.org> | ||||
| # Copyright (C) 2011 OpenWrt.org | ||||
| # Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> | ||||
| # | ||||
|  | ||||
| include $(TOPDIR)/rules.mk | ||||
|  | ||||
| LZMA_TEXT_START	:= 0x80a00000 | ||||
| LOADER		:= loader.bin | ||||
| LOADER_NAME	:= $(basename $(notdir $(LOADER))) | ||||
| LOADER_DATA 	:= | ||||
| TARGET_DIR	:= | ||||
|  | ||||
| UART_BASE_3329 := 0xb0000100 | ||||
| UART_BASE_3368 := 0xfff8c100 | ||||
| UART_BASE_3380 := 0xb4e00200 | ||||
| UART_BASE_3383 := 0xb4e00500 | ||||
| UART_BASE_3384 := 0xb4e00500 | ||||
| UART_BASE_6318 := 0xb0000100 | ||||
| UART_BASE_6328 := 0xb0000100 | ||||
| UART_BASE_6338 := 0xfffe0300 | ||||
| UART_BASE_6345 := 0xfffe0300 | ||||
| UART_BASE_6348 := 0xfffe0300 | ||||
| UART_BASE_6358 := 0xfffe0100 | ||||
| UART_BASE_6362 := 0xb0000100 | ||||
| UART_BASE_6368 := 0xb0000100 | ||||
| UART_BASE_63268 := 0xb0000180 | ||||
| UART_BASE_6816 := 0xb0000100 | ||||
| UART_BASE_6818 := 0xb0000100 | ||||
| UART_BASE_6828 := 0xb0000180 | ||||
| UART_BASE := $(if $(UART_BASE_$(CHIP_ID)),$(UART_BASE_$(CHIP_ID)),0) | ||||
|  | ||||
| ifeq ($(TARGET_DIR),) | ||||
| TARGET_DIR	:= $(KDIR) | ||||
| endif | ||||
|  | ||||
| LOADER_BIN	:= $(TARGET_DIR)/$(LOADER_NAME).bin | ||||
| LOADER_ELF	:= $(TARGET_DIR)/$(LOADER_NAME).elf | ||||
|  | ||||
| PKG_NAME := lzma-loader | ||||
| PKG_BUILD_DIR := $(KDIR)/$(PKG_NAME) | ||||
|  | ||||
| .PHONY : loader-compile loader.bin loader.elf | ||||
|  | ||||
| $(PKG_BUILD_DIR)/.prepared: | ||||
| 	mkdir $(PKG_BUILD_DIR) | ||||
| 	$(CP) ./src/* $(PKG_BUILD_DIR)/ | ||||
| 	touch $@ | ||||
|  | ||||
| loader-compile: $(PKG_BUILD_DIR)/.prepared | ||||
| 	$(MAKE) -C $(PKG_BUILD_DIR) CROSS_COMPILE="$(TARGET_CROSS)" \ | ||||
| 		LZMA_TEXT_START=$(LZMA_TEXT_START) \ | ||||
| 		LOADER_DATA=$(LOADER_DATA) \ | ||||
| 		UART_BASE=$(UART_BASE) \ | ||||
| 		clean all | ||||
|  | ||||
| loader.elf: $(PKG_BUILD_DIR)/loader.elf | ||||
| 	$(CP) $< $(LOADER_ELF) | ||||
|  | ||||
| loader.bin: $(PKG_BUILD_DIR)/loader.bin | ||||
| 	$(CP) $< $(LOADER_BIN) | ||||
|  | ||||
| download: | ||||
| prepare: $(PKG_BUILD_DIR)/.prepared | ||||
| compile: loader-compile | ||||
|  | ||||
| install: | ||||
|  | ||||
| clean: | ||||
| 	rm -rf $(PKG_BUILD_DIR) | ||||
							
								
								
									
										584
									
								
								target/linux/bmips/image/lzma-loader/src/LzmaDecode.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										584
									
								
								target/linux/bmips/image/lzma-loader/src/LzmaDecode.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,584 @@ | ||||
| /* | ||||
|   LzmaDecode.c | ||||
|   LZMA Decoder (optimized for Speed version) | ||||
|    | ||||
|   LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) | ||||
|   http://www.7-zip.org/ | ||||
|  | ||||
|   LZMA SDK is licensed under two licenses: | ||||
|   1) GNU Lesser General Public License (GNU LGPL) | ||||
|   2) Common Public License (CPL) | ||||
|   It means that you can select one of these two licenses and  | ||||
|   follow rules of that license. | ||||
|  | ||||
|   SPECIAL EXCEPTION: | ||||
|   Igor Pavlov, as the author of this Code, expressly permits you to  | ||||
|   statically or dynamically link your Code (or bind by name) to the  | ||||
|   interfaces of this file without subjecting your linked Code to the  | ||||
|   terms of the CPL or GNU LGPL. Any modifications or additions  | ||||
|   to this file, however, are subject to the LGPL or CPL terms. | ||||
| */ | ||||
|  | ||||
| #include "LzmaDecode.h" | ||||
|  | ||||
| #define kNumTopBits 24 | ||||
| #define kTopValue ((UInt32)1 << kNumTopBits) | ||||
|  | ||||
| #define kNumBitModelTotalBits 11 | ||||
| #define kBitModelTotal (1 << kNumBitModelTotalBits) | ||||
| #define kNumMoveBits 5 | ||||
|  | ||||
| #define RC_READ_BYTE (*Buffer++) | ||||
|  | ||||
| #define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \ | ||||
|   { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }} | ||||
|  | ||||
| #ifdef _LZMA_IN_CB | ||||
|  | ||||
| #define RC_TEST { if (Buffer == BufferLim) \ | ||||
|   { SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \ | ||||
|   BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }} | ||||
|  | ||||
| #define RC_INIT Buffer = BufferLim = 0; RC_INIT2 | ||||
|  | ||||
| #else | ||||
|  | ||||
| #define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; } | ||||
|  | ||||
| #define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2 | ||||
|   | ||||
| #endif | ||||
|  | ||||
| #define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; } | ||||
|  | ||||
| #define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound) | ||||
| #define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits; | ||||
| #define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits; | ||||
|  | ||||
| #define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \ | ||||
|   { UpdateBit0(p); mi <<= 1; A0; } else \ | ||||
|   { UpdateBit1(p); mi = (mi + mi) + 1; A1; }  | ||||
|    | ||||
| #define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)                | ||||
|  | ||||
| #define RangeDecoderBitTreeDecode(probs, numLevels, res) \ | ||||
|   { int i = numLevels; res = 1; \ | ||||
|   do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \ | ||||
|   res -= (1 << numLevels); } | ||||
|  | ||||
|  | ||||
| #define kNumPosBitsMax 4 | ||||
| #define kNumPosStatesMax (1 << kNumPosBitsMax) | ||||
|  | ||||
| #define kLenNumLowBits 3 | ||||
| #define kLenNumLowSymbols (1 << kLenNumLowBits) | ||||
| #define kLenNumMidBits 3 | ||||
| #define kLenNumMidSymbols (1 << kLenNumMidBits) | ||||
| #define kLenNumHighBits 8 | ||||
| #define kLenNumHighSymbols (1 << kLenNumHighBits) | ||||
|  | ||||
| #define LenChoice 0 | ||||
| #define LenChoice2 (LenChoice + 1) | ||||
| #define LenLow (LenChoice2 + 1) | ||||
| #define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) | ||||
| #define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) | ||||
| #define kNumLenProbs (LenHigh + kLenNumHighSymbols)  | ||||
|  | ||||
|  | ||||
| #define kNumStates 12 | ||||
| #define kNumLitStates 7 | ||||
|  | ||||
| #define kStartPosModelIndex 4 | ||||
| #define kEndPosModelIndex 14 | ||||
| #define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) | ||||
|  | ||||
| #define kNumPosSlotBits 6 | ||||
| #define kNumLenToPosStates 4 | ||||
|  | ||||
| #define kNumAlignBits 4 | ||||
| #define kAlignTableSize (1 << kNumAlignBits) | ||||
|  | ||||
| #define kMatchMinLen 2 | ||||
|  | ||||
| #define IsMatch 0 | ||||
| #define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) | ||||
| #define IsRepG0 (IsRep + kNumStates) | ||||
| #define IsRepG1 (IsRepG0 + kNumStates) | ||||
| #define IsRepG2 (IsRepG1 + kNumStates) | ||||
| #define IsRep0Long (IsRepG2 + kNumStates) | ||||
| #define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) | ||||
| #define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) | ||||
| #define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) | ||||
| #define LenCoder (Align + kAlignTableSize) | ||||
| #define RepLenCoder (LenCoder + kNumLenProbs) | ||||
| #define Literal (RepLenCoder + kNumLenProbs) | ||||
|  | ||||
| #if Literal != LZMA_BASE_SIZE | ||||
| StopCompilingDueBUG | ||||
| #endif | ||||
|  | ||||
| int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size) | ||||
| { | ||||
|   unsigned char prop0; | ||||
|   if (size < LZMA_PROPERTIES_SIZE) | ||||
|     return LZMA_RESULT_DATA_ERROR; | ||||
|   prop0 = propsData[0]; | ||||
|   if (prop0 >= (9 * 5 * 5)) | ||||
|     return LZMA_RESULT_DATA_ERROR; | ||||
|   { | ||||
|     for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5)); | ||||
|     for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9); | ||||
|     propsRes->lc = prop0; | ||||
|     /* | ||||
|     unsigned char remainder = (unsigned char)(prop0 / 9); | ||||
|     propsRes->lc = prop0 % 9; | ||||
|     propsRes->pb = remainder / 5; | ||||
|     propsRes->lp = remainder % 5; | ||||
|     */ | ||||
|   } | ||||
|  | ||||
|   #ifdef _LZMA_OUT_READ | ||||
|   { | ||||
|     int i; | ||||
|     propsRes->DictionarySize = 0; | ||||
|     for (i = 0; i < 4; i++) | ||||
|       propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8); | ||||
|     if (propsRes->DictionarySize == 0) | ||||
|       propsRes->DictionarySize = 1; | ||||
|   } | ||||
|   #endif | ||||
|   return LZMA_RESULT_OK; | ||||
| } | ||||
|  | ||||
| #define kLzmaStreamWasFinishedId (-1) | ||||
|  | ||||
| int LzmaDecode(CLzmaDecoderState *vs, | ||||
|     #ifdef _LZMA_IN_CB | ||||
|     ILzmaInCallback *InCallback, | ||||
|     #else | ||||
|     const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, | ||||
|     #endif | ||||
|     unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed) | ||||
| { | ||||
|   CProb *p = vs->Probs; | ||||
|   SizeT nowPos = 0; | ||||
|   Byte previousByte = 0; | ||||
|   UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1; | ||||
|   UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1; | ||||
|   int lc = vs->Properties.lc; | ||||
|  | ||||
|   #ifdef _LZMA_OUT_READ | ||||
|    | ||||
|   UInt32 Range = vs->Range; | ||||
|   UInt32 Code = vs->Code; | ||||
|   #ifdef _LZMA_IN_CB | ||||
|   const Byte *Buffer = vs->Buffer; | ||||
|   const Byte *BufferLim = vs->BufferLim; | ||||
|   #else | ||||
|   const Byte *Buffer = inStream; | ||||
|   const Byte *BufferLim = inStream + inSize; | ||||
|   #endif | ||||
|   int state = vs->State; | ||||
|   UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3]; | ||||
|   int len = vs->RemainLen; | ||||
|   UInt32 globalPos = vs->GlobalPos; | ||||
|   UInt32 distanceLimit = vs->DistanceLimit; | ||||
|  | ||||
|   Byte *dictionary = vs->Dictionary; | ||||
|   UInt32 dictionarySize = vs->Properties.DictionarySize; | ||||
|   UInt32 dictionaryPos = vs->DictionaryPos; | ||||
|  | ||||
|   Byte tempDictionary[4]; | ||||
|  | ||||
|   #ifndef _LZMA_IN_CB | ||||
|   *inSizeProcessed = 0; | ||||
|   #endif | ||||
|   *outSizeProcessed = 0; | ||||
|   if (len == kLzmaStreamWasFinishedId) | ||||
|     return LZMA_RESULT_OK; | ||||
|  | ||||
|   if (dictionarySize == 0) | ||||
|   { | ||||
|     dictionary = tempDictionary; | ||||
|     dictionarySize = 1; | ||||
|     tempDictionary[0] = vs->TempDictionary[0]; | ||||
|   } | ||||
|  | ||||
|   if (len == kLzmaNeedInitId) | ||||
|   { | ||||
|     { | ||||
|       UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); | ||||
|       UInt32 i; | ||||
|       for (i = 0; i < numProbs; i++) | ||||
|         p[i] = kBitModelTotal >> 1;  | ||||
|       rep0 = rep1 = rep2 = rep3 = 1; | ||||
|       state = 0; | ||||
|       globalPos = 0; | ||||
|       distanceLimit = 0; | ||||
|       dictionaryPos = 0; | ||||
|       dictionary[dictionarySize - 1] = 0; | ||||
|       #ifdef _LZMA_IN_CB | ||||
|       RC_INIT; | ||||
|       #else | ||||
|       RC_INIT(inStream, inSize); | ||||
|       #endif | ||||
|     } | ||||
|     len = 0; | ||||
|   } | ||||
|   while(len != 0 && nowPos < outSize) | ||||
|   { | ||||
|     UInt32 pos = dictionaryPos - rep0; | ||||
|     if (pos >= dictionarySize) | ||||
|       pos += dictionarySize; | ||||
|     outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos]; | ||||
|     if (++dictionaryPos == dictionarySize) | ||||
|       dictionaryPos = 0; | ||||
|     len--; | ||||
|   } | ||||
|   if (dictionaryPos == 0) | ||||
|     previousByte = dictionary[dictionarySize - 1]; | ||||
|   else | ||||
|     previousByte = dictionary[dictionaryPos - 1]; | ||||
|  | ||||
|   #else /* if !_LZMA_OUT_READ */ | ||||
|  | ||||
|   int state = 0; | ||||
|   UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; | ||||
|   int len = 0; | ||||
|   const Byte *Buffer; | ||||
|   const Byte *BufferLim; | ||||
|   UInt32 Range; | ||||
|   UInt32 Code; | ||||
|  | ||||
|   #ifndef _LZMA_IN_CB | ||||
|   *inSizeProcessed = 0; | ||||
|   #endif | ||||
|   *outSizeProcessed = 0; | ||||
|  | ||||
|   { | ||||
|     UInt32 i; | ||||
|     UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); | ||||
|     for (i = 0; i < numProbs; i++) | ||||
|       p[i] = kBitModelTotal >> 1; | ||||
|   } | ||||
|    | ||||
|   #ifdef _LZMA_IN_CB | ||||
|   RC_INIT; | ||||
|   #else | ||||
|   RC_INIT(inStream, inSize); | ||||
|   #endif | ||||
|  | ||||
|   #endif /* _LZMA_OUT_READ */ | ||||
|  | ||||
|   while(nowPos < outSize) | ||||
|   { | ||||
|     CProb *prob; | ||||
|     UInt32 bound; | ||||
|     int posState = (int)( | ||||
|         (nowPos  | ||||
|         #ifdef _LZMA_OUT_READ | ||||
|         + globalPos | ||||
|         #endif | ||||
|         ) | ||||
|         & posStateMask); | ||||
|  | ||||
|     prob = p + IsMatch + (state << kNumPosBitsMax) + posState; | ||||
|     IfBit0(prob) | ||||
|     { | ||||
|       int symbol = 1; | ||||
|       UpdateBit0(prob) | ||||
|       prob = p + Literal + (LZMA_LIT_SIZE *  | ||||
|         ((( | ||||
|         (nowPos  | ||||
|         #ifdef _LZMA_OUT_READ | ||||
|         + globalPos | ||||
|         #endif | ||||
|         ) | ||||
|         & literalPosMask) << lc) + (previousByte >> (8 - lc)))); | ||||
|  | ||||
|       if (state >= kNumLitStates) | ||||
|       { | ||||
|         int matchByte; | ||||
|         #ifdef _LZMA_OUT_READ | ||||
|         UInt32 pos = dictionaryPos - rep0; | ||||
|         if (pos >= dictionarySize) | ||||
|           pos += dictionarySize; | ||||
|         matchByte = dictionary[pos]; | ||||
|         #else | ||||
|         matchByte = outStream[nowPos - rep0]; | ||||
|         #endif | ||||
|         do | ||||
|         { | ||||
|           int bit; | ||||
|           CProb *probLit; | ||||
|           matchByte <<= 1; | ||||
|           bit = (matchByte & 0x100); | ||||
|           probLit = prob + 0x100 + bit + symbol; | ||||
|           RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break) | ||||
|         } | ||||
|         while (symbol < 0x100); | ||||
|       } | ||||
|       while (symbol < 0x100) | ||||
|       { | ||||
|         CProb *probLit = prob + symbol; | ||||
|         RC_GET_BIT(probLit, symbol) | ||||
|       } | ||||
|       previousByte = (Byte)symbol; | ||||
|  | ||||
|       outStream[nowPos++] = previousByte; | ||||
|       #ifdef _LZMA_OUT_READ | ||||
|       if (distanceLimit < dictionarySize) | ||||
|         distanceLimit++; | ||||
|  | ||||
|       dictionary[dictionaryPos] = previousByte; | ||||
|       if (++dictionaryPos == dictionarySize) | ||||
|         dictionaryPos = 0; | ||||
|       #endif | ||||
|       if (state < 4) state = 0; | ||||
|       else if (state < 10) state -= 3; | ||||
|       else state -= 6; | ||||
|     } | ||||
|     else              | ||||
|     { | ||||
|       UpdateBit1(prob); | ||||
|       prob = p + IsRep + state; | ||||
|       IfBit0(prob) | ||||
|       { | ||||
|         UpdateBit0(prob); | ||||
|         rep3 = rep2; | ||||
|         rep2 = rep1; | ||||
|         rep1 = rep0; | ||||
|         state = state < kNumLitStates ? 0 : 3; | ||||
|         prob = p + LenCoder; | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|         UpdateBit1(prob); | ||||
|         prob = p + IsRepG0 + state; | ||||
|         IfBit0(prob) | ||||
|         { | ||||
|           UpdateBit0(prob); | ||||
|           prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState; | ||||
|           IfBit0(prob) | ||||
|           { | ||||
|             #ifdef _LZMA_OUT_READ | ||||
|             UInt32 pos; | ||||
|             #endif | ||||
|             UpdateBit0(prob); | ||||
|              | ||||
|             #ifdef _LZMA_OUT_READ | ||||
|             if (distanceLimit == 0) | ||||
|             #else | ||||
|             if (nowPos == 0) | ||||
|             #endif | ||||
|               return LZMA_RESULT_DATA_ERROR; | ||||
|              | ||||
|             state = state < kNumLitStates ? 9 : 11; | ||||
|             #ifdef _LZMA_OUT_READ | ||||
|             pos = dictionaryPos - rep0; | ||||
|             if (pos >= dictionarySize) | ||||
|               pos += dictionarySize; | ||||
|             previousByte = dictionary[pos]; | ||||
|             dictionary[dictionaryPos] = previousByte; | ||||
|             if (++dictionaryPos == dictionarySize) | ||||
|               dictionaryPos = 0; | ||||
|             #else | ||||
|             previousByte = outStream[nowPos - rep0]; | ||||
|             #endif | ||||
|             outStream[nowPos++] = previousByte; | ||||
|             #ifdef _LZMA_OUT_READ | ||||
|             if (distanceLimit < dictionarySize) | ||||
|               distanceLimit++; | ||||
|             #endif | ||||
|  | ||||
|             continue; | ||||
|           } | ||||
|           else | ||||
|           { | ||||
|             UpdateBit1(prob); | ||||
|           } | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|           UInt32 distance; | ||||
|           UpdateBit1(prob); | ||||
|           prob = p + IsRepG1 + state; | ||||
|           IfBit0(prob) | ||||
|           { | ||||
|             UpdateBit0(prob); | ||||
|             distance = rep1; | ||||
|           } | ||||
|           else  | ||||
|           { | ||||
|             UpdateBit1(prob); | ||||
|             prob = p + IsRepG2 + state; | ||||
|             IfBit0(prob) | ||||
|             { | ||||
|               UpdateBit0(prob); | ||||
|               distance = rep2; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|               UpdateBit1(prob); | ||||
|               distance = rep3; | ||||
|               rep3 = rep2; | ||||
|             } | ||||
|             rep2 = rep1; | ||||
|           } | ||||
|           rep1 = rep0; | ||||
|           rep0 = distance; | ||||
|         } | ||||
|         state = state < kNumLitStates ? 8 : 11; | ||||
|         prob = p + RepLenCoder; | ||||
|       } | ||||
|       { | ||||
|         int numBits, offset; | ||||
|         CProb *probLen = prob + LenChoice; | ||||
|         IfBit0(probLen) | ||||
|         { | ||||
|           UpdateBit0(probLen); | ||||
|           probLen = prob + LenLow + (posState << kLenNumLowBits); | ||||
|           offset = 0; | ||||
|           numBits = kLenNumLowBits; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|           UpdateBit1(probLen); | ||||
|           probLen = prob + LenChoice2; | ||||
|           IfBit0(probLen) | ||||
|           { | ||||
|             UpdateBit0(probLen); | ||||
|             probLen = prob + LenMid + (posState << kLenNumMidBits); | ||||
|             offset = kLenNumLowSymbols; | ||||
|             numBits = kLenNumMidBits; | ||||
|           } | ||||
|           else | ||||
|           { | ||||
|             UpdateBit1(probLen); | ||||
|             probLen = prob + LenHigh; | ||||
|             offset = kLenNumLowSymbols + kLenNumMidSymbols; | ||||
|             numBits = kLenNumHighBits; | ||||
|           } | ||||
|         } | ||||
|         RangeDecoderBitTreeDecode(probLen, numBits, len); | ||||
|         len += offset; | ||||
|       } | ||||
|  | ||||
|       if (state < 4) | ||||
|       { | ||||
|         int posSlot; | ||||
|         state += kNumLitStates; | ||||
|         prob = p + PosSlot + | ||||
|             ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<  | ||||
|             kNumPosSlotBits); | ||||
|         RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot); | ||||
|         if (posSlot >= kStartPosModelIndex) | ||||
|         { | ||||
|           int numDirectBits = ((posSlot >> 1) - 1); | ||||
|           rep0 = (2 | ((UInt32)posSlot & 1)); | ||||
|           if (posSlot < kEndPosModelIndex) | ||||
|           { | ||||
|             rep0 <<= numDirectBits; | ||||
|             prob = p + SpecPos + rep0 - posSlot - 1; | ||||
|           } | ||||
|           else | ||||
|           { | ||||
|             numDirectBits -= kNumAlignBits; | ||||
|             do | ||||
|             { | ||||
|               RC_NORMALIZE | ||||
|               Range >>= 1; | ||||
|               rep0 <<= 1; | ||||
|               if (Code >= Range) | ||||
|               { | ||||
|                 Code -= Range; | ||||
|                 rep0 |= 1; | ||||
|               } | ||||
|             } | ||||
|             while (--numDirectBits != 0); | ||||
|             prob = p + Align; | ||||
|             rep0 <<= kNumAlignBits; | ||||
|             numDirectBits = kNumAlignBits; | ||||
|           } | ||||
|           { | ||||
|             int i = 1; | ||||
|             int mi = 1; | ||||
|             do | ||||
|             { | ||||
|               CProb *prob3 = prob + mi; | ||||
|               RC_GET_BIT2(prob3, mi, ; , rep0 |= i); | ||||
|               i <<= 1; | ||||
|             } | ||||
|             while(--numDirectBits != 0); | ||||
|           } | ||||
|         } | ||||
|         else | ||||
|           rep0 = posSlot; | ||||
|         if (++rep0 == (UInt32)(0)) | ||||
|         { | ||||
|           /* it's for stream version */ | ||||
|           len = kLzmaStreamWasFinishedId; | ||||
|           break; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       len += kMatchMinLen; | ||||
|       #ifdef _LZMA_OUT_READ | ||||
|       if (rep0 > distanceLimit)  | ||||
|       #else | ||||
|       if (rep0 > nowPos) | ||||
|       #endif | ||||
|         return LZMA_RESULT_DATA_ERROR; | ||||
|  | ||||
|       #ifdef _LZMA_OUT_READ | ||||
|       if (dictionarySize - distanceLimit > (UInt32)len) | ||||
|         distanceLimit += len; | ||||
|       else | ||||
|         distanceLimit = dictionarySize; | ||||
|       #endif | ||||
|  | ||||
|       do | ||||
|       { | ||||
|         #ifdef _LZMA_OUT_READ | ||||
|         UInt32 pos = dictionaryPos - rep0; | ||||
|         if (pos >= dictionarySize) | ||||
|           pos += dictionarySize; | ||||
|         previousByte = dictionary[pos]; | ||||
|         dictionary[dictionaryPos] = previousByte; | ||||
|         if (++dictionaryPos == dictionarySize) | ||||
|           dictionaryPos = 0; | ||||
|         #else | ||||
|         previousByte = outStream[nowPos - rep0]; | ||||
|         #endif | ||||
|         len--; | ||||
|         outStream[nowPos++] = previousByte; | ||||
|       } | ||||
|       while(len != 0 && nowPos < outSize); | ||||
|     } | ||||
|   } | ||||
|   RC_NORMALIZE; | ||||
|  | ||||
|   #ifdef _LZMA_OUT_READ | ||||
|   vs->Range = Range; | ||||
|   vs->Code = Code; | ||||
|   vs->DictionaryPos = dictionaryPos; | ||||
|   vs->GlobalPos = globalPos + (UInt32)nowPos; | ||||
|   vs->DistanceLimit = distanceLimit; | ||||
|   vs->Reps[0] = rep0; | ||||
|   vs->Reps[1] = rep1; | ||||
|   vs->Reps[2] = rep2; | ||||
|   vs->Reps[3] = rep3; | ||||
|   vs->State = state; | ||||
|   vs->RemainLen = len; | ||||
|   vs->TempDictionary[0] = tempDictionary[0]; | ||||
|   #endif | ||||
|  | ||||
|   #ifdef _LZMA_IN_CB | ||||
|   vs->Buffer = Buffer; | ||||
|   vs->BufferLim = BufferLim; | ||||
|   #else | ||||
|   *inSizeProcessed = (SizeT)(Buffer - inStream); | ||||
|   #endif | ||||
|   *outSizeProcessed = nowPos; | ||||
|   return LZMA_RESULT_OK; | ||||
| } | ||||
							
								
								
									
										113
									
								
								target/linux/bmips/image/lzma-loader/src/LzmaDecode.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								target/linux/bmips/image/lzma-loader/src/LzmaDecode.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,113 @@ | ||||
| /*  | ||||
|   LzmaDecode.h | ||||
|   LZMA Decoder interface | ||||
|  | ||||
|   LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) | ||||
|   http://www.7-zip.org/ | ||||
|  | ||||
|   LZMA SDK is licensed under two licenses: | ||||
|   1) GNU Lesser General Public License (GNU LGPL) | ||||
|   2) Common Public License (CPL) | ||||
|   It means that you can select one of these two licenses and  | ||||
|   follow rules of that license. | ||||
|  | ||||
|   SPECIAL EXCEPTION: | ||||
|   Igor Pavlov, as the author of this code, expressly permits you to  | ||||
|   statically or dynamically link your code (or bind by name) to the  | ||||
|   interfaces of this file without subjecting your linked code to the  | ||||
|   terms of the CPL or GNU LGPL. Any modifications or additions  | ||||
|   to this file, however, are subject to the LGPL or CPL terms. | ||||
| */ | ||||
|  | ||||
| #ifndef __LZMADECODE_H | ||||
| #define __LZMADECODE_H | ||||
|  | ||||
| #include "LzmaTypes.h" | ||||
|  | ||||
| /* #define _LZMA_IN_CB */ | ||||
| /* Use callback for input data */ | ||||
|  | ||||
| /* #define _LZMA_OUT_READ */ | ||||
| /* Use read function for output data */ | ||||
|  | ||||
| /* #define _LZMA_PROB32 */ | ||||
| /* It can increase speed on some 32-bit CPUs,  | ||||
|    but memory usage will be doubled in that case */ | ||||
|  | ||||
| /* #define _LZMA_LOC_OPT */ | ||||
| /* Enable local speed optimizations inside code */ | ||||
|  | ||||
| #ifdef _LZMA_PROB32 | ||||
| #define CProb UInt32 | ||||
| #else | ||||
| #define CProb UInt16 | ||||
| #endif | ||||
|  | ||||
| #define LZMA_RESULT_OK 0 | ||||
| #define LZMA_RESULT_DATA_ERROR 1 | ||||
|  | ||||
| #ifdef _LZMA_IN_CB | ||||
| typedef struct _ILzmaInCallback | ||||
| { | ||||
|   int (*Read)(void *object, const unsigned char **buffer, SizeT *bufferSize); | ||||
| } ILzmaInCallback; | ||||
| #endif | ||||
|  | ||||
| #define LZMA_BASE_SIZE 1846 | ||||
| #define LZMA_LIT_SIZE 768 | ||||
|  | ||||
| #define LZMA_PROPERTIES_SIZE 5 | ||||
|  | ||||
| typedef struct _CLzmaProperties | ||||
| { | ||||
|   int lc; | ||||
|   int lp; | ||||
|   int pb; | ||||
|   #ifdef _LZMA_OUT_READ | ||||
|   UInt32 DictionarySize; | ||||
|   #endif | ||||
| }CLzmaProperties; | ||||
|  | ||||
| int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size); | ||||
|  | ||||
| #define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp))) | ||||
|  | ||||
| #define kLzmaNeedInitId (-2) | ||||
|  | ||||
| typedef struct _CLzmaDecoderState | ||||
| { | ||||
|   CLzmaProperties Properties; | ||||
|   CProb *Probs; | ||||
|  | ||||
|   #ifdef _LZMA_IN_CB | ||||
|   const unsigned char *Buffer; | ||||
|   const unsigned char *BufferLim; | ||||
|   #endif | ||||
|  | ||||
|   #ifdef _LZMA_OUT_READ | ||||
|   unsigned char *Dictionary; | ||||
|   UInt32 Range; | ||||
|   UInt32 Code; | ||||
|   UInt32 DictionaryPos; | ||||
|   UInt32 GlobalPos; | ||||
|   UInt32 DistanceLimit; | ||||
|   UInt32 Reps[4]; | ||||
|   int State; | ||||
|   int RemainLen; | ||||
|   unsigned char TempDictionary[4]; | ||||
|   #endif | ||||
| } CLzmaDecoderState; | ||||
|  | ||||
| #ifdef _LZMA_OUT_READ | ||||
| #define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; } | ||||
| #endif | ||||
|  | ||||
| int LzmaDecode(CLzmaDecoderState *vs, | ||||
|     #ifdef _LZMA_IN_CB | ||||
|     ILzmaInCallback *inCallback, | ||||
|     #else | ||||
|     const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, | ||||
|     #endif | ||||
|     unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed); | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										45
									
								
								target/linux/bmips/image/lzma-loader/src/LzmaTypes.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								target/linux/bmips/image/lzma-loader/src/LzmaTypes.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| /*  | ||||
| LzmaTypes.h  | ||||
|  | ||||
| Types for LZMA Decoder | ||||
|  | ||||
| This file written and distributed to public domain by Igor Pavlov. | ||||
| This file is part of LZMA SDK 4.40 (2006-05-01) | ||||
| */ | ||||
|  | ||||
| #ifndef __LZMATYPES_H | ||||
| #define __LZMATYPES_H | ||||
|  | ||||
| #ifndef _7ZIP_BYTE_DEFINED | ||||
| #define _7ZIP_BYTE_DEFINED | ||||
| typedef unsigned char Byte; | ||||
| #endif  | ||||
|  | ||||
| #ifndef _7ZIP_UINT16_DEFINED | ||||
| #define _7ZIP_UINT16_DEFINED | ||||
| typedef unsigned short UInt16; | ||||
| #endif  | ||||
|  | ||||
| #ifndef _7ZIP_UINT32_DEFINED | ||||
| #define _7ZIP_UINT32_DEFINED | ||||
| #ifdef _LZMA_UINT32_IS_ULONG | ||||
| typedef unsigned long UInt32; | ||||
| #else | ||||
| typedef unsigned int UInt32; | ||||
| #endif | ||||
| #endif  | ||||
|  | ||||
| /* #define _LZMA_NO_SYSTEM_SIZE_T */ | ||||
| /* You can use it, if you don't want <stddef.h> */ | ||||
|  | ||||
| #ifndef _7ZIP_SIZET_DEFINED | ||||
| #define _7ZIP_SIZET_DEFINED | ||||
| #ifdef _LZMA_NO_SYSTEM_SIZE_T | ||||
| typedef UInt32 SizeT; | ||||
| #else | ||||
| #include <stddef.h> | ||||
| typedef size_t SizeT; | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										85
									
								
								target/linux/bmips/image/lzma-loader/src/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								target/linux/bmips/image/lzma-loader/src/Makefile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | ||||
| # SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| # | ||||
| # Makefile for the LZMA compressed kernel loader for BMIPS based boards | ||||
| # | ||||
| # Copyright (C) 2020 Álvaro Fernández Rojas <noltari@gmail.com> | ||||
| # Copyright (C) 2014 Jonas Gorski <jogo@openwrt.org> | ||||
| # Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> | ||||
| # | ||||
| # Some parts of this file was based on the OpenWrt specific lzma-loader | ||||
| # for the BCM47xx and ADM5120 based boards: | ||||
| #	Copyright (C) 2004 Manuel Novoa III (mjn3@codepoet.org) | ||||
| #	Copyright (C) 2005 Mineharu Takahara <mtakahar@yahoo.com> | ||||
| #	Copyright (C) 2005 by Oleg I. Vdovikin <oleg@cs.msu.su> | ||||
| # | ||||
|  | ||||
| LOADER_ADDR	:= | ||||
| KERNEL_ADDR	:= | ||||
| LZMA_TEXT_START	:= 0x80a00000 | ||||
| LOADER_DATA	:= | ||||
|  | ||||
| CC		:= $(CROSS_COMPILE)gcc | ||||
| LD		:= $(CROSS_COMPILE)ld | ||||
| OBJCOPY		:= $(CROSS_COMPILE)objcopy | ||||
| OBJDUMP		:= $(CROSS_COMPILE)objdump | ||||
|  | ||||
| BIN_FLAGS	:= -O binary -R .reginfo -R .note -R .comment -R .mdebug \ | ||||
| 		   -R .MIPS.abiflags -S | ||||
|  | ||||
| CFLAGS		= -D__KERNEL__ -Wall -Wstrict-prototypes -Wno-trigraphs -Os \ | ||||
| 		  -fno-strict-aliasing -fno-common -fomit-frame-pointer -G 0 \ | ||||
| 		  -mno-abicalls -fno-pic -ffunction-sections -pipe \ | ||||
| 		  -ffreestanding -fhonour-copts \ | ||||
| 		  -mabi=32 -march=mips32 \ | ||||
| 		  -Wa,-32 -Wa,-march=mips32 -Wa,-mips32 -Wa,--trap | ||||
| CFLAGS		+= -D_LZMA_PROB32 | ||||
| CFLAGS		+= -DUART_BASE=$(UART_BASE) | ||||
|  | ||||
| ASFLAGS		= $(CFLAGS) -D__ASSEMBLY__ | ||||
|  | ||||
| LDFLAGS		= -static --gc-sections -no-warn-mismatch | ||||
| LDFLAGS		+= -e startup -T loader.lds -Ttext $(LZMA_TEXT_START) | ||||
|  | ||||
| O_FORMAT 	= $(shell $(OBJDUMP) -i | head -2 | grep elf32) | ||||
|  | ||||
| OBJECTS		:= head.o loader.o cache.o board.o printf.o LzmaDecode.o | ||||
|  | ||||
| ifneq ($(strip $(LOADER_DATA)),) | ||||
| OBJECTS		+= data.o | ||||
| CFLAGS		+= -DLZMA_WRAPPER=1 -DLOADADDR=$(KERNEL_ADDR) | ||||
| endif | ||||
|  | ||||
|  | ||||
| all: loader.elf | ||||
|  | ||||
| # Don't build dependencies, this may die if $(CC) isn't gcc | ||||
| dep: | ||||
|  | ||||
| install: | ||||
|  | ||||
| %.o : %.c | ||||
| 	$(CC) $(CFLAGS) -c -o $@ $< | ||||
|  | ||||
| %.o : %.S | ||||
| 	$(CC) $(ASFLAGS) -c -o $@ $< | ||||
|  | ||||
| data.o: $(LOADER_DATA) | ||||
| 	$(LD) -r -b binary --oformat $(O_FORMAT) -T lzma-data.lds -o $@ $< | ||||
|  | ||||
| loader: $(OBJECTS) | ||||
| 	$(LD) $(LDFLAGS) -o $@ $(OBJECTS) | ||||
|  | ||||
| loader.bin: loader | ||||
| 	$(OBJCOPY) $(BIN_FLAGS) $< $@ | ||||
|  | ||||
| loader2.o: loader.bin | ||||
| 	$(LD) -r -b binary --oformat $(O_FORMAT) -o $@ $< | ||||
|  | ||||
| loader.elf: loader2.o | ||||
| 	$(LD) -e startup -T loader2.lds -Ttext $(LOADER_ADDR) -o $@ $< | ||||
|  | ||||
| mrproper: clean | ||||
|  | ||||
| clean: | ||||
| 	rm -f loader *.elf *.bin *.o | ||||
							
								
								
									
										37
									
								
								target/linux/bmips/image/lzma-loader/src/board.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								target/linux/bmips/image/lzma-loader/src/board.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
| /* | ||||
|  * BCM63XX specific implementation parts | ||||
|  * | ||||
|  * Copyright (C) 2020 Álvaro Fernández Rojas <noltari@gmail.com> | ||||
|  * Copyright (C) 2014 Jonas Gorski <jogo@openwrt.org> | ||||
|  */ | ||||
|  | ||||
| #include <stddef.h> | ||||
| #include "config.h" | ||||
|  | ||||
| #define READREG(r)	*(volatile unsigned int *)(r) | ||||
| #define WRITEREG(r,v)	*(volatile unsigned int *)(r) = v | ||||
|  | ||||
| #define UART_IR_REG	0x10 | ||||
| #define UART_FIFO_REG	0x14 | ||||
|  | ||||
| static void wait_xfered(void) | ||||
| { | ||||
|         unsigned int val; | ||||
|  | ||||
|         do { | ||||
|                 val = READREG(UART_BASE + UART_IR_REG); | ||||
|                 if (val & (1 << 5)) | ||||
|                         break; | ||||
|         } while (1); | ||||
| } | ||||
|  | ||||
| void board_putc(int ch) | ||||
| { | ||||
| 	if (!UART_BASE) | ||||
| 		return; | ||||
|  | ||||
| 	wait_xfered(); | ||||
| 	WRITEREG(UART_BASE + UART_FIFO_REG, ch); | ||||
| 	wait_xfered(); | ||||
| } | ||||
							
								
								
									
										42
									
								
								target/linux/bmips/image/lzma-loader/src/cache.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								target/linux/bmips/image/lzma-loader/src/cache.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
| /* | ||||
|  * LZMA compressed kernel loader for Atheros AR7XXX/AR9XXX based boards | ||||
|  * | ||||
|  * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> | ||||
|  * | ||||
|  * The cache manipulation routine has been taken from the U-Boot project. | ||||
|  *	(C) Copyright 2003 | ||||
|  *	Wolfgang Denk, DENX Software Engineering, <wd@denx.de> | ||||
|  */ | ||||
|  | ||||
| #include "cache.h" | ||||
| #include "cacheops.h" | ||||
| #include "config.h" | ||||
| #include "printf.h" | ||||
|  | ||||
| #define cache_op(op,addr)						\ | ||||
| 	__asm__ __volatile__(						\ | ||||
| 	"	.set	push					\n"	\ | ||||
| 	"	.set	noreorder				\n"	\ | ||||
| 	"	.set	mips3\n\t				\n"	\ | ||||
| 	"	cache	%0, %1					\n"	\ | ||||
| 	"	.set	pop					\n"	\ | ||||
| 	:								\ | ||||
| 	: "i" (op), "R" (*(unsigned char *)(addr))) | ||||
|  | ||||
| void flush_cache(unsigned long start_addr, unsigned long size) | ||||
| { | ||||
| 	unsigned long lsize = CONFIG_CACHELINE_SIZE; | ||||
| 	unsigned long addr = start_addr & ~(lsize - 1); | ||||
| 	unsigned long aend = (start_addr + size + (lsize - 1)) & ~(lsize - 1); | ||||
|  | ||||
| 	printf("blasting from 0x%08x to 0x%08x (0x%08x - 0x%08x)\n", start_addr, size, addr, aend); | ||||
|  | ||||
| 	while (1) { | ||||
| 		cache_op(Hit_Writeback_Inv_D, addr); | ||||
| 		cache_op(Hit_Invalidate_I, addr); | ||||
| 		if (addr == aend) | ||||
| 			break; | ||||
| 		addr += lsize; | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										13
									
								
								target/linux/bmips/image/lzma-loader/src/cache.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								target/linux/bmips/image/lzma-loader/src/cache.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
| /* | ||||
|  * LZMA compressed kernel loader for Atheros AR7XXX/AR9XXX based boards | ||||
|  * | ||||
|  * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> | ||||
|  */ | ||||
|  | ||||
| #ifndef __CACHE_H | ||||
| #define __CACHE_H | ||||
|  | ||||
| void flush_cache(unsigned long start_addr, unsigned long size); | ||||
|  | ||||
| #endif /* __CACHE_H */ | ||||
							
								
								
									
										82
									
								
								target/linux/bmips/image/lzma-loader/src/cacheops.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								target/linux/bmips/image/lzma-loader/src/cacheops.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
| /* | ||||
|  * Cache operations for the cache instruction. | ||||
|  * | ||||
|  * (C) Copyright 1996, 97, 99, 2002, 03 Ralf Baechle | ||||
|  * (C) Copyright 1999 Silicon Graphics, Inc. | ||||
|  */ | ||||
| #ifndef	__ASM_CACHEOPS_H | ||||
| #define	__ASM_CACHEOPS_H | ||||
|  | ||||
| /* | ||||
|  * Cache Operations available on all MIPS processors with R4000-style caches | ||||
|  */ | ||||
| #define Index_Invalidate_I      0x00 | ||||
| #define Index_Writeback_Inv_D   0x01 | ||||
| #define Index_Load_Tag_I	0x04 | ||||
| #define Index_Load_Tag_D	0x05 | ||||
| #define Index_Store_Tag_I	0x08 | ||||
| #define Index_Store_Tag_D	0x09 | ||||
| #if defined(CONFIG_CPU_LOONGSON2) | ||||
| #define Hit_Invalidate_I	0x00 | ||||
| #else | ||||
| #define Hit_Invalidate_I	0x10 | ||||
| #endif | ||||
| #define Hit_Invalidate_D	0x11 | ||||
| #define Hit_Writeback_Inv_D	0x15 | ||||
|  | ||||
| /* | ||||
|  * R4000-specific cacheops | ||||
|  */ | ||||
| #define Create_Dirty_Excl_D	0x0d | ||||
| #define Fill			0x14 | ||||
| #define Hit_Writeback_I		0x18 | ||||
| #define Hit_Writeback_D		0x19 | ||||
|  | ||||
| /* | ||||
|  * R4000SC and R4400SC-specific cacheops | ||||
|  */ | ||||
| #define Index_Invalidate_SI     0x02 | ||||
| #define Index_Writeback_Inv_SD  0x03 | ||||
| #define Index_Load_Tag_SI	0x06 | ||||
| #define Index_Load_Tag_SD	0x07 | ||||
| #define Index_Store_Tag_SI	0x0A | ||||
| #define Index_Store_Tag_SD	0x0B | ||||
| #define Create_Dirty_Excl_SD	0x0f | ||||
| #define Hit_Invalidate_SI	0x12 | ||||
| #define Hit_Invalidate_SD	0x13 | ||||
| #define Hit_Writeback_Inv_SD	0x17 | ||||
| #define Hit_Writeback_SD	0x1b | ||||
| #define Hit_Set_Virtual_SI	0x1e | ||||
| #define Hit_Set_Virtual_SD	0x1f | ||||
|  | ||||
| /* | ||||
|  * R5000-specific cacheops | ||||
|  */ | ||||
| #define R5K_Page_Invalidate_S	0x17 | ||||
|  | ||||
| /* | ||||
|  * RM7000-specific cacheops | ||||
|  */ | ||||
| #define Page_Invalidate_T	0x16 | ||||
|  | ||||
| /* | ||||
|  * R10000-specific cacheops | ||||
|  * | ||||
|  * Cacheops 0x02, 0x06, 0x0a, 0x0c-0x0e, 0x16, 0x1a and 0x1e are unused. | ||||
|  * Most of the _S cacheops are identical to the R4000SC _SD cacheops. | ||||
|  */ | ||||
| #define Index_Writeback_Inv_S	0x03 | ||||
| #define Index_Load_Tag_S	0x07 | ||||
| #define Index_Store_Tag_S	0x0B | ||||
| #define Hit_Invalidate_S	0x13 | ||||
| #define Cache_Barrier		0x14 | ||||
| #define Hit_Writeback_Inv_S	0x17 | ||||
| #define Index_Load_Data_I	0x18 | ||||
| #define Index_Load_Data_D	0x19 | ||||
| #define Index_Load_Data_S	0x1b | ||||
| #define Index_Store_Data_I	0x1c | ||||
| #define Index_Store_Data_D	0x1d | ||||
| #define Index_Store_Data_S	0x1f | ||||
|  | ||||
| #endif	/* __ASM_CACHEOPS_H */ | ||||
							
								
								
									
										15
									
								
								target/linux/bmips/image/lzma-loader/src/config.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								target/linux/bmips/image/lzma-loader/src/config.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
| /* | ||||
|  * LZMA compressed kernel loader for Atheros AR7XXX/AR9XXX based boards | ||||
|  * | ||||
|  * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> | ||||
|  */ | ||||
|  | ||||
| #ifndef _CONFIG_H_ | ||||
| #define _CONFIG_H_ | ||||
|  | ||||
| #define CONFIG_ICACHE_SIZE	(32 * 1024) | ||||
| #define CONFIG_DCACHE_SIZE	(32 * 1024) | ||||
| #define CONFIG_CACHELINE_SIZE	16 | ||||
|  | ||||
| #endif /* _CONFIG_H_ */ | ||||
							
								
								
									
										55
									
								
								target/linux/bmips/image/lzma-loader/src/cp0regdef.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								target/linux/bmips/image/lzma-loader/src/cp0regdef.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
| /* | ||||
|  * Copyright (C) 1994, 1995, 1996, 1997, 2000, 2001 by Ralf Baechle | ||||
|  * | ||||
|  * Copyright (C) 2001, Monta Vista Software | ||||
|  * Author: jsun@mvista.com or jsun@junsun.net | ||||
|  */ | ||||
| #ifndef _cp0regdef_h_ | ||||
| #define _cp0regdef_h_ | ||||
|  | ||||
| #define CP0_INDEX $0 | ||||
| #define CP0_RANDOM $1 | ||||
| #define CP0_ENTRYLO0 $2 | ||||
| #define CP0_ENTRYLO1 $3 | ||||
| #define CP0_CONTEXT $4 | ||||
| #define CP0_PAGEMASK $5 | ||||
| #define CP0_WIRED $6 | ||||
| #define CP0_BADVADDR $8 | ||||
| #define CP0_COUNT $9 | ||||
| #define CP0_ENTRYHI $10 | ||||
| #define CP0_COMPARE $11 | ||||
| #define CP0_STATUS $12 | ||||
| #define CP0_CAUSE $13 | ||||
| #define CP0_EPC $14 | ||||
| #define CP0_PRID $15 | ||||
| #define CP0_CONFIG $16 | ||||
| #define CP0_LLADDR $17 | ||||
| #define CP0_WATCHLO $18 | ||||
| #define CP0_WATCHHI $19 | ||||
| #define CP0_XCONTEXT $20 | ||||
| #define CP0_FRAMEMASK $21 | ||||
| #define CP0_DIAGNOSTIC $22 | ||||
| #define CP0_PERFORMANCE $25 | ||||
| #define CP0_ECC $26 | ||||
| #define CP0_CACHEERR $27 | ||||
| #define CP0_TAGLO $28 | ||||
| #define CP0_TAGHI $29 | ||||
| #define CP0_ERROREPC $30 | ||||
|  | ||||
| #define read_32bit_c0_register(reg,sel)					\ | ||||
| ({	int __res;							\ | ||||
| 	if (sel == 0)							\ | ||||
| 		__asm__ __volatile__(					\ | ||||
| 			"mfc0\t%0, " #reg "\n\t"			\ | ||||
| 			: "=r" (__res));				\ | ||||
| 	else								\ | ||||
| 		__asm__ __volatile__(					\ | ||||
| 			".set\tmips32\n\t"				\ | ||||
| 			"mfc0\t%0, " #reg ", " #sel "\n\t"		\ | ||||
| 			".set mips0\n\t"				\ | ||||
| 			: "=r" (__res));				\ | ||||
| 	__res;								\ | ||||
| }) | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										118
									
								
								target/linux/bmips/image/lzma-loader/src/head.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								target/linux/bmips/image/lzma-loader/src/head.S
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,118 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
| /* | ||||
|  * LZMA compressed kernel loader for Atheros AR7XXX/AR9XXX based boards | ||||
|  * | ||||
|  * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> | ||||
|  * | ||||
|  * Some parts of this code was based on the OpenWrt specific lzma-loader | ||||
|  * for the BCM47xx and ADM5120 based boards: | ||||
|  *	Copyright (C) 2004 Manuel Novoa III (mjn3@codepoet.org) | ||||
|  *	Copyright (C) 2005 by Oleg I. Vdovikin <oleg@cs.msu.su> | ||||
|  */ | ||||
|  | ||||
| #include <asm/asm.h> | ||||
| #include <asm/regdef.h> | ||||
| #include "cp0regdef.h" | ||||
| #include "cacheops.h" | ||||
| #include "config.h" | ||||
|  | ||||
| #define KSEG0		0x80000000 | ||||
|  | ||||
| 	.macro	ehb | ||||
| 	sll     zero, 3 | ||||
| 	.endm | ||||
|  | ||||
| 	.text | ||||
|  | ||||
| LEAF(startup) | ||||
| 	.set noreorder | ||||
| 	.set mips32 | ||||
|  | ||||
| 	mtc0	zero, CP0_WATCHLO	# clear watch registers | ||||
| 	mtc0	zero, CP0_WATCHHI | ||||
| 	mtc0	zero, CP0_CAUSE		# clear before writing status register | ||||
|  | ||||
| 	mfc0	t0, CP0_STATUS | ||||
| 	li	t1, 0x1000001f | ||||
| 	or	t0, t1 | ||||
| 	xori	t0, 0x1f | ||||
| 	mtc0	t0, CP0_STATUS | ||||
| 	ehb | ||||
|  | ||||
| 	mtc0	zero, CP0_COUNT | ||||
| 	mtc0	zero, CP0_COMPARE | ||||
| 	ehb | ||||
|  | ||||
| 	la	t0, __reloc_label	# get linked address of label | ||||
| 	bal	__reloc_label		# branch and link to label to | ||||
| 	nop				# get actual address | ||||
| __reloc_label: | ||||
| 	subu	t0, ra, t0		# get reloc_delta | ||||
|  | ||||
| 	beqz	t0, __reloc_done         # if delta is 0 we are in the right place | ||||
| 	nop | ||||
|  | ||||
| 	/* Copy our code to the right place */ | ||||
| 	la	t1, _code_start		# get linked address of _code_start | ||||
| 	la	t2, _code_end		# get linked address of _code_end | ||||
| 	addu	t0, t0, t1		# calculate actual address of _code_start | ||||
|  | ||||
| __reloc_copy: | ||||
| 	lw	t3, 0(t0) | ||||
| 	sw	t3, 0(t1) | ||||
| 	add	t1, 4 | ||||
| 	blt	t1, t2, __reloc_copy | ||||
| 	add	t0, 4 | ||||
|  | ||||
| 	/* flush cache */ | ||||
| 	la	t0, _code_start | ||||
| 	la	t1, _code_end | ||||
|  | ||||
| 	li	t2, ~(CONFIG_CACHELINE_SIZE - 1) | ||||
| 	and	t0, t2 | ||||
| 	and	t1, t2 | ||||
| 	li	t2, CONFIG_CACHELINE_SIZE | ||||
|  | ||||
| 	b	__flush_check | ||||
| 	nop | ||||
|  | ||||
| __flush_line: | ||||
| 	cache	Hit_Writeback_Inv_D, 0(t0) | ||||
| 	cache	Hit_Invalidate_I, 0(t0) | ||||
| 	add	t0, t2 | ||||
|  | ||||
| __flush_check: | ||||
| 	bne	t0, t1, __flush_line | ||||
| 	nop | ||||
|  | ||||
| 	sync | ||||
|  | ||||
| __reloc_done: | ||||
|  | ||||
| 	/* clear bss */ | ||||
| 	la	t0, _bss_start | ||||
| 	la	t1, _bss_end | ||||
| 	b	__bss_check | ||||
| 	nop | ||||
|  | ||||
| __bss_fill: | ||||
| 	sw	zero, 0(t0) | ||||
| 	addi	t0, 4 | ||||
|  | ||||
| __bss_check: | ||||
| 	bne	t0, t1, __bss_fill | ||||
| 	nop | ||||
|  | ||||
| 	/* Setup new "C" stack */ | ||||
| 	la	sp, _stack | ||||
|  | ||||
| 	/* reserve stack space for a0-a3 registers */ | ||||
| 	subu	sp, 16 | ||||
|  | ||||
| 	/* jump to the decompressor routine */ | ||||
| 	la	t0, loader_main | ||||
| 	jr	t0 | ||||
| 	nop | ||||
|  | ||||
| 	.set reorder | ||||
| END(startup) | ||||
							
								
								
									
										169
									
								
								target/linux/bmips/image/lzma-loader/src/loader.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								target/linux/bmips/image/lzma-loader/src/loader.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,169 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
| /* | ||||
|  * LZMA compressed kernel loader for Atheros AR7XXX/AR9XXX based boards | ||||
|  * | ||||
|  * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> | ||||
|  * | ||||
|  * Some parts of this code was based on the OpenWrt specific lzma-loader | ||||
|  * for the BCM47xx and ADM5120 based boards: | ||||
|  *	Copyright (C) 2004 Manuel Novoa III (mjn3@codepoet.org) | ||||
|  *	Copyright (C) 2005 Mineharu Takahara <mtakahar@yahoo.com> | ||||
|  *	Copyright (C) 2005 by Oleg I. Vdovikin <oleg@cs.msu.su> | ||||
|  * | ||||
|  * The image_header structure has been taken from the U-Boot project. | ||||
|  *	(C) Copyright 2008 Semihalf | ||||
|  *	(C) Copyright 2000-2005 | ||||
|  *	Wolfgang Denk, DENX Software Engineering, wd@denx.de. | ||||
|  */ | ||||
|  | ||||
| #include <stddef.h> | ||||
| #include <stdint.h> | ||||
|  | ||||
| #include "config.h" | ||||
| #include "cache.h" | ||||
| #include "printf.h" | ||||
| #include "LzmaDecode.h" | ||||
|  | ||||
| #define KSEG0			0x80000000 | ||||
| #define KSEG1			0xa0000000 | ||||
|  | ||||
| #define KSEG1ADDR(a)		((((unsigned)(a)) & 0x1fffffffU) | KSEG1) | ||||
|  | ||||
| #undef LZMA_DEBUG | ||||
|  | ||||
| #ifdef LZMA_DEBUG | ||||
| #  define DBG(f, a...)	printf(f, ## a) | ||||
| #else | ||||
| #  define DBG(f, a...)	do {} while (0) | ||||
| #endif | ||||
|  | ||||
| /* beyond the image end, size not known in advance */ | ||||
| extern unsigned char workspace[]; | ||||
|  | ||||
|  | ||||
| static CLzmaDecoderState lzma_state; | ||||
| static unsigned char *lzma_data; | ||||
| static unsigned long lzma_datasize; | ||||
| static unsigned long lzma_outsize; | ||||
| static unsigned long kernel_la; | ||||
|  | ||||
| static void halt(void) | ||||
| { | ||||
| 	printf("\nSystem halted!\n"); | ||||
| 	for(;;); | ||||
| } | ||||
|  | ||||
| static __inline__ unsigned char lzma_get_byte(void) | ||||
| { | ||||
| 	unsigned char c; | ||||
|  | ||||
| 	lzma_datasize--; | ||||
| 	c = *lzma_data++; | ||||
|  | ||||
| 	return c; | ||||
| } | ||||
|  | ||||
| static int lzma_init_props(void) | ||||
| { | ||||
| 	unsigned char props[LZMA_PROPERTIES_SIZE]; | ||||
| 	int res; | ||||
| 	int i; | ||||
|  | ||||
| 	/* read lzma properties */ | ||||
| 	for (i = 0; i < LZMA_PROPERTIES_SIZE; i++) | ||||
| 		props[i] = lzma_get_byte(); | ||||
|  | ||||
| 	/* read the lower half of uncompressed size in the header */ | ||||
| 	lzma_outsize = ((SizeT) lzma_get_byte()) + | ||||
| 		       ((SizeT) lzma_get_byte() << 8) + | ||||
| 		       ((SizeT) lzma_get_byte() << 16) + | ||||
| 		       ((SizeT) lzma_get_byte() << 24); | ||||
|  | ||||
| 	/* skip rest of the header (upper half of uncompressed size) */ | ||||
| 	for (i = 0; i < 4; i++) | ||||
| 		lzma_get_byte(); | ||||
|  | ||||
| 	res = LzmaDecodeProperties(&lzma_state.Properties, props, | ||||
| 					LZMA_PROPERTIES_SIZE); | ||||
| 	return res; | ||||
| } | ||||
|  | ||||
| static int lzma_decompress(unsigned char *outStream) | ||||
| { | ||||
| 	SizeT ip, op; | ||||
| 	int ret; | ||||
|  | ||||
| 	lzma_state.Probs = (CProb *) workspace; | ||||
|  | ||||
| 	ret = LzmaDecode(&lzma_state, lzma_data, lzma_datasize, &ip, outStream, | ||||
| 			 lzma_outsize, &op); | ||||
|  | ||||
| 	if (ret != LZMA_RESULT_OK) { | ||||
| 		int i; | ||||
|  | ||||
| 		DBG("LzmaDecode error %d at %08x, osize:%d ip:%d op:%d\n", | ||||
| 		    ret, lzma_data + ip, lzma_outsize, ip, op); | ||||
|  | ||||
| 		for (i = 0; i < 16; i++) | ||||
| 			DBG("%02x ", lzma_data[ip + i]); | ||||
|  | ||||
| 		DBG("\n"); | ||||
| 	} | ||||
|  | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| static void lzma_init_data(void) | ||||
| { | ||||
| 	extern unsigned char _lzma_data_start[]; | ||||
| 	extern unsigned char _lzma_data_end[]; | ||||
|  | ||||
| 	kernel_la = LOADADDR; | ||||
| 	lzma_data = _lzma_data_start; | ||||
| 	lzma_datasize = _lzma_data_end - _lzma_data_start; | ||||
| } | ||||
|  | ||||
| void loader_main(unsigned long reg_a0, unsigned long reg_a1, | ||||
| 		 unsigned long reg_a2, unsigned long reg_a3) | ||||
| { | ||||
| 	void (*kernel_entry) (unsigned long, unsigned long, unsigned long, | ||||
| 			      unsigned long); | ||||
| 	int res; | ||||
|  | ||||
| 	printf("\n\nOpenWrt kernel loader for BMIPS\n"); | ||||
| 	printf("Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>\n"); | ||||
| 	printf("Copyright (C) 2014 Jonas Gorski <jogo@openwrt.org>\n"); | ||||
| 	printf("Copyright (C) 2020 Alvaro Fernandez Rojas <noltari@gmail.com>\n"); | ||||
|  | ||||
| 	lzma_init_data(); | ||||
|  | ||||
| 	res = lzma_init_props(); | ||||
| 	if (res != LZMA_RESULT_OK) { | ||||
| 		printf("Incorrect LZMA stream properties!\n"); | ||||
| 		halt(); | ||||
| 	} | ||||
|  | ||||
| 	printf("Decompressing kernel... "); | ||||
|  | ||||
| 	res = lzma_decompress((unsigned char *) kernel_la); | ||||
| 	if (res != LZMA_RESULT_OK) { | ||||
| 		printf("failed, "); | ||||
| 		switch (res) { | ||||
| 		case LZMA_RESULT_DATA_ERROR: | ||||
| 			printf("data error!\n"); | ||||
| 			break; | ||||
| 		default: | ||||
| 			printf("unknown error %d!\n", res); | ||||
| 		} | ||||
| 		halt(); | ||||
| 	} else { | ||||
| 		printf("done!\n"); | ||||
| 	} | ||||
|  | ||||
| 	flush_cache(kernel_la, lzma_outsize); | ||||
|  | ||||
| 	printf("Starting kernel at %08x...\n\n", kernel_la); | ||||
|  | ||||
| 	kernel_entry = (void *) kernel_la; | ||||
| 	kernel_entry(reg_a0, reg_a1, reg_a2, reg_a3); | ||||
| } | ||||
							
								
								
									
										36
									
								
								target/linux/bmips/image/lzma-loader/src/loader.lds
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								target/linux/bmips/image/lzma-loader/src/loader.lds
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| /* SPDX-License-Identifier: GPL-2.0-or-later */ | ||||
|  | ||||
| OUTPUT_ARCH(mips) | ||||
| SECTIONS { | ||||
| 	.text : { | ||||
| 		_code_start = .; | ||||
| 		*(.text) | ||||
| 		*(.text.*) | ||||
| 		*(.rodata) | ||||
| 		*(.rodata.*) | ||||
| 		*(.data.lzma) | ||||
| 	} | ||||
|  | ||||
| 	. = ALIGN(32); | ||||
| 	.data : { | ||||
| 		*(.data) | ||||
| 		*(.data.*) | ||||
| 	} | ||||
|  | ||||
| 	. = ALIGN(32); | ||||
| 	_code_end = .; | ||||
|  | ||||
| 	_bss_start = .; | ||||
| 	.bss : { | ||||
| 		*(.bss) | ||||
| 		*(.bss.*) | ||||
| 	} | ||||
|  | ||||
| 	. = ALIGN(32); | ||||
| 	_bss_end = .; | ||||
|  | ||||
| 	. = . + 8192; | ||||
| 	_stack = .; | ||||
|  | ||||
| 	workspace = .; | ||||
| } | ||||
							
								
								
									
										12
									
								
								target/linux/bmips/image/lzma-loader/src/loader2.lds
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								target/linux/bmips/image/lzma-loader/src/loader2.lds
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| /* SPDX-License-Identifier: GPL-2.0-or-later */ | ||||
|  | ||||
| OUTPUT_ARCH(mips) | ||||
| SECTIONS { | ||||
| 	.text : { | ||||
| 		startup = .; | ||||
| 		*(.text) | ||||
| 		*(.text.*) | ||||
| 		*(.data) | ||||
| 		*(.data.*) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										10
									
								
								target/linux/bmips/image/lzma-loader/src/lzma-data.lds
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								target/linux/bmips/image/lzma-loader/src/lzma-data.lds
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| /* SPDX-License-Identifier: GPL-2.0-or-later */ | ||||
|  | ||||
| OUTPUT_ARCH(mips) | ||||
| SECTIONS { | ||||
| 	.data.lzma : { | ||||
| 		_lzma_data_start = .; | ||||
| 		*(.data) | ||||
| 		_lzma_data_end = .; | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										345
									
								
								target/linux/bmips/image/lzma-loader/src/printf.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										345
									
								
								target/linux/bmips/image/lzma-loader/src/printf.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,345 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
| /* | ||||
|  * Copyright (C) 2001 MontaVista Software Inc. | ||||
|  * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net | ||||
|  */ | ||||
|  | ||||
| #include	"printf.h" | ||||
|  | ||||
| extern void board_putc(int ch); | ||||
|  | ||||
| /* this is the maximum width for a variable */ | ||||
| #define		LP_MAX_BUF	256 | ||||
|  | ||||
| /* macros */ | ||||
| #define		IsDigit(x)	( ((x) >= '0') && ((x) <= '9') ) | ||||
| #define		Ctod(x)		( (x) - '0') | ||||
|  | ||||
| /* forward declaration */ | ||||
| static int PrintChar(char *, char, int, int); | ||||
| static int PrintString(char *, char *, int, int); | ||||
| static int PrintNum(char *, unsigned long, int, int, int, int, char, int); | ||||
|  | ||||
| /* private variable */ | ||||
| static const char theFatalMsg[] = "fatal error in lp_Print!"; | ||||
|  | ||||
| /* -*- | ||||
|  * A low level printf() function. | ||||
|  */ | ||||
| static void | ||||
| lp_Print(void (*output)(void *, char *, int), | ||||
| 	 void * arg, | ||||
| 	 char *fmt, | ||||
| 	 va_list ap) | ||||
| { | ||||
|  | ||||
| #define 	OUTPUT(arg, s, l)  \ | ||||
|   { if (((l) < 0) || ((l) > LP_MAX_BUF)) { \ | ||||
|        (*output)(arg, (char*)theFatalMsg, sizeof(theFatalMsg)-1); for(;;); \ | ||||
|     } else { \ | ||||
|       (*output)(arg, s, l); \ | ||||
|     } \ | ||||
|   } | ||||
|  | ||||
|     char buf[LP_MAX_BUF]; | ||||
|  | ||||
|     char c; | ||||
|     char *s; | ||||
|     long int num; | ||||
|  | ||||
|     int longFlag; | ||||
|     int negFlag; | ||||
|     int width; | ||||
|     int prec; | ||||
|     int ladjust; | ||||
|     char padc; | ||||
|  | ||||
|     int length; | ||||
|  | ||||
|     for(;;) { | ||||
| 	{ | ||||
| 	    /* scan for the next '%' */ | ||||
| 	    char *fmtStart = fmt; | ||||
| 	    while ( (*fmt != '\0') && (*fmt != '%')) { | ||||
| 		fmt ++; | ||||
| 	    } | ||||
|  | ||||
| 	    /* flush the string found so far */ | ||||
| 	    OUTPUT(arg, fmtStart, fmt-fmtStart); | ||||
|  | ||||
| 	    /* are we hitting the end? */ | ||||
| 	    if (*fmt == '\0') break; | ||||
| 	} | ||||
|  | ||||
| 	/* we found a '%' */ | ||||
| 	fmt ++; | ||||
|  | ||||
| 	/* check for long */ | ||||
| 	if (*fmt == 'l') { | ||||
| 	    longFlag = 1; | ||||
| 	    fmt ++; | ||||
| 	} else { | ||||
| 	    longFlag = 0; | ||||
| 	} | ||||
|  | ||||
| 	/* check for other prefixes */ | ||||
| 	width = 0; | ||||
| 	prec = -1; | ||||
| 	ladjust = 0; | ||||
| 	padc = ' '; | ||||
|  | ||||
| 	if (*fmt == '-') { | ||||
| 	    ladjust = 1; | ||||
| 	    fmt ++; | ||||
| 	} | ||||
|  | ||||
| 	if (*fmt == '0') { | ||||
| 	    padc = '0'; | ||||
| 	    fmt++; | ||||
| 	} | ||||
|  | ||||
| 	if (IsDigit(*fmt)) { | ||||
| 	    while (IsDigit(*fmt)) { | ||||
| 		width = 10 * width + Ctod(*fmt++); | ||||
| 	    } | ||||
| 	} | ||||
|  | ||||
| 	if (*fmt == '.') { | ||||
| 	    fmt ++; | ||||
| 	    if (IsDigit(*fmt)) { | ||||
| 		prec = 0; | ||||
| 		while (IsDigit(*fmt)) { | ||||
| 		    prec = prec*10 + Ctod(*fmt++); | ||||
| 		} | ||||
| 	    } | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	/* check format flag */ | ||||
| 	negFlag = 0; | ||||
| 	switch (*fmt) { | ||||
| 	 case 'b': | ||||
| 	    if (longFlag) { | ||||
| 		num = va_arg(ap, long int); | ||||
| 	    } else { | ||||
| 		num = va_arg(ap, int); | ||||
| 	    } | ||||
| 	    length = PrintNum(buf, num, 2, 0, width, ladjust, padc, 0); | ||||
| 	    OUTPUT(arg, buf, length); | ||||
| 	    break; | ||||
|  | ||||
| 	 case 'd': | ||||
| 	 case 'D': | ||||
| 	    if (longFlag) { | ||||
| 		num = va_arg(ap, long int); | ||||
| 	    } else { | ||||
| 		num = va_arg(ap, int); | ||||
| 	    } | ||||
| 	    if (num < 0) { | ||||
| 		num = - num; | ||||
| 		negFlag = 1; | ||||
| 	    } | ||||
| 	    length = PrintNum(buf, num, 10, negFlag, width, ladjust, padc, 0); | ||||
| 	    OUTPUT(arg, buf, length); | ||||
| 	    break; | ||||
|  | ||||
| 	 case 'o': | ||||
| 	 case 'O': | ||||
| 	    if (longFlag) { | ||||
| 		num = va_arg(ap, long int); | ||||
| 	    } else { | ||||
| 		num = va_arg(ap, int); | ||||
| 	    } | ||||
| 	    length = PrintNum(buf, num, 8, 0, width, ladjust, padc, 0); | ||||
| 	    OUTPUT(arg, buf, length); | ||||
| 	    break; | ||||
|  | ||||
| 	 case 'u': | ||||
| 	 case 'U': | ||||
| 	    if (longFlag) { | ||||
| 		num = va_arg(ap, long int); | ||||
| 	    } else { | ||||
| 		num = va_arg(ap, int); | ||||
| 	    } | ||||
| 	    length = PrintNum(buf, num, 10, 0, width, ladjust, padc, 0); | ||||
| 	    OUTPUT(arg, buf, length); | ||||
| 	    break; | ||||
|  | ||||
| 	 case 'x': | ||||
| 	    if (longFlag) { | ||||
| 		num = va_arg(ap, long int); | ||||
| 	    } else { | ||||
| 		num = va_arg(ap, int); | ||||
| 	    } | ||||
| 	    length = PrintNum(buf, num, 16, 0, width, ladjust, padc, 0); | ||||
| 	    OUTPUT(arg, buf, length); | ||||
| 	    break; | ||||
|  | ||||
| 	 case 'X': | ||||
| 	    if (longFlag) { | ||||
| 		num = va_arg(ap, long int); | ||||
| 	    } else { | ||||
| 		num = va_arg(ap, int); | ||||
| 	    } | ||||
| 	    length = PrintNum(buf, num, 16, 0, width, ladjust, padc, 1); | ||||
| 	    OUTPUT(arg, buf, length); | ||||
| 	    break; | ||||
|  | ||||
| 	 case 'c': | ||||
| 	    c = (char)va_arg(ap, int); | ||||
| 	    length = PrintChar(buf, c, width, ladjust); | ||||
| 	    OUTPUT(arg, buf, length); | ||||
| 	    break; | ||||
|  | ||||
| 	 case 's': | ||||
| 	    s = (char*)va_arg(ap, char *); | ||||
| 	    length = PrintString(buf, s, width, ladjust); | ||||
| 	    OUTPUT(arg, buf, length); | ||||
| 	    break; | ||||
|  | ||||
| 	 case '\0': | ||||
| 	    fmt --; | ||||
| 	    break; | ||||
|  | ||||
| 	 default: | ||||
| 	    /* output this char as it is */ | ||||
| 	    OUTPUT(arg, fmt, 1); | ||||
| 	}	/* switch (*fmt) */ | ||||
|  | ||||
| 	fmt ++; | ||||
|     }		/* for(;;) */ | ||||
|  | ||||
|     /* special termination call */ | ||||
|     OUTPUT(arg, "\0", 1); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* --------------- local help functions --------------------- */ | ||||
| static int | ||||
| PrintChar(char * buf, char c, int length, int ladjust) | ||||
| { | ||||
|     int i; | ||||
|  | ||||
|     if (length < 1) length = 1; | ||||
|     if (ladjust) { | ||||
| 	*buf = c; | ||||
| 	for (i=1; i< length; i++) buf[i] = ' '; | ||||
|     } else { | ||||
| 	for (i=0; i< length-1; i++) buf[i] = ' '; | ||||
| 	buf[length - 1] = c; | ||||
|     } | ||||
|     return length; | ||||
| } | ||||
|  | ||||
| static int | ||||
| PrintString(char * buf, char* s, int length, int ladjust) | ||||
| { | ||||
|     int i; | ||||
|     int len=0; | ||||
|     char* s1 = s; | ||||
|     while (*s1++) len++; | ||||
|     if (length < len) length = len; | ||||
|  | ||||
|     if (ladjust) { | ||||
| 	for (i=0; i< len; i++) buf[i] = s[i]; | ||||
| 	for (i=len; i< length; i++) buf[i] = ' '; | ||||
|     } else { | ||||
| 	for (i=0; i< length-len; i++) buf[i] = ' '; | ||||
| 	for (i=length-len; i < length; i++) buf[i] = s[i-length+len]; | ||||
|     } | ||||
|     return length; | ||||
| } | ||||
|  | ||||
| static int | ||||
| PrintNum(char * buf, unsigned long u, int base, int negFlag, | ||||
| 	 int length, int ladjust, char padc, int upcase) | ||||
| { | ||||
|     /* algorithm : | ||||
|      *  1. prints the number from left to right in reverse form. | ||||
|      *  2. fill the remaining spaces with padc if length is longer than | ||||
|      *     the actual length | ||||
|      *     TRICKY : if left adjusted, no "0" padding. | ||||
|      *		    if negtive, insert  "0" padding between "0" and number. | ||||
|      *  3. if (!ladjust) we reverse the whole string including paddings | ||||
|      *  4. otherwise we only reverse the actual string representing the num. | ||||
|      */ | ||||
|  | ||||
|     int actualLength =0; | ||||
|     char *p = buf; | ||||
|     int i; | ||||
|  | ||||
|     do { | ||||
| 	int tmp = u %base; | ||||
| 	if (tmp <= 9) { | ||||
| 	    *p++ = '0' + tmp; | ||||
| 	} else if (upcase) { | ||||
| 	    *p++ = 'A' + tmp - 10; | ||||
| 	} else { | ||||
| 	    *p++ = 'a' + tmp - 10; | ||||
| 	} | ||||
| 	u /= base; | ||||
|     } while (u != 0); | ||||
|  | ||||
|     if (negFlag) { | ||||
| 	*p++ = '-'; | ||||
|     } | ||||
|  | ||||
|     /* figure out actual length and adjust the maximum length */ | ||||
|     actualLength = p - buf; | ||||
|     if (length < actualLength) length = actualLength; | ||||
|  | ||||
|     /* add padding */ | ||||
|     if (ladjust) { | ||||
| 	padc = ' '; | ||||
|     } | ||||
|     if (negFlag && !ladjust && (padc == '0')) { | ||||
| 	for (i = actualLength-1; i< length-1; i++) buf[i] = padc; | ||||
| 	buf[length -1] = '-'; | ||||
|     } else { | ||||
| 	for (i = actualLength; i< length; i++) buf[i] = padc; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /* prepare to reverse the string */ | ||||
|     { | ||||
| 	int begin = 0; | ||||
| 	int end; | ||||
| 	if (ladjust) { | ||||
| 	    end = actualLength - 1; | ||||
| 	} else { | ||||
| 	    end = length -1; | ||||
| 	} | ||||
|  | ||||
| 	while (end > begin) { | ||||
| 	    char tmp = buf[begin]; | ||||
| 	    buf[begin] = buf[end]; | ||||
| 	    buf[end] = tmp; | ||||
| 	    begin ++; | ||||
| 	    end --; | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|     /* adjust the string pointer */ | ||||
|     return length; | ||||
| } | ||||
|  | ||||
| static void printf_output(void *arg, char *s, int l) | ||||
| { | ||||
|     int i; | ||||
|  | ||||
|     // special termination call | ||||
|     if ((l==1) && (s[0] == '\0')) return; | ||||
|  | ||||
|     for (i=0; i< l; i++) { | ||||
| 	board_putc(s[i]); | ||||
| 	if (s[i] == '\n') board_putc('\r'); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void printf(char *fmt, ...) | ||||
| { | ||||
|     va_list ap; | ||||
|     va_start(ap, fmt); | ||||
|     lp_Print(printf_output, 0, fmt, ap); | ||||
|     va_end(ap); | ||||
| } | ||||
							
								
								
									
										13
									
								
								target/linux/bmips/image/lzma-loader/src/printf.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								target/linux/bmips/image/lzma-loader/src/printf.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
| /* | ||||
|  * Copyright (C) 2001 MontaVista Software Inc. | ||||
|  * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net | ||||
|  */ | ||||
|  | ||||
| #ifndef _printf_h_ | ||||
| #define _printf_h_ | ||||
|  | ||||
| #include <stdarg.h> | ||||
| void printf(char *fmt, ...); | ||||
|  | ||||
| #endif /* _printf_h_ */ | ||||
		Reference in New Issue
	
	Block a user
	 domenico
					domenico