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