mirror of
				https://xff.cz/git/u-boot/
				synced 2025-10-31 10:26:10 +01:00 
			
		
		
		
	Adapt log buffer code to support Linux 2.6
A new environment variable, "logversion", selects the log buffer behaviour. If it is not set or set to a value other than 2, then the old, Linux 2.4.4, behaviour is selected. Signed-off-by: Igor Lisitsin <igor@emcraft.com> --
This commit is contained in:
		
				
					committed by
					
						 Wolfgang Denk
						Wolfgang Denk
					
				
			
			
				
	
			
			
			
						parent
						
							a11e06965e
						
					
				
				
					commit
					2dc64451b4
				
			
							
								
								
									
										114
									
								
								common/cmd_log.c
									
									
									
									
									
								
							
							
						
						
									
										114
									
								
								common/cmd_log.c
									
									
									
									
									
								
							| @@ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * (C) Copyright 2002 | ||||
|  * (C) Copyright 2002-2007 | ||||
|  * Detlev Zundel, DENX Software Engineering, dzu@denx.de. | ||||
|  * | ||||
|  * Code used from linux/kernel/printk.c | ||||
| @@ -60,45 +60,40 @@ static char buf[1024]; | ||||
| /* This combination will not print messages with the default loglevel */ | ||||
| static unsigned console_loglevel = 3; | ||||
| static unsigned default_message_loglevel = 4; | ||||
| static unsigned char *log_buf = NULL; | ||||
| static unsigned long *ext_log_size; | ||||
| static unsigned long *ext_log_start; | ||||
| static unsigned long *ext_logged_chars; | ||||
| #define log_size (*ext_log_size) | ||||
| #define log_start (*ext_log_start) | ||||
| #define logged_chars (*ext_logged_chars) | ||||
| static unsigned log_version = 1; | ||||
| static logbuff_t *log; | ||||
|  | ||||
| /* Forced by code, eh! */ | ||||
| #define LOGBUFF_MAGIC 0xc0de4ced | ||||
|  | ||||
| /* The mapping used here has to be the same as in setup_ext_logbuff () | ||||
|    in linux/kernel/printk */ | ||||
| void logbuff_init_ptrs (void) | ||||
| { | ||||
| 	unsigned long *ext_tag; | ||||
| 	unsigned long post_word; | ||||
| 	unsigned long tag, post_word; | ||||
| 	char *s; | ||||
|  | ||||
| 	log_buf = (unsigned char *)(gd->bd->bi_memsize-LOGBUFF_LEN); | ||||
| 	ext_tag = (unsigned long *)(log_buf)-4; | ||||
|  	ext_log_start = (unsigned long *)(log_buf)-3; | ||||
| 	ext_log_size = (unsigned long *)(log_buf)-2; | ||||
| 	ext_logged_chars = (unsigned long *)(log_buf)-1; | ||||
| 	log = (logbuff_t *)(gd->bd->bi_memsize-LOGBUFF_LEN) - 1; | ||||
|  | ||||
| 	/* Set up log version */ | ||||
| 	if ((s = getenv ("logversion")) != NULL) | ||||
| 		log_version = (int)simple_strtoul (s, NULL, 10); | ||||
|  | ||||
| 	if (log_version == 2) | ||||
| 		tag = log->v2.tag; | ||||
| 	else | ||||
| 		tag = log->v1.tag; | ||||
| 	post_word = post_word_load(); | ||||
| #ifdef CONFIG_POST | ||||
| 	/* The post routines have setup the word so we can simply test it */ | ||||
|  	if (post_word_load () & POST_COLDBOOT) { | ||||
|  		logged_chars = log_size = log_start = 0; | ||||
| 		*ext_tag = LOGBUFF_MAGIC; | ||||
| 	if (tag != LOGBUFF_MAGIC || (post_word & POST_COLDBOOT)) { | ||||
| 		logbuff_reset (); | ||||
|  	} | ||||
| #else | ||||
| 	/* No post routines, so we do our own checking                    */ | ||||
|  	if (post_word != LOGBUFF_MAGIC) { | ||||
|  		logged_chars = log_size = log_start = 0; | ||||
| 	if (tag != LOGBUFF_MAGIC || post_word != LOGBUFF_MAGIC) { | ||||
| 		logbuff_reset (); | ||||
| 		post_word_store (LOGBUFF_MAGIC); | ||||
| 		*ext_tag = LOGBUFF_MAGIC; | ||||
|  	} | ||||
| #endif | ||||
| 	if (log_version == 2 && (long)log->v2.start > (long)log->v2.con) | ||||
| 		log->v2.start = log->v2.con; | ||||
|  | ||||
| 	/* Initialize default loglevel if present */ | ||||
| 	if ((s = getenv ("loglevel")) != NULL) | ||||
| 		console_loglevel = (int)simple_strtoul (s, NULL, 10); | ||||
| @@ -106,6 +101,15 @@ void logbuff_init_ptrs (void) | ||||
| 	gd->post_log_word |= LOGBUFF_INITIALIZED; | ||||
| } | ||||
|  | ||||
| void logbuff_reset (void) | ||||
| { | ||||
| 	memset (log, 0, sizeof (logbuff_t)); | ||||
| 	if (log_version == 2) | ||||
| 		log->v2.tag = LOGBUFF_MAGIC; | ||||
| 	else | ||||
| 		log->v1.tag = LOGBUFF_MAGIC; | ||||
| } | ||||
|  | ||||
| int drv_logbuff_init (void) | ||||
| { | ||||
| 	device_t logdev; | ||||
| @@ -162,7 +166,7 @@ void logbuff_log(char *msg) | ||||
| int do_log (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | ||||
| { | ||||
| 	char *s; | ||||
| 	unsigned long i; | ||||
| 	unsigned long i, start, size; | ||||
|  | ||||
| 	if (strcmp(argv[1],"append") == 0) { | ||||
| 		/* Log concatenation of all arguments separated by spaces */ | ||||
| @@ -177,21 +181,34 @@ int do_log (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | ||||
|  | ||||
| 	case 2: | ||||
| 		if (strcmp(argv[1],"show") == 0) { | ||||
| 			for (i=0; i < (log_size&LOGBUFF_MASK); i++) { | ||||
| 				s = (char *)log_buf+((log_start+i)&LOGBUFF_MASK); | ||||
| 			if (log_version == 2) { | ||||
| 				start = log->v2.start; | ||||
| 				size = log->v2.end - log->v2.start; | ||||
| 			} | ||||
| 			else { | ||||
| 				start = log->v1.start; | ||||
| 				size = log->v1.size; | ||||
| 			} | ||||
| 			for (i=0; i < (size&LOGBUFF_MASK); i++) { | ||||
| 				s = (char *)log->buf+((start+i)&LOGBUFF_MASK); | ||||
| 				putc (*s); | ||||
| 			} | ||||
| 			return 0; | ||||
| 		} else if (strcmp(argv[1],"reset") == 0) { | ||||
| 			log_start    = 0; | ||||
| 			log_size     = 0; | ||||
| 			logged_chars = 0; | ||||
| 			logbuff_reset (); | ||||
| 			return 0; | ||||
| 		} else if (strcmp(argv[1],"info") == 0) { | ||||
| 			printf ("Logbuffer   at  %08lx\n", (unsigned long)log_buf); | ||||
| 			printf ("log_start    =  %08lx\n", log_start); | ||||
| 			printf ("log_size     =  %08lx\n", log_size); | ||||
| 			printf ("logged_chars =  %08lx\n", logged_chars); | ||||
| 			printf ("Logbuffer   at  %08lx\n", (unsigned long)log->buf); | ||||
| 			if (log_version == 2) { | ||||
| 				printf ("log_start    =  %08lx\n", log->v2.start); | ||||
| 				printf ("log_end      =  %08lx\n", log->v2.end); | ||||
| 				printf ("logged_chars =  %08lx\n", log->v2.chars); | ||||
| 			} | ||||
| 			else { | ||||
| 				printf ("log_start    =  %08lx\n", log->v1.start); | ||||
| 				printf ("log_size     =  %08lx\n", log->v1.size); | ||||
| 				printf ("logged_chars =  %08lx\n", log->v1.chars); | ||||
| 			} | ||||
| 			return 0; | ||||
| 		} | ||||
| 		printf ("Usage:\n%s\n", cmdtp->usage); | ||||
| @@ -202,7 +219,7 @@ int do_log (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | ||||
| 		return 1; | ||||
| 	} | ||||
| } | ||||
| #if defined(CONFIG_LOGBUFFER) | ||||
|  | ||||
| U_BOOT_CMD( | ||||
| 	log,     255,	1,	do_log, | ||||
| 	"log     - manipulate logbuffer\n", | ||||
| @@ -211,7 +228,7 @@ U_BOOT_CMD( | ||||
| 	"log show   - show contents\n" | ||||
| 	"log append <msg> - append <msg> to the logbuffer\n" | ||||
| ); | ||||
| #endif	/* CONFIG_LOGBUFFER */ | ||||
|  | ||||
| static int logbuff_printk(const char *line) | ||||
| { | ||||
| 	int i; | ||||
| @@ -241,13 +258,22 @@ static int logbuff_printk(const char *line) | ||||
| 		} | ||||
| 		line_feed = 0; | ||||
| 		for (; p < buf_end; p++) { | ||||
| 			log_buf[(log_start+log_size) & LOGBUFF_MASK] = *p; | ||||
| 			if (log_size < LOGBUFF_LEN) | ||||
| 				log_size++; | ||||
| 			if (log_version == 2) { | ||||
| 				log->buf[log->v2.end & LOGBUFF_MASK] = *p; | ||||
| 				log->v2.end++; | ||||
| 				if (log->v2.end - log->v2.start > LOGBUFF_LEN) | ||||
| 					log->v2.start++; | ||||
| 				log->v2.chars++; | ||||
| 			} | ||||
| 			else { | ||||
| 				log->buf[(log->v1.start + log->v1.size) & | ||||
| 					 LOGBUFF_MASK] = *p; | ||||
| 				if (log->v1.size < LOGBUFF_LEN) | ||||
| 					log->v1.size++; | ||||
| 				else | ||||
| 				log_start++; | ||||
|  | ||||
| 			logged_chars++; | ||||
| 					log->v1.start++; | ||||
| 				log->v1.chars++; | ||||
| 			} | ||||
| 			if (*p == '\n') { | ||||
| 				line_feed = 1; | ||||
| 				break; | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * (C) Copyright 2002 | ||||
|  * (C) Copyright 2002-2007 | ||||
|  * Detlev Zundel, dzu@denx.de. | ||||
|  * | ||||
|  * See file CREDITS for list of people who contributed to this | ||||
| @@ -25,6 +25,7 @@ | ||||
|  | ||||
| #ifdef CONFIG_LOGBUFFER | ||||
|  | ||||
| #define LOGBUFF_MAGIC	0xc0de4ced	/* Forced by code, eh!	*/ | ||||
| #define LOGBUFF_LEN	(16384)	/* Must be 16k right now */ | ||||
| #define LOGBUFF_MASK	(LOGBUFF_LEN-1) | ||||
| #define LOGBUFF_OVERHEAD (4096) /* Logbuffer overhead for extra info */ | ||||
| @@ -32,6 +33,29 @@ | ||||
|  | ||||
| #define LOGBUFF_INITIALIZED	(1<<31) | ||||
|  | ||||
| /* The mapping used here has to be the same as in setup_ext_logbuff () | ||||
|    in linux/kernel/printk */ | ||||
|  | ||||
| typedef struct { | ||||
| 	union { | ||||
| 		struct { | ||||
| 			unsigned long	tag; | ||||
| 			unsigned long	start; | ||||
| 			unsigned long	con; | ||||
| 			unsigned long	end; | ||||
| 			unsigned long	chars; | ||||
| 		} v2; | ||||
| 		struct { | ||||
| 			unsigned long	dummy; | ||||
| 			unsigned long	tag; | ||||
| 			unsigned long	start; | ||||
| 			unsigned long	size; | ||||
| 			unsigned long	chars; | ||||
| 		} v1; | ||||
| 	}; | ||||
| 	unsigned char	buf[0]; | ||||
| } logbuff_t; | ||||
|  | ||||
| int drv_logbuff_init (void); | ||||
| void logbuff_init_ptrs (void); | ||||
| void logbuff_log(char *msg); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user