Exemplo n.º 1
0
static void
ps3pic_eoi(device_t dev, u_int irq)
{
	uint64_t ppe;
	int thread;

	lv1_get_logical_ppe_id(&ppe);
	thread = 32 - fls(mfctrl());

	lv1_end_of_interrupt_ext(ppe, thread, irq);
}
Exemplo n.º 2
0
static int
ps3pic_attach(device_t dev)
{
	struct ps3pic_softc *sc;
	uint64_t ppe;
	int thread;

	sc = device_get_softc(dev);

	sc->bitmap_thread0 = contigmalloc(128 /* 512 bits * 2 */, M_PS3PIC,
	    M_NOWAIT | M_ZERO, 0, BUS_SPACE_MAXADDR, 64 /* alignment */,
	    PAGE_SIZE /* boundary */);
	sc->mask_thread0 = sc->bitmap_thread0 + 4;
	sc->bitmap_thread1 = sc->bitmap_thread0 + 8;
	sc->mask_thread1 = sc->bitmap_thread0 + 12;

	lv1_get_logical_ppe_id(&ppe);
	thread = 32 - fls(mfctrl());
	lv1_configure_irq_state_bitmap(ppe, thread,
	    vtophys(sc->bitmap_thread0));
#ifdef SMP
	lv1_configure_irq_state_bitmap(ppe, !thread,
	    vtophys(sc->bitmap_thread1));

	/* Map both IPIs to the same VIRQ to avoid changes in intr_machdep */
	lv1_construct_event_receive_port(&sc->sc_ipi_outlet[0]);
	lv1_connect_irq_plug_ext(ppe, thread, sc->sc_ipi_outlet[0],
	    sc->sc_ipi_outlet[0], 0);
	lv1_construct_event_receive_port(&sc->sc_ipi_outlet[1]);
	lv1_connect_irq_plug_ext(ppe, !thread, sc->sc_ipi_outlet[0],
	    sc->sc_ipi_outlet[1], 0);
#endif

	powerpc_register_pic(dev, 0, sc->sc_ipi_outlet[0], 1, FALSE);
	return (0);
}
Exemplo n.º 3
0
static void
ps3bus_resources_init_by_type(struct rman *rm, int bus_index, int dev_index,
    uint64_t irq_type, uint64_t reg_type, struct ps3bus_devinfo *dinfo)
{
	uint64_t _irq_type, irq, outlet;
	uint64_t _reg_type, paddr, len;
	uint64_t ppe, junk;
	int i, result;
	int thread;

	resource_list_init(&dinfo->resources);

	lv1_get_logical_ppe_id(&ppe);
	thread = 32 - fls(mfctrl());

	/* Scan for interrupts */
	for (i = 0; i < 10; i++) {
		result = lv1_get_repository_node_value(PS3_LPAR_ID_PME,
		    (lv1_repository_string("bus") >> 32) | bus_index,
		    lv1_repository_string("dev") | dev_index,
		    lv1_repository_string("intr") | i, 0, &_irq_type, &irq);

		if (result != 0)
			break;

		if (_irq_type != irq_type)
			continue;

		lv1_construct_io_irq_outlet(irq, &outlet);
		lv1_connect_irq_plug_ext(ppe, thread, outlet, outlet,
		    0);
		resource_list_add(&dinfo->resources, SYS_RES_IRQ, i,
		    outlet, outlet, 1);
	}

	/* Scan for registers */
	for (i = 0; i < 10; i++) {
		result = lv1_get_repository_node_value(PS3_LPAR_ID_PME,
		    (lv1_repository_string("bus") >> 32) | bus_index,
		    lv1_repository_string("dev") | dev_index,
		    lv1_repository_string("reg") | i, 
		    lv1_repository_string("type"), &_reg_type, &junk);

		if (result != 0)
			break;

		if (_reg_type != reg_type)
			continue;

		result = lv1_get_repository_node_value(PS3_LPAR_ID_PME,
		    (lv1_repository_string("bus") >> 32) | bus_index,
		    lv1_repository_string("dev") | dev_index,
		    lv1_repository_string("reg") | i, 
		    lv1_repository_string("data"), &paddr, &len);

		result = lv1_map_device_mmio_region(dinfo->bus, dinfo->dev,
		    paddr, len, 12 /* log_2(4 KB) */, &paddr);

		if (result != 0) {
			printf("Mapping registers failed for device "
			    "%d.%d (%ld.%ld): %d\n", dinfo->bus, dinfo->dev,
			    dinfo->bustype, dinfo->devtype, result);
			break;
		}

		rman_manage_region(rm, paddr, paddr + len - 1);
		resource_list_add(&dinfo->resources, SYS_RES_MEMORY, i,
		    paddr, paddr + len, len);
	}
}