? .boot32.c.swp
? boot32.s
Index: boot32.c
===================================================================
RCS file: /cvsroot/src/sys/arch/acorn32/stand/boot32/boot32.c,v
retrieving revision 1.32
diff -u -p -r1.32 boot32.c
--- boot32.c	26 Jan 2008 00:01:54 -0000	1.32
+++ boot32.c	3 Feb 2008 02:21:00 -0000
@@ -83,7 +83,6 @@ int	 first_mapped_PODRAM_page_index;/* o
 
 struct page_info *mem_pages_info;	/* {nr, virt, phys}*		*/
 struct page_info *free_relocation_page;	/* points to the page_info chain*/
-struct page_info *relocate_table_pages;	/* points to seq. relocate info */
 struct page_info *relocate_code_page;	/* points to the copied code	*/
 struct page_info *bconfig_page;		/* page for passing on settings	*/
 
@@ -119,8 +118,6 @@ u_long	 firstpage, lastpage, totalpages;
 /* RISC OS memory		*/
 char	*memory_image, *bottom_memory, *top_memory;
 
-u_long	 videomem_start_ro;		/* for debugging mainly		*/
-
 /* kernel info */
 u_long	 marks[MARK_MAX];		/* loader mark pointers 	*/
 u_long	 kernel_physical_start;		/* where does it get relocated	*/
