Lines Matching defs:its
60 * ITS translation table sizes
99 gits_read_4(struct gicv3_its *its, bus_size_t reg)
101 return bus_space_read_4(its->its_bst, its->its_bsh, reg);
105 gits_write_4(struct gicv3_its *its, bus_size_t reg, uint32_t val)
107 bus_space_write_4(its->its_bst, its->its_bsh, reg, val);
111 gits_read_8(struct gicv3_its *its, bus_size_t reg)
113 return bus_space_read_8(its->its_bst, its->its_bsh, reg);
117 gits_write_8(struct gicv3_its *its, bus_size_t reg, uint64_t val)
119 bus_space_write_8(its->its_bst, its->its_bsh, reg, val);
123 gits_command(struct gicv3_its *its, const struct gicv3_its_command *cmd)
128 creadr = gits_read_8(its, GITS_CREADR);
130 DPRINTF(("ITS: stalled! GITS_CREADR = 0x%lx\n", creadr));
134 cwriter = gits_read_8(its, GITS_CWRITER);
137 uint64_t *dw = (uint64_t *)(its->its_cmd.base + woff);
140 DPRINTF(("ITS: dw[%u] = 0x%016lx\n", i, cmd->dw[i]));
143 if (its->its_cmd_flush) {
149 if (woff == its->its_cmd.len)
152 gits_write_8(its, GITS_CWRITER, woff);
158 gits_command_mapc(struct gicv3_its *its, uint16_t icid, uint64_t rdbase, bool v)
175 DPRINTF(("ITS #%u: MAPC icid 0x%x rdbase 0x%lx valid %u\n",
176 its->its_id, icid, rdbase, v));
178 return gits_command(its, &cmd);
182 gits_command_mapd(struct gicv3_its *its, uint32_t deviceid, uint64_t itt_addr, u_int size, bool v)
189 * Map a device table entry (DeviceID) to its associated ITT (ITT_addr).
198 DPRINTF(("ITS #%u: MAPD deviceid 0x%x itt_addr 0x%lx size %u valid %u\n",
199 its->its_id, deviceid, itt_addr, size, v));
201 return gits_command(its, &cmd);
205 gits_command_mapti(struct gicv3_its *its, uint32_t deviceid, uint32_t eventid, uint32_t pintid, uint16_t icid)
210 * Map the event defined by EventID and DeviceID to its associated ITE, defined by ICID and pINTID
218 DPRINTF(("ITS #%u: MAPTI deviceid 0x%x eventid 0x%x pintid 0x%x icid 0x%x\n",
219 its->its_id, deviceid, eventid, pintid, icid));
221 return gits_command(its, &cmd);
225 gits_command_movi(struct gicv3_its *its, uint32_t deviceid, uint32_t eventid, uint16_t icid)
238 DPRINTF(("ITS #%u: MOVI deviceid 0x%x eventid 0x%x icid 0x%x\n",
239 its->its_id, deviceid, eventid, icid));
241 return gits_command(its, &cmd);
245 gits_command_inv(struct gicv3_its *its, uint32_t deviceid, uint32_t eventid)
257 DPRINTF(("ITS #%u: INV deviceid 0x%x eventid 0x%x\n",
258 its->its_id, deviceid, eventid));
260 return gits_command(its, &cmd);
264 gits_command_invall(struct gicv3_its *its, uint16_t icid)
276 DPRINTF(("ITS #%u: INVALL icid 0x%x\n", its->its_id, icid));
278 return gits_command(its, &cmd);
282 gits_command_sync(struct gicv3_its *its, uint64_t rdbase)
289 * Ensure all outstanding ITS operations associated with physical interrupts
291 * further ITS commands are executed.
297 DPRINTF(("ITS #%u: SYNC rdbase 0x%lx\n", its->its_id, rdbase));
299 return gits_command(its, &cmd);
304 gits_command_int(struct gicv3_its *its, uint32_t deviceid, uint32_t eventid)
318 DPRINTF(("ITS #%u: INT deviceid 0x%x eventid 0x%x\n",
319 its->its_id, deviceid, eventid));
321 return gits_command(its, &cmd);
326 gits_wait(struct gicv3_its *its)
332 * The ITS command queue is empty when CWRITER and CREADR specify the
336 woff = gits_read_8(its, GITS_CWRITER) & GITS_CWRITER_Offset;
337 roff = gits_read_8(its, GITS_CREADR) & GITS_CREADR_Offset;
343 device_printf(its->its_gic->sc_dev,
344 "ITS command queue timeout! CREADR=0x%lx CWRITER=0x%lx\n",
345 gits_read_8(its, GITS_CREADR), gits_read_8(its, GITS_CWRITER));
353 gicv3_its_msi_alloc_lpi(struct gicv3_its *its,
359 KASSERT(its->its_gic->sc_lpi_pool != NULL);
361 if (vmem_alloc(its->its_gic->sc_lpi_pool, 1, VM_INSTANTFIT|VM_SLEEP, &n) != 0)
364 KASSERT(its->its_pa[n] == NULL);
368 its->its_pa[n] = new_pa;
369 return n + its->its_pic->pic_irqbase;
373 gicv3_its_msi_free_lpi(struct gicv3_its *its, int lpi)
377 KASSERT(its->its_gic->sc_lpi_pool != NULL);
378 KASSERT(lpi >= its->its_pic->pic_irqbase);
380 pa = its->its_pa[lpi - its->its_pic->pic_irqbase];
381 its->its_pa[lpi - its->its_pic->pic_irqbase] = NULL;
384 vmem_free(its->its_gic->sc_lpi_pool, lpi - its->its_pic->pic_irqbase, 1);
401 gicv3_its_device_map(struct gicv3_its *its, uint32_t devid, u_int count)
404 struct gicv3_its_table *itstab = &its->its_tab_device;
412 const uint64_t typer = gits_read_8(its, GITS_TYPER);
416 LIST_FOREACH(dev, &its->its_devices, dev_list)
431 gicv3_dma_alloc(its->its_gic, &pt->pt_dma, itstab->tab_l2_entry_size,
446 DPRINTF(("ITS: Allocated L2 entry at index %u\n", index));
453 gicv3_dma_alloc(its->its_gic, &dev->dev_itt, itt_size, GITS_ITT_ALIGN);
454 LIST_INSERT_HEAD(&its->its_devices, dev, dev_list);
456 if (its->its_cmd_flush) {
465 mutex_enter(its->its_lock);
466 error = gits_command_mapd(its, devid, dev->dev_itt.segs[0].ds_addr, size, true);
468 error = gits_wait(its);
470 mutex_exit(its->its_lock);
476 gicv3_its_msi_enable(struct gicv3_its *its, int lpi, int count)
478 const struct pci_attach_args *pa = its->its_pa[lpi - its->its_pic->pic_irqbase];
492 const uint64_t addr = its->its_base + GITS_TRANSLATER;
500 lpi - its->its_pic->pic_irqbase);
506 lpi - its->its_pic->pic_irqbase);
513 gicv3_its_msi_disable(struct gicv3_its *its, int lpi)
515 const struct pci_attach_args *pa = its->its_pa[lpi - its->its_pic->pic_irqbase];
530 gicv3_its_msix_enable(struct gicv3_its *its, int lpi, int msix_vec,
533 const struct pci_attach_args *pa = its->its_pa[lpi - its->its_pic->pic_irqbase];
543 const uint64_t addr = its->its_base + GITS_TRANSLATER;
547 bus_space_write_4(bst, bsh, entry_base + PCI_MSIX_TABLE_ENTRY_DATA, lpi - its->its_pic->pic_irqbase);
558 gicv3_its_msix_disable(struct gicv3_its *its, int lpi)
560 const struct pci_attach_args *pa = its->its_pa[lpi - its->its_pic->pic_irqbase];
578 struct gicv3_its * const its = msi->msi_priv;
586 const uint64_t typer = gits_read_8(its, GITS_TYPER);
593 if (gicv3_its_device_map(its, devid, *count) != 0)
597 mutex_enter(its->its_lock);
599 const int lpi = gicv3_its_msi_alloc_lpi(its, pa);
607 gicv3_its_msi_enable(its, lpi, *count);
612 its->its_devid[lpi - its->its_pic->pic_irqbase] = devid;
613 its->its_targets[lpi - its->its_pic->pic_irqbase] = ci;
618 gits_command_mapti(its, devid, lpi - its->its_pic->pic_irqbase, lpi, cpu_index(ci));
619 gits_command_sync(its, its->its_rdbase[cpu_index(ci)]);
621 error = gits_wait(its);
622 mutex_exit(its->its_lock);
636 struct gicv3_its * const its = msi->msi_priv;
649 const uint64_t typer = gits_read_8(its, GITS_TYPER);
669 if (gicv3_its_device_map(its, devid, *count) != 0) {
675 mutex_enter(its->its_lock);
677 const int lpi = gicv3_its_msi_alloc_lpi(its, pa);
685 gicv3_its_msix_enable(its, lpi, msix_vec, bst, bsh);
690 its->its_devid[lpi - its->its_pic->pic_irqbase] = devid;
691 its->its_targets[lpi - its->its_pic->pic_irqbase] = ci;
696 gits_command_mapti(its, devid, lpi - its->its_pic->pic_irqbase, lpi, cpu_index(ci));
697 gits_command_sync(its, its->its_rdbase[cpu_index(ci)]);
699 gits_wait(its);
700 mutex_exit(its->its_lock);
711 struct gicv3_its * const its = msi->msi_priv;
717 intrh = pic_establish_intr(its->its_pic, lpi - its->its_pic->pic_irqbase, ipl,
723 KASSERT(its->its_pa[lpi - its->its_pic->pic_irqbase] != NULL);
724 const uint32_t devid = its->its_devid[lpi - its->its_pic->pic_irqbase];
725 gits_command_inv(its, devid, lpi - its->its_pic->pic_irqbase);
734 struct gicv3_its * const its = msi->msi_priv;
739 KASSERT(lpi >= its->its_pic->pic_irqbase);
741 gicv3_its_msix_disable(its, lpi);
743 gicv3_its_msi_disable(its, lpi);
744 gicv3_its_msi_free_lpi(its, lpi);
745 its->its_targets[lpi - its->its_pic->pic_irqbase] = NULL;
746 its->its_devid[lpi - its->its_pic->pic_irqbase] = 0;
748 its->its_pic->pic_sources[lpi - its->its_pic->pic_irqbase];
755 gicv3_its_command_init(struct gicv3_softc *sc, struct gicv3_its *its)
759 gicv3_dma_alloc(sc, &its->its_cmd, GITS_COMMANDS_SIZE, GITS_COMMANDS_ALIGN);
760 if (its->its_cmd_flush) {
761 cpu_dcache_wb_range((vaddr_t)its->its_cmd.base, GITS_COMMANDS_SIZE);
765 KASSERT((gits_read_4(its, GITS_CTLR) & GITS_CTLR_Enabled) == 0);
766 KASSERT((gits_read_4(its, GITS_CTLR) & GITS_CTLR_Quiescent) != 0);
768 cbaser = its->its_cmd.segs[0].ds_addr;
769 cbaser |= __SHIFTIN((its->its_cmd.len / 4096) - 1, GITS_CBASER_Size);
774 gits_write_8(its, GITS_CBASER, cbaser);
776 tmp = gits_read_8(its, GITS_CBASER);
783 gits_write_8(its, GITS_CBASER, cbaser);
786 its->its_cmd_flush = true;
788 aprint_normal_dev(sc->sc_dev, "ITS command table @ %#lx/%#lx, %s, %s\n",
789 its->its_cmd.segs[0].ds_addr, its->its_cmd.len,
793 gits_write_8(its, GITS_CWRITER, 0);
797 gicv3_its_table_params(struct gicv3_softc *sc, struct gicv3_its *its,
801 const uint64_t typer = gits_read_8(its, GITS_TYPER);
802 const uint32_t iidr = gits_read_4(its, GITS_IIDR);
818 gicv3_its_table_probe_indirect(struct gicv3_its *its, int tab)
822 baser = gits_read_8(its, GITS_BASERn(tab));
824 gits_write_8(its, GITS_BASERn(tab), baser);
826 baser = gits_read_8(its, GITS_BASERn(tab));
832 gicv3_its_table_init(struct gicv3_softc *sc, struct gicv3_its *its)
840 gicv3_its_table_params(sc, its, &devbits, &innercache, &share);
842 DPRINTF(("ITS: devbits = %u\n", devbits));
851 baser = gits_read_8(its, GITS_BASERn(tab));
876 DPRINTF(("ITS: l1_num_ids = %lu\n", l1_num_ids));
878 gicv3_its_table_probe_indirect(its, tab);
880 DPRINTF(("ITS: indirect\n"));
888 DPRINTF(("ITS: clamp table size 0x%lx -> ", table_size));
894 DPRINTF(("ITS: table_size is 0x%lx\n", table_size));
896 itstab = &its->its_tab_device;
920 gicv3_dma_alloc(sc, &its->its_tab[tab], table_size, table_align);
921 if (its->its_cmd_flush) {
922 cpu_dcache_wb_range((vaddr_t)its->its_tab[tab].base, table_size);
929 baser |= its->its_tab[tab].segs[0].ds_addr;
941 gits_write_8(its, GITS_BASERn(tab), baser);
943 baser = gits_read_8(its, GITS_BASERn(tab));
948 gits_write_8(its, GITS_BASERn(tab), baser);
951 baser = gits_read_8(its, GITS_BASERn(tab));
952 aprint_normal_dev(sc->sc_dev, "ITS [#%d] %s table @ %#lx/%#lx, %s, %s%s\n",
953 tab, table_type, its->its_tab[tab].segs[0].ds_addr, table_size,
959 its->its_tab_device.tab_l1 = its->its_tab[tab].base;
960 its->its_tab_device.tab_shareable =
968 gicv3_its_enable(struct gicv3_softc *sc, struct gicv3_its *its)
972 ctlr = gits_read_4(its, GITS_CTLR);
974 gits_write_4(its, GITS_CTLR, ctlr);
980 struct gicv3_its * const its = priv;
981 struct gicv3_softc * const sc = its->its_gic;
985 const uint64_t typer = bus_space_read_8(sc->sc_bst, its->its_bsh, GITS_TYPER);
992 its->its_rdbase[cpu_index(ci)] = rdbase;
997 mutex_enter(its->its_lock);
998 gits_command_mapc(its, cpu_index(ci), rdbase, true);
999 gits_command_invall(its, cpu_index(ci));
1000 gits_wait(its);
1005 for (irq = 0; irq < its->its_pic->pic_maxsources; irq++) {
1006 if (its->its_targets[irq] != ci)
1008 KASSERT(its->its_pa[irq] != NULL);
1010 const uint32_t devid = its->its_devid[irq];
1011 gits_command_movi(its, devid, irq, cpu_index(ci));
1012 gits_command_sync(its, its->its_rdbase[cpu_index(ci)]);
1014 gits_wait(its);
1015 mutex_exit(its->its_lock);
1017 its->its_cpuonline[cpu_index(ci)] = true;
1023 struct gicv3_its * const its = priv;
1026 ci = its->its_targets[irq];
1034 struct gicv3_its * const its = priv;
1042 pa = its->its_pa[irq];
1047 its->its_targets[irq] = ci;
1049 if (its->its_cpuonline[cpu_index(ci)] == true) {
1051 mutex_enter(its->its_lock);
1052 gits_command_movi(its, devid, irq, cpu_index(ci));
1053 gits_command_sync(its, its->its_rdbase[cpu_index(ci)]);
1054 mutex_exit(its->its_lock);
1064 struct gicv3_its *its;
1071 its = kmem_zalloc(sizeof(*its), KM_SLEEP);
1072 its->its_id = its_id;
1073 its->its_bst = sc->sc_bst;
1074 its->its_bsh = bsh;
1075 its->its_dmat = sc->sc_dmat;
1076 its->its_base = its_base;
1077 its->its_pic = &sc->sc_lpi;
1078 snprintf(its->its_pic->pic_name, sizeof(its->its_pic->pic_name), "gicv3-its");
1079 KASSERT(its->its_pic->pic_maxsources > 0);
1080 its->its_pa = kmem_zalloc(sizeof(struct pci_attach_args *) * its->its_pic->pic_maxsources, KM_SLEEP);
1081 its->its_targets = kmem_zalloc(sizeof(struct cpu_info *) * its->its_pic->pic_maxsources, KM_SLEEP);
1082 its->its_devid = kmem_zalloc(sizeof(uint32_t) * its->its_pic->pic_maxsources, KM_SLEEP);
1083 its->its_gic = sc;
1084 its->its_rdbase = kmem_zalloc(sizeof(*its->its_rdbase) * ncpu, KM_SLEEP);
1085 its->its_cpuonline = kmem_zalloc(sizeof(*its->its_cpuonline) * ncpu, KM_SLEEP);
1086 its->its_cb.cpu_init = gicv3_its_cpu_init;
1087 its->its_cb.get_affinity = gicv3_its_get_affinity;
1088 its->its_cb.set_affinity = gicv3_its_set_affinity;
1089 its->its_cb.priv = its;
1090 LIST_INIT(&its->its_devices);
1091 LIST_INSERT_HEAD(&sc->sc_lpi_callbacks, &its->its_cb, list);
1092 its->its_lock = mutex_obj_alloc(MUTEX_SPIN, IPL_NONE);
1094 gicv3_its_command_init(sc, its);
1095 gicv3_its_table_init(sc, its);
1097 gicv3_its_enable(sc, its);
1099 gicv3_its_cpu_init(its, curcpu());
1101 msi = &its->its_msi;
1104 msi->msi_priv = its;