Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset e731b0d in mainline


Ignore:
Timestamp:
2009-08-20T16:58:55Z (12 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master
Children:
b9c7425
Parents:
a11099f
Message:

make ppc32 OFW usage on par with sparc64, make appropriate modifications elsewhere

  • introduce ofw_tree_walk_by_device_type() to gather all OFW devices of a given type
  • ppc32 uses canonized OFW tree, mac-io and display devices are detected in kernel (not by the boot loader) by means of device type
  • various busses (PCI, EBUS, etc.) stay sparc64 specific for now
  • boot memcpy() is defined in a common way
  • BALLOC_MAX_SIZE is platform-dependent
  • ppc32 and sparc64 boot loaders cleanup (removal of obsolete stuff, data is not passed by global variables if not necessary, etc.)
  • balloc and OFW tree canonizer have now a provision to support different mapping of the data during boot time and kernel run-time
  • OFW tree canonizer uses balloc_rebase() to store pointers suitable for access during kernel run-time (with potentially different memory mapping than during boot time)
Files:
46 edited

Legend:

Unmodified
Added
Removed
  • HelenOS.config

    ra11099f re731b0d  
    273273
    274274% OpenFirmware tree support
    275 ! [PLATFORM=sparc64] CONFIG_OFW_TREE (y)
     275! [PLATFORM=ppc32|PLATFORM=sparc64] CONFIG_OFW_TREE (y)
     276
     277% OpenFirmware PCI bus support
     278! [PLATFORM=sparc64] CONFIG_OFW_PCI (y)
    276279
    277280% Multiboot standard support
  • boot/arch/arm32/loader/asm.h

    ra11099f re731b0d  
    4040
    4141
    42 /** Copies cnt bytes from dst to src.
    43  *
    44  * @param dst Destination address.
    45  * @param src Source address.
    46  * @param cnt Count of bytes to be copied.
    47  */
    48 #define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt))
    49 
    50 
    5142/** Called when the CPU is switched on.
    5243 *
  • boot/arch/arm32/loader/main.c

    ra11099f re731b0d  
    4343#include <macros.h>
    4444#include <string.h>
     45#include <memstr.h>
    4546
    4647#include "mm.h"
  • boot/arch/ia64/loader/asm.h

    ra11099f re731b0d  
    3434#include "main.h"
    3535
    36 #define PAGE_WIDTH      14
    37 #define PAGE_SIZE       (1 << PAGE_WIDTH)
     36#define PAGE_WIDTH  14
     37#define PAGE_SIZE   (1 << PAGE_WIDTH)
    3838
    39 #define memcpy(dst, src, cnt)  __builtin_memcpy((dst), (src), (cnt))
     39#define BALLOC_MAX_SIZE  (128 * 1024)
    4040
    4141extern void halt(void);
    42 /*extern void jump_to_kernel(void *entry, uint64_t cfg, bootinfo_t *bootinfo,
    43         unsigned int bootinfo_size) __attribute__((noreturn));*/
    44 
    4542extern void jump_to_kernel(void *) __attribute__((noreturn));
    4643
  • boot/arch/ia64/loader/main.h

    ra11099f re731b0d  
    3434
    3535
    36 #define CONFIG_INIT_TASKS       32
    37 
    38 
     36#define CONFIG_INIT_TASKS  32
    3937
    4038extern void start(void);
  • boot/arch/mips32/loader/asm.h

    ra11099f re731b0d  
    3333#define PAGE_WIDTH  14
    3434
    35 #define memcpy(dst, src, cnt)  __builtin_memcpy((dst), (src), (cnt))
    36 
    3735void jump_to_kernel(void *entry, void *bootinfo) __attribute__((noreturn));
    3836
  • boot/arch/mips32/loader/main.c

    ra11099f re731b0d  
    2727 */
    2828
    29 #include "main.h" 
     29#include "main.h"
    3030#include <printf.h>
    3131#include <align.h>
    3232#include <macros.h>
    3333#include <string.h>
     34#include <memstr.h>
    3435#include "msim.h"
    3536#include "asm.h"
  • boot/arch/ppc32/loader/Makefile

    ra11099f re731b0d  
    6262SOURCES = \
    6363        main.c \
    64         ofwarch.c \
    6564        _components.c \
    66         ../../../genarch/ofw.c \
    6765        ../../../generic/printf.c \
    6866        ../../../generic/string.c \
     67        ../../../genarch/balloc.c \
     68        ../../../genarch/ofw.c \
     69        ../../../genarch/ofw_tree.c \
     70        ofwarch.c \
    6971        asm.S \
    7072        boot.S
     
    7375        $(KERNELDIR)/kernel.bin \
    7476        $(USPACEDIR)/srv/ns/ns \
     77        $(USPACEDIR)/app/init/init \
    7578        $(USPACEDIR)/srv/loader/loader \
    76         $(USPACEDIR)/app/init/init \
    7779        $(USPACEDIR)/srv/devmap/devmap \
    7880        $(USPACEDIR)/srv/bd/rd/rd \
     
    99101        $(USPACEDIR)/app/tester/tester \
    100102        $(USPACEDIR)/app/trace/trace \
    101         $(USPACEDIR)/app/klog/klog \
    102         $(USPACEDIR)/app/bdsh/bdsh
     103        $(USPACEDIR)/app/bdsh/bdsh \
     104        $(USPACEDIR)/app/klog/klog
    103105
    104106OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
  • boot/arch/ppc32/loader/_link.ld.in

    ra11099f re731b0d  
    1919[[COMPONENTS]]
    2020        }
     21       
     22        /DISCARD/ : {
     23                *(.comment);
     24                *(.note*);
     25        }
    2126}
  • boot/arch/ppc32/loader/asm.S

    ra11099f re731b0d  
    2929#include "asm.h"
    3030#include "regname.h"
     31#include "ofwarch.h"
    3132
    3233.macro SMC_COHERENCY addr
     
    4546
    4647.macro TLB_FLUSH reg
    47         tlbie \reg
    48         addi \reg, \reg, 0x1000
     48        li \reg, 0
     49        sync
     50       
     51        .rept 64
     52                tlbie \reg
     53                addi \reg, \reg, 0x1000
     54        .endr
     55       
     56        eieio
     57        tlbsync
     58        sync
    4959.endm
    5060
     
    5464.global memcpy
    5565.global jump_to_kernel
     66.global balloc_base
    5667
    5768halt:
     
    6273        addi r6, r3, -4
    6374        addi r4, r4, -4
    64         beq     2f
     75        beq 2f
    6576       
    6677        andi. r0, r6, 3
     
    6980       
    7081        1:
    71        
    72         lwz r7, 4(r4)
    73         lwzu r8, 8(r4)
    74         stw r7, 4(r6)
    75         stwu r8, 8(r6)
    76         bdnz 1b
    77        
    78         andi. r5, r5, 7
     82                lwz r7, 4(r4)
     83                lwzu r8, 8(r4)
     84                stw r7, 4(r6)
     85                stwu r8, 8(r6)
     86                bdnz 1b
     87               
     88                andi. r5, r5, 7
    7989       
    8090        2:
    81        
    82         cmplwi 0, r5, 4
    83         blt 3f
    84        
    85         lwzu r0, 4(r4)
    86         addi r5, r5, -4
    87         stwu r0, 4(r6)
     91                cmplwi 0, r5, 4
     92                blt 3f
     93               
     94                lwzu r0, 4(r4)
     95                addi r5, r5, -4
     96                stwu r0, 4(r6)
    8897       
    8998        3:
    90        
    91         cmpwi 0, r5, 0
    92         beqlr
    93         mtctr r5
    94         addi r4, r4, 3
    95         addi r6, r6, 3
     99                cmpwi 0, r5, 0
     100                beqlr
     101                mtctr r5
     102                addi r4, r4, 3
     103                addi r6, r6, 3
    96104       
    97105        4:
    98        
    99         lbzu r0, 1(r4)
    100         stbu r0, 1(r6)
    101         bdnz 4b
    102         blr
     106                lbzu r0, 1(r4)
     107                stbu r0, 1(r6)
     108                bdnz 4b
     109                blr
    103110       
    104111        5:
    105        
    106         subfic r0, r0, 4
    107         mtctr r0
     112                subfic r0, r0, 4
     113                mtctr r0
    108114       
    109115        6:
    110        
    111         lbz r7, 4(r4)
    112         addi r4, r4, 1
    113         stb r7, 4(r6)
    114         addi r6, r6, 1
    115         bdnz 6b
    116         subf r5, r0, r5
    117         rlwinm. r7, r5, 32-3, 3, 31
    118         beq 2b
    119         mtctr r7
    120         b 1b
    121 
     116                lbz r7, 4(r4)
     117                addi r4, r4, 1
     118                stb r7, 4(r6)
     119                addi r6, r6, 1
     120                bdnz 6b
     121                subf r5, r0, r5
     122                rlwinm. r7, r5, 32-3, 3, 31
     123                beq 2b
     124                mtctr r7
     125                b 1b
    122126
    123127jump_to_kernel:
     
    128132        # r6 = bytes to copy
    129133        # r7 = real_mode (pa)
    130         # r8 = framebuffer (pa)
    131         # r9 = scanline
    132134       
    133135        # disable interrupts
     
    153155        rfi
    154156
     157.align PAGE_WIDTH
     158balloc_base:
     159        .fill BALLOC_MAX_SIZE
     160
    155161.section REALMODE, "ax"
     162
    156163.align PAGE_WIDTH
    157164.global real_mode
    158 
    159165real_mode:
    160166       
    161167        # copy kernel to proper location
    162168        #
     169        # r3 = bootinfo (pa)
     170        # r4 = bootinfo_size
    163171        # r5 = trans (pa)
    164172        # r6 = bytes to copy
    165         # r8 = framebuffer (pa)
    166         # r9 = scanline
    167173       
    168174        li r31, PAGE_SIZE >> 2
     
    343349        # flush TLB
    344350       
    345         li r31, 0
    346         sync
    347        
    348351        TLB_FLUSH r31
    349         TLB_FLUSH r31
    350         TLB_FLUSH r31
    351         TLB_FLUSH r31
    352         TLB_FLUSH r31
    353         TLB_FLUSH r31
    354         TLB_FLUSH r31
    355         TLB_FLUSH r31
    356        
    357         TLB_FLUSH r31
    358         TLB_FLUSH r31
    359         TLB_FLUSH r31
    360         TLB_FLUSH r31
    361         TLB_FLUSH r31
    362         TLB_FLUSH r31
    363         TLB_FLUSH r31
    364         TLB_FLUSH r31
    365        
    366         TLB_FLUSH r31
    367         TLB_FLUSH r31
    368         TLB_FLUSH r31
    369         TLB_FLUSH r31
    370         TLB_FLUSH r31
    371         TLB_FLUSH r31
    372         TLB_FLUSH r31
    373         TLB_FLUSH r31
    374        
    375         TLB_FLUSH r31
    376         TLB_FLUSH r31
    377         TLB_FLUSH r31
    378         TLB_FLUSH r31
    379         TLB_FLUSH r31
    380         TLB_FLUSH r31
    381         TLB_FLUSH r31
    382         TLB_FLUSH r31
    383        
    384         TLB_FLUSH r31
    385         TLB_FLUSH r31
    386         TLB_FLUSH r31
    387         TLB_FLUSH r31
    388         TLB_FLUSH r31
    389         TLB_FLUSH r31
    390         TLB_FLUSH r31
    391         TLB_FLUSH r31
    392        
    393         TLB_FLUSH r31
    394         TLB_FLUSH r31
    395         TLB_FLUSH r31
    396         TLB_FLUSH r31
    397         TLB_FLUSH r31
    398         TLB_FLUSH r31
    399         TLB_FLUSH r31
    400         TLB_FLUSH r31
    401        
    402         TLB_FLUSH r31
    403         TLB_FLUSH r31
    404         TLB_FLUSH r31
    405         TLB_FLUSH r31
    406         TLB_FLUSH r31
    407         TLB_FLUSH r31
    408         TLB_FLUSH r31
    409         TLB_FLUSH r31
    410        
    411         TLB_FLUSH r31
    412         TLB_FLUSH r31
    413         TLB_FLUSH r31
    414         TLB_FLUSH r31
    415         TLB_FLUSH r31
    416         TLB_FLUSH r31
    417         TLB_FLUSH r31
    418         TLB_FLUSH r31
    419        
    420         eieio
    421         tlbsync
    422         sync
    423352       
    424353        # start the kernel
    425354        #
    426         # pc = KERNEL_START_ADDR
     355        # pc = PA2KA(BOOT_OFFSET)
    427356        # r3 = bootinfo (pa)
    428         # sprg0 = KA2PA(KERNEL_START_ADDR)
     357        # sprg0 = BOOT_OFFSET
    429358        # sprg3 = physical memory size
    430359        # sp = 0 (pa)
    431360       
    432         lis r31, KERNEL_START_ADDR@ha
    433         addi r31, r31, KERNEL_START_ADDR@l
    434        
     361        lis r31, PA2KA(BOOT_OFFSET)@ha
     362        addi r31, r31, PA2KA(BOOT_OFFSET)@l
    435363        mtspr srr0, r31
    436364       
    437         subis r31, r31, 0x8000
     365        lis r31, BOOT_OFFSET@ha
     366        addi r31, r31, BOOT_OFFSET@l
    438367        mtsprg0 r31
    439368       
     
    454383.global trans
    455384trans:
    456         .space (TRANS_SIZE * TRANS_ITEM_SIZE)
     385        .rept TRANS_SIZE
     386        .int 0
     387        .endr
  • boot/arch/ppc32/loader/asm.h

    ra11099f re731b0d  
    3030#define BOOT_ppc32_ASM_H_
    3131
    32 #define PAGE_SIZE 4096
    33 #define PAGE_WIDTH 12
     32#define PAGE_WIDTH  12
     33#define PAGE_SIZE   (1 << PAGE_WIDTH)
    3434
    35 #define TRANS_SIZE 1024
    36 #define TRANS_ITEM_SIZE 4
     35#define TRANS_SIZE   1024
     36#define BOOT_OFFSET  0x8000
    3737
    38 #define KERNEL_START_ADDR 0x80008000
     38#define BALLOC_MAX_SIZE  (128 * 1024)
    3939
    4040#ifndef __ASM__
    4141
    42 #define memcpy(dst, src, cnt)  __builtin_memcpy((dst), (src), (cnt))
     42#include "types.h"
     43#include "main.h"
     44#include "ofwarch.h"
    4345
    44 extern void *trans[TRANS_SIZE];
     46#define PA2KA(x)  (((uintptr_t) (x)) + 0x80000000)
     47
     48extern uint8_t balloc_base[BALLOC_MAX_SIZE];
     49extern uintptr_t trans[TRANS_SIZE];
    4550
    4651extern void halt();
    47 extern void jump_to_kernel(void *bootinfo, unsigned int bootinfo_size, void *trans, unsigned int kernel_size, void *real_mode, void *fb, unsigned int scanline) __attribute__((noreturn));
     52extern void jump_to_kernel(void *bootinfo, unsigned int bootinfo_size,
     53    uintptr_t trans[], unsigned int kernel_size, void *real_mode) __attribute__((noreturn));
    4854extern void real_mode();
     55
     56#else
     57
     58#define PA2KA(x)  ((x) + 0x80000000)
    4959
    5060#endif
  • boot/arch/ppc32/loader/main.c

    ra11099f re731b0d  
    2727 */
    2828
    29 #include "main.h"
    3029#include <printf.h>
    31 #include "asm.h"
    32 #include "_components.h"
    3330#include <ofw.h>
    3431#include <align.h>
    3532#include <macros.h>
    3633#include <string.h>
     34#include "main.h"
     35#include "asm.h"
     36#include "_components.h"
    3737
    38 #define HEAP_GAP 1024000
     38static bootinfo_t bootinfo;
     39static component_t components[COMPONENTS];
     40static char *release = STRING(RELEASE);
    3941
    40 bootinfo_t bootinfo;
     42#ifdef REVISION
     43        static char *revision = ", revision " STRING(REVISION);
     44#else
     45        static char *revision = "";
     46#endif
    4147
     48#ifdef TIMESTAMP
     49        static char *timestamp = "\nBuilt on " STRING(TIMESTAMP);
     50#else
     51        static char *timestamp = "";
     52#endif
     53
     54/** Print version information. */
     55static void version_print(void)
     56{
     57        printf("HelenOS PPC32 Bootloader\nRelease %s%s%s\n"
     58            "Copyright (c) 2006 HelenOS project\n\n",
     59            release, revision, timestamp);
     60}
    4261
    4362static void check_align(const void *addr, const char *desc)
    4463{
    45         if ((unsigned int) addr % PAGE_SIZE != 0) {
     64        if ((uintptr_t) addr % PAGE_SIZE != 0) {
    4665                printf("Error: %s not on page boundary, halting.\n", desc);
    4766                halt();
     
    4968}
    5069
    51 
    52 static void fix_overlap(void *va, void **pa, const char *desc, unsigned int *top)
     70static void check_overlap(const void *pa, const char *desc, const uintptr_t top)
    5371{
    54         if ((unsigned int) *pa + PAGE_SIZE < *top) {
    55                 printf("Warning: %s overlaps kernel physical area\n", desc);
    56                
    57                 void *new_va = (void *) (ALIGN_UP((unsigned int) KERNEL_END + HEAP_GAP, PAGE_SIZE) + *top);
    58                 void *new_pa = (void *) (HEAP_GAP + *top);
    59                 *top += PAGE_SIZE;
    60                
    61                 if (ofw_map(new_pa, new_va, PAGE_SIZE, 0) != 0) {
    62                         printf("Error: Unable to map page aligned memory at %L (physical %L), halting.\n", new_va, new_pa);
    63                         halt();
    64                 }
    65                
    66                 if ((unsigned int) new_pa + PAGE_SIZE < KERNEL_SIZE) {
    67                         printf("Error: %s cannot be relocated, halting.\n", desc);
    68                         halt();
    69                 }
    70                
    71                 printf("Relocating %L -> %L (physical %L -> %L)\n", va, new_va, *pa, new_pa);
    72                 *pa = new_pa;
    73                 memcpy(new_va, va, PAGE_SIZE);
     72        if ((uintptr_t) pa + PAGE_SIZE < top) {
     73                printf("Error: %s overlaps destination physical area\n", desc);
     74                halt();
    7475        }
    75 }
    76 
    77 char *release = STRING(RELEASE);
    78 
    79 #ifdef REVISION
    80         char *revision = ", revision " STRING(REVISION);
    81 #else
    82         char *revision = "";
    83 #endif
    84 
    85 #ifdef TIMESTAMP
    86         char *timestamp = "\nBuilt on " STRING(TIMESTAMP);
    87 #else
    88         char *timestamp = "";
    89 #endif
    90 
    91 /** Print version information. */
    92 static void version_print(void)
    93 {
    94         printf("HelenOS PPC32 Bootloader\nRelease %s%s%s\nCopyright (c) 2006 HelenOS project\n\n", release, revision, timestamp);
    9576}
    9677
     
    9879{
    9980        version_print();
    100        
    101         component_t components[COMPONENTS];
    10281        init_components(components);
    103                
    104         unsigned int i;
    105         for (i = 0; i < COMPONENTS; i++)
    106                 check_align(components[i].start, components[i].name);
    107        
    108         check_align(&real_mode, "bootstrap trampoline");
    109         check_align(&trans, "translation table");
    11082       
    11183        if (!ofw_memmap(&bootinfo.memmap)) {
     
    11991        }
    12092       
    121         if (!ofw_screen(&bootinfo.screen))
    122                 printf("Warning: Unable to get screen properties.\n");
     93        check_align(&real_mode, "bootstrap trampoline");
     94        check_align(trans, "translation table");
     95        check_align(balloc_base, "boot allocations");
    12396       
    124         if (!ofw_macio(&bootinfo.macio))
    125                 printf("Warning: Unable to get macio properties.\n");
     97        unsigned int i;
     98        for (i = 0; i < COMPONENTS; i++)
     99                check_align(components[i].start, components[i].name);
    126100       
    127         printf("Device statistics\n");
     101        void *bootinfo_pa = ofw_translate(&bootinfo);
     102        void *real_mode_pa = ofw_translate(&real_mode);
     103        void *trans_pa = ofw_translate(trans);
     104        void *balloc_base_pa = ofw_translate(balloc_base);
    128105       
    129         if (bootinfo.screen.addr)
    130                 printf(" screen at %L, resolution %dx%d, %d bpp (scanline %d bytes)\n", bootinfo.screen.addr, bootinfo.screen.width, bootinfo.screen.height, bootinfo.screen.bpp, bootinfo.screen.scanline);
    131        
    132         if (bootinfo.macio.addr)
    133                 printf(" macio at %L (size %d bytes)\n", bootinfo.macio.addr, bootinfo.macio.size);
    134        
    135         void *real_mode_pa = ofw_translate(&real_mode);
    136         void *trans_pa = ofw_translate(&trans);
    137         void *bootinfo_pa = ofw_translate(&bootinfo);
    138        
    139         printf("\nMemory statistics (total %d MB)\n", bootinfo.memmap.total >> 20);
     106        printf("Memory statistics (total %d MB)\n", bootinfo.memmap.total >> 20);
    140107        printf(" %L: boot info structure (physical %L)\n", &bootinfo, bootinfo_pa);
    141108        printf(" %L: bootstrap trampoline (physical %L)\n", &real_mode, real_mode_pa);
    142         printf(" %L: translation table (physical %L)\n", &trans, trans_pa);
     109        printf(" %L: translation table (physical %L)\n", trans, trans_pa);
     110        printf(" %L: boot allocations (physical %L)\n", balloc_base, balloc_base_pa);
    143111        for (i = 0; i < COMPONENTS; i++)
    144112                printf(" %L: %s image (size %d bytes)\n", components[i].start, components[i].name, components[i].size);
    145113       
    146         unsigned int top = 0;
     114        uintptr_t top = 0;
    147115        for (i = 0; i < COMPONENTS; i++)
    148116                top += ALIGN_UP(components[i].size, PAGE_SIZE);
     117        top += ALIGN_UP(BALLOC_MAX_SIZE, PAGE_SIZE);
     118       
     119        if (top >= TRANS_SIZE * PAGE_SIZE) {
     120                printf("Error: boot image is too large\n");
     121                halt();
     122        }
     123       
     124        check_overlap(bootinfo_pa, "boot info", top);
     125        check_overlap(real_mode_pa, "bootstrap trampoline", top);
     126        check_overlap(trans_pa, "translation table", top);
    149127       
    150128        unsigned int pages = ALIGN_UP(KERNEL_SIZE, PAGE_SIZE) >> PAGE_WIDTH;
     
    152130        for (i = 0; i < pages; i++) {
    153131                void *pa = ofw_translate(KERNEL_START + (i << PAGE_WIDTH));
    154                 fix_overlap(KERNEL_START + (i << PAGE_WIDTH), &pa, "kernel", &top);
    155                 trans[i] = pa;
     132                check_overlap(pa, "kernel", top);
     133                trans[i] = (uintptr_t) pa;
    156134        }
    157135       
    158136        bootinfo.taskmap.count = 0;
    159137        for (i = 1; i < COMPONENTS; i++) {
     138                if (bootinfo.taskmap.count == TASKMAP_MAX_RECORDS) {
     139                        printf("\nSkipping superfluous components.\n");
     140                        break;
     141                }
     142               
    160143                unsigned int component_pages = ALIGN_UP(components[i].size, PAGE_SIZE) >> PAGE_WIDTH;
    161144                unsigned int j;
     
    163146                for (j = 0; j < component_pages; j++) {
    164147                        void *pa = ofw_translate(components[i].start + (j << PAGE_WIDTH));
    165                         fix_overlap(components[i].start + (j << PAGE_WIDTH), &pa, components[i].name, &top);
    166                         trans[pages + j] = pa;
     148                        check_overlap(pa, components[i].name, top);
     149                        trans[pages + j] = (uintptr_t) pa;
    167150                        if (j == 0) {
    168                                 bootinfo.taskmap.tasks[bootinfo.taskmap.count].addr = (void *) (pages << PAGE_WIDTH);
     151                               
     152                                bootinfo.taskmap.tasks[bootinfo.taskmap.count].addr = (void *) PA2KA(pages << PAGE_WIDTH);
    169153                                bootinfo.taskmap.tasks[bootinfo.taskmap.count].size = components[i].size;
    170154                                strncpy(bootinfo.taskmap.tasks[bootinfo.taskmap.count].name,
    171155                                    components[i].name, BOOTINFO_TASK_NAME_BUFLEN);
    172 
     156                               
    173157                                bootinfo.taskmap.count++;
    174158                        }
     
    178162        }
    179163       
    180         fix_overlap(&real_mode, &real_mode_pa, "bootstrap trampoline", &top);
    181         fix_overlap(&trans, &trans_pa, "translation table", &top);
    182         fix_overlap(&bootinfo, &bootinfo_pa, "boot info", &top);
     164        uintptr_t balloc_kernel_base = PA2KA(pages << PAGE_WIDTH);
     165        unsigned int balloc_pages = ALIGN_UP(BALLOC_MAX_SIZE, PAGE_SIZE) >> PAGE_WIDTH;
     166        for (i = 0; i < balloc_pages; i++) {
     167                void *pa = ofw_translate(balloc_base + (i << PAGE_WIDTH));
     168                check_overlap(pa, "boot allocations", top);
     169                trans[pages + i] = (uintptr_t) pa;
     170        }
     171       
     172        pages += balloc_pages;
     173       
     174        balloc_init(&bootinfo.ballocs, (uintptr_t) balloc_base, balloc_kernel_base);
     175        printf("\nCanonizing OpenFirmware device tree...");
     176        bootinfo.ofw_root = ofw_tree_build();
     177        printf("done.\n");
    183178       
    184179        ofw_setup_palette();
    185180       
    186181        printf("\nBooting the kernel...\n");
    187         jump_to_kernel(bootinfo_pa, sizeof(bootinfo), trans_pa, pages << PAGE_WIDTH, real_mode_pa, (void *) bootinfo.screen.addr, bootinfo.screen.scanline);
     182        jump_to_kernel(bootinfo_pa, sizeof(bootinfo), trans_pa, pages << PAGE_WIDTH, real_mode_pa);
    188183}
  • boot/arch/ppc32/loader/main.h

    ra11099f re731b0d  
    3030#define BOOT_ppc32_MAIN_H_
    3131
    32 #include "ofw.h"
     32#include <ofw.h>
     33#include <ofw_tree.h>
     34#include <balloc.h>
     35#include <types.h>
    3336
    34 #define TASKMAP_MAX_RECORDS 32
     37#define TASKMAP_MAX_RECORDS  32
    3538
    3639/** Size of buffer for storing task name in task_t. */
    37 #define BOOTINFO_TASK_NAME_BUFLEN 32
     40#define BOOTINFO_TASK_NAME_BUFLEN  32
    3841
    39 /** Struct holding information about single loaded task. */
    4042typedef struct {
    41         /** Address where the task was placed. */
    4243        void *addr;
    43         /** Size of the task's binary. */
    44         unsigned int size;
    45         /** Task name. */
     44        uint32_t size;
    4645        char name[BOOTINFO_TASK_NAME_BUFLEN];
    4746} task_t;
    4847
    4948typedef struct {
    50         unsigned int count;
     49        uint32_t count;
    5150        task_t tasks[TASKMAP_MAX_RECORDS];
    5251} taskmap_t;
     
    5554        memmap_t memmap;
    5655        taskmap_t taskmap;
    57         screen_t screen;
    58         macio_t macio;
     56        ballocs_t ballocs;
     57        ofw_tree_node_t *ofw_root;
    5958} bootinfo_t;
    6059
     
    6261extern void bootstrap(void);
    6362
    64 extern memmap_t memmap;
    65 
    6663#endif
  • boot/arch/ppc32/loader/ofwarch.c

    ra11099f re731b0d  
    3131#include <printf.h>
    3232
    33 typedef int (* ofw_entry_t)(ofw_args_t *args);
     33typedef int (*ofw_entry_t)(ofw_args_t *args);
    3434
    3535int ofw(ofw_args_t *args)
     
    4949}
    5050
    51 int ofw_macio(macio_t *macio)
    52 {
    53         char device_name[BUF_SIZE];
    54        
    55         if ((ofw_get_property(ofw_aliases, "macio", device_name, sizeof(device_name)) <= 0)
    56             && (ofw_get_property(ofw_aliases, "mac-io", device_name, sizeof(device_name)) <= 0))
    57                 return false;
    58        
    59         phandle device = ofw_find_device(device_name);
    60         if (device == -1)
    61                 return false;
    62        
    63         pci_reg_t pci_reg;
    64         if (ofw_get_property(device, "assigned-addresses", &pci_reg, sizeof(pci_reg)) <= 0)
    65                 return false;
    66        
    67         macio->addr = (void *) pci_reg.addr.addr_lo;
    68         macio->size = pci_reg.size_lo;
    69 
    70         return true;
    71 }
    72 
    7351int ofw_translate_failed(ofw_arg_t flag)
    7452{
     53        /* PearPC returns buggy flag */
    7554        return 0;
    7655}
  • boot/arch/ppc32/loader/ofwarch.h

    ra11099f re731b0d  
    3030#define BOOT_ppc32_OFWARCH_H_
    3131
    32 #define OFW_ADDRESS_CELLS       1
    33 #define OFW_SIZE_CELLS          1
     32#define OFW_ADDRESS_CELLS  1
     33#define OFW_SIZE_CELLS     1
    3434
    3535#endif
  • boot/arch/sparc64/loader/asm.S

    ra11099f re731b0d  
    3131#include <register.h>
    3232
    33 .register       %g2, #scratch
    34 .register       %g3, #scratch
     33.register %g2, #scratch
     34.register %g3, #scratch
    3535
    3636.text
     
    4343        ba %xcc, halt
    4444        nop
     45
     46memcpy:
     47        mov %o0, %o3      ! save dst
     48        add %o1, 7, %g1
     49        and %g1, -8, %g1
     50        cmp %o1, %g1
     51        be,pn %xcc, 3f
     52        add %o0, 7, %g1
     53        mov 0, %g3
    4554       
    46 memcpy:
    47         mov     %o0, %o3                ! save dst
    48         add     %o1, 7, %g1
    49         and     %g1, -8, %g1
    50         cmp     %o1, %g1
    51         be,pn   %xcc, 3f
    52         add     %o0, 7, %g1
    53         mov     0, %g3
    54 0:
    55         brz,pn  %o2, 2f
    56         mov     0, %g2
    57 1:
    58         ldub    [%g3 + %o1], %g1
    59         add     %g2, 1, %g2
    60         cmp     %o2, %g2
    61         stb     %g1, [%g3 + %o0]
    62         bne,pt  %xcc, 1b
    63         mov     %g2, %g3
    64 2:
    65         jmp     %o7 + 8                 ! exit point
    66         mov     %o3, %o0
    67 3:
    68         and     %g1, -8, %g1
    69         cmp     %o0, %g1
    70         bne,pt  %xcc, 0b
    71         mov     0, %g3
    72         srlx    %o2, 3, %g4
    73         brz,pn  %g4, 5f
    74         mov     0, %g5
    75 4:
    76         sllx    %g3, 3, %g2
    77         add     %g5, 1, %g3
    78         ldx     [%o1 + %g2], %g1
    79         mov     %g3, %g5
    80         cmp     %g4, %g3
    81         bne,pt  %xcc, 4b
    82         stx     %g1, [%o0 + %g2]
    83 5:
    84         and     %o2, 7, %o2
    85         brz,pn  %o2, 2b
    86         sllx    %g4, 3, %g1
    87         mov     0, %g2
    88         add     %g1, %o0, %o0
    89         add     %g1, %o1, %g4
    90         mov     0, %g3
    91 6:
    92         ldub    [%g2 + %g4], %g1
    93         stb     %g1, [%g2 + %o0]
    94         add     %g3, 1, %g2
    95         cmp     %o2, %g2
    96         bne,pt  %xcc, 6b
    97         mov     %g2, %g3
    98 
    99         jmp     %o7 + 8                 ! exit point
    100         mov     %o3, %o0
     55        0:
     56                brz,pn %o2, 2f
     57                mov 0, %g2
     58       
     59        1:
     60                ldub [%g3 + %o1], %g1
     61                add %g2, 1, %g2
     62                cmp %o2, %g2
     63                stb %g1, [%g3 + %o0]
     64                bne,pt %xcc, 1b
     65                mov %g2, %g3
     66       
     67        2:
     68                jmp %o7 + 8   ! exit point
     69                mov %o3, %o0
     70       
     71        3:
     72                and %g1, -8, %g1
     73                cmp %o0, %g1
     74                bne,pt %xcc, 0b
     75                mov 0, %g3
     76                srlx %o2, 3, %g4
     77                brz,pn %g4, 5f
     78                mov 0, %g5
     79       
     80        4:
     81                sllx %g3, 3, %g2
     82                add %g5, 1, %g3
     83                ldx [%o1 + %g2], %g1
     84                mov %g3, %g5
     85                cmp %g4, %g3
     86                bne,pt %xcc, 4b
     87                stx %g1, [%o0 + %g2]
     88       
     89        5:
     90                and %o2, 7, %o2
     91                brz,pn %o2, 2b
     92                sllx %g4, 3, %g1
     93                mov 0, %g2
     94                add %g1, %o0, %o0
     95                add %g1, %o1, %g4
     96                mov 0, %g3
     97       
     98        6:
     99                ldub [%g2 + %g4], %g1
     100                stb %g1, [%g2 + %o0]
     101                add %g3, 1, %g2
     102                cmp %o2, %g2
     103                bne,pt %xcc, 6b
     104                mov %g2, %g3
     105       
     106        jmp %o7 + 8   ! exit point
     107        mov %o3, %o0
    101108
    102109jump_to_kernel:
     
    107114         * 3. Flush instruction pipeline.
    108115         */
    109 
     116       
    110117        /*
    111118         * US3 processors have a write-invalidate cache, so explicitly
    112119         * invalidating it is not required. Whether to invalidate I-cache
    113          * or not is decided according to the value of the global
    114          * "subarchitecture" variable (set in the bootstrap).
     120         * or not is decided according to the value of the 5th argument
     121         * (subarchitecture).
    115122         */
    116         set subarchitecture, %g2
    117         ldub [%g2], %g2
    118         cmp %g2, 3
     123        cmp %i4, 3
    119124        be %xcc, 1f
    120125        nop
    121 0:
    122         call icache_flush
    123         nop
    124 1:
    125         membar #StoreStore
     126       
     127        0:
     128                call icache_flush
     129                nop
     130       
     131        1:
     132                membar #StoreStore
    126133       
    127134        /*
    128135         * Flush the instruction pipeline.
    129136         */
    130         flush   %i7
    131 
     137        flush %i7
     138       
    132139        mov %o0, %l1
    133140        mov %o1, %o0
    134141        mov %o2, %o1
    135142        mov %o3, %o2
    136         jmp %l1                         ! jump to kernel
     143        jmp %l1       ! jump to kernel
    137144        nop
    138145
    139 #define ICACHE_SIZE             8192
    140 #define ICACHE_LINE_SIZE        32
    141 #define ICACHE_SET_BIT          (1 << 13)
    142 #define ASI_ICACHE_TAG          0x67
     146#define ICACHE_SIZE       8192
     147#define ICACHE_LINE_SIZE  32
     148#define ICACHE_SET_BIT    (1 << 13)
     149#define ASI_ICACHE_TAG    0x67
    143150
    144151# Flush I-cache
    145152icache_flush:
    146         set     ((ICACHE_SIZE - ICACHE_LINE_SIZE) | ICACHE_SET_BIT), %g1
    147         stxa    %g0, [%g1] ASI_ICACHE_TAG
    148 0:      membar  #Sync
    149         subcc   %g1, ICACHE_LINE_SIZE, %g1
    150         bnz,pt  %xcc, 0b
    151         stxa    %g0, [%g1] ASI_ICACHE_TAG
    152         membar  #Sync
     153        set ((ICACHE_SIZE - ICACHE_LINE_SIZE) | ICACHE_SET_BIT), %g1
     154        stxa %g0, [%g1] ASI_ICACHE_TAG
     155       
     156        0:
     157                membar #Sync
     158                subcc %g1, ICACHE_LINE_SIZE, %g1
     159                bnz,pt %xcc, 0b
     160       
     161        stxa %g0, [%g1] ASI_ICACHE_TAG
     162        membar #Sync
    153163        retl
    154164        ! SF Erratum #51
    155165        nop
     166
    156167.global ofw
    157168ofw:
     
    159170        set ofw_cif, %l0
    160171        ldx [%l0], %l0
    161 
     172       
    162173        rdpr  %pstate, %l1
    163174        and  %l1, ~PSTATE_AM_BIT, %l2
    164175        wrpr  %l2, 0, %pstate
    165    
     176       
    166177        jmpl %l0, %o7
    167178        mov %i0, %o0
    168 
     179       
    169180        wrpr %l1, 0, %pstate
    170 
     181       
    171182        ret
    172183        restore %o0, 0, %o0
  • boot/arch/sparc64/loader/asm.h

    ra11099f re731b0d  
    3434#include "main.h"
    3535
    36 #define PAGE_WIDTH      14
    37 #define PAGE_SIZE       (1 << PAGE_WIDTH)
     36#define PAGE_WIDTH  14
     37#define PAGE_SIZE   (1 << PAGE_WIDTH)
    3838
    39 #define memcpy(dst, src, cnt)  __builtin_memcpy((dst), (src), (cnt))
     39#define BALLOC_MAX_SIZE  (128 * 1024)
    4040
    4141extern void halt(void);
    4242extern void jump_to_kernel(void *entry, uint64_t cfg, bootinfo_t *bootinfo,
    43         unsigned int bootinfo_size) __attribute__((noreturn));
     43    unsigned int bootinfo_size, uint8_t subarchitecture) __attribute__((noreturn));
    4444
    4545#endif
  • boot/arch/sparc64/loader/main.c

    ra11099f re731b0d  
    11/*
    22 * Copyright (c) 2005 Martin Decky
    3  * Copyright (c) 2006 Jakub Jermar 
     3 * Copyright (c) 2006 Jakub Jermar
    44 * All rights reserved.
    55 *
     
    2828 */
    2929
    30 #include "main.h" 
     30#include "main.h"
    3131#include <printf.h>
    3232#include "asm.h"
     
    3939#include <macros.h>
    4040#include <string.h>
    41 
    42 bootinfo_t bootinfo;
    43 
    44 component_t components[COMPONENTS];
    45 
    46 char *release = STRING(RELEASE);
     41#include <memstr.h>
     42
     43static bootinfo_t bootinfo;
     44static component_t components[COMPONENTS];
     45static char *release = STRING(RELEASE);
    4746
    4847#ifdef REVISION
    49         char *revision = ", revision " STRING(REVISION);
     48        static char *revision = ", revision " STRING(REVISION);
    5049#else
    51         char *revision = "";
     50        static char *revision = "";
    5251#endif
    5352
    5453#ifdef TIMESTAMP
    55         char *timestamp = "\nBuilt on " STRING(TIMESTAMP);
     54        static char *timestamp = "\nBuilt on " STRING(TIMESTAMP);
    5655#else
    57         char *timestamp = "";
     56        static char *timestamp = "";
    5857#endif
    5958
    6059/** UltraSPARC subarchitecture - 1 for US, 3 for US3 */
    61 uint8_t subarchitecture;
     60static uint8_t subarchitecture;
    6261
    6362/**
     
    6564 * MID_SHIFT bits to the right
    6665 */
    67 uint16_t mid_mask;
     66static uint16_t mid_mask;
    6867
    6968/** Print version information. */
     
    7675
    7776/* the lowest ID (read from the VER register) of some US3 CPU model */
    78 #define FIRST_US3_CPU   0x14
     77#define FIRST_US3_CPU  0x14
    7978
    8079/* the greatest ID (read from the VER register) of some US3 CPU model */
    81 #define LAST_US3_CPU    0x19
     80#define LAST_US3_CPU   0x19
    8281
    8382/* UltraSPARC IIIi processor implementation code */
    84 #define US_IIIi_CODE    0x15
     83#define US_IIIi_CODE   0x15
    8584
    8685/**
     
    9190{
    9291        uint64_t v;
    93         asm volatile ("rdpr %%ver, %0\n" : "=r" (v));
     92        asm volatile (
     93                "rdpr %%ver, %0\n"
     94                : "=r" (v)
     95        );
    9496       
    9597        v = (v << 16) >> 48;
     
    103105                subarchitecture = SUBARCH_US;
    104106                mid_mask = (1 << 5) - 1;
    105         } else {
     107        } else
    106108                printf("\nThis CPU is not supported by HelenOS.");
    107         }
    108109}
    109110
     
    113114        void *balloc_base;
    114115        unsigned int top = 0;
    115         int i, j;
    116 
     116        unsigned int i;
     117        unsigned int j;
     118       
    117119        version_print();
    118120       
    119121        detect_subarchitecture();
    120122        init_components(components);
    121 
     123       
    122124        if (!ofw_get_physmem_start(&bootinfo.physmem_start)) {
    123125                printf("Error: unable to get start of physical memory.\n");
    124126                halt();
    125127        }
    126 
     128       
    127129        if (!ofw_memmap(&bootinfo.memmap)) {
    128130                printf("Error: unable to get memory map, halting.\n");
    129131                halt();
    130132        }
    131 
     133       
    132134        if (bootinfo.memmap.total == 0) {
    133135                printf("Error: no memory detected, halting.\n");
    134136                halt();
    135137        }
    136 
     138       
    137139        /*
    138140         * SILO for some reason adds 0x400000 and subtracts
     
    143145                silo_ramdisk_image += bootinfo.physmem_start;
    144146                silo_ramdisk_image -= 0x400000;
    145                 /* Install 1:1 mapping for the ramdisk. */
    146                 if (ofw_map((void *)((uintptr_t) silo_ramdisk_image),
    147                     (void *)((uintptr_t) silo_ramdisk_image),
     147               
     148                /* Install 1:1 mapping for the RAM disk. */
     149                if (ofw_map((void *) ((uintptr_t) silo_ramdisk_image),
     150                    (void *) ((uintptr_t) silo_ramdisk_image),
    148151                    silo_ramdisk_size, -1) != 0) {
    149                         printf("Failed to map ramdisk.\n");
     152                        printf("Failed to map RAM disk.\n");
    150153                        halt();
    151154                }
    152155        }
    153156       
    154         printf("\nSystem info\n");
    155         printf(" memory: %dM starting at %P\n",
     157        printf("\nMemory statistics (total %d MB, starting at %P)\n",
    156158            bootinfo.memmap.total >> 20, bootinfo.physmem_start);
    157 
    158         printf("\nMemory statistics\n");
    159         printf(" kernel entry point at %P\n", KERNEL_VIRTUAL_ADDRESS);
     159        printf(" %P: kernel entry point\n", KERNEL_VIRTUAL_ADDRESS);
    160160        printf(" %P: boot info structure\n", &bootinfo);
    161161       
     
    176176                                break;
    177177                        }
     178                       
    178179                        bootinfo.taskmap.tasks[bootinfo.taskmap.count].addr =
    179180                            base + top;
     
    187188                top += components[i].size;
    188189        }
    189 
    190         j = bootinfo.taskmap.count - 1; /* do not consider ramdisk */
    191 
     190       
     191        /* Do not consider RAM disk */
     192        j = bootinfo.taskmap.count - 1;
     193       
    192194        if (silo_ramdisk_image) {
    193                 /* Treat the ramdisk as the last bootinfo task. */
     195                /* Treat the RAM disk as the last bootinfo task. */
    194196                if (bootinfo.taskmap.count == TASKMAP_MAX_RECORDS) {
    195                         printf("Skipping ramdisk.\n");
     197                        printf("Skipping RAM disk.\n");
    196198                        goto skip_ramdisk;
    197199                }
     200               
    198201                top = ALIGN_UP(top, PAGE_SIZE);
    199202                bootinfo.taskmap.tasks[bootinfo.taskmap.count].addr =
     
    202205                    silo_ramdisk_size;
    203206                bootinfo.taskmap.count++;
    204                 printf("\nCopying ramdisk...");
     207                printf("\nCopying RAM disk...");
     208               
    205209                /*
    206210                 * Claim and map the whole ramdisk as it may exceed the area
     
    210214                (void) ofw_map(bootinfo.physmem_start + base + top, base + top,
    211215                    silo_ramdisk_size, -1);
    212                 memmove(base + top, (void *)((uintptr_t)silo_ramdisk_image),
     216                memmove(base + top, (void *) ((uintptr_t) silo_ramdisk_image),
    213217                    silo_ramdisk_size);
     218               
    214219                printf("done.\n");
    215220                top += silo_ramdisk_size;
    216221        }
    217222skip_ramdisk:
    218 
     223       
    219224        /*
    220225         * Now we can proceed to copy the components. We do it in reverse order
     
    222227         * with base.
    223228         */
    224         printf("\nCopying bootinfo tasks\n");
     229        printf("\nCopying tasks...");
    225230        for (i = COMPONENTS - 1; i > 0; i--, j--) {
    226                 printf(" %s...", components[i].name);
    227 
     231                printf("%s ", components[i].name);
     232               
    228233                /*
    229234                 * At this point, we claim the physical memory that we are
     
    240245                    bootinfo.taskmap.tasks[j].addr,
    241246                    ALIGN_UP(components[i].size, PAGE_SIZE));
    242                    
    243                 memcpy((void *)bootinfo.taskmap.tasks[j].addr,
     247               
     248                memcpy((void *) bootinfo.taskmap.tasks[j].addr,
    244249                    components[i].start, components[i].size);
    245                 printf("done.\n");
    246         }
    247 
     250               
     251        }
     252        printf(".\n");
     253       
    248254        printf("\nCopying kernel...");
    249255        (void) ofw_claim_phys(bootinfo.physmem_start + base,
     
    251257        memcpy(base, components[0].start, components[0].size);
    252258        printf("done.\n");
    253 
     259       
    254260        /*
    255261         * Claim and map the physical memory for the boot allocator.
     
    261267        (void) ofw_map(bootinfo.physmem_start + balloc_base, balloc_base,
    262268            BALLOC_MAX_SIZE, -1);
    263         balloc_init(&bootinfo.ballocs, (uintptr_t)balloc_base);
    264 
     269        balloc_init(&bootinfo.ballocs, (uintptr_t) balloc_base,
     270            (uintptr_t) balloc_base);
     271       
    265272        printf("\nCanonizing OpenFirmware device tree...");
    266273        bootinfo.ofw_root = ofw_tree_build();
    267274        printf("done.\n");
    268 
     275       
    269276#ifdef CONFIG_AP
    270277        printf("\nChecking for secondary processors...");
    271         if (!ofw_cpu())
     278        if (!ofw_cpu(mid_mask, bootinfo.physmem_start))
    272279                printf("Error: unable to get CPU properties\n");
    273280        printf("done.\n");
    274281#endif
    275 
     282       
    276283        ofw_setup_palette();
    277 
     284       
    278285        printf("\nBooting the kernel...\n");
    279286        jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS,
    280287            bootinfo.physmem_start | BSP_PROCESSOR, &bootinfo,
    281             sizeof(bootinfo));
     288            sizeof(bootinfo), subarchitecture);
    282289}
  • boot/arch/sparc64/loader/main.h

    ra11099f re731b0d  
    3535#include <types.h>
    3636
    37 #define KERNEL_VIRTUAL_ADDRESS 0x400000
     37#define KERNEL_VIRTUAL_ADDRESS  0x400000
    3838
    39 #define TASKMAP_MAX_RECORDS 32
     39#define TASKMAP_MAX_RECORDS  32
    4040
    4141/** Size of buffer for storing task name in task_t. */
    42 #define BOOTINFO_TASK_NAME_BUFLEN 32
     42#define BOOTINFO_TASK_NAME_BUFLEN  32
    4343
    44 #define BSP_PROCESSOR   1
    45 #define AP_PROCESSOR    0
     44#define BSP_PROCESSOR  1
     45#define AP_PROCESSOR   0
    4646
    47 #define SUBARCH_US      1
    48 #define SUBARCH_US3     3
     47#define SUBARCH_US   1
     48#define SUBARCH_US3  3
    4949
    5050typedef struct {
     
    7070extern uint32_t silo_ramdisk_size;
    7171
    72 extern bootinfo_t bootinfo;
    73 
    7472extern void start(void);
    7573extern void bootstrap(void);
  • boot/arch/sparc64/loader/ofwarch.c

    ra11099f re731b0d  
    3030/**
    3131 * @file
    32  * @brief       Architecture dependent parts of OpenFirmware interface.
     32 * @brief Architecture dependent parts of OpenFirmware interface.
    3333 */
    3434
     
    4040#include "main.h"
    4141#include "asm.h"
    42 
    43 /* these tho variables will be set by the detect_subarchitecture function */
    44 extern uint8_t subarchitecture;
    45 extern uint16_t mid_mask;
    4642
    4743void write(const char *str, const int len)
     
    6561 * except for the current CPU.
    6662 *
    67  * @param child         The first child of the OFW tree node whose children
    68  *                      represent CPUs to be woken up.
    69  * @param current_mid   MID of the current CPU, the current CPU will
    70  *                      (of course) not be woken up.
    71  * @return              Number of CPUs which have the same parent node as
    72  *                      "child".
     63 * @param child         The first child of the OFW tree node whose children
     64 *                      represent CPUs to be woken up.
     65 * @param current_mid   MID of the current CPU, the current CPU will
     66 *                      (of course) not be woken up.
     67 * @param physmem_start Starting address of the physical memory.
     68 *
     69 * @return Number of CPUs which have the same parent node as
     70 *         "child".
     71 *
    7372 */
    74 static int wake_cpus_in_node(phandle child, uint64_t current_mid)
     73static int wake_cpus_in_node(phandle child, uint64_t current_mid,
     74    uintptr_t physmem_start)
    7575{
    7676        int cpus;
    77         char type_name[BUF_SIZE];
    7877       
    79         for (cpus = 0; child != 0 && child != -1;
     78        for (cpus = 0; (child != 0) && (child != -1);
    8079            child = ofw_get_peer_node(child), cpus++) {
     80                char type_name[BUF_SIZE];
     81               
    8182                if (ofw_get_property(child, "device_type", type_name,
    8283                    sizeof(type_name)) > 0) {
     
    8889                                 * "cpuid" for US-IV
    8990                                 */
    90                                 if (ofw_get_property(
    91                                     child, "upa-portid",
    92                                     &mid, sizeof(mid)) <= 0
    93                                     && ofw_get_property(child, "portid",
    94                                     &mid, sizeof(mid)) <= 0
    95                                     && ofw_get_property(child, "cpuid",
    96                                     &mid, sizeof(mid)) <= 0)
     91                                if ((ofw_get_property(child, "upa-portid", &mid, sizeof(mid)) <= 0)
     92                                    && (ofw_get_property(child, "portid", &mid, sizeof(mid)) <= 0)
     93                                    && (ofw_get_property(child, "cpuid", &mid, sizeof(mid)) <= 0))
    9794                                        continue;
    98                                        
     95                               
    9996                                if (current_mid != mid) {
    10097                                        /*
     
    103100                                        (void) ofw_call("SUNW,start-cpu", 3, 1,
    104101                                            NULL, child, KERNEL_VIRTUAL_ADDRESS,
    105                                             bootinfo.physmem_start |
    106                                             AP_PROCESSOR);
     102                                            physmem_start | AP_PROCESSOR);
    107103                                }
    108104                        }
    109105                }
    110106        }
    111 
     107       
    112108        return cpus;
    113109}
     
    116112 * Finds out the current CPU's MID and wakes up all AP processors.
    117113 */
    118 int ofw_cpu(void)
     114int ofw_cpu(uint16_t mid_mask, uintptr_t physmem_start)
    119115{
    120         int cpus;
    121         phandle node;
    122         phandle subnode;
    123         phandle cpus_parent;
    124         phandle cmp;
    125         char name[BUF_SIZE];
    126 
    127         /* get the current CPU MID */
     116        /* Get the current CPU MID */
    128117        uint64_t current_mid;
    129118       
    130         asm volatile ("ldxa [%1] %2, %0\n"
    131             : "=r" (current_mid)
    132             : "r" (0), "i" (ASI_ICBUS_CONFIG));
     119        asm volatile (
     120                "ldxa [%1] %2, %0\n"
     121                : "=r" (current_mid)
     122                : "r" (0), "i" (ASI_ICBUS_CONFIG)
     123        );
     124       
    133125        current_mid >>= ICBUS_CONFIG_MID_SHIFT;
    134 
    135126        current_mid &= mid_mask;
    136 
    137         /* wake up CPUs */
    138127       
    139         cpus_parent = ofw_find_device("/ssm@0,0");
    140         if (cpus_parent == 0 || cpus_parent == -1) {
     128        /* Wake up the CPUs */
     129       
     130        phandle cpus_parent = ofw_find_device("/ssm@0,0");
     131        if ((cpus_parent == 0) || (cpus_parent == -1))
    141132                cpus_parent = ofw_find_device("/");
    142         }
    143 
    144         node = ofw_get_child_node(cpus_parent);
    145         cpus = wake_cpus_in_node(node, current_mid);
    146         while (node != 0 && node != -1) {
     133       
     134        phandle node = ofw_get_child_node(cpus_parent);
     135        int cpus = wake_cpus_in_node(node, current_mid, physmem_start);
     136        while ((node != 0) && (node != -1)) {
     137                char name[BUF_SIZE];
     138               
    147139                if (ofw_get_property(node, "name", name,
    148                         sizeof(name)) > 0) {
     140                    sizeof(name)) > 0) {
    149141                        if (strcmp(name, "cmp") == 0) {
    150                                 subnode = ofw_get_child_node(node);
     142                                phandle subnode = ofw_get_child_node(node);
    151143                                cpus += wake_cpus_in_node(subnode,
    152                                         current_mid);
     144                                        current_mid, physmem_start);
    153145                        }
    154146                }
     
    157149       
    158150        return cpus;
    159        
    160151}
    161152
    162153/** Get physical memory starting address.
    163154 *
    164  * @param start         Pointer to variable where the physical memory starting
    165  *                      address will be stored.
     155 * @param start Pointer to variable where the physical memory starting
     156 *              address will be stored.
    166157 *
    167  * @return              Non-zero on succes, zero on failure.
     158 * @return Non-zero on succes, zero on failure.
     159 *
    168160 */
    169161int ofw_get_physmem_start(uintptr_t *start)
    170162{
    171163        uint32_t memreg[4];
    172 
    173164        if (ofw_get_property(ofw_memory, "reg", &memreg, sizeof(memreg)) <= 0)
    174165                return 0;
    175 
     166       
    176167        *start = (((uint64_t) memreg[0]) << 32) | memreg[1];
    177168        return 1;
    178169}
    179 
  • boot/arch/sparc64/loader/ofwarch.h

    ra11099f re731b0d  
    3333#include "types.h"
    3434
    35 #define OFW_ADDRESS_CELLS       2
    36 #define OFW_SIZE_CELLS          2
     35#define OFW_ADDRESS_CELLS  2
     36#define OFW_SIZE_CELLS     2
    3737
    38 extern int ofw_cpu(void);
    39 extern int ofw_get_physmem_start(uintptr_t *start); 
     38extern int ofw_cpu(uint16_t mid_mask, uintptr_t physmem_start);
     39extern int ofw_get_physmem_start(uintptr_t *start);
    4040
    4141#endif
  • boot/genarch/balloc.c

    ra11099f re731b0d  
    2828
    2929#include <balloc.h>
     30#include <asm.h>
    3031#include <types.h>
    3132#include <align.h>
    3233
    3334static ballocs_t *ballocs;
     35static uintptr_t phys_base;
    3436
    35 void balloc_init(ballocs_t *b, uintptr_t base)
     37void balloc_init(ballocs_t *ball, uintptr_t base, uintptr_t kernel_base)
    3638{
    37         ballocs = b;
    38         ballocs->base = base;
     39        ballocs = ball;
     40        phys_base = base;
     41        ballocs->base = kernel_base;
    3942        ballocs->size = 0;
    4043}
     
    4245void *balloc(size_t size, size_t alignment)
    4346{
    44         uintptr_t addr;
    45 
    4647        /* Enforce minimal alignment. */
    4748        alignment = ALIGN_UP(alignment, 4);
    4849       
    49         addr = ballocs->base + ALIGN_UP(ballocs->size, alignment);
    50 
     50        uintptr_t addr = phys_base + ALIGN_UP(ballocs->size, alignment);
     51       
    5152        if (ALIGN_UP(ballocs->size, alignment) + size > BALLOC_MAX_SIZE)
    5253                return NULL;
    53                
     54       
    5455        ballocs->size = ALIGN_UP(ballocs->size, alignment) + size;
    5556       
    5657        return (void *) addr;
    5758}
     59
     60void *balloc_rebase(void *ptr)
     61{
     62        return (void *) ((uintptr_t) ptr - phys_base + ballocs->base);
     63}
  • boot/genarch/balloc.h

    ra11099f re731b0d  
    3232#include <types.h>
    3333
    34 #define BALLOC_MAX_SIZE         (128 * 1024)
    35 
    3634typedef struct {
    3735        uintptr_t base;
     
    3937} ballocs_t;
    4038
    41 extern void balloc_init(ballocs_t *b, uintptr_t base);
     39extern void balloc_init(ballocs_t *ball, uintptr_t base, uintptr_t kernel_base);
    4240extern void *balloc(size_t size, size_t alignment);
     41extern void *balloc_rebase(void *ptr);
    4342
    4443#endif
  • boot/genarch/ofw.c

    ra11099f re731b0d  
    3333#include <types.h>
    3434
     35#define RED(i)    (((i) >> 5) & ((1 << 3) - 1))
     36#define GREEN(i)  (((i) >> 3) & ((1 << 2) - 1))
     37#define BLUE(i)   ((i) & ((1 << 3) - 1))
     38#define CLIP(i)   ((i) <= 255 ? (i) : 255)
     39
    3540uintptr_t ofw_cif;
    3641
     
    8590/** Perform a call to OpenFirmware client interface.
    8691 *
    87  * @param service       String identifying the service requested.
    88  * @param nargs         Number of input arguments.
    89  * @param nret          Number of output arguments. This includes the return
    90  *                      value.
    91  * @param rets          Buffer for output arguments or NULL. The buffer must
    92  *                      accommodate nret - 1 items.
    93  *
    94  * @return              Return value returned by the client interface.
     92 * @param service String identifying the service requested.
     93 * @param nargs   Number of input arguments.
     94 * @param nret    Number of output arguments. This includes the return
     95 *                value.
     96 * @param rets    Buffer for output arguments or NULL. The buffer must
     97 *                accommodate nret - 1 items.
     98 *
     99 * @return Return value returned by the client interface.
     100 *
    95101 */
    96102unsigned long
     
    221227}
    222228
    223 void *ofw_claim_virt(const void *virt, const int len)
     229void *ofw_claim_virt(const void *virt, const unsigned int len)
    224230{
    225231        ofw_arg_t retaddr;
     
    234240}
    235241
    236 void *ofw_claim_phys(const void *phys, const int len)
    237 {
    238         ofw_arg_t retaddr[2];
    239         int shift;
    240 
     242static void *ofw_claim_phys_internal(const void *phys, const unsigned int len, const unsigned int alignment)
     243{
     244        /*
     245         * Note that the return value check will help
     246         * us to discover conflicts between OpenFirmware
     247         * allocations and our use of physical memory.
     248         * It is better to detect collisions here
     249         * than to cope with weird errors later.
     250         *
     251         * So this is really not to make the loader
     252         * more generic; it is here for debugging
     253         * purposes.
     254         */
     255       
    241256        if (sizeof(unative_t) == 8) {
    242                 shift = 32;
     257                ofw_arg_t retaddr[2];
     258                int shift = 32;
     259               
    243260                if (ofw_call("call-method", 6, 3, retaddr, "claim",
    244                     ofw_memory_prop, 0, len, ((uintptr_t) phys) >> shift,
     261                    ofw_memory_prop, alignment, len, ((uintptr_t) phys) >> shift,
    245262                    ((uintptr_t) phys) & ((uint32_t) -1)) != 0) {
    246                         /*
    247                          * Note that this will help us to discover
    248                          * conflicts between OpenFirmware allocations
    249                          * and our use of physical memory.
    250                          * It is better to detect collisions here
    251                          * than to cope with weird errors later.
    252                          *
    253                          * So this is really not to make the loader
    254                          * more generic; it is here for debugging
    255                          * purposes.
    256                          */
    257263                        puts("Error: memory method claim() failed, halting.\n");
    258264                        halt();
    259265                }
     266               
     267                return (void *) ((retaddr[0] << shift) | retaddr[1]);
    260268        } else {
    261                 shift = 0;
    262                 /*
    263                  * FIXME: the number of arguments is probably different...
    264                  */
    265                 puts("Error: 32-bit ofw_claim_phys not implemented.\n");
    266                 halt();
    267         }
    268 
    269         return (void *) ((retaddr[0] << shift) | retaddr[1]);
    270 }
    271 
    272 int ofw_map(const void *phys, const void *virt, const int size, const int mode)
     269                ofw_arg_t retaddr[1];
     270               
     271                if (ofw_call("call-method", 5, 2, retaddr, "claim",
     272                    ofw_memory_prop, alignment, len, (uintptr_t) phys) != 0) {
     273                        puts("Error: memory method claim() failed, halting.\n");
     274                        halt();
     275                }
     276               
     277                return (void *) retaddr[0];
     278        }
     279}
     280
     281void *ofw_claim_phys(const void *phys, const unsigned int len)
     282{
     283        return ofw_claim_phys_internal(phys, len, 0);
     284}
     285
     286void *ofw_claim_phys_any(const unsigned int len, const unsigned int alignment)
     287{
     288        return ofw_claim_phys_internal(NULL, len, alignment);
     289}
     290
     291int ofw_map(const void *phys, const void *virt, const unsigned int size, const int mode)
    273292{
    274293        uintptr_t phys_hi, phys_lo;
     
    314333
    315334                /*
    316                  * This is a hot fix of the issue which occurs on machines
    317                  * where there are holes in the physical memory (such as
    318                  * SunBlade 1500). Should we detect a hole in the physical
    319                  * memory, we will ignore any memory detected behind
    320                  * the hole and pretend the hole does not exist.
     335                 * This is a hot fix of the issue which occurs on machines
     336                 * where there are holes in the physical memory (such as
     337                 * SunBlade 1500). Should we detect a hole in the physical
     338                 * memory, we will ignore any memory detected behind
     339                 * the hole and pretend the hole does not exist.
    321340                 */
    322341                if ((map->count > 0) && (map->zones[map->count - 1].start +
     
    335354}
    336355
    337 int ofw_screen(screen_t *screen)
    338 {
    339         char device_name[BUF_SIZE];
    340         uint32_t virtaddr;
    341        
    342         if (ofw_get_property(ofw_aliases, "screen", device_name,
    343             sizeof(device_name)) <= 0)
    344                 return false;
    345        
    346         phandle device = ofw_find_device(device_name);
    347         if (device == -1)
    348                 return false;
    349        
    350         if (ofw_get_property(device, "address", &virtaddr,
    351             sizeof(virtaddr)) <= 0)
    352                 return false;
    353 
    354         screen->addr = (void *) ((uintptr_t) virtaddr);
    355 
    356         if (ofw_get_property(device, "width", &screen->width,
    357             sizeof(screen->width)) <= 0)
    358                 return false;
    359        
    360         if (ofw_get_property(device, "height", &screen->height,
    361             sizeof(screen->height)) <= 0)
    362                 return false;
    363        
    364         if (ofw_get_property(device, "depth", &screen->bpp,
    365             sizeof(screen->bpp)) <= 0)
    366                 return false;
    367        
    368         if (ofw_get_property(device, "linebytes", &screen->scanline,
    369             sizeof(screen->scanline)) <= 0)
    370                 return false;
    371        
    372         return true;
    373 }
    374 
    375 #define RED(i)    (((i) >> 5) & ((1 << 3) - 1))
    376 #define GREEN(i)  (((i) >> 3) & ((1 << 2) - 1))
    377 #define BLUE(i)   ((i) & ((1 << 3) - 1))
    378 #define CLIP(i)   ((i) <= 255 ? (i) : 255)
    379 
    380 
    381356/**
    382357 * Sets up the palette for the 8-bit color depth configuration so that the
     
    392367        char device_name[BUF_SIZE];
    393368       
    394         /* resolve alias */
     369        /* Resolve alias */
    395370        if (ofw_get_property(ofw_aliases, "screen", device_name,
    396371            sizeof(device_name)) <= 0)
    397372                return false;
    398373       
    399         /* for depth greater than 8 it makes no sense to set up the palette */
     374        /* For depth greater than 8 it makes no sense to set up the palette */
    400375        uint32_t depth;
    401376        phandle device = ofw_find_device(device_name);
     
    407382                return false;
    408383       
    409         /* required in order to be able to make a method call */
     384        /* Required in order to be able to make a method call */
    410385        ihandle screen = ofw_open(device_name);
    411386        if (screen == -1)
    412387                return false;
    413388       
    414         /* setup the palette so that the (inverted) 3:2:3 scheme is usable */
     389        /* Setup the palette so that the (inverted) 3:2:3 scheme is usable */
    415390        unsigned int i;
    416391        for (i = 0; i < 256; i++)
  • boot/genarch/ofw.h

    ra11099f re731b0d  
    3333#include <stdarg.h>
    3434
    35 #define BUF_SIZE                1024
     35#define BUF_SIZE  1024
    3636
    37 #define MEMMAP_MAX_RECORDS      32
     37#define MEMMAP_MAX_RECORDS  32
    3838
    39 #define MAX_OFW_ARGS            12
     39#define MAX_OFW_ARGS  12
    4040
    4141typedef unative_t ofw_arg_t;
     
    4747 */
    4848typedef struct {
    49         ofw_arg_t service;              /**< Command name. */
    50         ofw_arg_t nargs;                /**< Number of in arguments. */
    51         ofw_arg_t nret;                 /**< Number of out arguments. */
    52         ofw_arg_t args[MAX_OFW_ARGS];   /**< List of arguments. */
     49        ofw_arg_t service;             /**< Command name. */
     50        ofw_arg_t nargs;               /**< Number of in arguments. */
     51        ofw_arg_t nret;                /**< Number of out arguments. */
     52        ofw_arg_t args[MAX_OFW_ARGS];  /**< List of arguments. */
    5353} ofw_args_t;
    5454
     
    6363        memzone_t zones[MEMMAP_MAX_RECORDS];
    6464} memmap_t;
    65 
    66 typedef struct {
    67         void *addr;
    68         uint32_t width;
    69         uint32_t height;
    70         uint32_t bpp;
    71         uint32_t scanline;
    72 } screen_t;
    73 
    74 typedef struct {
    75         void *addr;
    76         uint32_t size;
    77 } macio_t;
    7865
    7966typedef struct {
     
    118105extern void *ofw_translate(const void *virt);
    119106extern int ofw_translate_failed(ofw_arg_t flag);
    120 extern void *ofw_claim_virt(const void *virt, const int len);
    121 extern void *ofw_claim_phys(const void *virt, const int len);
    122 extern int ofw_map(const void *phys, const void *virt, const int size, const int mode);
     107extern void *ofw_claim_virt(const void *virt, const unsigned int len);
     108extern void *ofw_claim_phys(const void *virt, const unsigned int len);
     109extern void *ofw_claim_phys_any(const unsigned int len, const unsigned int alignment);
     110extern int ofw_map(const void *phys, const void *virt, const unsigned int size, const int mode);
    123111extern int ofw_memmap(memmap_t *map);
    124 extern int ofw_screen(screen_t *screen);
    125 extern int ofw_macio(macio_t *macio);
    126112extern int ofw_setup_palette(void);
    127113extern void ofw_quiesce(void);
  • boot/genarch/ofw_tree.c

    ra11099f re731b0d  
    2929#include <ofw_tree.h>
    3030#include <ofw.h>
     31#include <ofwarch.h>
    3132#include <types.h>
    3233#include <string.h>
    3334#include <balloc.h>
    3435#include <asm.h>
    35 
    36 #define MAX_PATH_LEN    256
     36#include <memstr.h>
     37
     38#define MAX_PATH_LEN  256
    3739
    3840static ofw_tree_node_t *ofw_tree_node_alloc(void)
     
    4951static void *ofw_tree_space_alloc(size_t size)
    5052{
    51         char *addr;
    52 
    5353        /*
    5454         * What we do here is a nasty hack :-)
     
    6161         * behind the requested memory.
    6262         */
    63         addr = balloc(size + 1, size);
     63        char *addr = balloc(size + 1, size);
    6464        if (addr)
    6565                addr[size] = '\0';
     66       
    6667        return addr;
    6768}
     
    7576 * order to prevent stack from overflowing.
    7677 *
    77  * @param current_node  Pointer to uninitialized ofw_tree_node structure that
    78  *                      will become the memory represenation of 'current'.
    79  * @param parent_node   Parent ofw_tree_node structure or NULL in case of root
    80  *                      node.
    81  * @param current       OpenFirmware phandle to the current device tree node.
     78 * @param current_node Pointer to uninitialized ofw_tree_node structure that
     79 *                     will become the memory represenation of 'current'.
     80 * @param parent_node  Parent ofw_tree_node structure or NULL in case of root
     81 *                     node.
     82 * @param current      OpenFirmware phandle to the current device tree node.
     83 *
    8284 */
    8385static void ofw_tree_node_process(ofw_tree_node_t *current_node,
    8486    ofw_tree_node_t *parent_node, phandle current)
    8587{
    86         static char path[MAX_PATH_LEN + 1];
    87         static char name[OFW_TREE_PROPERTY_MAX_NAMELEN];
    88         static char name2[OFW_TREE_PROPERTY_MAX_NAMELEN];
    89         phandle peer;
    90         phandle child;
    91         size_t len;
    92         int i;
    93 
    9488        while (current_node) {
    9589                /*
    9690                 * Initialize node.
    9791                 */
    98                 current_node->parent = parent_node;
     92                current_node->parent = (ofw_tree_node_t *) balloc_rebase(parent_node);
    9993                current_node->peer = NULL;
    10094                current_node->child = NULL;
     
    10397                current_node->property = NULL;
    10498                current_node->device = NULL;
    105        
     99               
    106100                /*
    107101                 * Get the disambigued name.
    108102                 */
    109                 len = ofw_package_to_path(current, path, MAX_PATH_LEN);
     103                static char path[MAX_PATH_LEN + 1];
     104                size_t len = ofw_package_to_path(current, path, MAX_PATH_LEN);
    110105                if (len == -1)
    111106                        return;
    112        
     107               
    113108                path[len] = '\0';
    114                 for (i = len - 1; i >= 0 && path[i] != '/'; i--)
    115                         ;
    116                 i++;    /* do not include '/' */
    117        
     109               
     110                /* Find last slash */
     111                int i;
     112                for (i = len - 1; (i >= 0) && (path[i] != '/'); i--);
     113               
     114                /* Do not include the slash */
     115                i++;
    118116                len -= i;
    119 
    120                 /* add space for trailing '\0' */
    121                 current_node->da_name = ofw_tree_space_alloc(len + 1);
    122                 if (!current_node->da_name)
    123                         return;
    124        
    125                 memcpy(current_node->da_name, &path[i], len);
    126                 current_node->da_name[len] = '\0';
    127        
     117               
     118                /* Add space for trailing '\0' */
     119                char *da_name = ofw_tree_space_alloc(len + 1);
     120                if (!da_name)
     121                        return;
     122               
     123                memcpy(da_name, &path[i], len);
     124                da_name[len] = '\0';
     125                current_node->da_name = (char *) balloc_rebase(da_name);
     126               
    128127                /*
    129128                 * Recursively process the potential child node.
    130129                 */
    131                 child = ofw_get_child_node(current);
    132                 if (child != 0 && child != -1) {
    133                         ofw_tree_node_t *child_node;
    134                
    135                         child_node = ofw_tree_node_alloc();
     130                phandle child = ofw_get_child_node(current);
     131                if ((child != 0) && (child != -1)) {
     132                        ofw_tree_node_t *child_node = ofw_tree_node_alloc();
    136133                        if (child_node) {
    137134                                ofw_tree_node_process(child_node, current_node,
    138135                                    child);
    139                                 current_node->child = child_node;
     136                                current_node->child =
     137                                    (ofw_tree_node_t *) balloc_rebase(child_node);
    140138                        }
    141139                }
    142        
     140               
    143141                /*
    144142                 * Count properties.
    145143                 */
     144                static char name[OFW_TREE_PROPERTY_MAX_NAMELEN];
     145                static char name2[OFW_TREE_PROPERTY_MAX_NAMELEN];
    146146                name[0] = '\0';
    147147                while (ofw_next_property(current, name, name2) == 1) {
     
    149149                        memcpy(name, name2, OFW_TREE_PROPERTY_MAX_NAMELEN);
    150150                }
    151 
     151               
    152152                if (!current_node->properties)
    153153                        return;
    154        
     154               
    155155                /*
    156156                 * Copy properties.
    157157                 */
    158                 current_node->property =
     158                ofw_tree_property_t *property =
    159159                    ofw_tree_properties_alloc(current_node->properties);
    160                 if (!current_node->property)
     160                if (!property)
    161161                        return;
    162162               
    163163                name[0] = '\0';
    164164                for (i = 0; ofw_next_property(current, name, name2) == 1; i++) {
    165                         size_t size;
    166                
    167165                        if (i == current_node->properties)
    168166                                break;
    169                
     167                       
    170168                        memcpy(name, name2, OFW_TREE_PROPERTY_MAX_NAMELEN);
    171                         memcpy(current_node->property[i].name, name,
    172                             OFW_TREE_PROPERTY_MAX_NAMELEN);
    173                         current_node->property[i].name[
    174                             OFW_TREE_PROPERTY_MAX_NAMELEN] = '\0';
    175 
    176                         size = ofw_get_proplen(current, name);
    177                         current_node->property[i].size = size;
     169                        memcpy(property[i].name, name, OFW_TREE_PROPERTY_MAX_NAMELEN);
     170                        property[i].name[OFW_TREE_PROPERTY_MAX_NAMELEN] = '\0';
     171                       
     172                        size_t size = ofw_get_proplen(current, name);
     173                        property[i].size = size;
     174                       
    178175                        if (size) {
    179                                 void *buf;
    180                        
    181                                 buf = ofw_tree_space_alloc(size);
    182                                 if (current_node->property[i].value = buf) {
     176                                void *buf = ofw_tree_space_alloc(size);
     177                                if (buf) {
    183178                                        /*
    184179                                         * Copy property value to memory node.
    185180                                         */
    186                                         (void) ofw_get_property(current, name,
    187                                             buf, size);
     181                                        (void) ofw_get_property(current, name, buf, size);
     182                                        property[i].value = balloc_rebase(buf);
    188183                                }
    189                         } else {
    190                                 current_node->property[i].value = NULL;
    191                         }
    192                 }
    193 
     184                        } else
     185                                property[i].value = NULL;
     186                }
     187               
    194188                /* Just in case we ran out of memory. */
    195189                current_node->properties = i;
    196 
     190                current_node->property = (ofw_tree_property_t *) balloc_rebase(property);
     191               
     192               
    197193                /*
    198194                 * Iteratively process the next peer node.
     
    202198                 * risk of overflowing the stack is too real.
    203199                 */
    204                 peer = ofw_get_peer_node(current);
    205                 if (peer != 0 && peer != -1) {
    206                         ofw_tree_node_t *peer_node;
    207                
    208                         peer_node = ofw_tree_node_alloc();
    209                         if (peer_node) {
    210                                 current_node->peer = peer_node;
     200                phandle peer = ofw_get_peer_node(current);
     201                if ((peer != 0) && (peer != -1)) {
     202                        ofw_tree_node_t *peer_node = ofw_tree_node_alloc();
     203                        if (peer_node) {
     204                                current_node->peer = (ofw_tree_node_t *) balloc_rebase(peer_node);
    211205                                current_node = peer_node;
    212206                                current = peer;
     
    217211                        }
    218212                }
     213               
    219214                /*
    220215                 * No more peers on this level.
     
    226221/** Construct memory representation of OpenFirmware device tree.
    227222 *
    228  * @return              NULL on failure or pointer to the root node.
     223 * @return NULL on failure or kernel pointer to the root node.
     224 *
    229225 */
    230226ofw_tree_node_t *ofw_tree_build(void)
    231227{
    232         ofw_tree_node_t *root;
    233         phandle ssm_node;
    234         ofw_tree_node_t *ssm;
    235        
    236         root = ofw_tree_node_alloc();
     228        ofw_tree_node_t *root = ofw_tree_node_alloc();
    237229        if (root)
    238230                ofw_tree_node_process(root, NULL, ofw_root);
    239 
     231       
    240232        /*
    241233         * The firmware client interface does not automatically include the
     
    243235         * solution is to explicitly stick "ssm" to the OFW tree.
    244236         */
    245         ssm_node = ofw_find_device("/ssm@0,0");
     237        phandle ssm_node = ofw_find_device("/ssm@0,0");
    246238        if (ssm_node != -1) {
    247                 ssm = ofw_tree_node_alloc();
     239                ofw_tree_node_t *ssm = ofw_tree_node_alloc();
    248240                if (ssm) {
    249241                        ofw_tree_node_process(ssm, root,
    250242                            ofw_find_device("/ssm@0,0"));
    251243                        ssm->peer = root->child;
    252                         root->child = ssm;
     244                        root->child = (ofw_tree_node_t *) balloc_rebase(ssm);
    253245                }
    254246        }
    255247       
    256         return root;
    257 }
     248        return (ofw_tree_node_t *) balloc_rebase(root);
     249}
  • boot/genarch/ofw_tree.h

    ra11099f re731b0d  
    3333#include <ofw.h>
    3434
    35 #define OFW_TREE_PROPERTY_MAX_NAMELEN   32
    36 
    37 typedef struct ofw_tree_node ofw_tree_node_t;
    38 typedef struct ofw_tree_property ofw_tree_property_t;
    39 
    40 /** Memory representation of OpenFirmware device tree node. */
    41 struct ofw_tree_node {
    42         ofw_tree_node_t *parent;
    43         ofw_tree_node_t *peer;
    44         ofw_tree_node_t *child;
    45 
    46         uint32_t node_handle;                   /**< Old OpenFirmware node handle. */
    47 
    48         char *da_name;                          /**< Disambigued name. */
    49 
    50         unsigned properties;                    /**< Number of properties. */
    51         ofw_tree_property_t *property;
    52        
    53         void *device;                           /**< Member used solely by the kernel. */
    54 };
     35#define OFW_TREE_PROPERTY_MAX_NAMELEN  32
    5536
    5637/** Memory representation of OpenFirmware device tree node property. */
    57 struct ofw_tree_property {
     38typedef struct {
    5839        char name[OFW_TREE_PROPERTY_MAX_NAMELEN];
    5940        size_t size;
    6041        void *value;
    61 };
     42} ofw_tree_property_t;
     43
     44/** Memory representation of OpenFirmware device tree node. */
     45typedef struct ofw_tree_node {
     46        struct ofw_tree_node *parent;
     47        struct ofw_tree_node *peer;
     48        struct ofw_tree_node *child;
     49       
     50        uint32_t node_handle;           /**< Old OpenFirmware node handle. */
     51       
     52        char *da_name;                  /**< Disambigued name. */
     53       
     54        unsigned int properties;        /**< Number of properties. */
     55        ofw_tree_property_t *property;
     56       
     57        void *device;                   /**< Member used solely by the kernel. */
     58} ofw_tree_node_t;
    6259
    6360extern ofw_tree_node_t *ofw_tree_build(void);
  • boot/generic/printf.c

    ra11099f re731b0d  
    2727 */
    2828
    29 /** @addtogroup generic 
     29/** @addtogroup generic
    3030 * @{
    3131 */
  • boot/generic/printf.h

    ra11099f re731b0d  
    2727 */
    2828
    29 /** @addtogroup generic 
     29/** @addtogroup generic
    3030 * @{
    3131 */
  • boot/generic/stdarg.h

    ra11099f re731b0d  
    3838typedef __builtin_va_list va_list;
    3939
    40 #define va_start(ap, last)              __builtin_va_start(ap, last)
    41 #define va_arg(ap, type)                __builtin_va_arg(ap, type)
    42 #define va_end(ap)                      __builtin_va_end(ap)
     40#define va_start(ap, last)   __builtin_va_start(ap, last)
     41#define va_arg(ap, type)     __builtin_va_arg(ap, type)
     42#define va_end(ap)           __builtin_va_end(ap)
    4343
    4444#endif
  • kernel/arch/ppc32/include/boot/boot.h

    ra11099f re731b0d  
    4141#define TEMP_STACK_SIZE  0x1000
    4242
    43 #define TASKMAP_MAX_RECORDS  32
    44 #define MEMMAP_MAX_RECORDS   32
     43#define TASKMAP_MAX_RECORDS        32
     44#define MEMMAP_MAX_RECORDS         32
     45#define BOOTINFO_TASK_NAME_BUFLEN  32
    4546
    4647#ifndef __ASM__
    4748
    48 #define BOOTINFO_TASK_NAME_BUFLEN 32
    49 
    5049#include <arch/types.h>
     50#include <config.h>
     51#include <genarch/ofw/ofw_tree.h>
    5152
    5253typedef struct {
     
    7374
    7475typedef struct {
    75         uintptr_t addr;
    76         unsigned int width;
    77         unsigned int height;
    78         unsigned int bpp;
    79         unsigned int scanline;
    80 } screen_t;
    81 
    82 typedef struct {
    83         uintptr_t addr;
    84         unsigned int size;
    85 } macio_t;
    86 
    87 typedef struct {
    8876        memmap_t memmap;
    8977        taskmap_t taskmap;
    90         screen_t screen;
    91         macio_t macio;
     78        ballocs_t ballocs;
     79        ofw_tree_node_t *ofw_root;
    9280} bootinfo_t;
    9381
  • kernel/arch/ppc32/src/mm/tlb.c

    ra11099f re731b0d  
    4545static unsigned int seed = 10;
    4646static unsigned int seed_real __attribute__ ((section("K_UNMAPPED_DATA_START"))) = 42;
    47 
    48 
    49 #define TLB_FLUSH \
    50         "tlbie %0\n" \
    51         "addi %0, %0, 0x1000\n"
    5247
    5348
     
    451446                "sync\n"
    452447               
    453                 TLB_FLUSH
    454                 TLB_FLUSH
    455                 TLB_FLUSH
    456                 TLB_FLUSH
    457                 TLB_FLUSH
    458                 TLB_FLUSH
    459                 TLB_FLUSH
    460                 TLB_FLUSH
    461                
    462                 TLB_FLUSH
    463                 TLB_FLUSH
    464                 TLB_FLUSH
    465                 TLB_FLUSH
    466                 TLB_FLUSH
    467                 TLB_FLUSH
    468                 TLB_FLUSH
    469                 TLB_FLUSH
    470                
    471                 TLB_FLUSH
    472                 TLB_FLUSH
    473                 TLB_FLUSH
    474                 TLB_FLUSH
    475                 TLB_FLUSH
    476                 TLB_FLUSH
    477                 TLB_FLUSH
    478                 TLB_FLUSH
    479                
    480                 TLB_FLUSH
    481                 TLB_FLUSH
    482                 TLB_FLUSH
    483                 TLB_FLUSH
    484                 TLB_FLUSH
    485                 TLB_FLUSH
    486                 TLB_FLUSH
    487                 TLB_FLUSH
    488                
    489                 TLB_FLUSH
    490                 TLB_FLUSH
    491                 TLB_FLUSH
    492                 TLB_FLUSH
    493                 TLB_FLUSH
    494                 TLB_FLUSH
    495                 TLB_FLUSH
    496                 TLB_FLUSH
    497                
    498                 TLB_FLUSH
    499                 TLB_FLUSH
    500                 TLB_FLUSH
    501                 TLB_FLUSH
    502                 TLB_FLUSH
    503                 TLB_FLUSH
    504                 TLB_FLUSH
    505                 TLB_FLUSH
    506                
    507                 TLB_FLUSH
    508                 TLB_FLUSH
    509                 TLB_FLUSH
    510                 TLB_FLUSH
    511                 TLB_FLUSH
    512                 TLB_FLUSH
    513                 TLB_FLUSH
    514                 TLB_FLUSH
    515                
    516                 TLB_FLUSH
    517                 TLB_FLUSH
    518                 TLB_FLUSH
    519                 TLB_FLUSH
    520                 TLB_FLUSH
    521                 TLB_FLUSH
    522                 TLB_FLUSH
    523                 TLB_FLUSH
     448                ".rept 64\n"
     449                "tlbie %0\n"
     450                "addi %0, %0, 0x1000\n"
     451                ".endr\n"
    524452               
    525453                "eieio\n"
  • kernel/arch/ppc32/src/ppc32.c

    ra11099f re731b0d  
    4141#include <genarch/fb/fb.h>
    4242#include <genarch/fb/visuals.h>
     43#include <genarch/ofw/ofw_tree.h>
     44#include <genarch/ofw/pci.h>
    4345#include <userspace.h>
    4446#include <proc/uarg.h>
     
    4951#include <macros.h>
    5052#include <string.h>
     53#include <print.h>
    5154
    5255#define IRQ_COUNT  64
     
    6366       
    6467        for (i = 0; i < min3(bootinfo.taskmap.count, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS); i++) {
    65                 init.tasks[i].addr = PA2KA(bootinfo.taskmap.tasks[i].addr);
     68                init.tasks[i].addr = bootinfo.taskmap.tasks[i].addr;
    6669                init.tasks[i].size = bootinfo.taskmap.tasks[i].size;
    6770                str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN,
    6871                    bootinfo.taskmap.tasks[i].name);
    6972        }
     73       
     74        /* Copy boot allocations info. */
     75        ballocs.base = bootinfo.ballocs.base;
     76        ballocs.size = bootinfo.ballocs.size;
     77       
     78        ofw_tree_init(bootinfo.ofw_root);
    7079}
    7180
     
    7483        /* Initialize dispatch table */
    7584        interrupt_init();
    76 
     85       
    7786        /* Start decrementer */
    7887        start_decrementer();
    7988}
    8089
     90static bool display_register(ofw_tree_node_t *node, void *arg)
     91{
     92        uintptr_t fb_addr = 0;
     93        uint32_t fb_width = 0;
     94        uint32_t fb_height = 0;
     95        uint32_t fb_scanline = 0;
     96        unsigned int visual = VISUAL_UNKNOWN;
     97       
     98        ofw_tree_property_t *prop = ofw_tree_getprop(node, "address");
     99        if ((prop) && (prop->value))
     100                fb_addr = *((uintptr_t *) prop->value);
     101       
     102        prop = ofw_tree_getprop(node, "width");
     103        if ((prop) && (prop->value))
     104                fb_width = *((uint32_t *) prop->value);
     105       
     106        prop = ofw_tree_getprop(node, "height");
     107        if ((prop) && (prop->value))
     108                fb_height = *((uint32_t *) prop->value);
     109       
     110        prop = ofw_tree_getprop(node, "depth");
     111        if ((prop) && (prop->value)) {
     112                uint32_t fb_bpp = *((uint32_t *) prop->value);
     113                switch (fb_bpp) {
     114                case 8:
     115                        visual = VISUAL_INDIRECT_8;
     116                        break;
     117                case 16:
     118                        visual = VISUAL_RGB_5_5_5_BE;
     119                        break;
     120                case 24:
     121                        visual = VISUAL_BGR_8_8_8;
     122                        break;
     123                case 32:
     124                        visual = VISUAL_RGB_0_8_8_8;
     125                        break;
     126                default:
     127                        visual = VISUAL_UNKNOWN;
     128                }
     129        }
     130       
     131        prop = ofw_tree_getprop(node, "linebytes");
     132        if ((prop) && (prop->value))
     133                fb_scanline = *((uint32_t *) prop->value);
     134       
     135        if ((fb_addr) && (fb_width > 0) && (fb_height > 0)
     136            && (fb_scanline > 0) && (visual != VISUAL_UNKNOWN)) {
     137                fb_properties_t fb_prop = {
     138                        .addr = fb_addr,
     139                        .offset = 0,
     140                        .x = fb_width,
     141                        .y = fb_height,
     142                        .scan = fb_scanline,
     143                        .visual = visual,
     144                };
     145                fb_init(&fb_prop);
     146        }
     147       
     148        /* Consider only a single device for now */
     149        return false;
     150}
     151
    81152void arch_post_mm_init(void)
    82153{
    83154        if (config.cpu_active == 1) {
    84 
    85155#ifdef CONFIG_FB
    86                 /* Initialize framebuffer */
    87                 if (bootinfo.screen.addr) {
    88                         unsigned int visual;
    89                        
    90                         switch (bootinfo.screen.bpp) {
    91                         case 8:
    92                                 visual = VISUAL_INDIRECT_8;
    93                                 break;
    94                         case 16:
    95                                 visual = VISUAL_RGB_5_5_5_BE;
    96                                 break;
    97                         case 24:
    98                                 visual = VISUAL_BGR_8_8_8;
    99                                 break;
    100                         case 32:
    101                                 visual = VISUAL_RGB_0_8_8_8;
    102                                 break;
    103                         default:
    104                                 panic("Unsupported bits per pixel.");
    105                         }
    106                         fb_properties_t prop = {
    107                                 .addr = bootinfo.screen.addr,
    108                                 .offset = 0,
    109                                 .x = bootinfo.screen.width,
    110                                 .y = bootinfo.screen.height,
    111                                 .scan = bootinfo.screen.scanline,
    112                                 .visual = visual,
    113                         };
    114                         fb_init(&prop);
    115                 }
     156                ofw_tree_walk_by_device_type("display", display_register, NULL);
    116157#endif
    117158               
     
    132173}
    133174
    134 void arch_post_smp_init(void)
    135 {
    136         if (bootinfo.macio.addr) {
     175static bool macio_register(ofw_tree_node_t *node, void *arg)
     176{
     177        ofw_pci_reg_t *assigned_address = NULL;
     178       
     179        ofw_tree_property_t *prop = ofw_tree_getprop(node, "assigned-addresses");
     180        if ((prop) && (prop->value))
     181                assigned_address = ((ofw_pci_reg_t *) prop->value);
     182       
     183        if (assigned_address) {
    137184                /* Initialize PIC */
    138185                cir_t cir;
    139186                void *cir_arg;
    140                 pic_init(bootinfo.macio.addr, PAGE_SIZE, &cir, &cir_arg);
    141 
     187                pic_init(assigned_address[0].addr, PAGE_SIZE, &cir, &cir_arg);
     188               
    142189#ifdef CONFIG_MAC_KBD
    143                 uintptr_t pa = bootinfo.macio.addr + 0x16000;
     190                uintptr_t pa = assigned_address[0].addr + 0x16000;
    144191                uintptr_t aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE);
    145192                size_t offset = pa - aligned_addr;
    146193                size_t size = 2 * PAGE_SIZE;
    147                        
     194               
    148195                cuda_t *cuda = (cuda_t *)
    149196                    (hw_map(aligned_addr, offset + size) + offset);
    150                        
     197               
    151198                /* Initialize I/O controller */
    152199                cuda_instance_t *cuda_instance =
     
    163210#endif
    164211        }
     212       
     213        /* Consider only a single device for now */
     214        return false;
     215}
     216
     217void arch_post_smp_init(void)
     218{
     219        ofw_tree_walk_by_device_type("mac-io", macio_register, NULL);
    165220}
    166221
  • kernel/arch/sparc64/include/drivers/fhc.h

    ra11099f re731b0d  
    2727 */
    2828
    29 /** @addtogroup sparc64 
     29/** @addtogroup sparc64
    3030 * @{
    3131 */
  • kernel/arch/sparc64/src/drivers/fhc.c

    ra11099f re731b0d  
    4646#include <arch/types.h>
    4747#include <genarch/ofw/ofw_tree.h>
     48#include <genarch/ofw/fhc.h>
    4849#include <sysinfo/sysinfo.h>
    4950
  • kernel/arch/sparc64/src/drivers/kbd.c

    ra11099f re731b0d  
    3535#include <arch/drivers/kbd.h>
    3636#include <genarch/ofw/ofw_tree.h>
    37 
    38 #ifdef CONFIG_SUN_KBD
    39 #include <genarch/kbrd/kbrd.h>
    40 #endif
    41 #ifdef CONFIG_Z8530
    42 #include <genarch/drivers/z8530/z8530.h>
    43 #endif
    44 #ifdef CONFIG_NS16550
    45 #include <genarch/drivers/ns16550/ns16550.h>
    46 #endif
    47 
     37#include <genarch/ofw/fhc.h>
     38#include <genarch/ofw/ebus.h>
    4839#include <console/console.h>
    4940#include <ddi/irq.h>
     
    5647
    5748#ifdef CONFIG_SUN_KBD
     49#include <genarch/kbrd/kbrd.h>
     50#endif
     51
     52#ifdef CONFIG_Z8530
     53#include <genarch/drivers/z8530/z8530.h>
     54#endif
     55
     56#ifdef CONFIG_NS16550
     57#include <genarch/drivers/ns16550/ns16550.h>
     58#endif
     59
     60#ifdef CONFIG_SUN_KBD
    5861
    5962#ifdef CONFIG_Z8530
  • kernel/arch/sparc64/src/drivers/pci.c

    ra11099f re731b0d  
    3737#include <arch/drivers/pci.h>
    3838#include <genarch/ofw/ofw_tree.h>
     39#include <genarch/ofw/upa.h>
    3940#include <arch/trap/interrupt.h>
    4041#include <mm/page.h>
  • kernel/arch/sparc64/src/drivers/scr.c

    ra11099f re731b0d  
    3535#include <arch/drivers/scr.h>
    3636#include <genarch/ofw/ofw_tree.h>
     37#include <genarch/ofw/pci.h>
     38#include <genarch/ofw/sbus.h>
     39#include <genarch/ofw/upa.h>
    3740#include <genarch/fb/fb.h>
    3841#include <genarch/fb/visuals.h>
  • kernel/genarch/Makefile.inc

    ra11099f re731b0d  
    130130ifeq ($(CONFIG_OFW_TREE),y)
    131131        GENARCH_SOURCES += \
    132                 genarch/src/ofw/ofw_tree.c \
     132                genarch/src/ofw/ofw_tree.c
     133endif
     134
     135ifeq ($(CONFIG_OFW_PCI),y)
     136        GENARCH_SOURCES += \
    133137                genarch/src/ofw/ebus.c \
    134138                genarch/src/ofw/fhc.c \
    135139                genarch/src/ofw/pci.c  \
    136140                genarch/src/ofw/sbus.c \
    137                 genarch/src/ofw/upa.c 
     141                genarch/src/ofw/upa.c
    138142endif
    139143
  • kernel/genarch/include/ofw/ofw_tree.h

    ra11099f re731b0d  
    3131
    3232#include <arch/types.h>
    33 #include <ddi/irq.h>
    3433#include <typedefs.h>
    3534
    36 #define OFW_TREE_PROPERTY_MAX_NAMELEN   32
     35#define OFW_TREE_PROPERTY_MAX_NAMELEN  32
    3736
    38 typedef struct ofw_tree_node ofw_tree_node_t;
    39 typedef struct ofw_tree_property ofw_tree_property_t;
     37/** Memory representation of OpenFirmware device tree node property. */
     38typedef struct {
     39        char name[OFW_TREE_PROPERTY_MAX_NAMELEN];
     40        size_t size;
     41        void *value;
     42} ofw_tree_property_t;
    4043
    4144/** Memory representation of OpenFirmware device tree node. */
    42 struct ofw_tree_node {
    43         ofw_tree_node_t *parent;
    44         ofw_tree_node_t *peer;
    45         ofw_tree_node_t *child;
    46 
    47         uint32_t node_handle;           /**< Old OpenFirmware node handle. */
    48 
    49         char *da_name;                  /**< Disambigued name. */
    50 
    51         unsigned properties;            /**< Number of properties. */
     45typedef struct ofw_tree_node {
     46        struct ofw_tree_node *parent;
     47        struct ofw_tree_node *peer;
     48        struct ofw_tree_node *child;
     49       
     50        uint32_t node_handle;           /**< Old OpenFirmware node handle. */
     51       
     52        char *da_name;                  /**< Disambigued name. */
     53       
     54        unsigned int properties;        /**< Number of properties. */
    5255        ofw_tree_property_t *property;
    5356       
     
    5760         */
    5861        void *device;
    59 };
     62} ofw_tree_node_t;
    6063
    61 /** Memory representation of OpenFirmware device tree node property. */
    62 struct ofw_tree_property {
    63         char name[OFW_TREE_PROPERTY_MAX_NAMELEN];
    64         size_t size;
    65         void *value;
    66 };
    67 
    68 /*
    69  * Definition of 'reg' and 'ranges' properties for various buses.
    70  */
    71  
    72 struct ofw_fhc_reg {
    73         uint64_t addr;
    74         uint32_t size;
    75 } __attribute__ ((packed));
    76 typedef struct ofw_fhc_reg ofw_fhc_reg_t;
    77                        
    78 struct ofw_fhc_range {
    79         uint64_t child_base;
    80         uint64_t parent_base;
    81         uint32_t size;
    82 } __attribute__ ((packed));
    83 typedef struct ofw_fhc_range ofw_fhc_range_t;
    84 
    85 struct ofw_central_reg {
    86         uint64_t addr;
    87         uint32_t size;
    88 } __attribute__ ((packed));
    89 typedef struct ofw_central_reg ofw_central_reg_t;
    90 
    91 struct ofw_central_range {
    92         uint64_t child_base;
    93         uint64_t parent_base;
    94         uint32_t size;
    95 } __attribute__ ((packed));
    96 typedef struct ofw_central_range ofw_central_range_t;
    97 
    98 struct ofw_ebus_reg {
    99         uint32_t space;
    100         uint32_t addr;
    101         uint32_t size;
    102 } __attribute__ ((packed));
    103 typedef struct ofw_ebus_reg ofw_ebus_reg_t;
    104 
    105 struct ofw_ebus_range {
    106         uint32_t child_space;
    107         uint32_t child_base;
    108         uint32_t parent_space;
    109         uint64_t parent_base;   /* group phys.mid and phys.lo together */
    110         uint32_t size;
    111 } __attribute__ ((packed));
    112 typedef struct ofw_ebus_range ofw_ebus_range_t;
    113 
    114 struct ofw_ebus_intr_map {
    115         uint32_t space;
    116         uint32_t addr;
    117         uint32_t intr;
    118         uint32_t controller_handle;
    119         uint32_t controller_ino;
    120 } __attribute__ ((packed));
    121 typedef struct ofw_ebus_intr_map ofw_ebus_intr_map_t;
    122 
    123 struct ofw_ebus_intr_mask {
    124         uint32_t space_mask;
    125         uint32_t addr_mask;
    126         uint32_t intr_mask;
    127 } __attribute__ ((packed));
    128 typedef struct ofw_ebus_intr_mask ofw_ebus_intr_mask_t;
    129 
    130 struct ofw_pci_reg {
    131         uint32_t space;         /* needs to be masked to obtain pure space id */
    132         uint64_t addr;          /* group phys.mid and phys.lo together */
    133         uint64_t size;
    134 } __attribute__ ((packed));
    135 typedef struct ofw_pci_reg ofw_pci_reg_t;
    136 
    137 struct ofw_pci_range {
    138         uint32_t space;
    139         uint64_t child_base;    /* group phys.mid and phys.lo together */
    140         uint64_t parent_base;
    141         uint64_t size;
    142 } __attribute__ ((packed));
    143 typedef struct ofw_pci_range ofw_pci_range_t;
    144 
    145 struct ofw_sbus_reg {
    146         uint64_t addr;
    147         uint32_t size;
    148 } __attribute__ ((packed));
    149 typedef struct ofw_sbus_reg ofw_sbus_reg_t;
    150 
    151 struct ofw_sbus_range {
    152         uint64_t child_base;
    153         uint64_t parent_base;
    154         uint32_t size;
    155 } __attribute__ ((packed));
    156 typedef struct ofw_sbus_range ofw_sbus_range_t;
    157 
    158 struct ofw_upa_reg {
    159         uint64_t addr;
    160         uint64_t size;
    161 } __attribute__ ((packed));
    162 typedef struct ofw_upa_reg ofw_upa_reg_t;
     64/* Walker for visiting OpenFirmware device tree nodes. */
     65typedef bool (* ofw_tree_walker_t)(ofw_tree_node_t *, void *);
    16366
    16467extern void ofw_tree_init(ofw_tree_node_t *);
    16568extern void ofw_tree_print(void);
     69
    16670extern const char *ofw_tree_node_name(const ofw_tree_node_t *);
    16771extern ofw_tree_node_t *ofw_tree_lookup(const char *);
    16872extern ofw_tree_property_t *ofw_tree_getprop(const ofw_tree_node_t *,
    16973    const char *);
     74extern void ofw_tree_walk_by_device_type(const char *, ofw_tree_walker_t,
     75    void *);
     76
    17077extern ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *, const char *);
    17178extern ofw_tree_node_t *ofw_tree_find_child_by_device_type(ofw_tree_node_t *,
    17279    const char *);
     80
    17381extern ofw_tree_node_t *ofw_tree_find_peer_by_device_type(ofw_tree_node_t *,
    17482    const char *);
    175 extern ofw_tree_node_t *ofw_tree_find_peer_by_name(ofw_tree_node_t *node,
    176     const char *name);
     83extern ofw_tree_node_t *ofw_tree_find_peer_by_name(ofw_tree_node_t *,
     84    const char *);
    17785extern ofw_tree_node_t *ofw_tree_find_node_by_handle(ofw_tree_node_t *,
    17886    uint32_t);
    17987
    180 extern bool ofw_fhc_apply_ranges(ofw_tree_node_t *, ofw_fhc_reg_t *,
    181     uintptr_t *);
    182 extern bool ofw_central_apply_ranges(ofw_tree_node_t *, ofw_central_reg_t *,
    183     uintptr_t *);
    184 extern bool ofw_ebus_apply_ranges(ofw_tree_node_t *, ofw_ebus_reg_t *,
    185     uintptr_t *);
    186 extern bool ofw_pci_apply_ranges(ofw_tree_node_t *, ofw_pci_reg_t *,
    187     uintptr_t *);
    188 extern bool ofw_sbus_apply_ranges(ofw_tree_node_t *, ofw_sbus_reg_t *,
    189     uintptr_t *);
    190 extern bool ofw_upa_apply_ranges(ofw_tree_node_t *, ofw_upa_reg_t *,
    191     uintptr_t *);
    192 
    193 extern bool ofw_pci_reg_absolutize(ofw_tree_node_t *, ofw_pci_reg_t *,
    194     ofw_pci_reg_t *);
    195 
    196 extern bool ofw_fhc_map_interrupt(ofw_tree_node_t *, ofw_fhc_reg_t *,
    197     uint32_t, int *, cir_t *, void **);
    198 extern bool ofw_ebus_map_interrupt(ofw_tree_node_t *, ofw_ebus_reg_t *,
    199     uint32_t, int *, cir_t *, void **);
    200 extern bool ofw_pci_map_interrupt(ofw_tree_node_t *, ofw_pci_reg_t *,
    201     int, int *, cir_t *, void **);
    202 
    20388#endif
  • kernel/genarch/src/ofw/ebus.c

    ra11099f re731b0d  
    3737
    3838#include <genarch/ofw/ofw_tree.h>
     39#include <genarch/ofw/ebus.h>
     40#include <genarch/ofw/pci.h>
    3941#include <arch/memstr.h>
    40 #include <arch/trap/interrupt.h>
    4142#include <string.h>
    4243#include <panic.h>
  • kernel/genarch/src/ofw/fhc.c

    ra11099f re731b0d  
    3737
    3838#include <genarch/ofw/ofw_tree.h>
     39#include <genarch/ofw/fhc.h>
    3940#include <arch/drivers/fhc.h>
    4041#include <arch/memstr.h>
  • kernel/genarch/src/ofw/ofw_tree.c

    ra11099f re731b0d  
    3232/**
    3333 * @file
    34  * @brief       OpenFirmware device tree navigation.
     34 * @brief OpenFirmware device tree navigation.
    3535 *
    3636 */
     
    4040#include <mm/slab.h>
    4141#include <string.h>
     42#include <panic.h>
    4243#include <print.h>
    43 #include <panic.h>
    44 
    45 #define PATH_MAX_LEN    80
    46 #define NAME_BUF_LEN    50
     44
     45#define PATH_MAX_LEN  256
     46#define NAME_BUF_LEN  50
    4747
    4848static ofw_tree_node_t *ofw_root;
     
    5555/** Get OpenFirmware node property.
    5656 *
    57  * @param node          Node in which to lookup the property.
    58  * @param name          Name of the property.
    59  *
    60  * @return              Pointer to the property structure or NULL if no such
    61  *                      property.
    62  */
    63 ofw_tree_property_t *
    64 ofw_tree_getprop(const ofw_tree_node_t *node, const char *name)
     57 * @param node Node in which to lookup the property.
     58 * @param name Name of the property.
     59 *
     60 * @return Pointer to the property structure or NULL if no such
     61 *         property.
     62 *
     63 */
     64ofw_tree_property_t *ofw_tree_getprop(const ofw_tree_node_t *node,
     65    const char *name)
    6566{
    6667        unsigned int i;
     
    7071                        return &node->property[i];
    7172        }
    72 
     73       
    7374        return NULL;
    7475}
     
    7677/** Return value of the 'name' property.
    7778 *
    78  * @param node          Node of interest.
    79  *
    80  * @return              Value of the 'name' property belonging to the node.
     79 * @param node Node of interest.
     80 *
     81 * @return Value of the 'name' property belonging to the node
     82 *         or NULL if the property is invalid.
     83 *
    8184 */
    8285const char *ofw_tree_node_name(const ofw_tree_node_t *node)
    8386{
    84         ofw_tree_property_t *prop;
    85        
    86         prop = ofw_tree_getprop(node, "name");
    87         if (!prop)
    88                 panic("Node without name property.");
    89                
    90         if (prop->size < 2)
    91                 panic("Invalid name property.");
     87        ofw_tree_property_t *prop = ofw_tree_getprop(node, "name");
     88        if ((!prop) || (prop->size < 2))
     89                return NULL;
    9290       
    9391        return prop->value;
     
    9694/** Lookup child of given name.
    9795 *
    98  * @param node          Node whose child is being looked up.
    99  * @param name          Name of the child being looked up.
    100  *
    101  * @return              NULL if there is no such child or pointer to the
    102  *                      matching child node.
    103  */
    104 ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *node, const char *name)
     96 * @param node Node whose child is being looked up.
     97 * @param name Name of the child being looked up.
     98 *
     99 * @return NULL if there is no such child or pointer to the
     100 *         matching child node.
     101 *
     102 */
     103ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *node,
     104    const char *name)
    105105{
    106106        ofw_tree_node_t *cur;
     
    125125                        return cur;
    126126        }
    127                
     127       
    128128        return NULL;
    129129}
     
    131131/** Lookup first child of given device type.
    132132 *
    133  * @param node          Node whose child is being looked up.
    134  * @param name          Device type of the child being looked up.
    135  *
    136  * @return              NULL if there is no such child or pointer to the
    137  *                      matching child node.
    138  */
    139 ofw_tree_node_t *
    140 ofw_tree_find_child_by_device_type(ofw_tree_node_t *node, const char *name)
    141 {
    142         ofw_tree_node_t *cur;
    143         ofw_tree_property_t *prop;
     133 * @param node  Node whose child is being looked up.
     134 * @param dtype Device type of the child being looked up.
     135 *
     136 * @return NULL if there is no such child or pointer to the
     137 *         matching child node.
     138 *
     139 */
     140ofw_tree_node_t *ofw_tree_find_child_by_device_type(ofw_tree_node_t *node,
     141    const char *dtype)
     142{
     143        ofw_tree_node_t *cur;
    144144       
    145145        for (cur = node->child; cur; cur = cur->peer) {
    146                 prop = ofw_tree_getprop(cur, "device_type");
    147                 if (!prop || !prop->value)
     146                ofw_tree_property_t *prop =
     147                    ofw_tree_getprop(cur, "device_type");
     148               
     149                if ((!prop) || (!prop->value))
    148150                        continue;
    149                 if (str_cmp(prop->value, name) == 0)
    150                         return cur;
    151         }
    152                        
     151               
     152                if (str_cmp(prop->value, dtype) == 0)
     153                        return cur;
     154        }
     155       
    153156        return NULL;
    154157}
     
    159162 * are looked up iteratively to avoid stack overflow.
    160163 *
    161  * @param root          Root of the searched subtree.
    162  * @param handle        OpenFirmware handle.
    163  *
    164  * @return              NULL if there is no such node or pointer to the matching
    165  *                      node.
    166  */
    167 ofw_tree_node_t *
    168 ofw_tree_find_node_by_handle(ofw_tree_node_t *root, uint32_t handle)
    169 {
    170         ofw_tree_node_t *cur;
    171 
    172         for (cur = root; cur; cur = cur->peer) {               
     164 * @param root   Root of the searched subtree.
     165 * @param handle OpenFirmware handle.
     166 *
     167 * @return NULL if there is no such node or pointer to the matching
     168 *         node.
     169 *
     170 */
     171ofw_tree_node_t *ofw_tree_find_node_by_handle(ofw_tree_node_t *root,
     172    uint32_t handle)
     173{
     174        ofw_tree_node_t *cur;
     175       
     176        for (cur = root; cur; cur = cur->peer) {
    173177                if (cur->node_handle == handle)
    174178                        return cur;
    175 
     179               
    176180                if (cur->child) {
    177                         ofw_tree_node_t *node;
    178                        
    179                         node = ofw_tree_find_node_by_handle(cur->child, handle);
     181                        ofw_tree_node_t *node
     182                            = ofw_tree_find_node_by_handle(cur->child, handle);
    180183                        if (node)
    181184                                return node;
     
    183186        }
    184187       
    185         return NULL;   
     188        return NULL;
    186189}
    187190
    188191/** Lookup first peer of given device type.
    189192 *
    190  * @param node          Node whose peer is being looked up.
    191  * @param name          Device type of the child being looked up.
    192  *
    193  * @return              NULL if there is no such child or pointer to the
    194  *                      matching child node.
    195  */
    196 ofw_tree_node_t *
    197 ofw_tree_find_peer_by_device_type(ofw_tree_node_t *node, const char *name)
    198 {
    199         ofw_tree_node_t *cur;
    200         ofw_tree_property_t *prop;
     193 * @param node  Node whose peer is being looked up.
     194 * @param dtype Device type of the child being looked up.
     195 *
     196 * @return NULL if there is no such child or pointer to the
     197 *         matching child node.
     198 *
     199 */
     200ofw_tree_node_t *ofw_tree_find_peer_by_device_type(ofw_tree_node_t *node,
     201    const char *dtype)
     202{
     203        ofw_tree_node_t *cur;
    201204       
    202205        for (cur = node->peer; cur; cur = cur->peer) {
    203                 prop = ofw_tree_getprop(cur, "device_type");
    204                 if (!prop || !prop->value)
     206                ofw_tree_property_t *prop =
     207                    ofw_tree_getprop(cur, "device_type");
     208               
     209                if ((!prop) || (!prop->value))
    205210                        continue;
     211               
     212                if (str_cmp(prop->value, dtype) == 0)
     213                        return cur;
     214        }
     215       
     216        return NULL;
     217}
     218
     219/** Lookup first peer of given name.
     220 *
     221 * @param node Node whose peer is being looked up.
     222 * @param name Name of the child being looked up.
     223 *
     224 * @return NULL if there is no such peer or pointer to the matching
     225 *         peer node.
     226 *
     227 */
     228ofw_tree_node_t *ofw_tree_find_peer_by_name(ofw_tree_node_t *node,
     229    const char *name)
     230{
     231        ofw_tree_node_t *cur;
     232       
     233        for (cur = node->peer; cur; cur = cur->peer) {
     234                ofw_tree_property_t *prop
     235                    = ofw_tree_getprop(cur, "name");
     236               
     237                if ((!prop) || (!prop->value))
     238                        continue;
     239               
    206240                if (str_cmp(prop->value, name) == 0)
    207241                        return cur;
    208242        }
    209                        
    210         return NULL;
    211 }
    212 
    213 
    214 /** Lookup first peer of given name.
    215  *
    216  * @param node          Node whose peer is being looked up.
    217  * @param name          Name of the child being looked up.
    218  *
    219  * @return              NULL if there is no such peer or pointer to the matching
    220  *                      peer node.
    221  */
    222 ofw_tree_node_t *
    223 ofw_tree_find_peer_by_name(ofw_tree_node_t *node, const char *name)
    224 {
    225         ofw_tree_node_t *cur;
    226         ofw_tree_property_t *prop;
    227        
    228         for (cur = node->peer; cur; cur = cur->peer) {
    229                 prop = ofw_tree_getprop(cur, "name");
    230                 if (!prop || !prop->value)
    231                         continue;
    232                 if (str_cmp(prop->value, name) == 0)
    233                         return cur;
    234         }
    235                        
     243       
    236244        return NULL;
    237245}
     
    239247/** Lookup OpenFirmware node by its path.
    240248 *
    241  * @param path          Path to the node.
    242  *
    243  * @return              NULL if there is no such node or pointer to the leaf
    244  *                      node.
     249 * @param path Path to the node.
     250 *
     251 * @return NULL if there is no such node or pointer to the leaf
     252 *         node.
     253 *
    245254 */
    246255ofw_tree_node_t *ofw_tree_lookup(const char *path)
    247256{
    248         char buf[NAME_BUF_LEN + 1];
     257        if (path[0] != '/')
     258                return NULL;
     259       
    249260        ofw_tree_node_t *node = ofw_root;
    250261        size_t i;
    251262        size_t j;
    252263       
    253         if (path[0] != '/')
    254                 return NULL;
    255        
    256264        for (i = 1; (i < str_size(path)) && (node); i = j + 1) {
    257265                for (j = i; (j < str_size(path)) && (path[j] != '/'); j++);
     
    261269                        continue;
    262270               
     271                char buf[NAME_BUF_LEN + 1];
    263272                memcpy(buf, &path[i], j - i);
    264273                buf[j - i] = 0;
     
    269278}
    270279
    271 /** Print OpenFirmware device subtree rooted in a node.
     280/** Walk the OpenFirmware device subtree rooted in a node.
    272281 *
    273282 * Child nodes are processed recursively and peer nodes are processed
    274283 * iteratively in order to avoid stack overflow.
    275284 *
    276  * @param node          Root of the subtree.
    277  * @param path          Current path, NULL for the very root of the entire tree.
    278  */
    279 static void ofw_tree_node_print(const ofw_tree_node_t *node, const char *path)
    280 {
    281         char *p;
    282         const ofw_tree_node_t *cur;
    283 
    284         p = (char *) malloc(PATH_MAX_LEN, 0);
    285 
     285 * @param node   Root of the subtree.
     286 * @param dtype  Device type to look for.
     287 * @param walker Routine to be invoked on found device.
     288 * @param arg    User argument to the walker.
     289 *
     290 * @return True if the walk should continue.
     291 *
     292 */
     293static bool ofw_tree_walk_by_device_type_internal(ofw_tree_node_t *node,
     294    const char *dtype, ofw_tree_walker_t walker, void *arg)
     295{
     296        ofw_tree_node_t *cur;
     297       
    286298        for (cur = node; cur; cur = cur->peer) {
    287                 if (cur->parent) {
    288                         snprintf(p, PATH_MAX_LEN, "%s/%s", path, cur->da_name);
    289                         printf("%s\n", p);
     299                ofw_tree_property_t *prop =
     300                    ofw_tree_getprop(cur, "device_type");
     301               
     302                if ((prop) && (prop->value) && (str_cmp(prop->value, dtype) == 0)) {
     303                        bool ret = walker(cur, arg);
     304                        if (!ret)
     305                                return false;
     306                }
     307               
     308                if (cur->child) {
     309                        bool ret =
     310                            ofw_tree_walk_by_device_type_internal(cur->child, dtype, walker, arg);
     311                        if (!ret)
     312                                return false;
     313                }
     314        }
     315       
     316        return true;
     317}
     318
     319/** Walk the OpenFirmware device tree and find devices by type.
     320 *
     321 * Walk the whole OpenFirmware device tree and if any node has
     322 * the property "device_type" equal to dtype, run a walker on it.
     323 * If the walker returns false, the walk does not continue.
     324 *
     325 * @param dtype  Device type to look for.
     326 * @param walker Routine to be invoked on found device.
     327 * @param arg    User argument to the walker.
     328 *
     329 */
     330void ofw_tree_walk_by_device_type(const char *dtype, ofw_tree_walker_t walker,
     331    void *arg)
     332{
     333        (void) ofw_tree_walk_by_device_type_internal(ofw_root, dtype, walker, arg);
     334}
     335
     336/** Print OpenFirmware device subtree rooted in a node.
     337 *
     338 * Child nodes are processed recursively and peer nodes are processed
     339 * iteratively in order to avoid stack overflow.
     340 *
     341 * @param node Root of the subtree.
     342 * @param path Current path, NULL for the very root of the entire tree.
     343 *
     344 */
     345static void ofw_tree_node_print(ofw_tree_node_t *node, const char *path)
     346{
     347        char *cur_path = (char *) malloc(PATH_MAX_LEN, 0);
     348        ofw_tree_node_t *cur;
     349       
     350        for (cur = node; cur; cur = cur->peer) {
     351                if ((cur->parent) && (path)) {
     352                        snprintf(cur_path, PATH_MAX_LEN, "%s/%s", path, cur->da_name);
     353                        printf("%s\n", cur_path);
    290354                } else {
    291                         snprintf(p, PATH_MAX_LEN, "%s", cur->da_name);
     355                        snprintf(cur_path, PATH_MAX_LEN, "%s", cur->da_name);
    292356                        printf("/\n");
    293357                }
    294 
     358               
    295359                if (cur->child)
    296                         ofw_tree_node_print(cur->child, p);
    297         }
    298 
    299         free(p);
     360                        ofw_tree_node_print(cur->child, cur_path);
     361        }
     362       
     363        free(cur_path);
    300364}
    301365
  • kernel/genarch/src/ofw/pci.c

    ra11099f re731b0d  
    3737
    3838#include <genarch/ofw/ofw_tree.h>
     39#include <genarch/ofw/pci.h>
    3940#include <arch/drivers/pci.h>
    4041#include <arch/trap/interrupt.h>
  • kernel/genarch/src/ofw/sbus.c

    ra11099f re731b0d  
    3737
    3838#include <genarch/ofw/ofw_tree.h>
     39#include <genarch/ofw/sbus.h>
    3940#include <macros.h>
    4041
  • kernel/genarch/src/ofw/upa.c

    ra11099f re731b0d  
    3737
    3838#include <genarch/ofw/ofw_tree.h>
     39#include <genarch/ofw/upa.h>
    3940#include <arch/memstr.h>
    4041#include <func.h>
Note: See TracChangeset for help on using the changeset viewer.