memtest86+: rewrite popup popdown popclear

Update the popup / popdown patch:
- Fix a copy/paste error for POP_SAVE_BUFFER_2 - it was a copy of
POP_SAVE_BUFFER_1, and needs to be updated for the new dimensions.
- SPD doesn't need any special popup/popdown now.

This is from a patch that was posted in the memtest86+ forum:

From: Maxime de Roucy <maxime.deroucy@gmail.com>
Date: Sun, 27 Sep 2015 15:33:34 +0200
Subject: [PATCH 7/8] rewrite popup popdown popclear

merge popup and pop2up
merge popdown and pop2down
merge popclear and pop2clear

"It merge popup and pop2up, popdown and pop2down, popclear and
pop2clear. So when you change popup you don't have to change
pop2up anymoreā€¦ it's less risky."

Change-Id: I0b79c2f78ae43f3d178d96bb21ab7661358d859f
Signed-off-by: Martin Roth <martinroth@google.com>
Reviewed-on: https://review.coreboot.org/14176
Tested-by: build bot (Jenkins)
Reviewed-by: Ben Gardner <gardner.ben@gmail.com>
Reviewed-by: Werner Zeh <werner.zeh@siemens.com>
diff --git a/config.c b/config.c
index 0f25165..55ed52e 100644
--- a/config.c
+++ b/config.c
@@ -25,8 +25,9 @@
 
 extern void get_list(int x, int y, int len, char *buf);
 
-char save[2][POP_H][POP_W];
-char save2[2][POP2_H][POP2_W];
+/* declared in test.h */
+char pop_save_buffer_1[2][POP_H][POP_W];
+char pop_save_buffer_2[2][POP2_H][POP2_W];
 
 void get_config()
 {
@@ -35,7 +36,7 @@
 	char cp[64];
 	ulong page;
 
-	popup();
+	popup(POP_SAVE_BUFFER_1);
 	wait_keyup();
 	while (!flag) {
 		cprint(POP_Y+1,  POP_X+2, "Settings:");
@@ -54,7 +55,7 @@
 		switch (get_key()) {
 		case 2:
 			/* 1 - Test Selection */
-			popclear();
+			popclear(POP_SAVE_BUFFER_1);
 			cprint(POP_Y+1, POP_X+2, "Test Selection:");
 			cprint(POP_Y+3, POP_X+6, "(1) Default Tests");
 			cprint(POP_Y+4, POP_X+6, "(2) Skip Current Test");
@@ -86,7 +87,7 @@
 					break;
 				case 4:
 					/* Select test */
-					popclear();
+					popclear(POP_SAVE_BUFFER_1);
 					cprint(POP_Y+1, POP_X+3,
 					       "Test Selection:");
 					cprint(POP_Y+4, POP_X+5,
@@ -110,7 +111,7 @@
 					break;
 				case 5:
 					/* Enter a test list */
-					popclear();
+					popclear(POP_SAVE_BUFFER_1);
 					cprint(POP_Y+1, POP_X+3,
 					       "Enter a comma separated list");
 					cprint(POP_Y+2, POP_X+3,
@@ -168,11 +169,11 @@
 					break;
 				}
 			}
-			popclear();
+			popclear(POP_SAVE_BUFFER_1);
 			break;
 		case 3:
 			/* 2 - Address Range */
-			popclear();
+			popclear(POP_SAVE_BUFFER_1);
 			cprint(POP_Y+1, POP_X+2, "Test Address Range:");
 			cprint(POP_Y+3, POP_X+6, "(1) Set Lower Limit");
 			cprint(POP_Y+4, POP_X+6, "(2) Set Upper Limit");
@@ -183,7 +184,7 @@
 				switch (get_key()) {
 				case 2:
 					/* Lower Limit */
-					popclear();
+					popclear(POP_SAVE_BUFFER_1);
 					cprint(POP_Y+2, POP_X+4,
 					       "Lower Limit: ");
 					cprint(POP_Y+4, POP_X+4,
@@ -204,7 +205,7 @@
 					break;
 				case 3:
 					/* Upper Limit */
-					popclear();
+					popclear(POP_SAVE_BUFFER_1);
 					cprint(POP_Y+2, POP_X+4,
 					       "Upper Limit: ");
 					cprint(POP_Y+4, POP_X+4,
@@ -242,11 +243,11 @@
 					break;
 				}
 			}
-			popclear();
+			popclear(POP_SAVE_BUFFER_1);
 			break;
 		case 4:
 			/* Error Mode */
-			popclear();
+			popclear(POP_SAVE_BUFFER_1);
 			cprint(POP_Y+1, POP_X+2, "Printing Mode:");
 			cprint(POP_Y+3, POP_X+6, "(1) Error Summary");
 			cprint(POP_Y+4, POP_X+6, "(2) Individual Errors");
@@ -299,12 +300,12 @@
 					break;
 				}
 			}
-			popclear();
+			popclear(POP_SAVE_BUFFER_1);
 			break;
 		case 5:
 			/* CPU Mode */
 			reprint_screen = 1;
-			popclear();
+			popclear(POP_SAVE_BUFFER_1);
 			cprint(POP_Y+1, POP_X+2, "CPU Selection Mode:");
 			cprint(POP_Y+3, POP_X+6, "(1) Parallel (All)");
 			cprint(POP_Y+4, POP_X+6, "(2) Round Robin (RRb)");
@@ -318,25 +319,25 @@
 					if (cpu_mode != CPM_ALL) bail++;
 					cpu_mode = CPM_ALL;
 					sflag++;
-					popdown();
+					popdown(POP_SAVE_BUFFER_1);
 					cprint(9, 34, "All");
-					popup();
+					popup(POP_SAVE_BUFFER_1);
 					break;
 				case 3:
 					if (cpu_mode != CPM_RROBIN) bail++;
 					cpu_mode = CPM_RROBIN;
 					sflag++;
-					popdown();
+					popdown(POP_SAVE_BUFFER_1);
 					cprint(9, 34, "RRb");
-					popup();
+					popup(POP_SAVE_BUFFER_1);
 					break;
 				case 4:
 					if (cpu_mode != CPM_SEQ) bail++;
 					cpu_mode = CPM_SEQ;
 					sflag++;
-					popdown();
+					popdown(POP_SAVE_BUFFER_1);
 					cprint(9, 34, "Seq");
-					popup();
+					popup(POP_SAVE_BUFFER_1);
 					break;
 				case 11:
 				case 57:
@@ -345,7 +346,7 @@
 					break;
 				}
 			}
