Changeset 01cb210 in mainline


Ignore:
Timestamp:
2006-03-16T18:55:50Z (19 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1f330de
Parents:
d89c554
Message:

relocate kernel in real mode

Location:
arch/ppc32/loader
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • arch/ppc32/loader/Makefile

    rd89c554 r01cb210  
    6666
    6767image.boot: depend $(OBJECTS) kernel.o
    68         $(LD) -no-check-sections -N -T _link.ld -Map map $(OBJECTS) kernel.o -o $@
     68        $(LD) -no-check-sections -N -T _link.ld $(OBJECTS) kernel.o -o $@
    6969
    7070depend:
     
    7575
    7676kernel.o: $(KERNEL)
    77         $(OBJCOPY) -I binary -O elf32-powerpc -B powerpc $(KERNEL) $@
     77        $(OBJCOPY) -I binary -O elf32-powerpc -B powerpc --rename-section .data=.image $(KERNEL) $@
    7878
    7979%.o: %.S
  • arch/ppc32/loader/_link.ld

    rd89c554 r01cb210  
    88
    99SECTIONS {
    10         .image 0x10000000: AT (0) {
    11                 *(BOOTSTRAP)
    12                 *(REALMODE)
     10        .boot 0x10000000: AT (0) {
     11                *(BOOTSTRAP);
     12                *(REALMODE);
    1313                *(.text);
    1414               
     
    2222                *(COMMON);              /* global variables */
    2323        }
     24       
     25        .image 0x10000000+SIZEOF(.boot): AT (SIZEOF(.boot)) SUBALIGN(4096) {
     26                *(.image);
     27        }
    2428}
  • arch/ppc32/loader/asm.S

    rd89c554 r01cb210  
    2727#
    2828
     29#include "asm.h"
    2930#include "regname.h"
    3031
     
    3637.text
    3738
    38 .global memsetb
    39 .global memcpy
    40 .global flush_instruction_cache
     39.global halt
    4140.global jump_to_kernel
    4241
    43 memsetb:
    44         rlwimi r5, r5, 8, 16, 23
    45         rlwimi r5, r5, 16, 0, 15
    46        
    47         addi r14, r3, -4
    48        
    49         cmplwi 0, r4, 4
    50         blt 7f
    51        
    52         stwu r5, 4(r14)
    53         beqlr
    54        
    55         andi. r15, r14, 3
    56         add r4, r15, r4
    57         subf r14, r15, r14
    58         srwi r15, r4, 2
    59         mtctr r15
    60        
    61         bdz 6f
    62        
    63         1:
    64                 stwu r5, 4(r14)
    65                 bdnz 1b
    66        
    67         6:
    68        
    69         andi. r4, r4, 3
    70        
    71         7:
    72        
    73         cmpwi 0, r4, 0
    74         beqlr
    75        
    76         mtctr r4
    77         addi r6, r6, 3
    78        
    79         8:
    80        
    81         stbu r5, 1(r14)
    82         bdnz 8b
    83        
    84         blr
    85 
    86 memcpy:
    87         srwi. r7, r5, 3
    88         addi r6, r3, -4
    89         addi r4, r4, -4
    90         beq     2f
    91        
    92         andi. r0, r6, 3
    93         mtctr r7
    94         bne 5f
    95        
    96         1:
    97        
    98         lwz r7, 4(r4)
    99         lwzu r8, 8(r4)
    100         stw r7, 4(r6)
    101         stwu r8, 8(r6)
    102         bdnz 1b
    103        
    104         andi. r5, r5, 7
    105        
    106         2:
    107        
    108         cmplwi 0, r5, 4
    109         blt 3f
    110        
    111         lwzu r0, 4(r4)
    112         addi r5, r5, -4
    113         stwu r0, 4(r6)
    114        
    115         3:
    116        
    117         cmpwi 0, r5, 0
    118         beqlr
    119         mtctr r5
    120         addi r4, r4, 3
    121         addi r6, r6, 3
    122        
    123         4:
    124        
    125         lbzu r0, 1(r4)
    126         stbu r0, 1(r6)
    127         bdnz 4b
    128         blr
    129        
    130         5:
    131        
    132         subfic r0, r0, 4
    133         mtctr r0
    134        
    135         6:
    136        
    137         lbz r7, 4(r4)
    138         addi r4, r4, 1
    139         stb r7, 4(r6)
    140         addi r6, r6, 1
    141         bdnz 6b
    142         subf r5, r0, r5
    143         rlwinm. r7, r5, 32-3, 3, 31
    144         beq 2b
    145         mtctr r7
    146         b 1b
    147        
    148 flush_instruction_cache:
    149 
    150         # Flush data cache
    151        
    152         lis r3, flush_buffer@h
    153         ori r3, r3, flush_buffer@l
    154         li r4, L1_CACHE_LINES
    155         mtctr r4
    156        
    157         0:
    158        
    159         lwz r4, 0(r3)
    160         addi r3, r3, L1_CACHE_BYTES
    161         bdnz 0b
    162        
    163         # Invalidate instruction cache
    164        
    165         li r3, 0
    166         ori     r3, r3, (hid0_ice | hid0_dce | hid0_icfi | hid0_dci)
    167         mfspr r4, hid0
    168         or r5, r4, r3
    169         isync
    170         mtspr hid0, r5
    171         sync
    172         isync
    173        
    174         # Enable instruction cache
    175        
    176         ori     r5, r4, hid0_ice
    177         mtspr hid0, r5
    178         sync
    179         isync
    180         blr
     42halt:
     43        b halt
    18144
    18245jump_to_kernel:
    18346       
    184         # r3 = kernel_start (va)
    185         # r4 = memmap (pa)
    186         # r5 = real_mode (pa)
     47        # r3 = memmap (pa)
     48        # r4 = trans (pa)
     49        # r5 = number of kernel pages
     50        # r6 = real_mode (pa)
    18751       
    188         mtspr srr0, r5
     52        mtspr srr0, r6
    18953       
    19054        # jumps to real_mode
    19155       
    192         mfmsr r5
    193         lis r6, ~0@h
    194         ori r6, r6, ~(msr_ir | msr_dr)@l
    195         and r5, r5, r6
    196         mtspr srr1, r5
     56        mfmsr r31
     57        lis r30, ~0@h
     58        ori r30, r30, ~(msr_ir | msr_dr)@l
     59        and r31, r31, r30
     60        mtspr srr1, r31
    19761        rfi
    19862
    19963.section REALMODE
    200 .align 12
     64.align PAGE_WIDTH
    20165.global real_mode
    20266
    20367real_mode:
    204 
     68       
     69        # copy kernel to proper location
     70        #
     71        # r4 = trans (pa)
     72        # r5 = number of kernel pages
     73       
     74        li r31, PAGE_SIZE >> 3
     75        li r30, 0
     76       
     77        page_copy:
     78               
     79                cmpwi r5, 0
     80                beq copy_end
     81               
     82                # copy single page
     83               
     84                mtctr r31
     85                lwz r29, 0(r4)
     86               
     87                copy_loop:
     88                       
     89                        lwz r28, 0(r29)
     90                        stw r28, 0(r30)
     91                       
     92                        addi r29, r29, 4
     93                        addi r30, r30, 4
     94                       
     95                        bdnz copy_loop
     96               
     97                subi r5, r5, 1
     98                addi r4, r4, 4
     99                b page_copy
     100       
     101        copy_end:
     102               
    205103        # fill segment registers
    206104
    207         li r5, 16
    208         mtctr r5
    209         li r5, 0
    210         li r6, 0
     105        li r31, 16
     106        mtctr r31
     107        li r31, 0
     108        li r30, 0x2000
    211109       
    212110        seg_fill:
    213111       
    214                 mtsrin r6, r5
    215                 addis r5, r5, 0x1000    # move to next SR
    216                 addis r6, r6, 0x10      # add 256 MB, move to next SR
     112                mtsrin r30, r31
     113               
     114                addis r31, r31, 0x1000    # add 256 MB
     115                addi  r30, r30, 0x111     # move to next SR
    217116               
    218117                bdnz seg_fill
    219118       
    220         # bootstrap kernel
     119        # create identity mapping
     120       
     121        tlbia
     122       
     123        # start the kernel
    221124        #
    222         # r3 = kernel_start (va)
    223         # r4 = memmap (pa)       -> r10
     125        # r3 = memmap (pa)
    224126       
    225         mtspr srr0, r3
     127        lis r31, KERNEL_START_ADDR@ha
     128        addi r31, r31, KERNEL_START_ADDR@l
    226129       
    227         mfmsr r5
    228         ori r5, r5, (msr_ir | msr_dr)@l
    229         mtspr srr1, r5
     130        mtspr srr0, r31
    230131       
    231         mr r10, r4
     132        mfmsr r31
     133        ori r31, r31, (msr_ir | msr_dr)@l
     134        mtspr srr1, r31
     135       
    232136        rfi
     137
     138.align PAGE_WIDTH
     139.global trans
     140trans:
     141        .space (TRANS_SIZE * TRANS_ITEM_SIZE)
  • arch/ppc32/loader/asm.h

    rd89c554 r01cb210  
    3030#define __ASM_H__
    3131
    32 void flush_instruction_cache(void);
    33 void jump_to_kernel(void *code, void *memmap, void *real_mode) __attribute__((noreturn));
    34 void real_mode(void *code, void *memmap);
     32#define PAGE_SIZE 4096
     33#define PAGE_WIDTH 12
    3534
    36 #define memcpy(dst, src, cnt)  __builtin_memcpy((dst), (src), (cnt))
     35#define TRANS_SIZE 1024
     36#define TRANS_ITEM_SIZE 4
     37
     38#define KERNEL_START_ADDR 0x80002000
     39
     40#ifndef __ASM__
     41
     42extern void *trans[TRANS_SIZE];
     43
     44extern void halt();
     45extern void jump_to_kernel(void *memmap, void *trans, unsigned int cnt, void *real_mode) __attribute__((noreturn));
     46extern void real_mode();
    3747
    3848#endif
     49
     50#endif
  • arch/ppc32/loader/main.c

    rd89c554 r01cb210  
    3131#include "asm.h"
    3232
    33 #define KERNEL_PHYSICAL_ADDRESS 0x0000
    34 #define KERNEL_VIRTUAL_ADDRESS 0x80000000
    35 #define KERNEL_BOOT_OFFSET 0x2000
    36 #define KERNEL_START &_binary_____________kernel_kernel_bin_start
    37 #define KERNEL_END &_binary_____________kernel_kernel_bin_end
     33#define KERNEL_START ((void *) &_binary_____________kernel_kernel_bin_start)
     34#define KERNEL_END ((void *) &_binary_____________kernel_kernel_bin_end)
    3835#define KERNEL_SIZE ((unsigned int) KERNEL_END - (unsigned int) KERNEL_START)
    3936
    4037memmap_t memmap;
     38
     39
     40static void check_align(const void *addr, const char *desc)
     41{
     42        if ((unsigned int) addr % PAGE_SIZE != 0) {
     43                printf("Error: %s not on page boundary\n", desc);
     44                halt();
     45        }
     46}
     47
    4148
    4249void bootstrap(void)
     
    4451        printf("\nHelenOS PPC Bootloader\n");
    4552       
    46         void *phys = ofw_translate(&start);
    47         printf("loaded at %L (physical %L)\n", &start, phys);
     53        check_align(KERNEL_START, "Kernel image");
     54        check_align(&real_mode, "Bootstrap trampoline");
     55        check_align(&trans, "Translation table");
     56       
     57        void *real_mode_pa = ofw_translate(&real_mode);
     58        void *trans_pa = ofw_translate(&trans);
     59        void *memmap_pa = ofw_translate(&memmap);
     60       
     61        printf("Memory statistics\n");
     62        printf(" kernel image         at %L (size %d bytes)\n", KERNEL_START, KERNEL_SIZE);
     63        printf(" memory map           at %L (physical %L)\n", &memmap, memmap_pa);
     64        printf(" bootstrap trampoline at %L (physical %L)\n", &real_mode, real_mode_pa);
     65        printf(" translation table    at %L (physical %L)\n", &trans, trans_pa);
    4866       
    4967        if (!ofw_memmap(&memmap)) {
     
    5169                halt();
    5270        }
    53         printf("total memory %d MB\n", memmap.total >> 20);
     71        printf("Total memory %d MB\n", memmap.total >> 20);
    5472       
    55         if (ofw_map((void *) KERNEL_PHYSICAL_ADDRESS, (void *) KERNEL_VIRTUAL_ADDRESS, KERNEL_SIZE + KERNEL_BOOT_OFFSET, 0) != 0) {
    56                 printf("Unable to map kernel memory at %L (physical %L)\n", KERNEL_VIRTUAL_ADDRESS, KERNEL_PHYSICAL_ADDRESS);
    57                 halt();
     73        unsigned int addr;
     74        unsigned int pages;
     75        for (addr = 0, pages = 0; addr < KERNEL_SIZE; addr += PAGE_SIZE, pages++) {
     76                void *pa = ofw_translate(KERNEL_START + addr);
     77                if ((unsigned int) pa < KERNEL_SIZE) {
     78                        printf("Error: Kernel image overlaps kernel physical area\n");
     79                        halt();
     80                }
     81                trans[addr >> PAGE_WIDTH] = pa;
    5882        }
    59         printf("kernel memory mapped at %L (physical %L, size %d bytes)\n", KERNEL_VIRTUAL_ADDRESS, KERNEL_PHYSICAL_ADDRESS, KERNEL_SIZE);
    60         // FIXME: relocate the kernel in real mode
    61         memcpy((void *) KERNEL_VIRTUAL_ADDRESS, KERNEL_START, KERNEL_SIZE);
    6283       
    63         // FIXME: proper hardware detection & mapping
    64         ofw_map((void *) 0x84000000, (void *) 0xf0000000, 0x01000000, 0);
    65         ofw_map((void *) 0x80816000, (void *) 0xf2000000, 0x00018000, 0);
    66        
    67         void *tramp = ofw_translate(&real_mode);
    68         printf("bootstrap trampoline at %L (physical %L)\n", &real_mode, tramp);
    6984        printf("Booting the kernel...\n");
    70        
    71         flush_instruction_cache();
    72         jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS + KERNEL_BOOT_OFFSET, ofw_translate(&memmap), tramp);
     85        jump_to_kernel(memmap_pa, trans_pa, pages, real_mode_pa);
    7386}
  • arch/ppc32/loader/ofw.c

    rd89c554 r01cb210  
    2828 
    2929#include "ofw.h"
     30#include "asm.h"
    3031#include "printf.h"
    3132
     
    114115
    115116
    116 void halt(void)
    117 {
    118         ofw_call("exit", 0, 0);
    119 }
    120 
    121 
    122117void ofw_write(const char *str, const int len)
    123118{
     
    132127{
    133128        return (void *) ofw_call("call-method", 7, 1, "translate", ofw_mmu, virt, 0, 0, 0, 0);
    134 }
    135 
    136 
    137 int ofw_map(const void *phys, const void *virt, const int size, const int mode)
    138 {
    139         return ofw_call("call-method", 6, 1, "map", ofw_mmu, mode, size, virt, phys);
    140129}
    141130
  • arch/ppc32/loader/ofw.h

    rd89c554 r01cb210  
    5454
    5555extern void init(void);
    56 extern void halt(void);
    57 
    5856extern void ofw_write(const char *str, const int len);
    5957
    6058extern void *ofw_translate(const void *virt);
    61 extern int ofw_map(const void *phys, const void *virt, const int size, const int mode);
    6259extern int ofw_memmap(memmap_t *map);
    6360
  • arch/ppc32/loader/regname.h

    rd89c554 r01cb210  
    182182#define ctr             9
    183183#define dec             22
     184#define sdr1    25
    184185#define srr0    26
    185186#define srr1    27
Note: See TracChangeset for help on using the changeset viewer.