Home | History | Annotate | Line # | Download | only in bfin
dv-bfin_sic.c revision 1.1.1.5
      1      1.1  christos /* Blackfin System Interrupt Controller (SIC) model.
      2      1.1  christos 
      3  1.1.1.5  christos    Copyright (C) 2010-2016 Free Software Foundation, Inc.
      4      1.1  christos    Contributed by Analog Devices, Inc.
      5      1.1  christos 
      6      1.1  christos    This file is part of simulators.
      7      1.1  christos 
      8      1.1  christos    This program is free software; you can redistribute it and/or modify
      9      1.1  christos    it under the terms of the GNU General Public License as published by
     10      1.1  christos    the Free Software Foundation; either version 3 of the License, or
     11      1.1  christos    (at your option) any later version.
     12      1.1  christos 
     13      1.1  christos    This program is distributed in the hope that it will be useful,
     14      1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     15      1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16      1.1  christos    GNU General Public License for more details.
     17      1.1  christos 
     18      1.1  christos    You should have received a copy of the GNU General Public License
     19      1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     20      1.1  christos 
     21      1.1  christos #include "config.h"
     22      1.1  christos 
     23      1.1  christos #include "sim-main.h"
     24      1.1  christos #include "devices.h"
     25      1.1  christos #include "dv-bfin_sic.h"
     26      1.1  christos #include "dv-bfin_cec.h"
     27      1.1  christos 
     28      1.1  christos struct bfin_sic
     29      1.1  christos {
     30      1.1  christos   /* We assume first element is the base.  */
     31      1.1  christos   bu32 base;
     32      1.1  christos 
     33      1.1  christos   /* Order after here is important -- matches hardware MMR layout.  */
     34      1.1  christos   bu16 BFIN_MMR_16(swrst);
     35      1.1  christos   bu16 BFIN_MMR_16(syscr);
     36      1.1  christos   bu16 BFIN_MMR_16(rvect);  /* XXX: BF59x has a 32bit AUX_REVID here.  */
     37      1.1  christos   union {
     38      1.1  christos     struct {
     39      1.1  christos       bu32 imask0;
     40      1.1  christos       bu32 iar0, iar1, iar2, iar3;
     41      1.1  christos       bu32 isr0, iwr0;
     42      1.1  christos       bu32 _pad0[9];
     43      1.1  christos       bu32 imask1;
     44      1.1  christos       bu32 iar4, iar5, iar6, iar7;
     45      1.1  christos       bu32 isr1, iwr1;
     46      1.1  christos     } bf52x;
     47      1.1  christos     struct {
     48      1.1  christos       bu32 imask;
     49      1.1  christos       bu32 iar0, iar1, iar2, iar3;
     50      1.1  christos       bu32 isr, iwr;
     51      1.1  christos     } bf537;
     52      1.1  christos     struct {
     53      1.1  christos       bu32 imask0, imask1, imask2;
     54      1.1  christos       bu32 isr0, isr1, isr2;
     55      1.1  christos       bu32 iwr0, iwr1, iwr2;
     56      1.1  christos       bu32 iar0, iar1, iar2, iar3;
     57      1.1  christos       bu32 iar4, iar5, iar6, iar7;
     58      1.1  christos       bu32 iar8, iar9, iar10, iar11;
     59      1.1  christos     } bf54x;
     60      1.1  christos     struct {
     61      1.1  christos       bu32 imask0, imask1;
     62      1.1  christos       bu32 iar0, iar1, iar2, iar3;
     63      1.1  christos       bu32 iar4, iar5, iar6, iar7;
     64      1.1  christos       bu32 isr0, isr1;
     65      1.1  christos       bu32 iwr0, iwr1;
     66      1.1  christos     } bf561;
     67      1.1  christos   };
     68      1.1  christos };
     69      1.1  christos #define mmr_base()      offsetof(struct bfin_sic, swrst)
     70      1.1  christos #define mmr_offset(mmr) (offsetof(struct bfin_sic, mmr) - mmr_base())
     71      1.1  christos #define mmr_idx(mmr)    (mmr_offset (mmr) / 4)
     72      1.1  christos 
     73      1.1  christos static const char * const bf52x_mmr_names[] =
     74      1.1  christos {
     75      1.1  christos   "SWRST", "SYSCR", "SIC_RVECT", "SIC_IMASK0", "SIC_IAR0", "SIC_IAR1",
     76      1.1  christos   "SIC_IAR2", "SIC_IAR3", "SIC_ISR0", "SIC_IWR0",
     77      1.1  christos   [mmr_idx (bf52x.imask1)] = "SIC_IMASK1", "SIC_IAR4", "SIC_IAR5",
     78      1.1  christos   "SIC_IAR6", "SIC_IAR7", "SIC_ISR1", "SIC_IWR1",
     79      1.1  christos };
     80      1.1  christos static const char * const bf537_mmr_names[] =
     81      1.1  christos {
     82      1.1  christos   "SWRST", "SYSCR", "SIC_RVECT", "SIC_IMASK", "SIC_IAR0", "SIC_IAR1",
     83      1.1  christos   "SIC_IAR2", "SIC_IAR3", "SIC_ISR", "SIC_IWR",
     84      1.1  christos };
     85      1.1  christos static const char * const bf54x_mmr_names[] =
     86      1.1  christos {
     87      1.1  christos   "SWRST", "SYSCR", "SIC_RVECT", "SIC_IMASK0", "SIC_IMASK1", "SIC_IMASK2",
     88      1.1  christos   "SIC_ISR0", "SIC_ISR1", "SIC_ISR2", "SIC_IWR0", "SIC_IWR1", "SIC_IWR2",
     89      1.1  christos   "SIC_IAR0", "SIC_IAR1", "SIC_IAR2", "SIC_IAR3",
     90      1.1  christos   "SIC_IAR4", "SIC_IAR5", "SIC_IAR6", "SIC_IAR7",
     91      1.1  christos   "SIC_IAR8", "SIC_IAR9", "SIC_IAR10", "SIC_IAR11",
     92      1.1  christos };
     93      1.1  christos static const char * const bf561_mmr_names[] =
     94      1.1  christos {
     95      1.1  christos   "SWRST", "SYSCR", "SIC_RVECT", "SIC_IMASK0", "SIC_IMASK1",
     96      1.1  christos   "SIC_IAR0", "SIC_IAR1", "SIC_IAR2", "SIC_IAR3",
     97      1.1  christos   "SIC_IAR4", "SIC_IAR5", "SIC_IAR6", "SIC_IAR7",
     98      1.1  christos   "SIC_ISR0", "SIC_ISR1", "SIC_IWR0", "SIC_IWR1",
     99      1.1  christos };
    100      1.1  christos static const char * const *mmr_names;
    101      1.1  christos #define mmr_name(off) (mmr_names[(off) / 4] ? : "<INV>")
    102      1.1  christos 
    103      1.1  christos static void
    104      1.1  christos bfin_sic_forward_interrupts (struct hw *me, bu32 *isr, bu32 *imask, bu32 *iar)
    105      1.1  christos {
    106      1.1  christos   int my_port;
    107      1.1  christos   bu32 ipend;
    108      1.1  christos 
    109      1.1  christos   /* Process pending and unmasked interrupts.  */
    110      1.1  christos   ipend = *isr & *imask;
    111      1.1  christos 
    112      1.1  christos   /* Usually none are pending unmasked, so avoid bit twiddling.  */
    113      1.1  christos   if (!ipend)
    114      1.1  christos     return;
    115      1.1  christos 
    116      1.1  christos   for (my_port = 0; my_port < 32; ++my_port)
    117      1.1  christos     {
    118      1.1  christos       bu32 iar_idx, iar_off, iar_val;
    119      1.1  christos       bu32 bit = (1 << my_port);
    120      1.1  christos 
    121      1.1  christos       /* This bit isn't pending, so check next one.  */
    122      1.1  christos       if (!(ipend & bit))
    123      1.1  christos 	continue;
    124      1.1  christos 
    125      1.1  christos       /* The IAR registers map the System input to the Core output.
    126      1.1  christos          Every 4 bits in the IAR are used to map to IVG{7..15}.  */
    127      1.1  christos       iar_idx = my_port / 8;
    128      1.1  christos       iar_off = (my_port % 8) * 4;
    129      1.1  christos       iar_val = (iar[iar_idx] & (0xf << iar_off)) >> iar_off;
    130      1.1  christos       HW_TRACE ((me, "forwarding int %i to CEC", IVG7 + iar_val));
    131      1.1  christos       hw_port_event (me, IVG7 + iar_val, 1);
    132      1.1  christos     }
    133      1.1  christos }
    134      1.1  christos 
    135      1.1  christos static void
    136      1.1  christos bfin_sic_52x_forward_interrupts (struct hw *me, struct bfin_sic *sic)
    137      1.1  christos {
    138      1.1  christos   bfin_sic_forward_interrupts (me, &sic->bf52x.isr0, &sic->bf52x.imask0, &sic->bf52x.iar0);
    139      1.1  christos   bfin_sic_forward_interrupts (me, &sic->bf52x.isr1, &sic->bf52x.imask1, &sic->bf52x.iar4);
    140      1.1  christos }
    141      1.1  christos 
    142      1.1  christos static unsigned
    143      1.1  christos bfin_sic_52x_io_write_buffer (struct hw *me, const void *source, int space,
    144      1.1  christos 			      address_word addr, unsigned nr_bytes)
    145      1.1  christos {
    146      1.1  christos   struct bfin_sic *sic = hw_data (me);
    147      1.1  christos   bu32 mmr_off;
    148      1.1  christos   bu32 value;
    149      1.1  christos   bu16 *value16p;
    150      1.1  christos   bu32 *value32p;
    151      1.1  christos   void *valuep;
    152      1.1  christos 
    153  1.1.1.5  christos   /* Invalid access mode is higher priority than missing register.  */
    154  1.1.1.5  christos   if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, true))
    155  1.1.1.5  christos     return 0;
    156  1.1.1.5  christos 
    157      1.1  christos   if (nr_bytes == 4)
    158      1.1  christos     value = dv_load_4 (source);
    159      1.1  christos   else
    160      1.1  christos     value = dv_load_2 (source);
    161      1.1  christos 
    162      1.1  christos   mmr_off = addr - sic->base;
    163      1.1  christos   valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
    164      1.1  christos   value16p = valuep;
    165      1.1  christos   value32p = valuep;
    166      1.1  christos 
    167      1.1  christos   HW_TRACE_WRITE ();
    168      1.1  christos 
    169      1.1  christos   /* XXX: Discard all SIC writes for now.  */
    170      1.1  christos   switch (mmr_off)
    171      1.1  christos     {
    172      1.1  christos     case mmr_offset(swrst):
    173      1.1  christos       /* XXX: This should trigger a software reset ...  */
    174      1.1  christos       break;
    175      1.1  christos     case mmr_offset(syscr):
    176      1.1  christos       /* XXX: what to do ...  */
    177      1.1  christos       break;
    178      1.1  christos     case mmr_offset(bf52x.imask0):
    179      1.1  christos     case mmr_offset(bf52x.imask1):
    180      1.1  christos       bfin_sic_52x_forward_interrupts (me, sic);
    181      1.1  christos       *value32p = value;
    182      1.1  christos       break;
    183      1.1  christos     case mmr_offset(bf52x.iar0) ... mmr_offset(bf52x.iar3):
    184      1.1  christos     case mmr_offset(bf52x.iar4) ... mmr_offset(bf52x.iar7):
    185      1.1  christos     case mmr_offset(bf52x.iwr0):
    186      1.1  christos     case mmr_offset(bf52x.iwr1):
    187      1.1  christos       *value32p = value;
    188      1.1  christos       break;
    189      1.1  christos     case mmr_offset(bf52x.isr0):
    190      1.1  christos     case mmr_offset(bf52x.isr1):
    191      1.1  christos       /* ISR is read-only.  */
    192      1.1  christos       break;
    193      1.1  christos     default:
    194      1.1  christos       /* XXX: Should discard other writes.  */
    195      1.1  christos       ;
    196      1.1  christos     }
    197      1.1  christos 
    198      1.1  christos   return nr_bytes;
    199      1.1  christos }
    200      1.1  christos 
    201      1.1  christos static unsigned
    202      1.1  christos bfin_sic_52x_io_read_buffer (struct hw *me, void *dest, int space,
    203      1.1  christos 			     address_word addr, unsigned nr_bytes)
    204      1.1  christos {
    205      1.1  christos   struct bfin_sic *sic = hw_data (me);
    206      1.1  christos   bu32 mmr_off;
    207      1.1  christos   bu16 *value16p;
    208      1.1  christos   bu32 *value32p;
    209      1.1  christos   void *valuep;
    210      1.1  christos 
    211  1.1.1.5  christos   /* Invalid access mode is higher priority than missing register.  */
    212  1.1.1.5  christos   if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, false))
    213  1.1.1.5  christos     return 0;
    214  1.1.1.5  christos 
    215      1.1  christos   mmr_off = addr - sic->base;
    216      1.1  christos   valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
    217      1.1  christos   value16p = valuep;
    218      1.1  christos   value32p = valuep;
    219      1.1  christos 
    220      1.1  christos   HW_TRACE_READ ();
    221      1.1  christos 
    222      1.1  christos   switch (mmr_off)
    223      1.1  christos     {
    224      1.1  christos     case mmr_offset(swrst):
    225      1.1  christos     case mmr_offset(syscr):
    226      1.1  christos     case mmr_offset(rvect):
    227      1.1  christos       dv_store_2 (dest, *value16p);
    228      1.1  christos       break;
    229      1.1  christos     case mmr_offset(bf52x.imask0):
    230      1.1  christos     case mmr_offset(bf52x.imask1):
    231      1.1  christos     case mmr_offset(bf52x.iar0) ... mmr_offset(bf52x.iar3):
    232      1.1  christos     case mmr_offset(bf52x.iar4) ... mmr_offset(bf52x.iar7):
    233      1.1  christos     case mmr_offset(bf52x.iwr0):
    234      1.1  christos     case mmr_offset(bf52x.iwr1):
    235      1.1  christos     case mmr_offset(bf52x.isr0):
    236      1.1  christos     case mmr_offset(bf52x.isr1):
    237      1.1  christos       dv_store_4 (dest, *value32p);
    238      1.1  christos       break;
    239      1.1  christos     default:
    240      1.1  christos       if (nr_bytes == 2)
    241      1.1  christos 	dv_store_2 (dest, 0);
    242      1.1  christos       else
    243      1.1  christos 	dv_store_4 (dest, 0);
    244      1.1  christos       break;
    245      1.1  christos     }
    246      1.1  christos 
    247      1.1  christos   return nr_bytes;
    248      1.1  christos }
    249      1.1  christos 
    250      1.1  christos static void
    251      1.1  christos bfin_sic_537_forward_interrupts (struct hw *me, struct bfin_sic *sic)
    252      1.1  christos {
    253      1.1  christos   bfin_sic_forward_interrupts (me, &sic->bf537.isr, &sic->bf537.imask, &sic->bf537.iar0);
    254      1.1  christos }
    255      1.1  christos 
    256      1.1  christos static unsigned
    257      1.1  christos bfin_sic_537_io_write_buffer (struct hw *me, const void *source, int space,
    258      1.1  christos 			      address_word addr, unsigned nr_bytes)
    259      1.1  christos {
    260      1.1  christos   struct bfin_sic *sic = hw_data (me);
    261      1.1  christos   bu32 mmr_off;
    262      1.1  christos   bu32 value;
    263      1.1  christos   bu16 *value16p;
    264      1.1  christos   bu32 *value32p;
    265      1.1  christos   void *valuep;
    266      1.1  christos 
    267  1.1.1.5  christos   /* Invalid access mode is higher priority than missing register.  */
    268  1.1.1.5  christos   if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, true))
    269  1.1.1.5  christos     return 0;
    270  1.1.1.5  christos 
    271      1.1  christos   if (nr_bytes == 4)
    272      1.1  christos     value = dv_load_4 (source);
    273      1.1  christos   else
    274      1.1  christos     value = dv_load_2 (source);
    275      1.1  christos 
    276      1.1  christos   mmr_off = addr - sic->base;
    277      1.1  christos   valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
    278      1.1  christos   value16p = valuep;
    279      1.1  christos   value32p = valuep;
    280      1.1  christos 
    281      1.1  christos   HW_TRACE_WRITE ();
    282      1.1  christos 
    283      1.1  christos   /* XXX: Discard all SIC writes for now.  */
    284      1.1  christos   switch (mmr_off)
    285      1.1  christos     {
    286      1.1  christos     case mmr_offset(swrst):
    287      1.1  christos       /* XXX: This should trigger a software reset ...  */
    288      1.1  christos       break;
    289      1.1  christos     case mmr_offset(syscr):
    290      1.1  christos       /* XXX: what to do ...  */
    291      1.1  christos       break;
    292      1.1  christos     case mmr_offset(bf537.imask):
    293      1.1  christos       bfin_sic_537_forward_interrupts (me, sic);
    294      1.1  christos       *value32p = value;
    295      1.1  christos       break;
    296      1.1  christos     case mmr_offset(bf537.iar0):
    297      1.1  christos     case mmr_offset(bf537.iar1):
    298      1.1  christos     case mmr_offset(bf537.iar2):
    299      1.1  christos     case mmr_offset(bf537.iar3):
    300      1.1  christos     case mmr_offset(bf537.iwr):
    301      1.1  christos       *value32p = value;
    302      1.1  christos       break;
    303      1.1  christos     case mmr_offset(bf537.isr):
    304      1.1  christos       /* ISR is read-only.  */
    305      1.1  christos       break;
    306      1.1  christos     default:
    307      1.1  christos       /* XXX: Should discard other writes.  */
    308      1.1  christos       ;
    309      1.1  christos     }
    310      1.1  christos 
    311      1.1  christos   return nr_bytes;
    312      1.1  christos }
    313      1.1  christos 
    314      1.1  christos static unsigned
    315      1.1  christos bfin_sic_537_io_read_buffer (struct hw *me, void *dest, int space,
    316      1.1  christos 			     address_word addr, unsigned nr_bytes)
    317      1.1  christos {
    318      1.1  christos   struct bfin_sic *sic = hw_data (me);
    319      1.1  christos   bu32 mmr_off;
    320      1.1  christos   bu16 *value16p;
    321      1.1  christos   bu32 *value32p;
    322      1.1  christos   void *valuep;
    323      1.1  christos 
    324  1.1.1.5  christos   /* Invalid access mode is higher priority than missing register.  */
    325  1.1.1.5  christos   if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, false))
    326  1.1.1.5  christos     return 0;
    327  1.1.1.5  christos 
    328      1.1  christos   mmr_off = addr - sic->base;
    329      1.1  christos   valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
    330      1.1  christos   value16p = valuep;
    331      1.1  christos   value32p = valuep;
    332      1.1  christos 
    333      1.1  christos   HW_TRACE_READ ();
    334      1.1  christos 
    335      1.1  christos   switch (mmr_off)
    336      1.1  christos     {
    337      1.1  christos     case mmr_offset(swrst):
    338      1.1  christos     case mmr_offset(syscr):
    339      1.1  christos     case mmr_offset(rvect):
    340      1.1  christos       dv_store_2 (dest, *value16p);
    341      1.1  christos       break;
    342      1.1  christos     case mmr_offset(bf537.imask):
    343      1.1  christos     case mmr_offset(bf537.iar0):
    344      1.1  christos     case mmr_offset(bf537.iar1):
    345      1.1  christos     case mmr_offset(bf537.iar2):
    346      1.1  christos     case mmr_offset(bf537.iar3):
    347      1.1  christos     case mmr_offset(bf537.isr):
    348      1.1  christos     case mmr_offset(bf537.iwr):
    349      1.1  christos       dv_store_4 (dest, *value32p);
    350      1.1  christos       break;
    351      1.1  christos     default:
    352      1.1  christos       if (nr_bytes == 2)
    353      1.1  christos 	dv_store_2 (dest, 0);
    354      1.1  christos       else
    355      1.1  christos 	dv_store_4 (dest, 0);
    356      1.1  christos       break;
    357      1.1  christos     }
    358      1.1  christos 
    359      1.1  christos   return nr_bytes;
    360      1.1  christos }
    361      1.1  christos 
    362      1.1  christos static void
    363      1.1  christos bfin_sic_54x_forward_interrupts (struct hw *me, struct bfin_sic *sic)
    364      1.1  christos {
    365      1.1  christos   bfin_sic_forward_interrupts (me, &sic->bf54x.isr0, &sic->bf54x.imask0, &sic->bf54x.iar0);
    366      1.1  christos   bfin_sic_forward_interrupts (me, &sic->bf54x.isr1, &sic->bf54x.imask1, &sic->bf54x.iar4);
    367      1.1  christos   bfin_sic_forward_interrupts (me, &sic->bf54x.isr2, &sic->bf54x.imask2, &sic->bf54x.iar8);
    368      1.1  christos }
    369      1.1  christos 
    370      1.1  christos static unsigned
    371      1.1  christos bfin_sic_54x_io_write_buffer (struct hw *me, const void *source, int space,
    372      1.1  christos 			      address_word addr, unsigned nr_bytes)
    373      1.1  christos {
    374      1.1  christos   struct bfin_sic *sic = hw_data (me);
    375      1.1  christos   bu32 mmr_off;
    376      1.1  christos   bu32 value;
    377      1.1  christos   bu16 *value16p;
    378      1.1  christos   bu32 *value32p;
    379      1.1  christos   void *valuep;
    380      1.1  christos 
    381  1.1.1.5  christos   /* Invalid access mode is higher priority than missing register.  */
    382  1.1.1.5  christos   if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, true))
    383  1.1.1.5  christos     return 0;
    384  1.1.1.5  christos 
    385      1.1  christos   if (nr_bytes == 4)
    386      1.1  christos     value = dv_load_4 (source);
    387      1.1  christos   else
    388      1.1  christos     value = dv_load_2 (source);
    389      1.1  christos 
    390      1.1  christos   mmr_off = addr - sic->base;
    391      1.1  christos   valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
    392      1.1  christos   value16p = valuep;
    393      1.1  christos   value32p = valuep;
    394      1.1  christos 
    395      1.1  christos   HW_TRACE_WRITE ();
    396      1.1  christos 
    397      1.1  christos   /* XXX: Discard all SIC writes for now.  */
    398      1.1  christos   switch (mmr_off)
    399      1.1  christos     {
    400      1.1  christos     case mmr_offset(swrst):
    401      1.1  christos       /* XXX: This should trigger a software reset ...  */
    402      1.1  christos       break;
    403      1.1  christos     case mmr_offset(syscr):
    404      1.1  christos       /* XXX: what to do ...  */
    405      1.1  christos       break;
    406      1.1  christos     case mmr_offset(bf54x.imask0) ... mmr_offset(bf54x.imask2):
    407      1.1  christos       bfin_sic_54x_forward_interrupts (me, sic);
    408      1.1  christos       *value32p = value;
    409      1.1  christos       break;
    410      1.1  christos     case mmr_offset(bf54x.iar0) ... mmr_offset(bf54x.iar11):
    411      1.1  christos     case mmr_offset(bf54x.iwr0) ... mmr_offset(bf54x.iwr2):
    412      1.1  christos       *value32p = value;
    413      1.1  christos       break;
    414      1.1  christos     case mmr_offset(bf54x.isr0) ... mmr_offset(bf54x.isr2):
    415      1.1  christos       /* ISR is read-only.  */
    416      1.1  christos       break;
    417      1.1  christos     default:
    418      1.1  christos       /* XXX: Should discard other writes.  */
    419      1.1  christos       ;
    420      1.1  christos     }
    421      1.1  christos 
    422      1.1  christos   return nr_bytes;
    423      1.1  christos }
    424      1.1  christos 
    425      1.1  christos static unsigned
    426      1.1  christos bfin_sic_54x_io_read_buffer (struct hw *me, void *dest, int space,
    427      1.1  christos 			     address_word addr, unsigned nr_bytes)
    428      1.1  christos {
    429      1.1  christos   struct bfin_sic *sic = hw_data (me);
    430      1.1  christos   bu32 mmr_off;
    431      1.1  christos   bu16 *value16p;
    432      1.1  christos   bu32 *value32p;
    433      1.1  christos   void *valuep;
    434      1.1  christos 
    435  1.1.1.5  christos   /* Invalid access mode is higher priority than missing register.  */
    436  1.1.1.5  christos   if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, false))
    437  1.1.1.5  christos     return 0;
    438  1.1.1.5  christos 
    439      1.1  christos   mmr_off = addr - sic->base;
    440      1.1  christos   valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
    441      1.1  christos   value16p = valuep;
    442      1.1  christos   value32p = valuep;
    443      1.1  christos 
    444      1.1  christos   HW_TRACE_READ ();
    445      1.1  christos 
    446      1.1  christos   switch (mmr_off)
    447      1.1  christos     {
    448      1.1  christos     case mmr_offset(swrst):
    449      1.1  christos     case mmr_offset(syscr):
    450      1.1  christos     case mmr_offset(rvect):
    451      1.1  christos       dv_store_2 (dest, *value16p);
    452      1.1  christos       break;
    453      1.1  christos     case mmr_offset(bf54x.imask0) ... mmr_offset(bf54x.imask2):
    454      1.1  christos     case mmr_offset(bf54x.iar0) ... mmr_offset(bf54x.iar11):
    455      1.1  christos     case mmr_offset(bf54x.iwr0) ... mmr_offset(bf54x.iwr2):
    456      1.1  christos     case mmr_offset(bf54x.isr0) ... mmr_offset(bf54x.isr2):
    457      1.1  christos       dv_store_4 (dest, *value32p);
    458      1.1  christos       break;
    459      1.1  christos     default:
    460      1.1  christos       if (nr_bytes == 2)
    461      1.1  christos 	dv_store_2 (dest, 0);
    462      1.1  christos       else
    463      1.1  christos 	dv_store_4 (dest, 0);
    464      1.1  christos       break;
    465      1.1  christos     }
    466      1.1  christos 
    467      1.1  christos   return nr_bytes;
    468      1.1  christos }
    469      1.1  christos 
    470      1.1  christos static void
    471      1.1  christos bfin_sic_561_forward_interrupts (struct hw *me, struct bfin_sic *sic)
    472      1.1  christos {
    473      1.1  christos   bfin_sic_forward_interrupts (me, &sic->bf561.isr0, &sic->bf561.imask0, &sic->bf561.iar0);
    474      1.1  christos   bfin_sic_forward_interrupts (me, &sic->bf561.isr1, &sic->bf561.imask1, &sic->bf561.iar4);
    475      1.1  christos }
    476      1.1  christos 
    477      1.1  christos static unsigned
    478      1.1  christos bfin_sic_561_io_write_buffer (struct hw *me, const void *source, int space,
    479      1.1  christos 			      address_word addr, unsigned nr_bytes)
    480      1.1  christos {
    481      1.1  christos   struct bfin_sic *sic = hw_data (me);
    482      1.1  christos   bu32 mmr_off;
    483      1.1  christos   bu32 value;
    484      1.1  christos   bu16 *value16p;
    485      1.1  christos   bu32 *value32p;
    486      1.1  christos   void *valuep;
    487      1.1  christos 
    488  1.1.1.5  christos   /* Invalid access mode is higher priority than missing register.  */
    489  1.1.1.5  christos   if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, true))
    490  1.1.1.5  christos     return 0;
    491  1.1.1.5  christos 
    492      1.1  christos   if (nr_bytes == 4)
    493      1.1  christos     value = dv_load_4 (source);
    494      1.1  christos   else
    495      1.1  christos     value = dv_load_2 (source);
    496      1.1  christos 
    497      1.1  christos   mmr_off = addr - sic->base;
    498      1.1  christos   valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
    499      1.1  christos   value16p = valuep;
    500      1.1  christos   value32p = valuep;
    501      1.1  christos 
    502      1.1  christos   HW_TRACE_WRITE ();
    503      1.1  christos 
    504      1.1  christos   /* XXX: Discard all SIC writes for now.  */
    505      1.1  christos   switch (mmr_off)
    506      1.1  christos     {
    507      1.1  christos     case mmr_offset(swrst):
    508      1.1  christos       /* XXX: This should trigger a software reset ...  */
    509      1.1  christos       break;
    510      1.1  christos     case mmr_offset(syscr):
    511      1.1  christos       /* XXX: what to do ...  */
    512      1.1  christos       break;
    513      1.1  christos     case mmr_offset(bf561.imask0):
    514      1.1  christos     case mmr_offset(bf561.imask1):
    515      1.1  christos       bfin_sic_561_forward_interrupts (me, sic);
    516      1.1  christos       *value32p = value;
    517      1.1  christos       break;
    518      1.1  christos     case mmr_offset(bf561.iar0) ... mmr_offset(bf561.iar3):
    519      1.1  christos     case mmr_offset(bf561.iar4) ... mmr_offset(bf561.iar7):
    520      1.1  christos     case mmr_offset(bf561.iwr0):
    521      1.1  christos     case mmr_offset(bf561.iwr1):
    522      1.1  christos       *value32p = value;
    523      1.1  christos       break;
    524      1.1  christos     case mmr_offset(bf561.isr0):
    525      1.1  christos     case mmr_offset(bf561.isr1):
    526      1.1  christos       /* ISR is read-only.  */
    527      1.1  christos       break;
    528      1.1  christos     default:
    529      1.1  christos       /* XXX: Should discard other writes.  */
    530      1.1  christos       ;
    531      1.1  christos     }
    532      1.1  christos 
    533      1.1  christos   return nr_bytes;
    534      1.1  christos }
    535      1.1  christos 
    536      1.1  christos static unsigned
    537      1.1  christos bfin_sic_561_io_read_buffer (struct hw *me, void *dest, int space,
    538      1.1  christos 			     address_word addr, unsigned nr_bytes)
    539      1.1  christos {
    540      1.1  christos   struct bfin_sic *sic = hw_data (me);
    541      1.1  christos   bu32 mmr_off;
    542      1.1  christos   bu16 *value16p;
    543      1.1  christos   bu32 *value32p;
    544      1.1  christos   void *valuep;
    545      1.1  christos 
    546  1.1.1.5  christos   /* Invalid access mode is higher priority than missing register.  */
    547  1.1.1.5  christos   if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, false))
    548  1.1.1.5  christos     return 0;
    549  1.1.1.5  christos 
    550      1.1  christos   mmr_off = addr - sic->base;
    551      1.1  christos   valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
    552      1.1  christos   value16p = valuep;
    553      1.1  christos   value32p = valuep;
    554      1.1  christos 
    555      1.1  christos   HW_TRACE_READ ();
    556      1.1  christos 
    557      1.1  christos   switch (mmr_off)
    558      1.1  christos     {
    559      1.1  christos     case mmr_offset(swrst):
    560      1.1  christos     case mmr_offset(syscr):
    561      1.1  christos     case mmr_offset(rvect):
    562      1.1  christos       dv_store_2 (dest, *value16p);
    563      1.1  christos       break;
    564      1.1  christos     case mmr_offset(bf561.imask0):
    565      1.1  christos     case mmr_offset(bf561.imask1):
    566      1.1  christos     case mmr_offset(bf561.iar0) ... mmr_offset(bf561.iar3):
    567      1.1  christos     case mmr_offset(bf561.iar4) ... mmr_offset(bf561.iar7):
    568      1.1  christos     case mmr_offset(bf561.iwr0):
    569      1.1  christos     case mmr_offset(bf561.iwr1):
    570      1.1  christos     case mmr_offset(bf561.isr0):
    571      1.1  christos     case mmr_offset(bf561.isr1):
    572      1.1  christos       dv_store_4 (dest, *value32p);
    573      1.1  christos       break;
    574      1.1  christos     default:
    575      1.1  christos       if (nr_bytes == 2)
    576      1.1  christos 	dv_store_2 (dest, 0);
    577      1.1  christos       else
    578      1.1  christos 	dv_store_4 (dest, 0);
    579      1.1  christos       break;
    580      1.1  christos     }
    581      1.1  christos 
    582      1.1  christos   return nr_bytes;
    583      1.1  christos }
    584      1.1  christos 
    585  1.1.1.2  christos /* Give each SIC its own base to make it easier to extract the pin at
    586  1.1.1.2  christos    runtime.  The pin is used as its bit position in the SIC MMRs.  */
    587  1.1.1.2  christos #define ENC(sic, pin) (((sic) << 8) + (pin))
    588  1.1.1.2  christos #define DEC_PIN(pin) ((pin) % 0x100)
    589  1.1.1.2  christos #define DEC_SIC(pin) ((pin) >> 8)
    590  1.1.1.2  christos 
    591  1.1.1.2  christos /* It would be nice to declare just one set of input_ports, and then
    592  1.1.1.2  christos    have the device tree instantiate multiple SICs, but the MMR layout
    593  1.1.1.2  christos    on the BF54x/BF561 makes this pretty hard to pull off since their
    594  1.1.1.2  christos    regs are interwoven in the address space.  */
    595  1.1.1.2  christos 
    596      1.1  christos #define BFIN_SIC_TO_CEC_PORTS \
    597      1.1  christos   { "ivg7",  IVG7,  0, output_port, }, \
    598      1.1  christos   { "ivg8",  IVG8,  0, output_port, }, \
    599      1.1  christos   { "ivg9",  IVG9,  0, output_port, }, \
    600      1.1  christos   { "ivg10", IVG10, 0, output_port, }, \
    601      1.1  christos   { "ivg11", IVG11, 0, output_port, }, \
    602      1.1  christos   { "ivg12", IVG12, 0, output_port, }, \
    603      1.1  christos   { "ivg13", IVG13, 0, output_port, }, \
    604      1.1  christos   { "ivg14", IVG14, 0, output_port, }, \
    605      1.1  christos   { "ivg15", IVG15, 0, output_port, },
    606      1.1  christos 
    607  1.1.1.2  christos #define SIC_PORTS(n) \
    608  1.1.1.2  christos   { "int0@"#n,   ENC(n,  0), 0, input_port, }, \
    609  1.1.1.2  christos   { "int1@"#n,   ENC(n,  1), 0, input_port, }, \
    610  1.1.1.2  christos   { "int2@"#n,   ENC(n,  2), 0, input_port, }, \
    611  1.1.1.2  christos   { "int3@"#n,   ENC(n,  3), 0, input_port, }, \
    612  1.1.1.2  christos   { "int4@"#n,   ENC(n,  4), 0, input_port, }, \
    613  1.1.1.2  christos   { "int5@"#n,   ENC(n,  5), 0, input_port, }, \
    614  1.1.1.2  christos   { "int6@"#n,   ENC(n,  6), 0, input_port, }, \
    615  1.1.1.2  christos   { "int7@"#n,   ENC(n,  7), 0, input_port, }, \
    616  1.1.1.2  christos   { "int8@"#n,   ENC(n,  8), 0, input_port, }, \
    617  1.1.1.2  christos   { "int9@"#n,   ENC(n,  9), 0, input_port, }, \
    618  1.1.1.2  christos   { "int10@"#n,  ENC(n, 10), 0, input_port, }, \
    619  1.1.1.2  christos   { "int11@"#n,  ENC(n, 11), 0, input_port, }, \
    620  1.1.1.2  christos   { "int12@"#n,  ENC(n, 12), 0, input_port, }, \
    621  1.1.1.2  christos   { "int13@"#n,  ENC(n, 13), 0, input_port, }, \
    622  1.1.1.2  christos   { "int14@"#n,  ENC(n, 14), 0, input_port, }, \
    623  1.1.1.2  christos   { "int15@"#n,  ENC(n, 15), 0, input_port, }, \
    624  1.1.1.2  christos   { "int16@"#n,  ENC(n, 16), 0, input_port, }, \
    625  1.1.1.2  christos   { "int17@"#n,  ENC(n, 17), 0, input_port, }, \
    626  1.1.1.2  christos   { "int18@"#n,  ENC(n, 18), 0, input_port, }, \
    627  1.1.1.2  christos   { "int19@"#n,  ENC(n, 19), 0, input_port, }, \
    628  1.1.1.2  christos   { "int20@"#n,  ENC(n, 20), 0, input_port, }, \
    629  1.1.1.2  christos   { "int21@"#n,  ENC(n, 21), 0, input_port, }, \
    630  1.1.1.2  christos   { "int22@"#n,  ENC(n, 22), 0, input_port, }, \
    631  1.1.1.2  christos   { "int23@"#n,  ENC(n, 23), 0, input_port, }, \
    632  1.1.1.2  christos   { "int24@"#n,  ENC(n, 24), 0, input_port, }, \
    633  1.1.1.2  christos   { "int25@"#n,  ENC(n, 25), 0, input_port, }, \
    634  1.1.1.2  christos   { "int26@"#n,  ENC(n, 26), 0, input_port, }, \
    635  1.1.1.2  christos   { "int27@"#n,  ENC(n, 27), 0, input_port, }, \
    636  1.1.1.2  christos   { "int28@"#n,  ENC(n, 28), 0, input_port, }, \
    637  1.1.1.2  christos   { "int29@"#n,  ENC(n, 29), 0, input_port, }, \
    638  1.1.1.2  christos   { "int30@"#n,  ENC(n, 30), 0, input_port, }, \
    639  1.1.1.2  christos   { "int31@"#n,  ENC(n, 31), 0, input_port, },
    640      1.1  christos 
    641  1.1.1.2  christos static const struct hw_port_descriptor bfin_sic1_ports[] =
    642      1.1  christos {
    643      1.1  christos   BFIN_SIC_TO_CEC_PORTS
    644  1.1.1.2  christos   SIC_PORTS(0)
    645      1.1  christos   { NULL, 0, 0, 0, },
    646      1.1  christos };
    647      1.1  christos 
    648  1.1.1.2  christos static const struct hw_port_descriptor bfin_sic2_ports[] =
    649      1.1  christos {
    650      1.1  christos   BFIN_SIC_TO_CEC_PORTS
    651  1.1.1.2  christos   SIC_PORTS(0)
    652  1.1.1.2  christos   SIC_PORTS(1)
    653      1.1  christos   { NULL, 0, 0, 0, },
    654      1.1  christos };
    655      1.1  christos 
    656  1.1.1.2  christos static const struct hw_port_descriptor bfin_sic3_ports[] =
    657      1.1  christos {
    658      1.1  christos   BFIN_SIC_TO_CEC_PORTS
    659  1.1.1.2  christos   SIC_PORTS(0)
    660  1.1.1.2  christos   SIC_PORTS(1)
    661  1.1.1.2  christos   SIC_PORTS(2)
    662  1.1.1.2  christos   { NULL, 0, 0, 0, },
    663  1.1.1.2  christos };
    664  1.1.1.2  christos 
    665  1.1.1.2  christos static const struct hw_port_descriptor bfin_sic_561_ports[] =
    666  1.1.1.2  christos {
    667  1.1.1.2  christos   { "sup_irq@0", 0, 0, output_port, },
    668  1.1.1.2  christos   { "sup_irq@1", 1, 0, output_port, },
    669  1.1.1.2  christos   BFIN_SIC_TO_CEC_PORTS
    670  1.1.1.2  christos   SIC_PORTS(0)
    671  1.1.1.2  christos   SIC_PORTS(1)
    672      1.1  christos   { NULL, 0, 0, 0, },
    673      1.1  christos };
    674      1.1  christos 
    675      1.1  christos static void
    676  1.1.1.2  christos bfin_sic_port_event (struct hw *me, bu32 *isr, bu32 bit, int level)
    677  1.1.1.2  christos {
    678  1.1.1.2  christos   if (level)
    679  1.1.1.2  christos     *isr |= bit;
    680  1.1.1.2  christos   else
    681  1.1.1.2  christos     *isr &= ~bit;
    682  1.1.1.2  christos }
    683  1.1.1.2  christos 
    684  1.1.1.2  christos static void
    685      1.1  christos bfin_sic_52x_port_event (struct hw *me, int my_port, struct hw *source,
    686      1.1  christos 			 int source_port, int level)
    687      1.1  christos {
    688      1.1  christos   struct bfin_sic *sic = hw_data (me);
    689      1.1  christos   bu32 idx = DEC_SIC (my_port);
    690      1.1  christos   bu32 pin = DEC_PIN (my_port);
    691      1.1  christos   bu32 bit = 1 << pin;
    692      1.1  christos 
    693  1.1.1.2  christos   HW_TRACE ((me, "processing level %i from port %i (SIC %u pin %u)",
    694  1.1.1.2  christos 	     level, my_port, idx, pin));
    695      1.1  christos 
    696      1.1  christos   /* SIC only exists to forward interrupts from the system to the CEC.  */
    697      1.1  christos   switch (idx)
    698      1.1  christos     {
    699  1.1.1.2  christos     case 0: bfin_sic_port_event (me, &sic->bf52x.isr0, bit, level); break;
    700  1.1.1.2  christos     case 1: bfin_sic_port_event (me, &sic->bf52x.isr1, bit, level); break;
    701      1.1  christos     }
    702      1.1  christos 
    703      1.1  christos   /* XXX: Handle SIC wakeup source ?
    704      1.1  christos   if (sic->bf52x.iwr0 & bit)
    705      1.1  christos     What to do ?;
    706      1.1  christos   if (sic->bf52x.iwr1 & bit)
    707      1.1  christos     What to do ?;
    708      1.1  christos    */
    709      1.1  christos 
    710      1.1  christos   bfin_sic_52x_forward_interrupts (me, sic);
    711      1.1  christos }
    712      1.1  christos 
    713      1.1  christos static void
    714      1.1  christos bfin_sic_537_port_event (struct hw *me, int my_port, struct hw *source,
    715      1.1  christos 			 int source_port, int level)
    716      1.1  christos {
    717      1.1  christos   struct bfin_sic *sic = hw_data (me);
    718      1.1  christos   bu32 idx = DEC_SIC (my_port);
    719      1.1  christos   bu32 pin = DEC_PIN (my_port);
    720      1.1  christos   bu32 bit = 1 << pin;
    721      1.1  christos 
    722  1.1.1.2  christos   HW_TRACE ((me, "processing level %i from port %i (SIC %u pin %u)",
    723  1.1.1.2  christos 	     level, my_port, idx, pin));
    724      1.1  christos 
    725      1.1  christos   /* SIC only exists to forward interrupts from the system to the CEC.  */
    726  1.1.1.2  christos   bfin_sic_port_event (me, &sic->bf537.isr, bit, level);
    727      1.1  christos 
    728      1.1  christos   /* XXX: Handle SIC wakeup source ?
    729      1.1  christos   if (sic->bf537.iwr & bit)
    730      1.1  christos     What to do ?;
    731      1.1  christos    */
    732      1.1  christos 
    733      1.1  christos   bfin_sic_537_forward_interrupts (me, sic);
    734      1.1  christos }
    735      1.1  christos 
    736      1.1  christos static void
    737      1.1  christos bfin_sic_54x_port_event (struct hw *me, int my_port, struct hw *source,
    738      1.1  christos 			 int source_port, int level)
    739      1.1  christos {
    740      1.1  christos   struct bfin_sic *sic = hw_data (me);
    741      1.1  christos   bu32 idx = DEC_SIC (my_port);
    742      1.1  christos   bu32 pin = DEC_PIN (my_port);
    743      1.1  christos   bu32 bit = 1 << pin;
    744      1.1  christos 
    745  1.1.1.2  christos   HW_TRACE ((me, "processing level %i from port %i (SIC %u pin %u)",
    746  1.1.1.2  christos 	     level, my_port, idx, pin));
    747      1.1  christos 
    748      1.1  christos   /* SIC only exists to forward interrupts from the system to the CEC.  */
    749      1.1  christos   switch (idx)
    750      1.1  christos     {
    751  1.1.1.2  christos     case 0: bfin_sic_port_event (me, &sic->bf54x.isr0, bit, level); break;
    752  1.1.1.2  christos     case 1: bfin_sic_port_event (me, &sic->bf54x.isr0, bit, level); break;
    753  1.1.1.2  christos     case 2: bfin_sic_port_event (me, &sic->bf54x.isr0, bit, level); break;
    754      1.1  christos     }
    755      1.1  christos 
    756      1.1  christos   /* XXX: Handle SIC wakeup source ?
    757      1.1  christos   if (sic->bf54x.iwr0 & bit)
    758      1.1  christos     What to do ?;
    759      1.1  christos   if (sic->bf54x.iwr1 & bit)
    760      1.1  christos     What to do ?;
    761      1.1  christos   if (sic->bf54x.iwr2 & bit)
    762      1.1  christos     What to do ?;
    763      1.1  christos    */
    764      1.1  christos 
    765      1.1  christos   bfin_sic_54x_forward_interrupts (me, sic);
    766      1.1  christos }
    767      1.1  christos 
    768      1.1  christos static void
    769      1.1  christos bfin_sic_561_port_event (struct hw *me, int my_port, struct hw *source,
    770      1.1  christos 			 int source_port, int level)
    771      1.1  christos {
    772      1.1  christos   struct bfin_sic *sic = hw_data (me);
    773      1.1  christos   bu32 idx = DEC_SIC (my_port);
    774      1.1  christos   bu32 pin = DEC_PIN (my_port);
    775      1.1  christos   bu32 bit = 1 << pin;
    776      1.1  christos 
    777  1.1.1.2  christos   HW_TRACE ((me, "processing level %i from port %i (SIC %u pin %u)",
    778  1.1.1.2  christos 	     level, my_port, idx, pin));
    779      1.1  christos 
    780      1.1  christos   /* SIC only exists to forward interrupts from the system to the CEC.  */
    781      1.1  christos   switch (idx)
    782      1.1  christos     {
    783  1.1.1.2  christos     case 0: bfin_sic_port_event (me, &sic->bf561.isr0, bit, level); break;
    784  1.1.1.2  christos     case 1: bfin_sic_port_event (me, &sic->bf561.isr1, bit, level); break;
    785      1.1  christos     }
    786      1.1  christos 
    787      1.1  christos   /* XXX: Handle SIC wakeup source ?
    788      1.1  christos   if (sic->bf561.iwr0 & bit)
    789      1.1  christos     What to do ?;
    790      1.1  christos   if (sic->bf561.iwr1 & bit)
    791      1.1  christos     What to do ?;
    792      1.1  christos    */
    793      1.1  christos 
    794      1.1  christos   bfin_sic_561_forward_interrupts (me, sic);
    795      1.1  christos }
    796      1.1  christos 
    797      1.1  christos static void
    798      1.1  christos attach_bfin_sic_regs (struct hw *me, struct bfin_sic *sic)
    799      1.1  christos {
    800      1.1  christos   address_word attach_address;
    801      1.1  christos   int attach_space;
    802      1.1  christos   unsigned attach_size;
    803      1.1  christos   reg_property_spec reg;
    804      1.1  christos 
    805      1.1  christos   if (hw_find_property (me, "reg") == NULL)
    806      1.1  christos     hw_abort (me, "Missing \"reg\" property");
    807      1.1  christos 
    808      1.1  christos   if (!hw_find_reg_array_property (me, "reg", 0, &reg))
    809      1.1  christos     hw_abort (me, "\"reg\" property must contain three addr/size entries");
    810      1.1  christos 
    811      1.1  christos   hw_unit_address_to_attach_address (hw_parent (me),
    812      1.1  christos 				     &reg.address,
    813      1.1  christos 				     &attach_space, &attach_address, me);
    814      1.1  christos   hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
    815      1.1  christos 
    816      1.1  christos   if (attach_size != BFIN_MMR_SIC_SIZE)
    817      1.1  christos     hw_abort (me, "\"reg\" size must be %#x", BFIN_MMR_SIC_SIZE);
    818      1.1  christos 
    819      1.1  christos   hw_attach_address (hw_parent (me),
    820      1.1  christos 		     0, attach_space, attach_address, attach_size, me);
    821      1.1  christos 
    822      1.1  christos   sic->base = attach_address;
    823      1.1  christos }
    824      1.1  christos 
    825      1.1  christos static void
    826      1.1  christos bfin_sic_finish (struct hw *me)
    827      1.1  christos {
    828      1.1  christos   struct bfin_sic *sic;
    829      1.1  christos 
    830      1.1  christos   sic = HW_ZALLOC (me, struct bfin_sic);
    831      1.1  christos 
    832      1.1  christos   set_hw_data (me, sic);
    833      1.1  christos   attach_bfin_sic_regs (me, sic);
    834      1.1  christos 
    835      1.1  christos   switch (hw_find_integer_property (me, "type"))
    836      1.1  christos     {
    837      1.1  christos     case 500 ... 509:
    838      1.1  christos       set_hw_io_read_buffer (me, bfin_sic_52x_io_read_buffer);
    839      1.1  christos       set_hw_io_write_buffer (me, bfin_sic_52x_io_write_buffer);
    840  1.1.1.2  christos       set_hw_ports (me, bfin_sic2_ports);
    841      1.1  christos       set_hw_port_event (me, bfin_sic_52x_port_event);
    842      1.1  christos       mmr_names = bf52x_mmr_names;
    843      1.1  christos 
    844      1.1  christos       /* Initialize the SIC.  */
    845      1.1  christos       sic->bf52x.imask0 = sic->bf52x.imask1 = 0;
    846      1.1  christos       sic->bf52x.isr0 = sic->bf52x.isr1 = 0;
    847      1.1  christos       sic->bf52x.iwr0 = sic->bf52x.iwr1 = 0xFFFFFFFF;
    848      1.1  christos       sic->bf52x.iar0 = 0x00000000;
    849      1.1  christos       sic->bf52x.iar1 = 0x22111000;
    850      1.1  christos       sic->bf52x.iar2 = 0x33332222;
    851      1.1  christos       sic->bf52x.iar3 = 0x44444433;
    852      1.1  christos       sic->bf52x.iar4 = 0x55555555;
    853      1.1  christos       sic->bf52x.iar5 = 0x06666655;
    854      1.1  christos       sic->bf52x.iar6 = 0x33333003;
    855      1.1  christos       sic->bf52x.iar7 = 0x00000000;	/* XXX: Find and fix */
    856      1.1  christos       break;
    857      1.1  christos     case 510 ... 519:
    858      1.1  christos       set_hw_io_read_buffer (me, bfin_sic_52x_io_read_buffer);
    859      1.1  christos       set_hw_io_write_buffer (me, bfin_sic_52x_io_write_buffer);
    860  1.1.1.2  christos       set_hw_ports (me, bfin_sic2_ports);
    861      1.1  christos       set_hw_port_event (me, bfin_sic_52x_port_event);
    862      1.1  christos       mmr_names = bf52x_mmr_names;
    863      1.1  christos 
    864      1.1  christos       /* Initialize the SIC.  */
    865      1.1  christos       sic->bf52x.imask0 = sic->bf52x.imask1 = 0;
    866      1.1  christos       sic->bf52x.isr0 = sic->bf52x.isr1 = 0;
    867      1.1  christos       sic->bf52x.iwr0 = sic->bf52x.iwr1 = 0xFFFFFFFF;
    868      1.1  christos       sic->bf52x.iar0 = 0x00000000;
    869      1.1  christos       sic->bf52x.iar1 = 0x11000000;
    870      1.1  christos       sic->bf52x.iar2 = 0x33332222;
    871      1.1  christos       sic->bf52x.iar3 = 0x44444433;
    872      1.1  christos       sic->bf52x.iar4 = 0x55555555;
    873      1.1  christos       sic->bf52x.iar5 = 0x06666655;
    874      1.1  christos       sic->bf52x.iar6 = 0x33333000;
    875      1.1  christos       sic->bf52x.iar7 = 0x00000000;	/* XXX: Find and fix */
    876      1.1  christos       break;
    877      1.1  christos     case 522 ... 527:
    878      1.1  christos       set_hw_io_read_buffer (me, bfin_sic_52x_io_read_buffer);
    879      1.1  christos       set_hw_io_write_buffer (me, bfin_sic_52x_io_write_buffer);
    880  1.1.1.2  christos       set_hw_ports (me, bfin_sic2_ports);
    881      1.1  christos       set_hw_port_event (me, bfin_sic_52x_port_event);
    882      1.1  christos       mmr_names = bf52x_mmr_names;
    883      1.1  christos 
    884      1.1  christos       /* Initialize the SIC.  */
    885      1.1  christos       sic->bf52x.imask0 = sic->bf52x.imask1 = 0;
    886      1.1  christos       sic->bf52x.isr0 = sic->bf52x.isr1 = 0;
    887      1.1  christos       sic->bf52x.iwr0 = sic->bf52x.iwr1 = 0xFFFFFFFF;
    888      1.1  christos       sic->bf52x.iar0 = 0x00000000;
    889      1.1  christos       sic->bf52x.iar1 = 0x11000000;
    890      1.1  christos       sic->bf52x.iar2 = 0x33332222;
    891      1.1  christos       sic->bf52x.iar3 = 0x44444433;
    892      1.1  christos       sic->bf52x.iar4 = 0x55555555;
    893      1.1  christos       sic->bf52x.iar5 = 0x06666655;
    894      1.1  christos       sic->bf52x.iar6 = 0x33333000;
    895      1.1  christos       sic->bf52x.iar7 = 0x00000000;	/* XXX: Find and fix */
    896      1.1  christos       break;
    897      1.1  christos     case 531 ... 533:
    898      1.1  christos       set_hw_io_read_buffer (me, bfin_sic_537_io_read_buffer);
    899      1.1  christos       set_hw_io_write_buffer (me, bfin_sic_537_io_write_buffer);
    900  1.1.1.2  christos       set_hw_ports (me, bfin_sic1_ports);
    901      1.1  christos       set_hw_port_event (me, bfin_sic_537_port_event);
    902      1.1  christos       mmr_names = bf537_mmr_names;
    903      1.1  christos 
    904      1.1  christos       /* Initialize the SIC.  */
    905      1.1  christos       sic->bf537.imask = 0;
    906      1.1  christos       sic->bf537.isr = 0;
    907      1.1  christos       sic->bf537.iwr = 0xFFFFFFFF;
    908      1.1  christos       sic->bf537.iar0 = 0x10000000;
    909      1.1  christos       sic->bf537.iar1 = 0x33322221;
    910      1.1  christos       sic->bf537.iar2 = 0x66655444;
    911      1.1  christos       sic->bf537.iar3 = 0; /* XXX: fix this */
    912      1.1  christos       break;
    913      1.1  christos     case 534:
    914      1.1  christos     case 536:
    915      1.1  christos     case 537:
    916      1.1  christos       set_hw_io_read_buffer (me, bfin_sic_537_io_read_buffer);
    917      1.1  christos       set_hw_io_write_buffer (me, bfin_sic_537_io_write_buffer);
    918  1.1.1.2  christos       set_hw_ports (me, bfin_sic1_ports);
    919      1.1  christos       set_hw_port_event (me, bfin_sic_537_port_event);
    920      1.1  christos       mmr_names = bf537_mmr_names;
    921      1.1  christos 
    922      1.1  christos       /* Initialize the SIC.  */
    923      1.1  christos       sic->bf537.imask = 0;
    924      1.1  christos       sic->bf537.isr = 0;
    925      1.1  christos       sic->bf537.iwr = 0xFFFFFFFF;
    926      1.1  christos       sic->bf537.iar0 = 0x22211000;
    927      1.1  christos       sic->bf537.iar1 = 0x43333332;
    928      1.1  christos       sic->bf537.iar2 = 0x55555444;
    929      1.1  christos       sic->bf537.iar3 = 0x66655555;
    930      1.1  christos       break;
    931      1.1  christos     case 538 ... 539:
    932      1.1  christos       set_hw_io_read_buffer (me, bfin_sic_52x_io_read_buffer);
    933      1.1  christos       set_hw_io_write_buffer (me, bfin_sic_52x_io_write_buffer);
    934  1.1.1.2  christos       set_hw_ports (me, bfin_sic2_ports);
    935      1.1  christos       set_hw_port_event (me, bfin_sic_52x_port_event);
    936      1.1  christos       mmr_names = bf52x_mmr_names;
    937      1.1  christos 
    938      1.1  christos       /* Initialize the SIC.  */
    939      1.1  christos       sic->bf52x.imask0 = sic->bf52x.imask1 = 0;
    940      1.1  christos       sic->bf52x.isr0 = sic->bf52x.isr1 = 0;
    941      1.1  christos       sic->bf52x.iwr0 = sic->bf52x.iwr1 = 0xFFFFFFFF;
    942      1.1  christos       sic->bf52x.iar0 = 0x10000000;
    943      1.1  christos       sic->bf52x.iar1 = 0x33322221;
    944      1.1  christos       sic->bf52x.iar2 = 0x66655444;
    945      1.1  christos       sic->bf52x.iar3 = 0x00000000;
    946      1.1  christos       sic->bf52x.iar4 = 0x32222220;
    947      1.1  christos       sic->bf52x.iar5 = 0x44433333;
    948      1.1  christos       sic->bf52x.iar6 = 0x00444664;
    949      1.1  christos       sic->bf52x.iar7 = 0x00000000;	/* XXX: Find and fix */
    950      1.1  christos       break;
    951      1.1  christos     case 540 ... 549:
    952      1.1  christos       set_hw_io_read_buffer (me, bfin_sic_54x_io_read_buffer);
    953      1.1  christos       set_hw_io_write_buffer (me, bfin_sic_54x_io_write_buffer);
    954  1.1.1.2  christos       set_hw_ports (me, bfin_sic3_ports);
    955      1.1  christos       set_hw_port_event (me, bfin_sic_54x_port_event);
    956      1.1  christos       mmr_names = bf54x_mmr_names;
    957      1.1  christos 
    958      1.1  christos       /* Initialize the SIC.  */
    959      1.1  christos       sic->bf54x.imask0 = sic->bf54x.imask1 = sic->bf54x.imask2 = 0;
    960      1.1  christos       sic->bf54x.isr0 = sic->bf54x.isr1 = sic->bf54x.isr2 = 0;
    961  1.1.1.2  christos       sic->bf54x.iwr0 = sic->bf54x.iwr1 = sic->bf54x.iwr2 = 0xFFFFFFFF;
    962      1.1  christos       sic->bf54x.iar0 = 0x10000000;
    963      1.1  christos       sic->bf54x.iar1 = 0x33322221;
    964      1.1  christos       sic->bf54x.iar2 = 0x66655444;
    965      1.1  christos       sic->bf54x.iar3 = 0x00000000;
    966      1.1  christos       sic->bf54x.iar4 = 0x32222220;
    967      1.1  christos       sic->bf54x.iar5 = 0x44433333;
    968      1.1  christos       sic->bf54x.iar6 = 0x00444664;
    969      1.1  christos       sic->bf54x.iar7 = 0x00000000;
    970      1.1  christos       sic->bf54x.iar8 = 0x44111111;
    971      1.1  christos       sic->bf54x.iar9 = 0x44444444;
    972      1.1  christos       sic->bf54x.iar10 = 0x44444444;
    973      1.1  christos       sic->bf54x.iar11 = 0x55444444;
    974      1.1  christos       break;
    975      1.1  christos     case 561:
    976      1.1  christos       set_hw_io_read_buffer (me, bfin_sic_561_io_read_buffer);
    977      1.1  christos       set_hw_io_write_buffer (me, bfin_sic_561_io_write_buffer);
    978      1.1  christos       set_hw_ports (me, bfin_sic_561_ports);
    979      1.1  christos       set_hw_port_event (me, bfin_sic_561_port_event);
    980      1.1  christos       mmr_names = bf561_mmr_names;
    981      1.1  christos 
    982      1.1  christos       /* Initialize the SIC.  */
    983      1.1  christos       sic->bf561.imask0 = sic->bf561.imask1 = 0;
    984      1.1  christos       sic->bf561.isr0 = sic->bf561.isr1 = 0;
    985      1.1  christos       sic->bf561.iwr0 = sic->bf561.iwr1 = 0xFFFFFFFF;
    986      1.1  christos       sic->bf561.iar0 = 0x00000000;
    987      1.1  christos       sic->bf561.iar1 = 0x11111000;
    988      1.1  christos       sic->bf561.iar2 = 0x21111111;
    989      1.1  christos       sic->bf561.iar3 = 0x22222222;
    990      1.1  christos       sic->bf561.iar4 = 0x33333222;
    991      1.1  christos       sic->bf561.iar5 = 0x43333333;
    992      1.1  christos       sic->bf561.iar6 = 0x21144444;
    993      1.1  christos       sic->bf561.iar7 = 0x00006552;
    994      1.1  christos       break;
    995      1.1  christos     case 590 ... 599:
    996      1.1  christos       set_hw_io_read_buffer (me, bfin_sic_537_io_read_buffer);
    997      1.1  christos       set_hw_io_write_buffer (me, bfin_sic_537_io_write_buffer);
    998  1.1.1.2  christos       set_hw_ports (me, bfin_sic1_ports);
    999      1.1  christos       set_hw_port_event (me, bfin_sic_537_port_event);
   1000      1.1  christos       mmr_names = bf537_mmr_names;
   1001      1.1  christos 
   1002      1.1  christos       /* Initialize the SIC.  */
   1003      1.1  christos       sic->bf537.imask = 0;
   1004      1.1  christos       sic->bf537.isr = 0;
   1005      1.1  christos       sic->bf537.iwr = 0xFFFFFFFF;
   1006      1.1  christos       sic->bf537.iar0 = 0x00000000;
   1007      1.1  christos       sic->bf537.iar1 = 0x33322221;
   1008      1.1  christos       sic->bf537.iar2 = 0x55444443;
   1009      1.1  christos       sic->bf537.iar3 = 0x66600005;
   1010      1.1  christos       break;
   1011      1.1  christos     default:
   1012      1.1  christos       hw_abort (me, "no support for SIC on this Blackfin model yet");
   1013      1.1  christos     }
   1014      1.1  christos }
   1015      1.1  christos 
   1016      1.1  christos const struct hw_descriptor dv_bfin_sic_descriptor[] =
   1017      1.1  christos {
   1018      1.1  christos   {"bfin_sic", bfin_sic_finish,},
   1019      1.1  christos   {NULL, NULL},
   1020      1.1  christos };
   1021