@@ -146,6 +143,7 @@ int	 page_info_cmp(const void *a, const 
 void	 add_initvectors(void);
 void	 create_configuration(int argc, char **argv, int start_args);
 void	 prepare_and_check_relocation_system(void);
+void	 compact_relocations(void);
 void	 twirl(void);
 int	 vdu_var(int);
 void	 process_args(int argc, char **argv, int *howto, char *file,
@@ -158,7 +156,7 @@ extern void start_kernel(
 		int relocate_code_page,
 		int relocation_pv_offset,
 		int configuration_structure_in_flat_physical_space,
-		int physical_address_of_relocation_tables,
+		int virtual_address_relocation_table,
 		int physical_address_of_new_L1_pages,
 		int kernel_entry_point
 		);	/* asm */
@@ -232,105 +230,56 @@ init_datastructures(void)
 		panic("Can't alloc my initial page tables");
 }
 
-
 void
-prepare_and_check_relocation_system(void)
+compact_relocations(void)
 {
-	int     relocate_size, relocate_pages;
-	int     bank, pages, found;
-	u_long  dst, src, base, destination, extend;
-	u_long *reloc_entry, last_src, length;
-
-	/* set the number of relocation entries in the 1st word */
-	*reloc_instruction_table = reloc_entries;
-
-	/*
-	 * The relocate information needs to be in one sequential physical
-	 * space in order to be able to access it as one stream when the MMU
-	 * is switched off later.
-	 */
-	relocate_size = (reloc_tablesize + nbpp-1) & ~(nbpp-1);  /* round up */
-	printf("\nPreparing for booting %s ... ", booted_file);
-	relocate_pages = relocate_size / nbpp;
-
-	relocate_table_pages = free_relocation_page;
-	pages = 0;
-	while (pages < relocate_pages) {
-		src = (u_long)reloc_instruction_table + pages*nbpp;
-		dst = relocate_table_pages[pages].logical;
-		memcpy((void *)dst, (void *)src, nbpp);
-
-		if (pages < relocate_pages - 1) {
-			/* check if next page is sequential physically */
-			if (relocate_table_pages[pages+1].physical -
-			    relocate_table_pages[pages].physical != nbpp) {
-				/*
-				 * Non contigunous relocate area ->
-				 * try again
-				 */
-				printf("*");
-				relocate_table_pages += pages;
-				pages = 0;
-				continue;	/* while */
-			}
-		}
-		pages++;
-	}
-	free_relocation_page = relocate_table_pages + pages;
-
-	/* copy the relocation code into this page in start_kernel */
-	relocate_code_page = free_relocation_page++;
-
-	/*
-	 * All relocations are pages allocated in one big strict increasing
-	 * physical DRAM address sequence. When the MMU is switched off all
-	 * code and data is in this increasing order but not at the right
-	 * place. This is where the relocation code kicks in; relocation is
-	 * done in flat physical memory without MMU.
-	 */
-
-	printf("shift and check ... ");
-	reloc_entry = reloc_instruction_table + 1;
-	last_src = -1;
+	u_long *reloc_entry, current_length, length;
+	u_long  src, destination, current_src, current_destination;
+	u_long *current_entry;
+
+	current_entry = reloc_entry = reloc_instruction_table + 1;
+
+	/* prime the loop */
+	current_src		= reloc_entry[0];
+	current_destination	= reloc_entry[1];
+	current_length		= reloc_entry[2];
+	
+	reloc_entry += 3;
 	while (reloc_entry < reloc_pos) {
 		src         = reloc_entry[0];
 		destination = reloc_entry[1];
 		length      = reloc_entry[2];
 
-		/* paranoia check */
-		if ((long) (src - last_src) <= 0)
-			printf("relocation sequence challenged -- "
-			    "booting might fail ");
-		last_src = src;
-
-		/* check if its gonna be relocated into (PO)DRAM ! */
-		extend = destination + length;
-		found = 0;
-		for (bank = 0; (bank < dram_blocks) && !found; bank++) {
-			base   = DRAM_addr[bank];
-			found = (destination >= base) &&
-			    (extend <= base + DRAM_pages[bank]*nbpp);
-		}
-		for (bank = 0; (bank < podram_blocks) && !found; bank++) {
-			base = PODRAM_addr[bank];
-			found = (destination >= base) &&
-			    (extend <= base + PODRAM_pages[bank]*nbpp);
+		if (src == (current_src + current_length) &&
+		    destination == (current_destination + current_length)) {
+			/* can merge */
+			current_length += length;
+		} else {
+			/* nothing else to do, so save the length */
+			current_entry[2] = current_length;
+			/* fill in next entry */
+			current_entry += 3;
+			current_src = current_entry[0] = src;
+			current_destination = current_entry[1] = destination;
+			current_length = length;
 		}
-		if (!found || (extend > top_physdram)) {
-			panic("Internal error: relocating range "
-			    "[%lx +%lx => %lx] outside (PO)DRAM banks!",
-			    src, length, destination);
-		}
-
 		reloc_entry += 3;
 	}
-	if (reloc_entry != reloc_pos)
-		panic("Relocation instruction table is corrupted");
-
-	printf("OK!\n");
+	/* save last length */
+	current_entry[2] = current_length;
+	current_entry += 3;
+
+	/* workout new count of entries */
+	length = current_entry - (reloc_instruction_table + 1);
+	printf("Compacted relocations from %d entries to %ld\n",
+		       reloc_entries, length/3);
+
+	/* update table to reflect new size */
+	reloc_entries = length/3;
+	reloc_instruction_table[0] = length/3;
+	reloc_pos = current_entry;
 }
 
-
 void
 get_memory_configuration(void)
 {
@@ -506,8 +455,6 @@ get_memory_configuration(void)
 		panic("Top is not not aligned on a Mb; "
 		    "remove very small DIMMS?");
 
-	videomem_start_ro = vdu_var(os_VDUVAR_DISPLAY_START);
-
 	/* pretty print the individual page types */
 	for (count = 0; count < rom_blocks; count++) {
 		printf("Found ROM  (%d)", count);
@@ -880,9 +827,20 @@ main(int argc, char **argv)
 	 * done relocating and creating information, now update and
 	 * check the relocation mechanism
 	 */
-	prepare_and_check_relocation_system();
+	compact_relocations();
+
+	/*
+	 * grab a page to copy the bootstrap code into
+	 */
+	relocate_code_page = free_relocation_page++;
 	
 	printf("\nStarting at 0x%lx, p@0x%lx\n", marks[MARK_ENTRY], kernel_physical_start);
+	printf("%ld entries, first one is 0x%lx->0x%lx for %lx bytes\n",
+			reloc_instruction_table[0],
+			reloc_instruction_table[1],
+			reloc_instruction_table[2],
+			reloc_instruction_table[3]);
+
 	printf("Will boot in a few secs due to relocation....\n"
 	    "bye bye from RISC OS!");
 
@@ -897,8 +855,8 @@ main(int argc, char **argv)
 		/* r1 relocation pv offset	*/
 		relocate_code_page->physical-relocate_code_page->logical,
 		/* r2 configuration structure	*/ bconfig_new_phys,
-		/* r3 relocation table (P)	*/
-		relocate_table_pages->physical,	/* one piece! */
+		/* r3 relocation table (l)	*/ 
+		(int)reloc_instruction_table,	/* one piece! */
 		/* r4 L1 page descriptor (P)	*/ new_L1_pages_phys,
 		/* r5 kernel entry point	*/ marks[MARK_ENTRY]
 	);
@@ -1007,6 +965,15 @@ get_relocated_page(u_long destination, i
 		panic("\n\nToo many relocations! What are you loading ??");
 
 	/* record the relocation */
+	if (free_relocation_page->physical & 0x3)
+		panic("\n\nphysical address is not aligned!");
+
+	if (destination & 0x3)
+		panic("\n\ndestination address is not aligned!");
+
+	if (size & 0x3)
+		panic("\n\nsize is not aligned!");
+
 	*reloc_pos++ = free_relocation_page->physical;
 	*reloc_pos++ = destination;
 	*reloc_pos++ = size;
Index: start.S
===================================================================
RCS file: /cvsroot/src/sys/arch/acorn32/stand/boot32/start.S,v
retrieving revision 1.2
diff -u -p -r1.2 start.S
--- start.S	25 Jan 2008 23:18:59 -0000	1.2
+++ start.S	3 Feb 2008 02:21:00 -0000
@@ -37,7 +37,6 @@ ENTRY(relocate_code)
 	/*
 		- r0 pointer to configuration structure
 		- r1 pointer to physical restart point
-		- r2 pointer to relocation table (P)
 		- r3 pointer to physical new L1 page address (P)
 		- r4 kernel entry point
 	*/
@@ -73,6 +72,18 @@ ENTRY(relocate_code)
 	cmp	r2, r1
 	moveq	r14, #0							/* mark v3				*/
 
+	/* flush everything out before we turn off the MMU */
+
+	/* flush ID cache											*/
+	mov	r0, #0
+	cmp	r14, #0
+	mcreq	15, 0, r0, c7, c0, 0					/* flush v3 ID cache			*/
+	mcrne	15, 0, r0, c7, c7, 0					/* flush v4 ID cache			*/
+	mcrne	15, 0, r0, c7, c10, 4					/* drain WB (v4)			*/
+
+	/* flush TLB												*/
+	mcr	15, 0, r0, c5, c0, 0					/* flush TLB for v3 and v4		*/
+
 	/* switch off MMU, IDcache and WB and branch to physical code space					*/
 	cmp	r14, #0
 	mrcne	15, 0, r0, c1, c0, 0					/* read processor control register if v4*/
@@ -87,23 +98,35 @@ ENTRY(relocate_code)
 	
 relocate_code_physical_restart:
 	/* we are running in physical flat 1:1 space now */
-	mov	r5, r10							/* r5 = is start of relocation table	*/
-	ldr	r6, [r5], #4						/* r4 = number of relocated pages	*/
+
+	/* make the screen border red */
+	mov	r4, #0x03400000
+	mov	r0, #0x40000000
+	orr	r0, r0, #0xff
+	str	r0, [r4]
+	
+	adr	r5, relocate_table_start
+	ldr	r6, [r5], #4						/* r6 = number of relocated pages	*/
+
 loop_relocate_pages:
 	ldr	r2, [r5], #4						/* r2 = from address			*/
 	ldr	r3, [r5], #4						/* r3 = to address			*/
 	ldr	r7, [r5], #4						/* r7 = number of bytes to travel	*/
-	mov	r1, #0							/* r1 = offset in page			*/
 	/* its slow ... we dont know anything about alignment here 						*/
 loop_one_page:
-	ldrb	r0, [r2, r1]
-	strb	r0, [r3, r1]
-	add	r1, r1, #1
-	cmp	r1, r7							/* all bytes copied?			*/
-	bne	loop_one_page
+	ldr	r0, [r2], #4
+	str	r0, [r3], #4
+	subs	r7, r7, #4
+	bgt	loop_one_page
+
 	subs	r6, r6, #1
 	bne	loop_relocate_pages
 
+	/* make the screen border go green */
+	mov	r0, #0x40000000
+	orr	r0, r0, #0xff00
+	str	r0, [r4]
+	
 	/* OK! all is relocated... now switch over to the new L1 pages						*/
 
 	/* flush ID cache											*/
@@ -132,6 +155,11 @@ loop_one_page:
 	mov	r0, r0							/* flat					*/
 	/* not flat anymore but we just continue								*/
 
+	/* make the screen border go blue */
+	mov	r0, #0x40000000
+	orr	r0, r0, #0xff0000
+	str	r0, [r4]
+	
 	/* call the kernel!											*/
 	mov	r0, r8							/* saved configuration structure	*/
 	mov	pc, r12							/* entry point ..... bye bye!		*/
@@ -139,6 +167,10 @@ loop_one_page:
 relocate_code_end:
 	b	relocate_code_end
 
+relocate_table_start:
+	/* relocation table is copied here, so it must be kept small */
+
+
 /* ----------------------------------------------------------------------- */
 
 
@@ -150,7 +182,7 @@ ENTRY(start_kernel)
 		- r0 relocation code page (V)
 		- r1 relocation pv offset
 		- r2 configuration structure
-		- r3 relocation table (P)
+		- r3 relocation table (V)
 		- r4 L1 page descriptor (P)
 		- r5 kernel entry point
 	*/
@@ -164,7 +196,7 @@ ENTRY(start_kernel)
 
 	/* relocate the relocation routine to the given page */
 	adr	r6, relocate_code
-	ldr	r7, Lnbpp
+	mov	r7, #relocate_table_start - relocate_code	/* get length to copy */
 	mov	r8, r0
 relocate_code_loop:
 	ldr	r9, [r6], #4
@@ -172,6 +204,22 @@ relocate_code_loop:
 	subs	r7, r7, #4
 	bne	relocate_code_loop
 
+	/* now relocate the relocate table onto the same page */
+
+	/* next we need to copy the table over */
+	ldr	r6, [r3], #4					/* r6 has number of threes to copy */
+	str	r6, [r8], #4
+
+relocate_table_loop:
+	ldr	r9, [r3], #4
+	str	r9, [r8], #4
+	ldr	r9, [r3], #4
+	str	r9, [r8], #4
+	ldr	r9, [r3], #4
+	str	r9, [r8], #4
+	subs	r6, r6, #1
+	bne	relocate_table_loop
+	
 	/* we messed up the data cache : lets read a 64 or 128 kb <-- GROSS */
 	mov	r7, #128*1024
 	mov	r6, #0x8000						/* start of RISCOS application area	*/
@@ -198,7 +246,7 @@ flush_ID_cache_try:
 	add	r1, r0, r1						/* get physical address			*/
 	add	r1, r1, r7						/* add offset				*/
 	mov	r0, r2							/* put configuration structure in r0	*/
-	mov	r2, r3							/* relocation table			*/
+	mov	r2, r3
 	mov	r3, r4							/* L1 page discriptor			*/
 	mov	r4, r5							/* kernel entry point			*/
 
@@ -207,8 +255,3 @@ flush_ID_cache_try:
 emergency_exit:
 	ldmdb	fp, {r4-r9, fp, sp, pc}
 
-Lnbpp:
-	.word	nbpp
-Lvideomem_start_ro:
-	.word	videomem_start_ro
-