Пример #1
0
/* NB this function blocks until the transfer is complete */
static void
smi_dma_read_sgl(struct bcm2835_smi_instance *inst,
	struct scatterlist *sgl, size_t sg_len, size_t n_bytes)
{
	struct dma_async_tx_descriptor *desc;

	/* Disable SMI and set to read before dispatching DMA - if SMI is in
	 * write mode and TX fifo is empty, it will generate a DREQ which may
	 * cause the read DMA to complete before the SMI read command is even
	 * dispatched! We want to dispatch DMA before SMI read so that reading
	 * is gapless, for logic analyser.
	 */

	smi_disable(inst, DMA_DEV_TO_MEM);

	desc = smi_dma_submit_sgl(inst, sgl, sg_len, DMA_DEV_TO_MEM, NULL);
	dma_async_issue_pending(inst->dma_chan);

	if (inst->settings.data_width == SMI_WIDTH_8BIT)
		smi_init_programmed_read(inst, n_bytes);
	else
		smi_init_programmed_read(inst, n_bytes / 2);

	if (dma_wait_for_async_tx(desc) == DMA_ERROR)
		smi_dump_context_labelled(inst, "DMA timeout!");
}
Пример #2
0
ssize_t bcm2835_smi_user_dma(
	struct bcm2835_smi_instance *inst,
	enum dma_transfer_direction dma_dir,
	char __user *user_ptr, size_t count,
	struct bcm2835_smi_bounce_info **bounce)
{
	int chunk_no = 0, chunk_size, count_left = count;
	struct scatterlist *sgl;
	void (*init_trans_func)(struct bcm2835_smi_instance *, int);

	spin_lock(&inst->transaction_lock);

	if (dma_dir == DMA_DEV_TO_MEM)
		init_trans_func = smi_init_programmed_read;
	else
		init_trans_func = smi_init_programmed_write;

	smi_disable(inst, dma_dir);

	sema_init(&inst->bounce.callback_sem, 0);
	if (bounce)
		*bounce = &inst->bounce;
	while (count_left) {
		chunk_size = count_left > DMA_BOUNCE_BUFFER_SIZE ?
			DMA_BOUNCE_BUFFER_SIZE : count_left;
		if (chunk_size == DMA_BOUNCE_BUFFER_SIZE) {
			sgl =
			&inst->bounce.sgl[chunk_no % DMA_BOUNCE_BUFFER_COUNT];
		} else {
			sgl = smi_scatterlist_from_buffer(
				inst,
				inst->bounce.phys[
					chunk_no % DMA_BOUNCE_BUFFER_COUNT],
				chunk_size,
				&inst->buffer_sgl);
		}

		if (!smi_dma_submit_sgl(inst, sgl, 1, dma_dir,
			smi_dma_callback_user_copy
		)) {
			dev_err(inst->dev, "sgl submit failed");
			count = 0;
			goto out;
		}
		count_left -= chunk_size;
		chunk_no++;
	}
	dma_async_issue_pending(inst->dma_chan);

	if (inst->settings.data_width == SMI_WIDTH_8BIT)
		init_trans_func(inst, count);
	else if (inst->settings.data_width == SMI_WIDTH_16BIT)
		init_trans_func(inst, count / 2);
out:
	spin_unlock(&inst->transaction_lock);
	return count;
}
Пример #3
0
void smi_init() {
	smram_state_t smram;
	pci_driver_t **driver;
	
	smram = smram_save_state();
	smram_tseg_set_state(SMRAM_TSEG_OPEN);

	outputf("NetWatch running");

	/* Turn on the SMIs we want */
	smi_disable();
	
	eth_init();
	
	crc32_init();
	
	/* After everything is initialized, load drivers. */
	for (driver = drivers; *driver; driver++)
	{
		outputf("Probing driver: %s", (*driver)->name);
		if (pci_probe_driver(*driver))
			output("Found a card");
	}
	outputf("Driver probe complete");
	
	/* Load in fonts. */
	text_init();

	smi_register_handler(SMI_EVENT_FAST_TIMER, timer_handler);
	smi_enable_event(SMI_EVENT_FAST_TIMER);

	smi_register_handler(SMI_EVENT_DEVTRAP_KBC, kbc_handler);
	smi_enable_event(SMI_EVENT_DEVTRAP_KBC);
	
	smi_register_handler(SMI_EVENT_GBL_RLS, gbl_rls_handler);
	smi_enable_event(SMI_EVENT_GBL_RLS);

	smi_enable();
	
	vga_flush_imm(1);
	
	smram_restore_state(smram);
}
Пример #4
0
void c_start(unsigned int magic, struct mb_info *mbinfo)
{
	struct mod_info *mods = mbinfo->mods;
	smram_state_t old_smramc;
	struct info_section * info;
	int i;
	
	void (*realmode)() = (void (*)()) 0x4000;
	
	show_cursor();
	outputf("NetWatch loader");
	
	if (magic != MULTIBOOT_LOADER_MAGIC)
		panic("Bootloader was not multiboot compliant; cannot continue.");
	
	for (i = 0; i < mbinfo->mod_cnt; i++)
	{
		outputf("Module found:");
		outputf("  Start: %08x", (unsigned long) mods[i].mod_start);
		outputf("  Size: %08x", (unsigned long)mods[i].mod_end - (unsigned long)mods[i].mod_start);
		outputf("  Name: %s", mods[i].mod_string);
	}

	if (mbinfo->mod_cnt != 1)
		panic("Expected exactly one module; cannot continue.");
	outputf("Current SMRAMC state is: %02x", (unsigned char)smram_save_state());
	outputf("Current SMI state is: %08x", inl(0x830));	// XXX ICH2 specific
	
	smi_disable();
	
	/* Open the SMRAM aperture and load our ELF. */
	old_smramc = smram_save_state();

	if (smram_aseg_set_state(SMRAM_ASEG_OPEN) != 0)
		panic("Opening SMRAM failed; cannot load ELF.");

	load_elf(mods[0].mod_start, (unsigned long)mods[0].mod_end - (unsigned long)mods[0].mod_start);

	info = (struct info_section *)0x10000;
	if (info->signature != INFO_SIGNATURE)
	{
		smram_restore_state(old_smramc);		/* Restore so that video ram is touchable again. */
		panic("Info section signature mismatch.");
	}

	info->firstrun();
	smram_restore_state(old_smramc);
	
	outputf("New SMRAMC state is: %02x", (unsigned char)smram_save_state());

	puts("Waiting for a bit before returning to real mode...");
	for (i=0; i<0x500000; i++)
	{
		if ((i % 0x100000) == 0)
			puts(".");
		inb(0x80);
	}
	puts("\n");

	outputf("Now returning to real mode.");
	memcpy((void *)0x4000, _binary_realmode_bin_start, (int)&_binary_realmode_bin_size);
	realmode();	// goodbye!
}