2 * QEMU JZ Soc emulation
4 * Copyright (c) 2008 yajin (yajin@vm-kernel.org)
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
27 * The emulation target is pavo demo board.
28 * http://www.ingenic.cn/eng/productServ/kfyd/Hardware/pffaqQuestionContent.aspx?Category=2&Question=3
36 #include "qemu-timer.h"
37 #include "qemu-char.h"
40 #include "audio/audio.h"
42 #define DEBUG_CPM (1<<0x1)
44 #define DEBUG_FLAG (DEBUG_CPM)
50 static void debug_init()
52 fp
= fopen("jz4740.txt", "w+");
55 fprintf(stderr
, "can not open jz4740.txt \n");
59 static void debug_out(uint32_t flag
, const char *format
, ...)
64 if (flag
& DEBUG_FLAG
)
67 vfprintf(fp
, format
, ap
);
74 static void debug_init(void)
77 static void debug_out(uint32_t flag
, const char *format
, ...)
82 static uint32_t jz4740_badwidth_read8(void *opaque
, target_phys_addr_t addr
)
87 cpu_physical_memory_read(addr
, (void *) &ret
, 1);
91 static void jz4740_badwidth_write8(void *opaque
, target_phys_addr_t addr
,
97 cpu_physical_memory_write(addr
, (void *) &val8
, 1);
100 static uint32_t jz4740_badwidth_read16(void *opaque
, target_phys_addr_t addr
)
103 JZ4740_16B_REG(addr
);
104 cpu_physical_memory_read(addr
, (void *) &ret
, 2);
108 static void jz4740_badwidth_write16(void *opaque
, target_phys_addr_t addr
,
111 uint16_t val16
= value
;
113 JZ4740_16B_REG(addr
);
114 cpu_physical_memory_write(addr
, (void *) &val16
, 2);
117 static uint32_t jz4740_badwidth_read32(void *opaque
, target_phys_addr_t addr
)
121 JZ4740_32B_REG(addr
);
122 cpu_physical_memory_read(addr
, (void *) &ret
, 4);
126 static void jz4740_badwidth_write32(void *opaque
, target_phys_addr_t addr
,
129 JZ4740_32B_REG(addr
);
130 cpu_physical_memory_write(addr
, (void *) &value
, 4);
134 /*clock reset and power control*/
137 target_phys_addr_t base
;
138 struct jz_state_s
*soc
;
150 static void jz4740_dump_clocks(jz_clk parent
)
154 debug_out(DEBUG_CPM
, "clock %x rate 0x%x \n", i
->name
, i
->rate
);
155 for (i
= i
->child1
; i
; i
= i
->sibling
)
156 jz4740_dump_clocks(i
);
159 static inline void jz4740_cpccr_update(struct jz4740_cpm_s
*s
,
162 uint32_t ldiv
, mdiv
, pdiv
, hdiv
, cdiv
, udiv
;
163 uint32_t div_table
[10] = { 1, 2, 3, 4, 6, 8, 12, 16, 24, 32 };
165 if (unlikely(new_value
== s
->cpccr
))
168 if (new_value
& CPM_CPCCR_PCS
)
169 jz_clk_setrate(jz_findclk(s
->soc
, "pll_divider"), 1, 1);
171 jz_clk_setrate(jz_findclk(s
->soc
, "pll_divider"), 2, 1);
174 ldiv
= (new_value
& CPM_CPCCR_LDIV_MASK
) >> CPM_CPCCR_LDIV_BIT
;
177 mdiv
= div_table
[(new_value
& CPM_CPCCR_MDIV_MASK
) >> CPM_CPCCR_MDIV_BIT
];
178 pdiv
= div_table
[(new_value
& CPM_CPCCR_PDIV_MASK
) >> CPM_CPCCR_PDIV_BIT
];
179 hdiv
= div_table
[(new_value
& CPM_CPCCR_HDIV_MASK
) >> CPM_CPCCR_HDIV_BIT
];
180 cdiv
= div_table
[(new_value
& CPM_CPCCR_CDIV_MASK
) >> CPM_CPCCR_CDIV_BIT
];
181 udiv
= div_table
[(new_value
& CPM_CPCCR_UDIV_MASK
) >> CPM_CPCCR_UDIV_BIT
];
183 jz_clk_setrate(jz_findclk(s
->soc
, "ldclk"), ldiv
, 1);
184 jz_clk_setrate(jz_findclk(s
->soc
, "mclk"), mdiv
, 1);
185 jz_clk_setrate(jz_findclk(s
->soc
, "pclk"), pdiv
, 1);
186 jz_clk_setrate(jz_findclk(s
->soc
, "hclk"), hdiv
, 1);
187 jz_clk_setrate(jz_findclk(s
->soc
, "cclk"), cdiv
, 1);
188 jz_clk_setrate(jz_findclk(s
->soc
, "usbclk"), udiv
, 1);
190 if (new_value
& CPM_CPCCR_UCS
)
191 jz_clk_reparent(jz_findclk(s
->soc
, "usbclk"),
192 jz_findclk(s
->soc
, "pll_divider"));
194 jz_clk_reparent(jz_findclk(s
->soc
, "usbclk"),
195 jz_findclk(s
->soc
, "osc_extal"));
197 if (new_value
& CPM_CPCCR_I2CS
)
198 jz_clk_reparent(jz_findclk(s
->soc
, "i2sclk"),
199 jz_findclk(s
->soc
, "pll_divider"));
201 jz_clk_reparent(jz_findclk(s
->soc
, "i2sclk"),
202 jz_findclk(s
->soc
, "osc_extal"));
204 s
->cpccr
= new_value
;
206 debug_out(DEBUG_CPM
, "write to cpccr 0x%x\n", new_value
);
207 jz4740_dump_clocks(jz_findclk(s
->soc
, "osc_extal"));
211 static inline void jz4740_cppcr_update(struct jz4740_cpm_s
*s
,
214 uint32_t pllm
, plln
, pllod
, pllbp
, pllen
;
215 uint32_t pll0
[4] = { 1, 2, 2, 4 };
218 pllen
= new_value
& CPM_CPPCR_PLLEN
;
219 pllbp
= new_value
& CPM_CPPCR_PLLBP
;
220 if ((!pllen
) || (pllen
&& pllbp
))
222 jz_clk_setrate(jz_findclk(s
->soc
, "pll_output"), 1, 1);
223 debug_out(DEBUG_CPM
, "pll is bypassed \n");
224 s
->cppcr
= new_value
| CPM_CPPCR_PLLS
;
229 pllm
= (new_value
& CPM_CPPCR_PLLM_MASK
) >> CPM_CPPCR_PLLM_BIT
;
230 plln
= (new_value
& CPM_CPPCR_PLLN_MASK
) >> CPM_CPPCR_PLLN_BIT
;
231 pllod
= (new_value
& CPM_CPPCR_PLLOD_MASK
) >> CPM_CPPCR_PLLOD_BIT
;
232 jz_clk_setrate(jz_findclk(s
->soc
, "pll_output"), (plln
+ 2) * pll0
[pllod
],
235 s
->cppcr
= new_value
;
237 debug_out(DEBUG_CPM
, "write to cppcr 0x%x\n", new_value
);
238 jz4740_dump_clocks(jz_findclk(s
->soc
, "osc_extal"));
242 static inline void jz4740_i2scdr_update(struct jz4740_cpm_s
*s
,
247 i2scdr
= new_value
& CPM_I2SCDR_I2SDIV_MASK
;
248 if (unlikely(i2scdr
== s
->i2scdr
))
252 jz_clk_setrate(jz_findclk(s
->soc
, "i2sclk"), i2scdr
+ 1, 1);
256 debug_out(DEBUG_CPM
, "write to i2scdr 0x%x\n", new_value
);
257 jz4740_dump_clocks(jz_findclk(s
->soc
, "osc_extal"));
261 static inline void jz4740_lpcdr_update(struct jz4740_cpm_s
*s
,
266 ipcdr
= new_value
& CPM_LPCDR_PIXDIV_MASK
;
271 static inline void jz4740_msccdr_update(struct jz4740_cpm_s
*s
,
276 msccdr
= new_value
& CPM_MSCCDR_MSCDIV_MASK
;
278 if (unlikely(msccdr
== s
->msccdr
))
282 jz_clk_setrate(jz_findclk(s
->soc
, "mscclk"), msccdr
+ 1, 1);
286 debug_out(DEBUG_CPM
, "write to msccdr 0x%x\n", new_value
);
287 jz4740_dump_clocks(jz_findclk(s
->soc
, "osc_extal"));
291 static inline void jz4740_uhccdr_update(struct jz4740_cpm_s
*s
,
296 uhccdr
= new_value
& 0xf;
301 static void jz4740_cpm_write(void *opaque
, target_phys_addr_t addr
,
304 struct jz4740_cpm_s
*s
= (struct jz4740_cpm_s
*) opaque
;
305 int offset
= addr
- s
->base
;
310 jz4740_cpccr_update(s
, value
);
313 jz4740_cppcr_update(s
, value
);
316 jz4740_i2scdr_update(s
, value
);
319 jz4740_lpcdr_update(s
, value
);
322 jz4740_msccdr_update(s
, value
);
325 jz4740_uhccdr_update(s
, value
);
328 s
->uhctst
= value
& 0x3f;
331 s
->ssicdr
= value
& 0xf;
334 cpu_abort(s
->soc
->env
,
335 "jz4740_cpm_write undefined addr " JZ_FMT_plx
" value %x \n",
342 static uint32_t jz474_cpm_read(void *opaque
, target_phys_addr_t addr
)
344 struct jz4740_cpm_s
*s
= (struct jz4740_cpm_s
*) opaque
;
345 int offset
= addr
- s
->base
;
366 cpu_abort(s
->soc
->env
,
367 "jz474_cpm_read undefined addr " JZ_FMT_plx
" \n", addr
);
374 static CPUReadMemoryFunc
*jz4740_cpm_readfn
[] = {
375 jz4740_badwidth_read32
,
376 jz4740_badwidth_read32
,
380 static CPUWriteMemoryFunc
*jz4740_cpm_writefn
[] = {
381 jz4740_badwidth_write32
,
382 jz4740_badwidth_write32
,
386 static void jz4740_cpm_reset(struct jz4740_cpm_s
*s
)
388 s
->cpccr
= 0x42040000;
389 s
->cppcr
= 0x28080011;
390 s
->i2scdr
= 0x00000004;
391 s
->lpcdr
= 0x00000004;
392 s
->msccdr
= 0x00000004;
393 s
->uhccdr
= 0x00000004;
395 s
->ssicdr
= 0x00000004;
398 static struct jz4740_cpm_s
*jz4740_cpm_init(struct jz_state_s
*soc
)
401 struct jz4740_cpm_s
*s
= (struct jz4740_cpm_s
*) qemu_mallocz(sizeof(*s
));
402 s
->base
= JZ4740_PHYS_BASE(JZ4740_CPM_BASE
);
408 cpu_register_io_memory(0, jz4740_cpm_readfn
, jz4740_cpm_writefn
, s
);
409 cpu_register_physical_memory(s
->base
, 0x00001000, iomemtype
);
414 /* JZ4740 interrupt controller
415 * It issues INT2 to MIPS
421 target_phys_addr_t base
;
422 struct jz_state_s
*soc
;
431 static uint32_t jz4740_intc_read(void *opaque
, target_phys_addr_t addr
)
433 struct jz4740_intc_s
*s
= (struct jz4740_intc_s
*) opaque
;
434 int offset
= addr
- s
->base
;
448 cpu_abort(s
->soc
->env
,
449 "jz4740_intc_read undefined addr " JZ_FMT_plx
" \n", addr
);
455 static void jz4740_intc_write(void *opaque
, target_phys_addr_t addr
,
458 struct jz4740_intc_s
*s
= (struct jz4740_intc_s
*) opaque
;
459 int offset
= addr
- s
->base
;
477 cpu_abort(s
->soc
->env
,
478 "jz4740_intc_write undefined addr " JZ_FMT_plx
479 " value %x \n", addr
, value
);
484 static CPUReadMemoryFunc
*jz4740_intc_readfn
[] = {
485 jz4740_badwidth_read32
,
486 jz4740_badwidth_read32
,
490 static CPUWriteMemoryFunc
*jz4740_intc_writefn
[] = {
491 jz4740_badwidth_write32
,
492 jz4740_badwidth_write32
,
496 static void jz4740_intc_reset(struct jz4740_intc_s
*s
)
499 s
->icmr
= 0xffffffff;
503 static void jz4740_set_irq(void *opaque
, int irq
, int level
)
505 struct jz4740_intc_s
*s
= (struct jz4740_intc_s
*) opaque
;
506 uint32_t irq_mask
= 1 << irq
;
512 if (((~s
->icmr
) & irq_mask
) && (level
))
513 qemu_set_irq(s
->parent_irq
, 1);
515 qemu_set_irq(s
->parent_irq
, 0);
518 static qemu_irq
*jz4740_intc_init(struct jz_state_s
*soc
, qemu_irq parent_irq
)
521 struct jz4740_intc_s
*s
= (struct jz4740_intc_s
*) qemu_mallocz(sizeof(*s
));
522 s
->base
= JZ4740_PHYS_BASE(JZ4740_INTC_BASE
);
523 s
->parent_irq
= parent_irq
;
526 jz4740_intc_reset(s
);
529 cpu_register_io_memory(0, jz4740_intc_readfn
, jz4740_intc_writefn
, s
);
530 cpu_register_physical_memory(s
->base
, 0x00001000, iomemtype
);
531 return qemu_allocate_irqs(jz4740_set_irq
, s
, 32);
534 /*external memory controller*/
538 target_phys_addr_t base
;
539 struct jz_state_s
*soc
;
541 uint32_t smcr1
; /*0x13010014 */
542 uint32_t smcr2
; /*0x13010018 */
543 uint32_t smcr3
; /*0x1301001c */
544 uint32_t smcr4
; /*0x13010020 */
545 uint32_t sacr1
; /*0x13010034 */
546 uint32_t sacr2
; /*0x13010038 */
547 uint32_t sacr3
; /*0x1301003c */
548 uint32_t sacr4
; /*0x13010040 */
550 uint32_t nfcsr
; /*0x13010050 */
551 uint32_t nfeccr
; /*0x13010100 */
552 uint32_t nfecc
; /*0x13010104 */
553 uint32_t nfpar0
; /*0x13010108 */
554 uint32_t nfpar1
; /*0x1301010c */
555 uint32_t nfpar2
; /*0x13010110 */
556 uint32_t nfints
; /*0x13010114 */
557 uint32_t nfinte
; /*0x13010118 */
558 uint32_t nferr0
; /*0x1301011c */
559 uint32_t nferr1
; /*0x13010120 */
560 uint32_t nferr2
; /*0x13010124 */
561 uint32_t nferr3
; /*0x13010128 */
563 uint32_t dmcr
; /*0x13010080 */
564 uint32_t rtcsr
; /*0x13010084 */
565 uint32_t rtcnt
; /*0x13010088 */
566 uint32_t rtcor
; /*0x1301008c */
567 uint32_t dmar
; /*0x13010090 */
568 uint32_t sdmr
; /*0x1301a000 */
573 static void jz4740_emc_reset(struct jz4740_emc_s
*s
)
575 s
->smcr1
= 0xfff7700;
576 s
->smcr2
= 0xfff7700;
577 s
->smcr3
= 0xfff7700;
578 s
->smcr4
= 0xfff7700;
606 static uint32_t jz4740_emc_read8(void *opaque
, target_phys_addr_t addr
)
608 struct jz4740_emc_s
*s
= (struct jz4740_emc_s
*) opaque
;
609 int offset
= addr
- s
->base
;
616 return (s
->nfpar0
>> ((offset
- 0x108) * 8)) & 0xff;
621 return (s
->nfpar1
>> ((offset
- 0x10c) * 8)) & 0xff;
626 return (s
->nfpar2
>> ((offset
- 0x110) * 8)) & 0xff;
631 return (s
->sdmr
>> ((offset
- 0xa000) * 8)) & 0xff;
633 cpu_abort(s
->soc
->env
,
634 "jz4740_emc_read8 undefined addr " JZ_FMT_plx
" \n", addr
);
641 static uint32_t jz4740_emc_read16(void *opaque
, target_phys_addr_t addr
)
643 struct jz4740_emc_s
*s
= (struct jz4740_emc_s
*) opaque
;
644 int offset
= addr
- s
->base
;
649 return (s
->nfpar0
>> ((offset
- 0x108) * 8)) & 0xffff;
652 return (s
->nfpar1
>> ((offset
- 0x10c) * 8)) & 0xffff;
655 return (s
->nfpar2
>> ((offset
- 0x110) * 8)) & 0xffff;
658 return (s
->nferr0
>> ((offset
- 0x11c) * 8)) & 0xffff;
661 return (s
->nferr1
>> ((offset
- 0x120) * 8)) & 0xffff;
664 return (s
->nferr2
>> ((offset
- 0x124) * 8)) & 0xffff;
667 return (s
->nferr3
>> ((offset
- 0x128) * 8)) & 0xffff;
669 cpu_abort(s
->soc
->env
,
670 "jz4740_emc_read16 undefined addr " JZ_FMT_plx
" \n", addr
);
675 static uint32_t jz4740_emc_read32(void *opaque
, target_phys_addr_t addr
)
677 struct jz4740_emc_s
*s
= (struct jz4740_emc_s
*) opaque
;
678 int offset
= addr
- s
->base
;
726 cpu_abort(s
->soc
->env
,
727 "jz4740_emc_read32 undefined addr " JZ_FMT_plx
" \n", addr
);
732 static void jz4740_emc_write8(void *opaque
, target_phys_addr_t addr
,
735 struct jz4740_emc_s
*s
= (struct jz4740_emc_s
*) opaque
;
736 int offset
= addr
- s
->base
;
744 s
->nfpar0
|= (value
& 0xff) << ((offset
- 0x108) * 8);
750 s
->nfpar1
|= (value
& 0xff) << ((offset
- 0x10c) * 8);
756 s
->nfpar2
|= (value
& 0xff) << ((offset
- 0x110) * 8);
762 s
->sdmr
|= (value
& 0xff) << ((offset
- 0x110) * 8);
765 cpu_abort(s
->soc
->env
,
766 "jz4740_emc_write8 undefined addr " JZ_FMT_plx
767 " value %x \n", addr
, value
);
770 static void jz4740_emc_write16(void *opaque
, target_phys_addr_t addr
,
773 struct jz4740_emc_s
*s
= (struct jz4740_emc_s
*) opaque
;
774 int offset
= addr
- s
->base
;
780 s
->nfpar0
|= (value
& 0xffff) << ((offset
- 0x108) * 8);
784 s
->nfpar1
|= (value
& 0xffff) << ((offset
- 0x10c) * 8);
788 s
->nfpar2
|= (value
& 0xffff) << ((offset
- 0x110) * 8);
792 s
->rtcsr
|= (value
& 0xffff) << ((offset
- 0x84) * 8);
796 s
->rtcnt
|= (value
& 0xffff) << ((offset
- 0x88) * 8);
799 s
->rtcor
|= (value
& 0xffff) << ((offset
- 0x8c) * 8);
802 cpu_abort(s
->soc
->env
,
803 "jz4740_emc_write16 undefined addr " JZ_FMT_plx
804 " value %x \n", addr
, value
);
808 static void jz4740_emc_upate_interrupt(struct jz4740_emc_s
*s
)
810 qemu_set_irq(s
->irq
, s
->nfints
& s
->nfinte
);
813 static void jz4740_emc_write32(void *opaque
, target_phys_addr_t addr
,
816 struct jz4740_emc_s
*s
= (struct jz4740_emc_s
*) opaque
;
817 int offset
= addr
- s
->base
;
829 s
->smcr1
= value
& 0xfff77cf;
832 s
->smcr2
= value
& 0xfff77cf;
835 s
->smcr3
= value
& 0xfff77cf;
838 s
->smcr4
= value
& 0xfff77cf;
841 s
->sacr1
= value
& 0xffff;
844 s
->sacr2
= value
& 0xffff;
847 s
->sacr3
= value
& 0xffff;
850 s
->sacr4
= value
& 0xffff;
853 s
->nfcsr
= value
& 0xffff;
856 s
->nfeccr
= value
& 0x1f;
871 /*TODO: Real RS error correction */
874 if ((s
->nfeccr
& 0x10) && (!(s
->nfeccr
& 0x8)))
886 s
->nfpar0
= 0xffffffff; /*fake value. for debug */
887 s
->nfpar1
= 0xffffffff; /*fake value */
888 s
->nfpar2
= 0xff; /*fake value */
895 jz4740_emc_upate_interrupt(s
);
904 s
->nfpar2
= value
& 0xff;
907 s
->nfints
= value
& 0x1fffffff;
908 jz4740_emc_upate_interrupt(s
);
911 s
->nfinte
= value
& 0x1f;
912 jz4740_emc_upate_interrupt(s
);
915 s
->dmcr
= value
& 0x9fbeff7f;
918 s
->dmar
= value
& 0xffff;
921 cpu_abort(s
->soc
->env
,
922 "jz4740_emc_write32 undefined addr " JZ_FMT_plx
923 " value %x \n", addr
, value
);
929 static CPUReadMemoryFunc
*jz4740_emc_readfn
[] = {
935 static CPUWriteMemoryFunc
*jz4740_emc_writefn
[] = {
942 static struct jz4740_emc_s
*jz4740_emc_init(struct jz_state_s
*soc
, qemu_irq irq
)
945 struct jz4740_emc_s
*s
= (struct jz4740_emc_s
*) qemu_mallocz(sizeof(*s
));
946 s
->base
= JZ4740_PHYS_BASE(JZ4740_EMC_BASE
);
953 cpu_register_io_memory(0, jz4740_emc_readfn
, jz4740_emc_writefn
, s
);
954 cpu_register_physical_memory(s
->base
, 0x00010000, iomemtype
);
960 static void jz4740_cpu_reset(void *opaque
)
962 fprintf(stderr
, "%s: UNIMPLEMENTED!", __FUNCTION__
);
965 struct jz_state_s
*jz4740_init(unsigned long sdram_size
,
966 uint32_t osc_extal_freq
)
968 struct jz_state_s
*s
= (struct jz_state_s
*)
969 qemu_mallocz(sizeof(struct jz_state_s
));
970 ram_addr_t sram_base
, sdram_base
;
973 s
->mpu_model
= jz4740
;
974 s
->env
= cpu_init("jz4740");
978 fprintf(stderr
, "Unable to find CPU definition\n");
983 qemu_register_reset(jz4740_cpu_reset
, s
->env
);
985 s
->sdram_size
= sdram_size
;
986 s
->sram_size
= JZ4740_SRAM_SIZE
;
989 jz_clk_init(s
, osc_extal_freq
);
991 /*map sram to 0x80000000 and sdram to 0x80004000 */
992 sram_base
= qemu_ram_alloc(s
->sram_size
);
993 cpu_register_physical_memory(JZ4740_SRAM_BASE
, s
->sram_size
,
994 (sram_base
| IO_MEM_RAM
));
995 sdram_base
= qemu_ram_alloc(s
->sdram_size
);
996 cpu_register_physical_memory(JZ4740_SDRAM_BASE
, s
->sdram_size
,
997 (sdram_base
| IO_MEM_RAM
));
999 /* Init internal devices */
1000 cpu_mips_irq_init_cpu(s
->env
);
1001 cpu_mips_clock_init(s
->env
);
1005 jz_clk_init(s
, osc_extal_freq
);
1007 intc
= jz4740_intc_init(s
, s
->env
->irq
[2]);
1008 s
->cpm
= jz4740_cpm_init(s
);
1009 s
->emc
= jz4740_emc_init(s
,intc
[2]);