Changeset f941347 in mainline


Ignore:
Timestamp:
2006-03-17T12:46:35Z (19 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
7dcde32
Parents:
543c31f
Message:

relocate boot loader structures if needed
(allowing to boot on stupid OFW implementations)

Location:
arch/ppc32/loader
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • arch/ppc32/loader/asm.S

    r543c31f rf941347  
    3838
    3939.global halt
     40.global memcpy
    4041.global jump_to_kernel
    4142
    4243halt:
    4344        b halt
     45
     46memcpy:
     47        srwi. r7, r5, 3
     48        addi r6, r3, -4
     49        addi r4, r4, -4
     50        beq     2f
     51       
     52        andi. r0, r6, 3
     53        mtctr r7
     54        bne 5f
     55       
     56        1:
     57       
     58        lwz r7, 4(r4)
     59        lwzu r8, 8(r4)
     60        stw r7, 4(r6)
     61        stwu r8, 8(r6)
     62        bdnz 1b
     63       
     64        andi. r5, r5, 7
     65       
     66        2:
     67       
     68        cmplwi 0, r5, 4
     69        blt 3f
     70       
     71        lwzu r0, 4(r4)
     72        addi r5, r5, -4
     73        stwu r0, 4(r6)
     74       
     75        3:
     76       
     77        cmpwi 0, r5, 0
     78        beqlr
     79        mtctr r5
     80        addi r4, r4, 3
     81        addi r6, r6, 3
     82       
     83        4:
     84       
     85        lbzu r0, 1(r4)
     86        stbu r0, 1(r6)
     87        bdnz 4b
     88        blr
     89       
     90        5:
     91       
     92        subfic r0, r0, 4
     93        mtctr r0
     94       
     95        6:
     96       
     97        lbz r7, 4(r4)
     98        addi r4, r4, 1
     99        stb r7, 4(r6)
     100        addi r6, r6, 1
     101        bdnz 6b
     102        subf r5, r0, r5
     103        rlwinm. r7, r5, 32-3, 3, 31
     104        beq 2b
     105        mtctr r7
     106        b 1b
     107
    44108
    45109jump_to_kernel:
  • arch/ppc32/loader/asm.h

    r543c31f rf941347  
    4040#ifndef __ASM__
    4141
     42#define memcpy(dst, src, cnt)  __builtin_memcpy((dst), (src), (cnt))
     43
    4244extern void *trans[TRANS_SIZE];
    4345
  • arch/ppc32/loader/main.c

    r543c31f rf941347  
    3535#define KERNEL_SIZE ((unsigned int) KERNEL_END - (unsigned int) KERNEL_START)
    3636
     37#define HEAP_GAP 1024000
     38
    3739memmap_t memmap;
    3840
     
    4749
    4850
    49 static void check_overlap(const void *addr, const char *desc)
     51static void fix_overlap(void *va, void **pa, const char *desc, unsigned int *top)
    5052{
    51         if ((unsigned int) addr < KERNEL_SIZE) {
    52                 printf("Error: %s overlaps kernel physical area\n", desc);
    53                 halt();
     53        if ((unsigned int) *pa + PAGE_SIZE < *top) {
     54                printf("Warning: %s overlaps kernel physical area\n", desc);
     55               
     56                void *new_va = (void *) (ALIGN_UP((unsigned int) KERNEL_END + HEAP_GAP, PAGE_SIZE) + *top);
     57                void *new_pa = (void *) (HEAP_GAP + *top);
     58                *top += PAGE_SIZE;
     59               
     60                if (ofw_map(new_pa, new_va, PAGE_SIZE, 0) != 0) {
     61                        printf("Error: Unable to map page aligned memory at %L (physical %L)\n", new_va, new_pa);
     62                        halt();
     63                }
     64               
     65                if ((unsigned int) new_pa + PAGE_SIZE < KERNEL_SIZE) {
     66                        printf("Error: %s cannot be relocated\n", desc);
     67                        halt();
     68                }
     69               
     70                printf("Relocating %L -> %L (physical %L -> %L)\n", va, new_va, *pa, new_pa);
     71                *pa = new_pa;
     72                memcpy(new_va, va, PAGE_SIZE);
    5473        }
    5574}
     
    7392        void *memmap_pa = ofw_translate(&memmap);
    7493       
    75         check_overlap(real_mode_pa, "Bootstrap trampoline");
    76         check_overlap(trans_pa, "Translation table");
    77         check_overlap(memmap_pa, "Memory map");
    78        
    7994        printf("Memory statistics (total %d MB)\n", memmap.total >> 20);
    8095        printf(" kernel image         at %L (size %d bytes)\n", KERNEL_START, KERNEL_SIZE);
     
    8398        printf(" translation table    at %L (physical %L)\n", &trans, trans_pa);
    8499       
     100        unsigned int top = ALIGN_UP(KERNEL_SIZE, PAGE_SIZE);
    85101        unsigned int addr;
    86102        for (addr = 0; addr < KERNEL_SIZE; addr += PAGE_SIZE) {
    87103                void *pa = ofw_translate(KERNEL_START + addr);
    88                 check_overlap(pa, "Kernel image");
     104                fix_overlap(KERNEL_START + addr, &pa, "Kernel image", &top);
    89105                trans[addr >> PAGE_WIDTH] = pa;
    90106        }
     107       
     108        fix_overlap(&real_mode, &real_mode_pa, "Bootstrap trampoline", &top);
     109        fix_overlap(&trans, &trans_pa, "Translation table", &top);
     110        fix_overlap(&memmap, &memmap_pa, "Memory map", &top);
    91111       
    92112        printf("Booting the kernel...\n");
  • arch/ppc32/loader/main.h

    r543c31f rf941347  
    3232#include "ofw.h"
    3333
     34/** Align to the nearest higher address.
     35 *
     36 * @param addr  Address or size to be aligned.
     37 * @param align Size of alignment, must be power of 2.
     38 */
     39#define ALIGN_UP(addr, align) (((addr) + ((align) - 1)) & ~((align) - 1))
     40
    3441extern int _binary_____________kernel_kernel_bin_start;
    3542extern int _binary_____________kernel_kernel_bin_end;
  • arch/ppc32/loader/ofw.c

    r543c31f rf941347  
    130130
    131131
     132int ofw_map(const void *phys, const void *virt, const int size, const int mode)
     133{
     134        return ofw_call("call-method", 6, 1, "map", ofw_mmu, mode, size, virt, phys);
     135}
     136
     137
    132138int ofw_memmap(memmap_t *map)
    133139{
  • arch/ppc32/loader/ofw.h

    r543c31f rf941347  
    5757
    5858extern void *ofw_translate(const void *virt);
     59extern int ofw_map(const void *phys, const void *virt, const int size, const int mode);
    5960extern int ofw_memmap(memmap_t *map);
    6061
Note: See TracChangeset for help on using the changeset viewer.