Changeset e731b0d in mainline for kernel


Ignore:
Timestamp:
2009-08-20T16:58:55Z (16 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
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)
Location:
kernel
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • 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.