Hi,
again two patches.

20090424-3-selfboot-shuffle.patch moves decompression further down the code 
flow, so that - where possible - code is decompressed directly to the right 
place (instead of copying around, as before). 
The downside of this approach is that it's not possible (without API changes 
to the decompressors) to put partial segments into bounce buffers. So if a 
segment collides with coreboot _and_ is compressed, it's bounced entirely.
But, this only brings back the copy we already had before, so the new worst 
case is better than the average before.

It also fixes handling of compressed segments, but I'm too tired to split them 
into separate patches, sorry.

20090424-4-activate-cbfs-payload-compression.patch enables cbfs payload 
compression (the "l" flag) if payloads are supposed to be compressed (with 
lzma only, as cbfstool lacks nrv2b compression support)

as usual,
Signed-off-by: Patrick Georgi <[email protected]>


Patrick
Index: src/boot/selfboot.c
===================================================================
--- src/boot/selfboot.c	(Revision 4204)
+++ src/boot/selfboot.c	(Arbeitskopie)
@@ -55,6 +55,7 @@
 	unsigned long s_srcaddr;
 	unsigned long s_memsz;
 	unsigned long s_filesz;
+	int compression;
 };
 
 struct verify_callback {
@@ -70,54 +71,6 @@
 	unsigned short ip_checksum;
 };
 
-int cbfs_self_decompress(int algo, void *src,struct segment *new)
-{
-	u8 *dst;
-
-	/* for uncompressed, it's easy: just point at the area in ROM */
-	if (algo ==  CBFS_COMPRESS_NONE) {
-		new->s_srcaddr = (u32) src;
-		new->s_filesz =  new->s_memsz;
-		return 0;
-	}
-
-	/* for compression, let's keep it simple. We'll malloc the destination 
-	 * area and decompress to there. The compression overhead far outweighs
-	 * any overhead for an extra copy. 
-	 */
-	dst = malloc(new->s_memsz);
-	if (! dst)
-		return -1;
-
-	switch(algo) {
-#if CONFIG_COMPRESSED_PAYLOAD_LZMA==1
-	case CBFS_COMPRESS_LZMA: {
-		unsigned long ulzma(unsigned char *src, unsigned char *dst);		
-		ulzma(src, dst);
-		break;
-	}
-#endif
-
-#if CONFIG_COMPRESSED_PAYLOAD_NRV2B==1
-	case CBFS_COMPRESS_NRV2B: {
-		unsigned long unrv2b(u8 *src, u8 *dst, unsigned long *ilen_p);
-		unsigned long tmp;
-		unrv2b(src, dst, &tmp);
-		break;
-	}
-#endif
-	default:
-		printk_info( "CBFS:  Unknown compression type %d\n",
-		       algo);
-		return -1;
-	}
-
-	new->s_srcaddr = (u32) dst;
-	new->s_filesz =  new->s_memsz;
-	return 0;
-	
-}
-
 /* The problem:  
  * Static executables all want to share the same addresses
  * in memory because only a few addresses are reliably present on
@@ -249,6 +202,7 @@
 	printk_spew("segment: [0x%016lx, 0x%016lx, 0x%016lx)\n", 
 		start, middle, end);
 
+    if (seg->compression == CBFS_COMPRESS_NONE) {
 	/* Slice off a piece at the beginning
 	 * that doesn't conflict with coreboot.
 	 */
@@ -326,6 +280,7 @@
 			new->s_dstaddr + new->s_memsz);
 		
 	}
+    }
 	/* Now retarget this segment onto the bounce buffer */
 	/* sort of explanation: the buffer is a 1:1 mapping to coreboot. 
 	 * so you will make the dstaddr be this buffer, and it will get copied
@@ -371,15 +326,11 @@
 		new = malloc(sizeof(*new));
 		new->s_dstaddr = ntohl((u32) segment->load_addr);
 		new->s_memsz = ntohl(segment->mem_len);
+		new->compression = ntohl(segment->compression);
 
 		datasize = ntohl(segment->len);
-		/* figure out decompression, do it, get pointer to the area */
-		if (cbfs_self_decompress(ntohl(segment->compression),
-					     ((unsigned char *) first_segment) +
-					     ntohl(segment->offset), new)) {
-			printk_emerg("cbfs_self_decompress failed\n");
-			return;
-		}
+		new->s_srcaddr = (u32) ((unsigned char *) first_segment) + ntohl(segment->offset);
+		new->s_filesz = ntohl(segment->len);
 		printk_debug("New segment dstaddr 0x%lx memsize 0x%lx srcaddr 0x%lx filesize 0x%lx\n",
 			new->s_dstaddr, new->s_memsz, new->s_srcaddr, new->s_filesz);
 		/* Clean up the values */
