void starfire_pc_ittrans_init(int upaid) { paddr_t pa; pa = STARFIRE_UPAID2UPS(upaid) | STARFIRE_PSI_BASE; pa |= (STARFIRE_PSI_PCREG_OFF | STARFIRE_PC_INT_MAP); /* * Since we direct all interrupts to the boot processor, we * simply program the port controller ITTR hardware with a * single mapping. */ pa += CPU_UPAID * 0x10; stwa(pa, ASI_PHYS_NON_CACHED, STARFIRE_UPAID2HWMID(cpu_myid())); }
/* * This routine searches for a slot in the soft ITTR table * that was reserved earlier by matching the mondovec * mapping regaddr argument with the corresponding field in * the table. Note that the soft ITTR table mirrors the * corresponding hw table in the starfire port controller(PC) * asics. A new slot will be obtained if the slot cannot * be found. (not reserved previously). The routine then programs * in the target cpu id into the PC ITTR hardware, updates the * soft table and return the index to this slot as the target * id cookie. */ int pc_translate_tgtid(caddr_t ittr_cookie, int cpu_id, volatile uint64_t *mondovec_addr) { struct pc_ittrans_data *ittptr; int i; int foundslot = -1; ASSERT(ittr_cookie != NULL); ittptr = (struct pc_ittrans_data *)ittr_cookie; mutex_enter(&ittptr->ittrans_lock); /* * Search the mondovec addrlist to see if we * already reserved/used a slot for this particular * mondovec mapping regaddr. */ for (i = 0; i < 32; i++) { if (mondovec_addr == ittptr->ittrans_mondovec[i]) { /* * found the slot that matches the * mondo vec in question */ foundslot = i; break; } if (foundslot == -1 && ittptr->ittrans_mondovec[i] == NULL) /* keep track of a empty slot */ foundslot = i; } if (foundslot != -1) { /* We found a slot for this mondo vec, let's use it */ stphysio(ittptr->ittransreg_physaddr[foundslot], STARFIRE_UPAID2HWMID(cpu_id)); ittptr->ittrans_mondovec[foundslot] = mondovec_addr; } else { cmn_err(CE_PANIC, "No more ITTR slots!!"); } mutex_exit(&ittptr->ittrans_lock); return (foundslot); }