fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
at master 431 lines 9.6 kB view raw
1/***************************************************************************** 2 * pce * 3 *****************************************************************************/ 4 5/***************************************************************************** 6 * File name: src/arch/simarm/intc.c * 7 * Created: 2004-11-13 by Hampa Hug <hampa@hampa.ch> * 8 * Copyright: (C) 2004-2013 Hampa Hug <hampa@hampa.ch> * 9 * Copyright: (C) 2004-2006 Lukas Ruf <ruf@lpr.ch> * 10 *****************************************************************************/ 11 12/***************************************************************************** 13 * This program is free software. You can redistribute it and / or modify it * 14 * under the terms of the GNU General Public License version 2 as published * 15 * by the Free Software Foundation. * 16 * * 17 * This program is distributed in the hope that it will be useful, but * 18 * WITHOUT ANY WARRANTY, without even the implied warranty of * 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * 20 * Public License for more details. * 21 *****************************************************************************/ 22 23/***************************************************************************** 24 * This software was developed at the Computer Engineering and Networks * 25 * Laboratory (TIK), Swiss Federal Institute of Technology (ETH) Zurich. * 26 *****************************************************************************/ 27 28 29#include "main.h" 30#include "intc.h" 31 32#include <stdlib.h> 33 34#include <lib/log.h> 35 36 37static unsigned char ict_get_uint8 (ixp_intc_t *ic, unsigned long addr); 38static unsigned short ict_get_uint16 (ixp_intc_t *ic, unsigned long addr); 39static unsigned long ict_get_uint32 (ixp_intc_t *ic, unsigned long addr); 40static void ict_set_uint8 (ixp_intc_t *ic, unsigned long addr, unsigned char val); 41static void ict_set_uint16 (ixp_intc_t *ic, unsigned long addr, unsigned short val); 42static void ict_set_uint32 (ixp_intc_t *ic, unsigned long addr, unsigned long val); 43 44 45static 46void *ict_irqf[32] = { 47 ict_set_irq0, ict_set_irq1, ict_set_irq2, ict_set_irq3, 48 ict_set_irq4, ict_set_irq5, ict_set_irq6, ict_set_irq7, 49 ict_set_irq8, ict_set_irq9, ict_set_irq10, ict_set_irq11, 50 ict_set_irq12, ict_set_irq13, ict_set_irq14, ict_set_irq15, 51 ict_set_irq16, ict_set_irq17, ict_set_irq18, ict_set_irq19, 52 ict_set_irq20, ict_set_irq21, ict_set_irq22, ict_set_irq23, 53 ict_set_irq24, ict_set_irq25, ict_set_irq26, ict_set_irq27, 54 ict_set_irq28, ict_set_irq29, ict_set_irq30, ict_set_irq31 55}; 56 57 58void ict_init (ixp_intc_t *ict, unsigned long base) 59{ 60 ict->base = base; 61 62 mem_blk_init (&ict->io, base, 0x01000000UL, 0); 63 ict->io.ext = ict; 64 ict->io.get_uint8 = (mem_get_uint8_f) ict_get_uint8; 65 ict->io.set_uint8 = (mem_set_uint8_f) ict_set_uint8; 66 ict->io.get_uint16 = (mem_get_uint16_f) ict_get_uint16; 67 ict->io.set_uint16 = (mem_set_uint16_f) ict_set_uint16; 68 ict->io.get_uint32 = (mem_get_uint32_f) ict_get_uint32; 69 ict->io.set_uint32 = (mem_set_uint32_f) ict_set_uint32; 70 71 ict->fiq = NULL; 72 ict->fiq_ext = NULL; 73 ict->fiq_val = 0; 74 75 ict->irq = NULL; 76 ict->irq_ext = NULL; 77 ict->irq_val = 0; 78 79 ict->status_raw = 0; 80 ict->status_fiq = 0; 81 ict->status_irq = 0; 82 ict->enable_fiq = 0; 83 ict->enable_irq = 0; 84} 85 86ixp_intc_t *ict_new (unsigned long base) 87{ 88 ixp_intc_t *ict; 89 90 ict = malloc (sizeof (ixp_intc_t)); 91 if (ict == NULL) { 92 return (NULL); 93 } 94 95 ict_init (ict, base); 96 97 return (ict); 98} 99 100void ict_free (ixp_intc_t *ict) 101{ 102 mem_blk_free (&ict->io); 103} 104 105void ict_del (ixp_intc_t *ict) 106{ 107 if (ict != NULL) { 108 ict_free (ict); 109 free (ict); 110 } 111} 112 113mem_blk_t *ict_get_io (ixp_intc_t *ict, unsigned i) 114{ 115 if (i == 0) { 116 return (&ict->io); 117 } 118 119 return (NULL); 120} 121 122void ict_set_fiq_f (ixp_intc_t *ict, void *f, void *ext) 123{ 124 ict->fiq = f; 125 ict->fiq_ext = ext; 126} 127 128void ict_set_irq_f (ixp_intc_t *ict, void *f, void *ext) 129{ 130 ict->irq = f; 131 ict->irq_ext = ext; 132} 133 134void *ict_get_irq_f (ixp_intc_t *ict, unsigned irq) 135{ 136 return (ict_irqf[irq & 0x1f]); 137} 138 139static 140void ict_check_fiq (ixp_intc_t *ict) 141{ 142 ict->status_fiq = ict->status_raw & ict->enable_fiq; 143 144 if (ict->status_fiq) { 145 if ((ict->fiq != NULL) && (ict->fiq_val == 0)) { 146 ict->fiq (ict->fiq_ext, 1); 147 ict->fiq_val = 1; 148 } 149 } 150 else { 151 if ((ict->fiq != NULL) && (ict->fiq_val != 0)) { 152 ict->fiq (ict->fiq_ext, 0); 153 ict->fiq_val = 0; 154 } 155 } 156} 157 158static 159void ict_check_irq (ixp_intc_t *ict) 160{ 161 ict->status_irq = ict->status_raw & ict->enable_irq; 162 163 if (ict->status_irq) { 164 if ((ict->irq != NULL) && (ict->irq_val == 0)) { 165 ict->irq (ict->irq_ext, 1); 166 ict->irq_val = 1; 167 } 168 } 169 else { 170 if ((ict->irq != NULL) && (ict->irq_val != 0)) { 171 ict->irq (ict->irq_ext, 0); 172 ict->irq_val = 0; 173 } 174 } 175} 176 177void ict_set_irq (ixp_intc_t *ict, unsigned i, unsigned char val) 178{ 179 if (val) { 180 ict->status_raw |= (1UL << i); 181 } 182 else { 183 ict->status_raw &= ~(1UL << i); 184 } 185 186 ict_check_fiq (ict); 187 ict_check_irq (ict); 188} 189 190void ict_set_irq0 (ixp_intc_t *ict, unsigned char val) 191{ 192 ict_set_irq (ict, 0, val); 193} 194 195void ict_set_irq1 (ixp_intc_t *ict, unsigned char val) 196{ 197 ict_set_irq (ict, 1, val); 198} 199 200void ict_set_irq2 (ixp_intc_t *ict, unsigned char val) 201{ 202 ict_set_irq (ict, 2, val); 203} 204 205void ict_set_irq3 (ixp_intc_t *ict, unsigned char val) 206{ 207 ict_set_irq (ict, 3, val); 208} 209 210void ict_set_irq4 (ixp_intc_t *ict, unsigned char val) 211{ 212 ict_set_irq (ict, 4, val); 213} 214 215void ict_set_irq5 (ixp_intc_t *ict, unsigned char val) 216{ 217 ict_set_irq (ict, 5, val); 218} 219 220void ict_set_irq6 (ixp_intc_t *ict, unsigned char val) 221{ 222 ict_set_irq (ict, 6, val); 223} 224 225void ict_set_irq7 (ixp_intc_t *ict, unsigned char val) 226{ 227 ict_set_irq (ict, 7, val); 228} 229 230void ict_set_irq8 (ixp_intc_t *ict, unsigned char val) 231{ 232 ict_set_irq (ict, 8, val); 233} 234 235void ict_set_irq9 (ixp_intc_t *ict, unsigned char val) 236{ 237 ict_set_irq (ict, 9, val); 238} 239 240void ict_set_irq10 (ixp_intc_t *ict, unsigned char val) 241{ 242 ict_set_irq (ict, 10, val); 243} 244 245void ict_set_irq11 (ixp_intc_t *ict, unsigned char val) 246{ 247 ict_set_irq (ict, 11, val); 248} 249 250void ict_set_irq12 (ixp_intc_t *ict, unsigned char val) 251{ 252 ict_set_irq (ict, 12, val); 253} 254 255void ict_set_irq13 (ixp_intc_t *ict, unsigned char val) 256{ 257 ict_set_irq (ict, 13, val); 258} 259 260void ict_set_irq14 (ixp_intc_t *ict, unsigned char val) 261{ 262 ict_set_irq (ict, 14, val); 263} 264 265void ict_set_irq15 (ixp_intc_t *ict, unsigned char val) 266{ 267 ict_set_irq (ict, 15, val); 268} 269 270void ict_set_irq16 (ixp_intc_t *ict, unsigned char val) 271{ 272 ict_set_irq (ict, 16, val); 273} 274 275void ict_set_irq17 (ixp_intc_t *ict, unsigned char val) 276{ 277 ict_set_irq (ict, 17, val); 278} 279 280void ict_set_irq18 (ixp_intc_t *ict, unsigned char val) 281{ 282 ict_set_irq (ict, 18, val); 283} 284 285void ict_set_irq19 (ixp_intc_t *ict, unsigned char val) 286{ 287 ict_set_irq (ict, 19, val); 288} 289 290void ict_set_irq20 (ixp_intc_t *ict, unsigned char val) 291{ 292 ict_set_irq (ict, 20, val); 293} 294 295void ict_set_irq21 (ixp_intc_t *ict, unsigned char val) 296{ 297 ict_set_irq (ict, 21, val); 298} 299 300void ict_set_irq22 (ixp_intc_t *ict, unsigned char val) 301{ 302 ict_set_irq (ict, 22, val); 303} 304 305void ict_set_irq23 (ixp_intc_t *ict, unsigned char val) 306{ 307 ict_set_irq (ict, 23, val); 308} 309 310void ict_set_irq24 (ixp_intc_t *ict, unsigned char val) 311{ 312 ict_set_irq (ict, 24, val); 313} 314 315void ict_set_irq25 (ixp_intc_t *ict, unsigned char val) 316{ 317 ict_set_irq (ict, 25, val); 318} 319 320void ict_set_irq26 (ixp_intc_t *ict, unsigned char val) 321{ 322 ict_set_irq (ict, 26, val); 323} 324 325void ict_set_irq27 (ixp_intc_t *ict, unsigned char val) 326{ 327 ict_set_irq (ict, 27, val); 328} 329 330void ict_set_irq28 (ixp_intc_t *ict, unsigned char val) 331{ 332 ict_set_irq (ict, 28, val); 333} 334 335void ict_set_irq29 (ixp_intc_t *ict, unsigned char val) 336{ 337 ict_set_irq (ict, 29, val); 338} 339 340void ict_set_irq30 (ixp_intc_t *ict, unsigned char val) 341{ 342 ict_set_irq (ict, 30, val); 343} 344 345void ict_set_irq31 (ixp_intc_t *ict, unsigned char val) 346{ 347 ict_set_irq (ict, 31, val); 348} 349 350static 351unsigned char ict_get_uint8 (ixp_intc_t *ict, unsigned long addr) 352{ 353 pce_log (MSG_DEB, "ICT: get_uint8 (%08lX)\n", addr); 354 355 return (0); 356} 357 358static 359unsigned short ict_get_uint16 (ixp_intc_t *ict, unsigned long addr) 360{ 361 pce_log (MSG_DEB, "ICT: get_uint16 (%08lX)\n", addr); 362 363 return (0); 364} 365 366static 367unsigned long ict_get_uint32 (ixp_intc_t *ict, unsigned long addr) 368{ 369 switch (addr) { 370 case 0x00: 371 return (ict->status_raw); 372 373 case 0x04: 374 return (ict->status_fiq); 375 376 case 0x08: 377 return (ict->status_irq); 378 379 case 0x0c: 380 return (ict->enable_fiq); 381 382 case 0x10: 383 return (ict->enable_irq); 384 385 case 0x14: /* fiq enable clr */ 386 return (0); 387 388 case 0x18: /* irq enable clr */ 389 return (0); 390 } 391 392 return (0); 393} 394 395static 396void ict_set_uint8 (ixp_intc_t *ict, unsigned long addr, unsigned char val) 397{ 398 pce_log (MSG_DEB, "ICT: set_uint8 (%08lX, %02X)\n", addr, (unsigned) val); 399} 400 401static 402void ict_set_uint16 (ixp_intc_t *ict, unsigned long addr, unsigned short val) 403{ 404 pce_log (MSG_DEB, "ICT: set_uint16 (%08lX, %04X)\n", addr, (unsigned) val); 405} 406 407static 408void ict_set_uint32 (ixp_intc_t *ict, unsigned long addr, unsigned long val) 409{ 410 switch (addr) { 411 case 0x0c: /* fiq enable set */ 412 ict->enable_fiq |= val; 413 ict_check_fiq (ict); 414 break; 415 416 case 0x10: /* irq enable set */ 417 ict->enable_irq |= val; 418 ict_check_irq (ict); 419 break; 420 421 case 0x14: /* fiq enable clr */ 422 ict->enable_fiq &= ~val; 423 ict_check_fiq (ict); 424 break; 425 426 case 0x18: /* irq enable clr */ 427 ict->enable_irq &= ~val; 428 ict_check_irq (ict); 429 break; 430 } 431}