symbian-qemu-0.9.1-12/qemu-symbian-svp/hw/rc4030.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2  * QEMU JAZZ RC4030 chipset
       
     3  *
       
     4  * Copyright (c) 2007-2008 Hervé Poussineau
       
     5  *
       
     6  * Permission is hereby granted, free of charge, to any person obtaining a copy
       
     7  * of this software and associated documentation files (the "Software"), to deal
       
     8  * in the Software without restriction, including without limitation the rights
       
     9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       
    10  * copies of the Software, and to permit persons to whom the Software is
       
    11  * furnished to do so, subject to the following conditions:
       
    12  *
       
    13  * The above copyright notice and this permission notice shall be included in
       
    14  * all copies or substantial portions of the Software.
       
    15  *
       
    16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
       
    17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
       
    18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
       
    19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
       
    20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
       
    21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
       
    22  * THE SOFTWARE.
       
    23  */
       
    24 
       
    25 #include "hw.h"
       
    26 #include "mips.h"
       
    27 #include "qemu-timer.h"
       
    28 
       
    29 //#define DEBUG_RC4030
       
    30 
       
    31 #ifdef DEBUG_RC4030
       
    32 static const char* irq_names[] = { "parallel", "floppy", "sound", "video",
       
    33             "network", "scsi", "keyboard", "mouse", "serial0", "serial1" };
       
    34 #endif
       
    35 
       
    36 typedef struct rc4030State
       
    37 {
       
    38     uint32_t config; /* 0x0000: RC4030 config register */
       
    39     uint32_t invalid_address_register; /* 0x0010: Invalid Address register */
       
    40 
       
    41     /* DMA */
       
    42     uint32_t dma_regs[8][4];
       
    43     uint32_t dma_tl_base; /* 0x0018: DMA transl. table base */
       
    44     uint32_t dma_tl_limit; /* 0x0020: DMA transl. table limit */
       
    45 
       
    46     /* cache */
       
    47     uint32_t remote_failed_address; /* 0x0038: Remote Failed Address */
       
    48     uint32_t memory_failed_address; /* 0x0040: Memory Failed Address */
       
    49     uint32_t cache_ptag; /* 0x0048: I/O Cache Physical Tag */
       
    50     uint32_t cache_ltag; /* 0x0050: I/O Cache Logical Tag */
       
    51     uint32_t cache_bmask; /* 0x0058: I/O Cache Byte Mask */
       
    52     uint32_t cache_bwin; /* 0x0060: I/O Cache Buffer Window */
       
    53 
       
    54     uint32_t offset208;
       
    55     uint32_t offset210;
       
    56     uint32_t nvram_protect; /* 0x0220: NV ram protect register */
       
    57     uint32_t offset238;
       
    58     uint32_t rem_speed[15];
       
    59     uint32_t imr_jazz; /* Local bus int enable mask */
       
    60     uint32_t isr_jazz; /* Local bus int source */
       
    61 
       
    62     /* timer */
       
    63     QEMUTimer *periodic_timer;
       
    64     uint32_t itr; /* Interval timer reload */
       
    65 
       
    66     uint32_t dummy32;
       
    67     qemu_irq timer_irq;
       
    68     qemu_irq jazz_bus_irq;
       
    69 } rc4030State;
       
    70 
       
    71 static void set_next_tick(rc4030State *s)
       
    72 {
       
    73     qemu_irq_lower(s->timer_irq);
       
    74     uint32_t tm_hz;
       
    75 
       
    76     tm_hz = 1000 / (s->itr + 1);
       
    77 
       
    78     qemu_mod_timer(s->periodic_timer, qemu_get_clock(vm_clock) + ticks_per_sec / tm_hz);
       
    79 }
       
    80 
       
    81 /* called for accesses to rc4030 */
       
    82 static uint32_t rc4030_readl(void *opaque, target_phys_addr_t addr)
       
    83 {
       
    84     rc4030State *s = opaque;
       
    85     uint32_t val;
       
    86 
       
    87     addr &= 0x3fff;
       
    88     switch (addr & ~0x3) {
       
    89     /* Global config register */
       
    90     case 0x0000:
       
    91         val = s->config;
       
    92         break;
       
    93     /* Invalid Address register */
       
    94     case 0x0010:
       
    95         val = s->invalid_address_register;
       
    96         break;
       
    97     /* DMA transl. table base */
       
    98     case 0x0018:
       
    99         val = s->dma_tl_base;
       
   100         break;
       
   101     /* DMA transl. table limit */
       
   102     case 0x0020:
       
   103         val = s->dma_tl_limit;
       
   104         break;
       
   105     /* Remote Failed Address */
       
   106     case 0x0038:
       
   107         val = s->remote_failed_address;
       
   108         break;
       
   109     /* Memory Failed Address */
       
   110     case 0x0040:
       
   111         val = s->memory_failed_address;
       
   112         break;
       
   113     /* I/O Cache Byte Mask */
       
   114     case 0x0058:
       
   115         val = s->cache_bmask;
       
   116         /* HACK */
       
   117         if (s->cache_bmask == (uint32_t)-1)
       
   118             s->cache_bmask = 0;
       
   119         break;
       
   120     /* Remote Speed Registers */
       
   121     case 0x0070:
       
   122     case 0x0078:
       
   123     case 0x0080:
       
   124     case 0x0088:
       
   125     case 0x0090:
       
   126     case 0x0098:
       
   127     case 0x00a0:
       
   128     case 0x00a8:
       
   129     case 0x00b0:
       
   130     case 0x00b8:
       
   131     case 0x00c0:
       
   132     case 0x00c8:
       
   133     case 0x00d0:
       
   134     case 0x00d8:
       
   135     case 0x00e0:
       
   136         val = s->rem_speed[(addr - 0x0070) >> 3];
       
   137         break;
       
   138     /* DMA channel base address */
       
   139     case 0x0100:
       
   140     case 0x0108:
       
   141     case 0x0110:
       
   142     case 0x0118:
       
   143     case 0x0120:
       
   144     case 0x0128:
       
   145     case 0x0130:
       
   146     case 0x0138:
       
   147     case 0x0140:
       
   148     case 0x0148:
       
   149     case 0x0150:
       
   150     case 0x0158:
       
   151     case 0x0160:
       
   152     case 0x0168:
       
   153     case 0x0170:
       
   154     case 0x0178:
       
   155     case 0x0180:
       
   156     case 0x0188:
       
   157     case 0x0190:
       
   158     case 0x0198:
       
   159     case 0x01a0:
       
   160     case 0x01a8:
       
   161     case 0x01b0:
       
   162     case 0x01b8:
       
   163     case 0x01c0:
       
   164     case 0x01c8:
       
   165     case 0x01d0:
       
   166     case 0x01d8:
       
   167     case 0x01e0:
       
   168     case 0x1e8:
       
   169     case 0x01f0:
       
   170     case 0x01f8:
       
   171         {
       
   172             int entry = (addr - 0x0100) >> 5;
       
   173             int idx = (addr & 0x1f) >> 3;
       
   174             val = s->dma_regs[entry][idx];
       
   175         }
       
   176         break;
       
   177     /* Offset 0x0208 */
       
   178     case 0x0208:
       
   179         val = s->offset208;
       
   180         break;
       
   181     /* Offset 0x0210 */
       
   182     case 0x0210:
       
   183         val = s->offset210;
       
   184         break;
       
   185     /* NV ram protect register */
       
   186     case 0x0220:
       
   187         val = s->nvram_protect;
       
   188         break;
       
   189     /* Interval timer count */
       
   190     case 0x0230:
       
   191         val = s->dummy32;
       
   192         qemu_irq_lower(s->timer_irq);
       
   193         break;
       
   194     /* Offset 0x0238 */
       
   195     case 0x0238:
       
   196         val = s->offset238;
       
   197         break;
       
   198     default:
       
   199 #ifdef DEBUG_RC4030
       
   200         printf("rc4030: invalid read [" TARGET_FMT_lx "]\n", addr);
       
   201 #endif
       
   202         val = 0;
       
   203         break;
       
   204     }
       
   205 
       
   206 #ifdef DEBUG_RC4030
       
   207     if ((addr & ~3) != 0x230)
       
   208         printf("rc4030: read 0x%02x at " TARGET_FMT_lx "\n", val, addr);
       
   209 #endif
       
   210 
       
   211     return val;
       
   212 }
       
   213 
       
   214 static uint32_t rc4030_readw(void *opaque, target_phys_addr_t addr)
       
   215 {
       
   216     uint32_t v = rc4030_readl(opaque, addr & ~0x3);
       
   217     if (addr & 0x2)
       
   218         return v >> 16;
       
   219     else
       
   220         return v & 0xffff;
       
   221 }
       
   222 
       
   223 static uint32_t rc4030_readb(void *opaque, target_phys_addr_t addr)
       
   224 {
       
   225     uint32_t v = rc4030_readl(opaque, addr & ~0x3);
       
   226     return (v >> (8 * (addr & 0x3))) & 0xff;
       
   227 }
       
   228 
       
   229 static void rc4030_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
       
   230 {
       
   231     rc4030State *s = opaque;
       
   232     addr &= 0x3fff;
       
   233 
       
   234 #ifdef DEBUG_RC4030
       
   235     printf("rc4030: write 0x%02x at " TARGET_FMT_lx "\n", val, addr);
       
   236 #endif
       
   237 
       
   238     switch (addr & ~0x3) {
       
   239     /* Global config register */
       
   240     case 0x0000:
       
   241         s->config = val;
       
   242         break;
       
   243     /* DMA transl. table base */
       
   244     case 0x0018:
       
   245         s->dma_tl_base = val;
       
   246         break;
       
   247     /* DMA transl. table limit */
       
   248     case 0x0020:
       
   249         s->dma_tl_limit = val;
       
   250         break;
       
   251     /* I/O Cache Physical Tag */
       
   252     case 0x0048:
       
   253         s->cache_ptag = val;
       
   254         break;
       
   255     /* I/O Cache Logical Tag */
       
   256     case 0x0050:
       
   257         s->cache_ltag = val;
       
   258         break;
       
   259     /* I/O Cache Byte Mask */
       
   260     case 0x0058:
       
   261         s->cache_bmask |= val; /* HACK */
       
   262         break;
       
   263     /* I/O Cache Buffer Window */
       
   264     case 0x0060:
       
   265         s->cache_bwin = val;
       
   266         /* HACK */
       
   267         if (s->cache_ltag == 0x80000001 && s->cache_bmask == 0xf0f0f0f) {
       
   268             target_phys_addr_t dests[] = { 4, 0, 8, 0x10 };
       
   269             static int current = 0;
       
   270             target_phys_addr_t dest = 0 + dests[current];
       
   271             uint8_t buf;
       
   272             current = (current + 1) % (ARRAY_SIZE(dests));
       
   273             buf = s->cache_bwin - 1;
       
   274             cpu_physical_memory_rw(dest, &buf, 1, 1);
       
   275         }
       
   276         break;
       
   277     /* Remote Speed Registers */
       
   278     case 0x0070:
       
   279     case 0x0078:
       
   280     case 0x0080:
       
   281     case 0x0088:
       
   282     case 0x0090:
       
   283     case 0x0098:
       
   284     case 0x00a0:
       
   285     case 0x00a8:
       
   286     case 0x00b0:
       
   287     case 0x00b8:
       
   288     case 0x00c0:
       
   289     case 0x00c8:
       
   290     case 0x00d0:
       
   291     case 0x00d8:
       
   292     case 0x00e0:
       
   293         s->rem_speed[(addr - 0x0070) >> 3] = val;
       
   294         break;
       
   295     /* DMA channel base address */
       
   296     case 0x0100:
       
   297     case 0x0108:
       
   298     case 0x0110:
       
   299     case 0x0118:
       
   300     case 0x0120:
       
   301     case 0x0128:
       
   302     case 0x0130:
       
   303     case 0x0138:
       
   304     case 0x0140:
       
   305     case 0x0148:
       
   306     case 0x0150:
       
   307     case 0x0158:
       
   308     case 0x0160:
       
   309     case 0x0168:
       
   310     case 0x0170:
       
   311     case 0x0178:
       
   312     case 0x0180:
       
   313     case 0x0188:
       
   314     case 0x0190:
       
   315     case 0x0198:
       
   316     case 0x01a0:
       
   317     case 0x01a8:
       
   318     case 0x01b0:
       
   319     case 0x01b8:
       
   320     case 0x01c0:
       
   321     case 0x01c8:
       
   322     case 0x01d0:
       
   323     case 0x01d8:
       
   324     case 0x01e0:
       
   325     case 0x1e8:
       
   326     case 0x01f0:
       
   327     case 0x01f8:
       
   328         {
       
   329             int entry = (addr - 0x0100) >> 5;
       
   330             int idx = (addr & 0x1f) >> 3;
       
   331             s->dma_regs[entry][idx] = val;
       
   332         }
       
   333         break;
       
   334     /* Offset 0x0210 */
       
   335     case 0x0210:
       
   336         s->offset210 = val;
       
   337         break;
       
   338     /* Interval timer reload */
       
   339     case 0x0228:
       
   340         s->itr = val;
       
   341         qemu_irq_lower(s->timer_irq);
       
   342         set_next_tick(s);
       
   343         break;
       
   344     default:
       
   345 #ifdef DEBUG_RC4030
       
   346         printf("rc4030: invalid write of 0x%02x at [" TARGET_FMT_lx "]\n", val, addr);
       
   347 #endif
       
   348         break;
       
   349     }
       
   350 }
       
   351 
       
   352 static void rc4030_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
       
   353 {
       
   354     uint32_t old_val = rc4030_readl(opaque, addr & ~0x3);
       
   355 
       
   356     if (addr & 0x2)
       
   357         val = (val << 16) | (old_val & 0x0000ffff);
       
   358     else
       
   359         val = val | (old_val & 0xffff0000);
       
   360     rc4030_writel(opaque, addr & ~0x3, val);
       
   361 }
       
   362 
       
   363 static void rc4030_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
       
   364 {
       
   365     uint32_t old_val = rc4030_readl(opaque, addr & ~0x3);
       
   366 
       
   367     switch (addr & 3) {
       
   368     case 0:
       
   369         val = val | (old_val & 0xffffff00);
       
   370         break;
       
   371     case 1:
       
   372         val = (val << 8) | (old_val & 0xffff00ff);
       
   373         break;
       
   374     case 2:
       
   375         val = (val << 16) | (old_val & 0xff00ffff);
       
   376         break;
       
   377     case 3:
       
   378         val = (val << 24) | (old_val & 0x00ffffff);
       
   379         break;
       
   380     }
       
   381     rc4030_writel(opaque, addr & ~0x3, val);
       
   382 }
       
   383 
       
   384 static CPUReadMemoryFunc *rc4030_read[3] = {
       
   385     rc4030_readb,
       
   386     rc4030_readw,
       
   387     rc4030_readl,
       
   388 };
       
   389 
       
   390 static CPUWriteMemoryFunc *rc4030_write[3] = {
       
   391     rc4030_writeb,
       
   392     rc4030_writew,
       
   393     rc4030_writel,
       
   394 };
       
   395 
       
   396 static void update_jazz_irq(rc4030State *s)
       
   397 {
       
   398     uint16_t pending;
       
   399 
       
   400     pending = s->isr_jazz & s->imr_jazz;
       
   401 
       
   402 #ifdef DEBUG_RC4030
       
   403     if (s->isr_jazz != 0) {
       
   404         uint32_t irq = 0;
       
   405         printf("jazz pending:");
       
   406         for (irq = 0; irq < ARRAY_SIZE(irq_names); irq++) {
       
   407             if (s->isr_jazz & (1 << irq)) {
       
   408                 printf(" %s", irq_names[irq]);
       
   409                 if (!(s->imr_jazz & (1 << irq))) {
       
   410                     printf("(ignored)");
       
   411                 }
       
   412             }
       
   413         }
       
   414         printf("\n");
       
   415     }
       
   416 #endif
       
   417 
       
   418     if (pending != 0)
       
   419         qemu_irq_raise(s->jazz_bus_irq);
       
   420     else
       
   421         qemu_irq_lower(s->jazz_bus_irq);
       
   422 }
       
   423 
       
   424 static void rc4030_irq_jazz_request(void *opaque, int irq, int level)
       
   425 {
       
   426     rc4030State *s = opaque;
       
   427 
       
   428     if (level) {
       
   429         s->isr_jazz |= 1 << irq;
       
   430     } else {
       
   431         s->isr_jazz &= ~(1 << irq);
       
   432     }
       
   433 
       
   434     update_jazz_irq(s);
       
   435 }
       
   436 
       
   437 static void rc4030_periodic_timer(void *opaque)
       
   438 {
       
   439     rc4030State *s = opaque;
       
   440 
       
   441     set_next_tick(s);
       
   442     qemu_irq_raise(s->timer_irq);
       
   443 }
       
   444 
       
   445 static uint32_t int_readb(void *opaque, target_phys_addr_t addr)
       
   446 {
       
   447     rc4030State *s = opaque;
       
   448     uint32_t val;
       
   449     uint32_t irq;
       
   450     addr &= 0xfff;
       
   451 
       
   452     switch (addr) {
       
   453     case 0x00: {
       
   454         /* Local bus int source */
       
   455         uint32_t pending = s->isr_jazz & s->imr_jazz;
       
   456         val = 0;
       
   457         irq = 0;
       
   458         while (pending) {
       
   459             if (pending & 1) {
       
   460                 //printf("returning irq %s\n", irq_names[irq]);
       
   461                 val = (irq + 1) << 2;
       
   462                 break;
       
   463             }
       
   464             irq++;
       
   465             pending >>= 1;
       
   466         }
       
   467         break;
       
   468     }
       
   469     default:
       
   470 #ifdef DEBUG_RC4030
       
   471             printf("rc4030: (interrupt controller) invalid read [" TARGET_FMT_lx "]\n", addr);
       
   472 #endif
       
   473             val = 0;
       
   474     }
       
   475 
       
   476 #ifdef DEBUG_RC4030
       
   477     printf("rc4030: (interrupt controller) read 0x%02x at " TARGET_FMT_lx "\n", val, addr);
       
   478 #endif
       
   479 
       
   480     return val;
       
   481 }
       
   482 
       
   483 static uint32_t int_readw(void *opaque, target_phys_addr_t addr)
       
   484 {
       
   485     uint32_t v;
       
   486     v = int_readb(opaque, addr);
       
   487     v |= int_readb(opaque, addr + 1) << 8;
       
   488     return v;
       
   489 }
       
   490 
       
   491 static uint32_t int_readl(void *opaque, target_phys_addr_t addr)
       
   492 {
       
   493     uint32_t v;
       
   494     v = int_readb(opaque, addr);
       
   495     v |= int_readb(opaque, addr + 1) << 8;
       
   496     v |= int_readb(opaque, addr + 2) << 16;
       
   497     v |= int_readb(opaque, addr + 3) << 24;
       
   498     return v;
       
   499 }
       
   500 
       
   501 static void int_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
       
   502 {
       
   503     rc4030State *s = opaque;
       
   504     addr &= 0xfff;
       
   505 
       
   506 #ifdef DEBUG_RC4030
       
   507     printf("rc4030: (interrupt controller) write 0x%02x at " TARGET_FMT_lx "\n", val, addr);
       
   508 #endif
       
   509 
       
   510     switch (addr) {
       
   511     /* Local bus int enable mask */
       
   512     case 0x02:
       
   513         s->imr_jazz = (s->imr_jazz & 0xff00) | (val << 0); update_jazz_irq(s);
       
   514         break;
       
   515     case 0x03:
       
   516         s->imr_jazz = (s->imr_jazz & 0x00ff) | (val << 8); update_jazz_irq(s);
       
   517         break;
       
   518     default:
       
   519 #ifdef DEBUG_RC4030
       
   520         printf("rc4030: (interrupt controller) invalid write of 0x%02x at [" TARGET_FMT_lx "]\n", val, addr);
       
   521 #endif
       
   522         break;
       
   523     }
       
   524 }
       
   525 
       
   526 static void int_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
       
   527 {
       
   528     int_writeb(opaque, addr, val & 0xff);
       
   529     int_writeb(opaque, addr + 1, (val >> 8) & 0xff);
       
   530 }
       
   531 
       
   532 static void int_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
       
   533 {
       
   534     int_writeb(opaque, addr, val & 0xff);
       
   535     int_writeb(opaque, addr + 1, (val >> 8) & 0xff);
       
   536     int_writeb(opaque, addr + 2, (val >> 16) & 0xff);
       
   537     int_writeb(opaque, addr + 3, (val >> 24) & 0xff);
       
   538 }
       
   539 
       
   540 static CPUReadMemoryFunc *int_read[3] = {
       
   541     int_readb,
       
   542     int_readw,
       
   543     int_readl,
       
   544 };
       
   545 
       
   546 static CPUWriteMemoryFunc *int_write[3] = {
       
   547     int_writeb,
       
   548     int_writew,
       
   549     int_writel,
       
   550 };
       
   551 
       
   552 #define G364_512KB_RAM (0x0)
       
   553 #define G364_2MB_RAM   (0x1)
       
   554 #define G364_8MB_RAM   (0x2)
       
   555 #define G364_32MB_RAM  (0x3)
       
   556 
       
   557 static void rc4030_reset(void *opaque)
       
   558 {
       
   559     rc4030State *s = opaque;
       
   560     int i;
       
   561 
       
   562     s->config = (G364_2MB_RAM << 8) | 0x04;
       
   563     s->invalid_address_register = 0;
       
   564 
       
   565     memset(s->dma_regs, 0, sizeof(s->dma_regs));
       
   566     s->dma_tl_base = s->dma_tl_limit = 0;
       
   567 
       
   568     s->remote_failed_address = s->memory_failed_address = 0;
       
   569     s->cache_ptag = s->cache_ltag = 0;
       
   570     s->cache_bmask = s->cache_bwin = 0;
       
   571 
       
   572     s->offset208 = 0;
       
   573     s->offset210 = 0x18186;
       
   574     s->nvram_protect = 7;
       
   575     s->offset238 = 7;
       
   576     for (i = 0; i < 15; i++)
       
   577         s->rem_speed[i] = 7;
       
   578     s->imr_jazz = s->isr_jazz = 0;
       
   579 
       
   580     s->itr = 0;
       
   581     s->dummy32 = 0;
       
   582 
       
   583     qemu_irq_lower(s->timer_irq);
       
   584     qemu_irq_lower(s->jazz_bus_irq);
       
   585 }
       
   586 
       
   587 qemu_irq *rc4030_init(qemu_irq timer, qemu_irq jazz_bus)
       
   588 {
       
   589     rc4030State *s;
       
   590     int s_chipset, s_int;
       
   591 
       
   592     s = qemu_mallocz(sizeof(rc4030State));
       
   593     if (!s)
       
   594         return NULL;
       
   595 
       
   596     s->periodic_timer = qemu_new_timer(vm_clock, rc4030_periodic_timer, s);
       
   597     s->timer_irq = timer;
       
   598     s->jazz_bus_irq = jazz_bus;
       
   599 
       
   600     qemu_register_reset(rc4030_reset, s);
       
   601     rc4030_reset(s);
       
   602 
       
   603     s_chipset = cpu_register_io_memory(0, rc4030_read, rc4030_write, s);
       
   604     cpu_register_physical_memory(0x80000000, 0x300, s_chipset);
       
   605     s_int = cpu_register_io_memory(0, int_read, int_write, s);
       
   606     cpu_register_physical_memory(0xf0000000, 0x00001000, s_int);
       
   607 
       
   608     return qemu_allocate_irqs(rc4030_irq_jazz_request, s, 16);
       
   609 }