@@ -449,23 +400,47 @@
 		
 		/* Compute the boundaries of the segment */
 		dest = (unsigned char *)(ptr->s_dstaddr);
-		end = dest + ptr->s_memsz;
-		middle = dest + ptr->s_filesz;
 		src = ptr->s_srcaddr;
-		printk_spew("[ 0x%016lx, %016lx, 0x%016lx) <- %016lx\n",
-			(unsigned long)dest,
-			(unsigned long)middle,
-			(unsigned long)end,
-			(unsigned long)src);
 		
 		/* Copy data from the initial buffer */
 		if (ptr->s_filesz) {
 			size_t len;
 			len = ptr->s_filesz;
-			memcpy(dest, src, len);
-			dest += len;
+			switch(ptr->compression) {
+#if CONFIG_COMPRESSED_PAYLOAD_LZMA==1
+				case CBFS_COMPRESS_LZMA: {
+					printk_debug("using LZMA\n");
+					unsigned long ulzma(unsigned char *src, unsigned char *dst);		
+					len = ulzma(src, dest);
+					break;
+				}
+#endif
+#if CONFIG_COMPRESSED_PAYLOAD_NRV2B==1
+				case CBFS_COMPRESS_NRV2B: {
+					printk_debug("using NRV2B\n");
+					unsigned long unrv2b(u8 *src, u8 *dst, unsigned long *ilen_p);
+					unsigned long tmp;
+					len = unrv2b(src, dest, &tmp);
+					break;
+				}
+#endif
+				case CBFS_COMPRESS_NONE: {
+					printk_debug("it's not compressed!\n");
+					memcpy(dest, src, len);
+					break;
+				}
+				default:
+					printk_info( "CBFS:  Unknown compression type %d\n", ptr->compression);
+					return -1;
+			}
+			end = dest + ptr->s_memsz;
+			middle = dest + len;
+			printk_spew("[ 0x%016lx, %016lx, 0x%016lx) <- %016lx\n",
+				(unsigned long)dest,
+				(unsigned long)middle,
+				(unsigned long)end,
+				(unsigned long)src);
 		}
-		
 		/* Zero the extra bytes between middle & end */
 		if (middle < end) {
 			printk_debug("Clearing Segment: addr: 0x%016lx memsz: 0x%016lx\n",
Index: util/newconfig/config.g
===================================================================
--- util/newconfig/config.g	(Revision 4204)
+++ util/newconfig/config.g	(Arbeitskopie)
@@ -2293,6 +2293,8 @@
 	file.write("\trm -f romcc*\n\n")
 
 	file.write("ifeq \"$(CONFIG_CBFS)\" \"1\"\n\n")
+	file.write("CBFS_COMPRESS_FLAG:=\n")
+	file.write("ifeq \"$(CONFIG_COMPRESSED_PAYLOAD_LZMA)\" \"1\"\nCBFS_COMPRESS_FLAG:=l\nendif\n\n")
 
 	for i in buildroms:
 		file.write("%s: cbfstool" %(i.name))
@@ -2316,7 +2318,7 @@
 		for j in i.roms:
 			#failover is a hack that will go away soon. 
 			if (j != "failover") and (rommapping[j] != "/dev/null"):
-				file.write("\t./cbfstool %s add-payload %s %s/payload\n" % (i.name, rommapping[j], j,))
+				file.write("\t./cbfstool %s add-payload %s %s/payload $(CBFS_COMPRESS_FLAG)\n" % (i.name, rommapping[j], j,))
 		file.write("\t./cbfstool %s print\n" % i.name)
 		file.write("\n")
 	file.write("else\n\n")
-- 
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to