-			popclear();
+			popclear(POP_SAVE_BUFFER_1);
 			break;
 		case 6:
 			reprint_screen = 1;
@@ -353,15 +354,15 @@
 			break;
 		case 7:
 			/* Display DMI Memory Info */
-			pop2up();
+			popup(POP_SAVE_BUFFER_2);
 			print_dmi_info();
-			pop2down();
+			popdown(POP_SAVE_BUFFER_2);
 			break;
 		case 8:
 			/* Display SPD Data */
-			popdown();
+			popup(POP_SAVE_BUFFER_2);
 			show_spd();
-			popup();
+			popdown(POP_SAVE_BUFFER_2);
 			sflag++;
 			break;
 		case 11:
@@ -372,7 +373,7 @@
 			break;
 		}
 	}
-	popdown();
+	popdown(POP_SAVE_BUFFER_1);
 	if (prt) {
 		printpatn();
 	}
@@ -381,108 +382,67 @@
 	}
 }
 
-void popup()
+void popup(int pop_x, int pop_y, int pop_h, int pop_w, char pop_save_buffer[2][pop_h][pop_w])
 {
 	int i, j;
 	char *pp;
 
-	for (i=POP_Y; i<POP_Y + POP_H; i++) {
-		for (j=POP_X; j<POP_X + POP_W; j++) {
+	for (i = pop_y; i < pop_y + pop_h; i++) {
+		for (j = pop_x; j < pop_x + pop_w; j++) {
+			/* Point to the write position in the screen */
 			pp = (char *)(SCREEN_ADR + (i * 160) + (j * 2));
-			save[0][i-POP_Y][j-POP_X] = *pp;  /* Save screen */
-			set_scrn_buf(i, j, ' ');
-			*pp = ' ';              /* Clear */
+
+			/* pp and get_scrn_buf(i,j) should be equal here
+			 * except on board that don't have screen (e.g. only serial port)
+			 * that's why we save the screen buffer:
+			 * save screen buffer */
+			pop_save_buffer[0][i - pop_y][j - pop_x] = get_scrn_buf(i, j);
+			*pp = ' ';               /* Clear screen */
+			set_scrn_buf(i, j, ' '); /* Clear screen buffer */
 			pp++;
-			save[1][i-POP_Y][j-POP_X] = *pp;
-			*pp = 0x07;             /* Change Background to black */
+			pop_save_buffer[1][i - pop_y][j - pop_x] = *pp; /* Save screen background color */
+			*pp = 0x07;             /* Change screen Background to black */
 		}
 	}
-	tty_print_region(POP_Y, POP_X, POP_Y+POP_H, POP_X+POP_W);
+	/* print the screen buffer in the serial console */
+	tty_print_region(pop_y, pop_x, pop_y+pop_h, pop_x+pop_w);
 }
 
-void popdown()
+void popdown(int pop_x, int pop_y, int pop_h, int pop_w, char pop_save_buffer[2][pop_h][pop_w])
 {
 	int i, j;
 	char *pp;
 
-	for (i=POP_Y; i<POP_Y + POP_H; i++) {
-		for (j=POP_X; j<POP_X + POP_W; j++) {
+	for (i = pop_y; i < pop_y + pop_h; i++) {
+		for (j = pop_x; j < pop_x + pop_w; j++) {
+			/* Point to the write position in the screen */
 			pp = (char *)(SCREEN_ADR + (i * 160) + (j * 2));
-			*pp = save[0][i-POP_Y][j-POP_X]; /* Restore screen */
-			set_scrn_buf(i, j, save[0][i-POP_Y][j-POP_X]);
+			*pp = pop_save_buffer[0][i-pop_y][j-pop_x]; /* Restore screen */
+			set_scrn_buf(i, j, pop_save_buffer[0][i - pop_y][j - pop_x]); /* Restore the screen buffer*/
 			pp++;
-			*pp = save[1][i-POP_Y][j-POP_X]; /* Restore color */
+			*pp = pop_save_buffer[1][i - pop_y][j - pop_x]; /* Restore screen color */
 		}
 	}
-	tty_print_region(POP_Y, POP_X, POP_Y+POP_H, POP_X+POP_W);
+	/* print the screen buffer in the serial console */
+	tty_print_region(pop_y, pop_x, pop_y+pop_h, pop_x+pop_w);
 }
 
-void popclear()
+void popclear(int pop_x, int pop_y, int pop_h, int pop_w, char pop_save_buffer[2][pop_h][pop_w])
 {
 	int i, j;
 	char *pp;
 
-	for (i=POP_Y; i<POP_Y + POP_H; i++) {
-		for (j=POP_X; j<POP_X + POP_W; j++) {
+	for (i = pop_y; i < pop_y + pop_h; i++) {
+		for (j  =pop_x; j < pop_x + pop_w; j++) {
+			/* Point to the write position in the screen */
 			pp = (char *)(SCREEN_ADR + (i * 160) + (j * 2));
-			*pp = ' ';              /* Clear popup */
-			set_scrn_buf(i, j, ' ');
+			*pp = ' ';               /* Clear screen */
+			set_scrn_buf(i, j, ' '); /* Clear screen buffer */
 			pp++;
 		}
 	}
-	tty_print_region(POP_Y, POP_X, POP_Y+POP_H, POP_X+POP_W);
-}
-
-void pop2up()
-{
-	int i, j;
-	char *pp;
-
-	for (i=POP2_Y; i<POP2_Y + POP2_H; i++) {
-		for (j=POP2_X; j<POP2_X + POP2_W; j++) {
-			pp = (char *)(SCREEN_ADR + (i * 160) + (j * 2));
-			save2[0][i-POP2_Y][j-POP2_X] = *pp;  /* Save screen */
-			set_scrn_buf(i, j, ' ');
-			*pp = ' ';              /* Clear */
-			pp++;
-			save2[1][i-POP2_Y][j-POP2_X] = *pp;
-			*pp = 0x07;             /* Change Background to black */
-		}
-	}
-	tty_print_region(POP2_Y, POP2_X, POP2_Y+POP2_H, POP2_X+POP2_W);
-}
-
-void pop2down()
-{
-	int i, j;
-	char *pp;
-
-	for (i=POP2_Y; i<POP2_Y + POP2_H; i++) {
-		for (j=POP2_X; j<POP2_X + POP2_W; j++) {
-			pp = (char *)(SCREEN_ADR + (i * 160) + (j * 2));
-			*pp = save2[0][i-POP2_Y][j-POP2_X]; /* Restore screen */
-			set_scrn_buf(i, j, save2[0][i-POP2_Y][j-POP2_X]);
-			pp++;
-			*pp = save2[1][i-POP2_Y][j-POP2_X]; /* Restore color */
-		}
-	}
-	tty_print_region(POP2_Y, POP2_X, POP2_Y+POP2_H, POP2_X+POP2_W);
-}
-
-void pop2clear()
-{
-	int i, j;
-	char *pp;
-
-	for (i=POP2_Y; i<POP2_Y + POP2_H; i++) {
-		for (j=POP2_X; j<POP2_X + POP2_W; j++) {
-			pp = (char *)(SCREEN_ADR + (i * 160) + (j * 2));
-			*pp = ' ';              /* Clear popup */
-			set_scrn_buf(i, j, ' ');
-			pp++;
-		}
-	}
-	tty_print_region(POP2_Y, POP2_X, POP2_Y+POP2_H, POP2_X+POP2_W);
+	/* print the screen buffer in the serial console */
+	tty_print_region(pop_y, pop_x, pop_y+pop_h, pop_x+pop_w);
 }
 
 void adj_mem(void)
diff --git a/dmi.c b/dmi.c
index 9f781c1..b90067f 100644
--- a/dmi.c
+++ b/dmi.c
@@ -298,7 +298,7 @@
 	}
 
 	for(page=1; page <= 1 + (mem_devs_count-1)/8; page++){
-		pop2clear();
+		popclear(POP_SAVE_BUFFER_2);
 		cprint(POP2_Y+1, POP2_X+2, "DMI Memory Device Info  (page ");
 		itoa(string,page);
 		cprint(POP2_Y+1, POP2_X+32, string);
diff --git a/lib.c b/lib.c
index fb285bd..a34fefa 100644
--- a/lib.c
+++ b/lib.c
@@ -648,7 +648,8 @@
 			break;
 		case 0x26:
 			/* ^L/L - redraw the display */
-			tty_print_screen();
+		        clear_screen_buf();
+			tty_print_region(0, 0, 80, 100);
 			break;
 		}
 	}
diff --git a/spd.c b/spd.c
index 2e14e7c..d88069b 100644
--- a/spd.c
+++ b/spd.c
@@ -389,14 +389,12 @@
     int index;
     int i, j;
     int flag = 0;
-    pop2up();
     wait_keyup();
     index = find_smb_controller();
     if (index == -1) {
 	cprint(POP2_Y, POP2_X+1, "SMBus Controller not known");
 	while (!get_key());
 	wait_keyup();
-	pop2down();
 	return;
     }
     else cprint(POP2_Y, POP2_X+1, "SPD Data: Slot");
@@ -414,7 +412,6 @@
 	    wait_keyup();
 	}
     }
-    pop2down();
 }
 
 int get_ddr3_module_size(int sdram_capacity, int prim_bus_width, int sdram_width, int ranks)
diff --git a/test.h b/test.h
index b6bf9ac..cd091d7 100644
--- a/test.h
+++ b/test.h
@@ -149,12 +149,13 @@
 void footer(void);
 void scroll(void);
 void clear_scroll(void);
-void popup(void);
-void popdown(void);
-void popclear(void);
-void pop2up(void);
-void pop2down(void);
-void pop2clear(void);
+extern char pop_save_buffer_1[2][POP_H][POP_W];
+extern char pop_save_buffer_2[2][POP2_H][POP2_W];
+#define POP_SAVE_BUFFER_1 POP_X, POP_Y, POP_H, POP_W, pop_save_buffer_1
+#define POP_SAVE_BUFFER_2 POP2_X, POP2_Y, POP2_H, POP2_W, pop_save_buffer_2
+void popup(int pop_x, int pop_y, int pop_h, int pop_w, char pop_save_buffer[2][pop_h][pop_w]);
+void popdown(int pop_x, int pop_y, int pop_h, int pop_w, char pop_save_buffer[2][pop_h][pop_w]);
+void popclear(int pop_x, int pop_y, int pop_h, int pop_w, char pop_save_buffer[2][pop_h][pop_w]);
 void get_config(void);
 void get_menu(void);
 void get_printmode(void);