天天看点

中断分析-解析interrupt-controller节点

1.设备节点结构体

节点的结构体device_node

49 struct device_node {                                                            
  50         const char *name;                                                       
  51         const char *type;                                                       
  52         phandle phandle;                                                        
  53         const char *full_name;                                                  
  54         struct fwnode_handle fwnode;                                            
  55                                                                                 
  56         struct  property *properties;                                           
  57         struct  property *deadprops;    /* removed properties */                
  58         struct  device_node *parent;                                            
  59         struct  device_node *child;                                             
  60         struct  device_node *sibling;                                                                                                                                                                        
  61         struct  kobject kobj;                                                   
  62         unsigned long _flags;                                                   
  63         void    *data;                                                          
  64 #if defined(CONFIG_SPARC)                                                       
  65         const char *path_component_name;                                        
  66         unsigned int unique_id;                                                 
  67         struct of_irq_controller *irq_trans;                                    
  68 #endif                                                                          
  69 }; 
           

2. 属性property

35 struct property {                                                               
  36         char    *name;                                                          
  37         int     length;                                                         
  38         void    *value;                                                                                                                                                                                      
  39         struct property *next;                                                  
  40         unsigned long _flags;                                                   
  41         unsigned int unique_id;                                                 
  42         struct bin_attribute attr;                                              
  43 }; 
           

举例:

160         gic: [email protected] {                                                                                                                                                             
161                 compatible = "arm,cortex-a9-gic";                               
162                 #interrupt-cells = <3>;                                         
163                 #address-cells = <0>;                                           
164                 interrupt-controller;                                           
165                 reg = <0x1e001000 0x1000>,                                      
166                       <0x1e000100 0x100>;                                       
167         }; 
           

解析:

device_node->name = "interrupt-controller"
device_node->full_name = "/[email protected]"

节点中的每一组数据( compatible = "arm,cortex-a9-gic")通过结构体property表示,property->next指向另外一组数据。
device_node->property->name="compatible "
device_node->property->value="arm,cortex-a9-gic "
device_node->property->length=16   //字符串长度

device_node->property->next->name="reg "
device_node->property->next->value={0x1e,0x0,0x10,0x0,   0x0,0x0,0x,10,0x0            0x1e,0x0,0x01,0x0,   0x0,0x0,0x,01,0x0         }
device_node->property->next->length=4  //每个数值的长度,也就是4个字节代表一个值


           

1)节点中的每一组数据( compatible = “arm,cortex-a9-gic”)通过结构体property表示

2)property->next指向另外一组数据;这样把一个节点中所有组数据串联起来

3) property->length如果property->value是字符串,则length是字符串长度;

如果property->value数字,这length表示一个字段占几个字节。

比如

reg = <0x1e001000 0x1000>,                                      
                             <0x1e000100 0x100>;     
           

device_node->property->next->value={0x1e,0x0,0x10,0x0, 0x0,0x0,0x,10,0x0 0x1e,0x0,0x01,0x0, 0x0,0x0,0x,01,0x0 }

如果length=4,一共16个字节,数据就会变成0x1e001000 0x1000 0x1e000100 0x100和reg配置对应起来

获取REG数值

获取REG的函数是of_address_to_resource:

参数: 1.解析节点 2.REG中的第几组参数 3解析结果保存到res中

829 int of_address_to_resource(struct device_node *dev, int index,                  
 830                            struct resource *r)                                  
 831 {                                                                               
 832         const __be32    *addrp;                                                 
 833         u64             size;                                                   
 834         unsigned int    flags;                                                  
 835         const char      *name = NULL;                                           
 836                                                                                 
 837         addrp = of_get_address(dev, index, &size, &flags);                      
 838         if (addrp == NULL)                                                      
 839                 return -EINVAL;                                                 
 840                                                                                 
 841         /* Get optional "reg-names" property to add a name to a resource */     
 842         of_property_read_string_index(dev, "reg-names", index, &name);          
 843                                                                                 
 844         return __of_address_to_resource(dev, addrp, size, flags, name, r);      
 845 }
           

举例:

reg = <0x1e001000 0x1000>,                                      
                             <0x1e000100 0x100>;     
           

如果这样调用:

of_address_to_resource(np, 0, &res)
res.start=1e001000
res.end=1e001fff

of_address_to_resource(np, 1, &res)
res.start=1e000100
res.end=1e0001ff
           

of_iomap

874 void __iomem *of_iomap(struct device_node *np, int index)                       
 875 {                                                                               
 876         struct resource res;                                                    
 877                                                                                 
 878         if (of_address_to_resource(np, index, &res))                            
 879                 return NULL;                                                                                                                   
 884                                                                                 
 885         return ioremap(res.start, resource_size(&res));                                                                                                                                                      
 886 }  
           

说明:把reg配置的物理地址转化为虚拟地址。

dts