File indexing completed on 2025-05-11 08:24:08
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 #include <stdio.h>
0039 #include <stdlib.h>
0040 #include <string.h>
0041
0042 #include <drvmgr/drvmgr.h>
0043 #include <drvmgr/leon2_amba_bus.h>
0044
0045 #include <bsp.h>
0046 #include <rtems/bspIo.h>
0047
0048 #define DBG(args...)
0049
0050
0051 struct drvmgr_drv leon2_bus_drv;
0052
0053 int leon2_amba_bus_init1(struct drvmgr_bus *bus);
0054 int leon2_amba_unite(struct drvmgr_drv *drv, struct drvmgr_dev *dev);
0055 int leon2_amba_int_register(
0056 struct drvmgr_dev *dev,
0057 int index,
0058 const char *info,
0059 drvmgr_isr isr,
0060 void *arg);
0061 int leon2_amba_int_unregister(
0062 struct drvmgr_dev *dev,
0063 int index,
0064 drvmgr_isr isr,
0065 void *arg);
0066 int leon2_amba_int_clear(
0067 struct drvmgr_dev *dev,
0068 int index);
0069 int leon2_amba_int_mask(
0070 struct drvmgr_dev *dev,
0071 int index);
0072 int leon2_amba_int_unmask(
0073 struct drvmgr_dev *dev,
0074 int index);
0075
0076
0077 struct drvmgr_bus_ops leon2_amba_bus_ops =
0078 {
0079 .init = {
0080 leon2_amba_bus_init1,
0081 NULL,
0082 NULL,
0083 NULL
0084 },
0085 .remove = NULL,
0086 .unite = leon2_amba_unite,
0087 .int_register = leon2_amba_int_register,
0088 .int_unregister = leon2_amba_int_unregister,
0089 .int_clear = leon2_amba_int_clear,
0090 .int_mask = leon2_amba_int_mask,
0091 .int_unmask = leon2_amba_int_unmask,
0092 .get_params = NULL,
0093 };
0094
0095 struct leon2_isr_handler {
0096 void (*handler)(int irq, void *arg);
0097 void *arg;
0098 };
0099
0100
0101
0102 struct drvmgr_key leon2_timers[] =
0103 {
0104 {"REG0", DRVMGR_KT_INT, {0x80000040}},
0105 {"IRQ0", DRVMGR_KT_INT, {8}},
0106 {"IRQ1", DRVMGR_KT_INT, {9}},
0107 DRVMGR_KEY_EMPTY
0108 };
0109
0110 struct drvmgr_key leon2_uart1[] =
0111 {
0112 {"REG0", DRVMGR_KT_INT, {0x80000070}},
0113 {"IRQ0", DRVMGR_KT_INT, {3}},
0114 DRVMGR_KEY_EMPTY
0115 };
0116
0117 struct drvmgr_key leon2_uart2[] =
0118 {
0119 {"REG0", DRVMGR_KT_INT, {0x80000080}},
0120 {"IRQ0", DRVMGR_KT_INT, {2}},
0121 DRVMGR_KEY_EMPTY
0122 };
0123
0124 struct drvmgr_key leon2_irqctrl[] =
0125 {
0126 {"REG0", DRVMGR_KT_INT, {0x80000090}},
0127 DRVMGR_KEY_EMPTY
0128 };
0129
0130 struct drvmgr_key leon2_gpio0[] =
0131 {
0132 {"REG0", DRVMGR_KT_INT, {0x800000A0}},
0133 {"IRQ0", DRVMGR_KT_INT, {4}},
0134 {"IRQ1", DRVMGR_KT_INT, {5}},
0135 {"IRQ2", DRVMGR_KT_INT, {6}},
0136 {"IRQ3", DRVMGR_KT_INT, {7}},
0137 DRVMGR_KEY_EMPTY
0138 };
0139
0140 struct leon2_core leon2_std_cores[] =
0141 {
0142 {{LEON2_AMBA_TIMER_ID}, "Timers", &leon2_timers[0]},
0143 {{LEON2_AMBA_UART_ID}, "Uart1", &leon2_uart1[0]},
0144 {{LEON2_AMBA_UART_ID}, "Uart2", &leon2_uart2[0]},
0145 {{LEON2_AMBA_IRQCTRL_ID}, "IRQCtrl", &leon2_irqctrl[0]},
0146 {{LEON2_AMBA_GPIO_ID}, "GPIO", &leon2_gpio0[0]},
0147 EMPTY_LEON2_CORE
0148 };
0149
0150 static struct leon2_bus *leon2_bus_config = NULL;
0151 static struct drvmgr_bus_res *leon2_bus_res = NULL;
0152
0153 int leon2_root_register(
0154 struct leon2_bus *bus_config,
0155 struct drvmgr_bus_res *resources)
0156 {
0157
0158 leon2_bus_config = bus_config;
0159 leon2_bus_res = resources;
0160
0161
0162 drvmgr_root_drv_register(&leon2_bus_drv);
0163
0164 return 0;
0165 }
0166
0167 static int leon2_amba_dev_register(
0168 struct drvmgr_bus *bus,
0169 struct leon2_core *core,
0170 int index)
0171 {
0172 struct drvmgr_dev *newdev;
0173 struct leon2_amba_dev_info *info;
0174 union drvmgr_key_value *value;
0175 char irq_name[8];
0176 int i;
0177
0178
0179 drvmgr_alloc_dev(&newdev, sizeof(struct leon2_amba_dev_info));
0180 info = (struct leon2_amba_dev_info *)(newdev + 1);
0181
0182
0183 info->core_id = core->id.core_id;
0184
0185
0186 value = drvmgr_key_val_get(core->keys, "REG0", DRVMGR_KT_INT);
0187 if ( !value ) {
0188 printk("leon2_amba_dev_register: Failed getting resource REG0\n");
0189 info->reg_base = 0x00000000;
0190 } else {
0191 DBG("leon2_amba_dev_register: REG0: 0x%08x\n", value->i);
0192 info->reg_base = value->i;
0193 }
0194
0195 strcpy(irq_name, "IRQ");
0196 for(i=0; i<16; i++){
0197 if ( i < 10 ){
0198 irq_name[3] = '0' + i;
0199 irq_name[4] = '\0';
0200 } else {
0201 irq_name[3] = '1';
0202 irq_name[4] = '0' + (i-10);
0203 irq_name[5] = '\0';
0204 }
0205
0206 value = drvmgr_key_val_get(core->keys, irq_name, DRVMGR_KT_INT);
0207 if ( !value ) {
0208 DBG("leon2_amba_dev_register: Failed getting resource IRQ%d for REG 0x%x\n", i, info->reg_base);
0209 info->irqs[i] = 0;
0210 } else {
0211 DBG("leon2_amba_dev_register: IRQ%d: %d\n", i, value->i);
0212 info->irqs[i] = value->i;
0213 }
0214 }
0215
0216
0217 newdev->next = NULL;
0218 newdev->parent = bus;
0219 newdev->minor_drv = 0;
0220 newdev->minor_bus = 0;
0221 newdev->businfo = (void *)info;
0222 newdev->priv = NULL;
0223 newdev->drv = NULL;
0224 newdev->name = core->name;
0225 newdev->next_in_drv = NULL;
0226 newdev->bus = NULL;
0227
0228
0229 drvmgr_dev_register(newdev);
0230
0231 return 0;
0232 }
0233
0234 static int leon2_amba_init1(struct drvmgr_dev *dev)
0235 {
0236
0237 dev->priv = NULL;
0238 dev->name = "LEON2 AMBA";
0239
0240
0241 drvmgr_alloc_bus(&dev->bus, 0);
0242 dev->bus->bus_type = DRVMGR_BUS_TYPE_LEON2_AMBA;
0243 dev->bus->next = NULL;
0244 dev->bus->dev = dev;
0245 dev->bus->priv = NULL;
0246 dev->bus->children = NULL;
0247 dev->bus->ops = &leon2_amba_bus_ops;
0248 dev->bus->dev_cnt = 0;
0249 dev->bus->reslist = NULL;
0250 dev->bus->maps_up = leon2_bus_config->maps_up;
0251 dev->bus->maps_down = leon2_bus_config->maps_down;
0252 drvmgr_bus_register(dev->bus);
0253
0254 return DRVMGR_OK;
0255 }
0256
0257 static int leon2_amba_init2(struct drvmgr_dev *dev)
0258 {
0259 return DRVMGR_OK;
0260 }
0261
0262 static int leon2_amba_remove(struct drvmgr_dev *dev)
0263 {
0264 return DRVMGR_OK;
0265 }
0266
0267 int leon2_amba_bus_init1(struct drvmgr_bus *bus)
0268 {
0269 struct leon2_core *core;
0270 int i;
0271
0272 if ( leon2_bus_res )
0273 drvmgr_bus_res_add(bus, leon2_bus_res);
0274
0275
0276 i=0;
0277 core = leon2_bus_config->std_cores;
0278 if ( core ) {
0279 while ( core->id.core_id ) {
0280 if ( leon2_amba_dev_register(bus, core, i) ) {
0281 return RTEMS_UNSATISFIED;
0282 }
0283 i++;
0284 core++;
0285 }
0286 }
0287 core = leon2_bus_config->custom_cores;
0288 if ( core ) {
0289 while ( core->id.core_id ) {
0290 if ( leon2_amba_dev_register(bus, core, i) ) {
0291 return RTEMS_UNSATISFIED;
0292 }
0293 i++;
0294 core++;
0295 }
0296 }
0297
0298 return 0;
0299 }
0300
0301 int leon2_amba_unite(struct drvmgr_drv *drv, struct drvmgr_dev *dev)
0302 {
0303 struct leon2_amba_dev_info *info;
0304 struct leon2_amba_drv_info *adrv;
0305 struct leon2_amba_dev_id *id;
0306
0307 if ( !drv || !dev || !dev->parent )
0308 return 0;
0309
0310 if ( (drv->bus_type!=DRVMGR_BUS_TYPE_LEON2_AMBA) || (dev->parent->bus_type != DRVMGR_BUS_TYPE_LEON2_AMBA) ) {
0311 return 0;
0312 }
0313
0314 info = (struct leon2_amba_dev_info *)dev->businfo;
0315 if ( !info )
0316 return 0;
0317
0318
0319 adrv = (struct leon2_amba_drv_info *)drv;
0320 id = adrv->ids;
0321 if ( !id )
0322 return 0;
0323
0324 while ( id->core_id ) {
0325 if ( id->core_id == info->core_id ) {
0326
0327 return 1;
0328 }
0329 id++;
0330 }
0331
0332 return 0;
0333 }
0334
0335 static int leon2_amba_get_irq(struct drvmgr_dev *dev, int index)
0336 {
0337 int irq;
0338 struct leon2_amba_dev_info *info;
0339
0340 if ( !dev || (index > 15) )
0341 return -1;
0342
0343
0344 if ( index >= 0 ) {
0345
0346
0347
0348 info = (struct leon2_amba_dev_info *)dev->businfo;
0349 irq = info->irqs[index];
0350 if ( irq == 0 )
0351 return -1;
0352 } else {
0353
0354 irq = -index;
0355 }
0356 return irq;
0357 }
0358
0359 int leon2_amba_int_register
0360 (
0361 struct drvmgr_dev *dev,
0362 int index,
0363 const char *info,
0364 drvmgr_isr isr,
0365 void *arg
0366 )
0367 {
0368 int irq;
0369
0370 irq = leon2_amba_get_irq(dev, index);
0371 if ( irq < 0 )
0372 return -1;
0373
0374 DBG("Registering IRQ %d to func 0x%x arg 0x%x\n", irq, (unsigned int)isr, (unsigned int)arg);
0375
0376 return rtems_interrupt_handler_install(irq, info, RTEMS_INTERRUPT_SHARED, isr, arg);
0377 }
0378
0379 int leon2_amba_int_unregister
0380 (
0381 struct drvmgr_dev *dev,
0382 int index,
0383 drvmgr_isr isr,
0384 void *arg
0385 )
0386 {
0387 int irq;
0388
0389 irq = leon2_amba_get_irq(dev, index);
0390 if ( irq < 0 )
0391 return -1;
0392
0393 DBG("Unregistering IRQ %d to func 0x%x arg 0x%x\n", irq, (unsigned int)handler, (unsigned int)arg);
0394
0395 return rtems_interrupt_handler_remove(irq, isr, arg);
0396 }
0397
0398 int leon2_amba_int_clear
0399 (
0400 struct drvmgr_dev *dev,
0401 int index
0402 )
0403 {
0404 int irq;
0405
0406 irq = leon2_amba_get_irq(dev, index);
0407 if ( irq < 0 )
0408 return -1;
0409
0410 if (rtems_interrupt_clear(irq) != RTEMS_SUCCESSFUL) {
0411 return DRVMGR_FAIL;
0412 }
0413
0414 return DRVMGR_OK;
0415 }
0416
0417 int leon2_amba_int_mask
0418 (
0419 struct drvmgr_dev *dev,
0420 int index
0421 )
0422 {
0423 int irq;
0424
0425 irq = leon2_amba_get_irq(dev, index);
0426 if ( irq < 0 )
0427 return -1;
0428
0429 if (rtems_interrupt_vector_disable(irq) != RTEMS_SUCCESSFUL) {
0430 return DRVMGR_FAIL;
0431 }
0432
0433 return DRVMGR_OK;
0434 }
0435
0436 int leon2_amba_int_unmask
0437 (
0438 struct drvmgr_dev *dev,
0439 int index
0440 )
0441 {
0442 int irq;
0443
0444 irq = leon2_amba_get_irq(dev, index);
0445 if ( irq < 0 )
0446 return -1;
0447
0448 if (rtems_interrupt_vector_enable(irq) != RTEMS_SUCCESSFUL) {
0449 return DRVMGR_FAIL;
0450 }
0451
0452 return DRVMGR_OK;
0453 }
0454
0455 struct drvmgr_drv_ops leon2_amba_ops =
0456 {
0457 .init = {leon2_amba_init1, leon2_amba_init2, NULL, NULL},
0458 .remove = leon2_amba_remove,
0459 .info = NULL
0460 };
0461
0462 struct drvmgr_drv leon2_bus_drv =
0463 {
0464 DRVMGR_OBJ_DRV,
0465 NULL,
0466 NULL,
0467 DRIVER_LEON2_AMBA_ID,
0468 "LEON2_AMBA_DRV",
0469 DRVMGR_BUS_TYPE_ROOT,
0470 &leon2_amba_ops,
0471 NULL,
0472 0,
0473 0,
0474 };