? .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 -