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