Пример #1
0
static int transferToFlash(void* buffer, int size) {
	int controller = 0;
	int channel = 0;

	if((((uint32_t)buffer) & 0x3) != 0) {
		// the buffer needs to be aligned for DMA, last two bits have to be clear
		return ERROR_ALIGN;
	}

	SET_REG(NAND + NAND_CONFIG, GET_REG(NAND + NAND_CONFIG) | (1 << NAND_CONFIG_DMASETTINGSHIFT));
	SET_REG(NAND + NAND_TRANSFERSIZE, size - 1);
	SET_REG(NAND + NAND_CON, 0x7F4);

	CleanCPUDataCache();

	dma_request(DMA_MEMORY, 4, 4, DMA_NAND, 4, 4, &controller, &channel, NULL);
	dma_perform((uint32_t)buffer, DMA_NAND, size, 0, &controller, &channel);

	if(dma_finish(controller, channel, 500) != 0) {
		bufferPrintf("nand: dma timed out\r\n");
		return ERROR_TIMEOUT;
	}

	if(wait_for_status_bit_3(500) != 0) {
		bufferPrintf("nand: waiting for status bit 3 timed out\r\n");
		return ERROR_TIMEOUT;
	}

	SET_REG(NAND + NAND_CON, NAND_CON_SETTING1);

	CleanAndInvalidateCPUDataCache();

	return 0;
}
Пример #2
0
static int transferToFlash(void* buffer, int size) {
	int controller = 0;
	int channel = 0;

	if((((uint32_t)buffer) & 0x3) != 0) {
		// the buffer needs to be aligned for DMA, last two bits have to be clear
		return ERROR_ALIGN;
	}

	SET_REG(NAND + FMCTRL0, GET_REG(NAND + FMCTRL0) | (1 << FMCTRL0_DMASETTINGSHIFT));
	SET_REG(NAND + FMDNUM, size - 1);
	SET_REG(NAND + FMCTRL1, 0x7F4);

	CleanCPUDataCache();

	dma_request(DMA_MEMORY, 4, 4, DMA_NAND, 4, 4, &controller, &channel, NULL);
	dma_perform((uint32_t)buffer, DMA_NAND, size, 0, &controller, &channel);

	if(dma_finish(controller, channel, 500) != 0) {
		bufferPrintf("nand: dma timed out\r\n");
		return ERROR_TIMEOUT;
	}

	if(wait_for_transfer_done(500) != 0) {
		bufferPrintf("nand: waiting for transfer done timed out\r\n");
		return ERROR_TIMEOUT;
	}

	SET_REG(NAND + FMCTRL1, FMCTRL1_FLUSHFIFOS);

	CleanAndInvalidateCPUDataCache();

	return 0;
}
Пример #3
0
static int setup_processor() {

	CleanAndInvalidateCPUDataCache();
	ClearCPUInstructionCache();

	WriteControlRegisterConfigData(ReadControlRegisterConfigData() & ~(ARM11_Control_INSTRUCTIONCACHE));	// Disable instruction cache
	WriteControlRegisterConfigData(ReadControlRegisterConfigData() & ~(ARM11_Control_DATACACHE));		// Disable data cache

	GiveFullAccessCP10CP11();
	EnableVFP();

	// Map the peripheral port of size 128 MB to 0x38000000
	WritePeripheralPortMemoryRemapRegister(PeripheralPort | ARM11_PeripheralPortSize128MB);
	InvalidateCPUDataCache();
	ClearCPUInstructionCache();

	WriteControlRegisterConfigData(ReadControlRegisterConfigData() | ARM11_Control_INSTRUCTIONCACHE);	// Enable instruction cache
	WriteControlRegisterConfigData(ReadControlRegisterConfigData() | ARM11_Control_DATACACHE);		// Enable data cache

	WriteControlRegisterConfigData((ReadControlRegisterConfigData()
		& ~(ARM11_Control_STRICTALIGNMENTCHECKING))				// Disable strict alignment fault checking
		| ARM11_Control_UNALIGNEDDATAACCESS);					// Enable unaligned data access operations


	WriteControlRegisterConfigData(ReadControlRegisterConfigData() | ARM11_Control_BRANCHPREDICTION); 	// Enable branch prediction

	// Enable return stack, dynamic branch prediction, static branch prediction
	WriteAuxiliaryControlRegister(ReadAuxiliaryControlRegister()
		| ARM11_AuxControl_RETURNSTACK
		| ARM11_AuxControl_DYNAMICBRANCHPREDICTION
		| ARM11_AuxControl_STATICBRANCHPREDICTION);

	return 0;
}
Пример #4
0
static void ecc_generate(int setting, int sectors, uint8_t* sectorData, uint8_t* eccData) {
	SET_REG(NANDECC + NANDECC_CLEARINT, 1);
	SET_REG(NANDECC + NANDECC_SETUP, ((sectors - 1) & 0x3) | setting);
	SET_REG(NANDECC + NANDECC_DATA, (uint32_t) sectorData);
	SET_REG(NANDECC + NANDECC_ECC, (uint32_t) eccData);

	CleanAndInvalidateCPUDataCache();

	SET_REG(NANDECC + NANDECC_START, 2);
}
Пример #5
0
static void usbTxRx(int endpoint, USBDirection direction, USBTransferType transferType, void* buffer, int bufferLen) {
	int packetLength;

	if(transferType == USBControl || transferType == USBInterrupt) {
		packetLength = USB_MAX_PACKETSIZE;
	} else {
		packetLength = packetsizeFromSpeed(usb_speed);
	}

	CleanAndInvalidateCPUDataCache();

	if(direction == USBOut) {
		receive(endpoint, transferType, buffer, packetLength, bufferLen);
		return;
	}

	if(GNPTXFSTS_GET_TXQSPCAVAIL(GET_REG(USB + GNPTXFSTS)) == 0) {
		// no space available
		return;
	}

	// enable interrupts for this endpoint
	SET_REG(USB + DAINTMSK, GET_REG(USB + DAINTMSK) | ((1 << endpoint) << DAINTMSK_IN_SHIFT));
	
	InEPRegs[endpoint].dmaAddress = buffer;

	if(endpoint == USB_CONTROLEP) {
		// we'll only send one packet at a time on CONTROLEP
		InEPRegs[endpoint].transferSize = ((1 & DEPTSIZ_PKTCNT_MASK) << DEPTSIZ_PKTCNT_SHIFT) | (bufferLen & DEPTSIZ0_XFERSIZ_MASK);
		InEPRegs[endpoint].control = USB_EPCON_CLEARNAK;
		return;
	}

	int packetCount = bufferLen / packetLength;
	if((bufferLen % packetLength) != 0)
		++packetCount;


	InEPRegs[endpoint].transferSize = ((packetCount & DEPTSIZ_PKTCNT_MASK) << DEPTSIZ_PKTCNT_SHIFT)
		| (bufferLen & DEPTSIZ_XFERSIZ_MASK) | ((USB_MULTICOUNT & DIEPTSIZ_MC_MASK) << DIEPTSIZ_MC_SHIFT);


	InEPRegs[endpoint].control = USB_EPCON_CLEARNAK | USB_EPCON_ACTIVE | ((transferType & USB_EPCON_TYPE_MASK) << USB_EPCON_TYPE_SHIFT) | (packetLength & USB_EPCON_MPS_MASK);
	
}
Пример #6
0
int dma_perform(uint32_t Source, uint32_t Destination, int size, int continueList, int* controller, int* channel) {
	uint32_t regSrcAddress;
	uint32_t regDestAddress;
	uint32_t regLLI;
	uint32_t regControl0;
	uint32_t regConfiguration;

	const uint32_t regControl0Mask = ~(DMAC0Control0_SIZEMASK | DMAC0Control0_SOURCEINCREMENT | DMAC0Control0_DESTINATIONINCREMENT);

	uint32_t regOffset = (*channel * DMAChannelRegSize);

	if(*controller == 1) {
		regOffset += DMAC0;
	} else if(*controller == 2) {
		regOffset += DMAC1;
	}

	regSrcAddress = regOffset + DMAC0SrcAddress;
	regDestAddress = regOffset + DMAC0DestAddress;
	regLLI = regOffset + DMAC0LLI;
	regControl0 = regOffset + DMAC0Control0;
	regConfiguration = regOffset + DMAC0Configuration;

	int transfers = size/(1 << DMAC0Control0_DWIDTH(GET_REG(regControl0)));

	uint32_t sourcePeripheral = 0;
	uint32_t destPeripheral = 0;
	uint32_t flowControl = 0;
	uint32_t sourceIncrement = 0;
	uint32_t destinationIncrement = 0;

	if(Source <= (sizeof(AddressLookupTable)/sizeof(uint32_t))) {
		if(Destination <= (sizeof(AddressLookupTable)/sizeof(uint32_t))) {
			SET_REG(regSrcAddress, AddressLookupTable[Source]);
			SET_REG(regDestAddress, AddressLookupTable[Destination]);
			sourcePeripheral = PeripheralLookupTable[Source][*controller - 1];
			destPeripheral = PeripheralLookupTable[Destination][*controller - 1];
			flowControl =  DMAC0Configuration_FLOWCNTRL_P2P;
		} else {
			SET_REG(regSrcAddress, AddressLookupTable[Source]);
			SET_REG(regDestAddress, Destination);
			sourcePeripheral = PeripheralLookupTable[Source][*controller - 1];
			destPeripheral = PeripheralLookupTable[DMA_MEMORY][*controller - 1];
			flowControl =  DMAC0Configuration_FLOWCNTRL_P2M;
			destinationIncrement = 1 << DMAC0Control0_DESTINATIONINCREMENT;
		}
	} else {
		if(Destination <= (sizeof(AddressLookupTable)/sizeof(uint32_t))) {
			SET_REG(regSrcAddress, Source);
			SET_REG(regDestAddress, AddressLookupTable[Destination]);
			sourcePeripheral = PeripheralLookupTable[DMA_MEMORY][*controller - 1];
			destPeripheral = PeripheralLookupTable[Destination][*controller - 1];
			flowControl =  DMAC0Configuration_FLOWCNTRL_M2P;
			sourceIncrement = 1 << DMAC0Control0_SOURCEINCREMENT;
		} else {
			SET_REG(regSrcAddress, Source);
			SET_REG(regDestAddress, Destination);
			sourcePeripheral = PeripheralLookupTable[DMA_MEMORY][*controller - 1];
			destPeripheral = PeripheralLookupTable[DMA_MEMORY][*controller - 1];
			flowControl =  DMAC0Configuration_FLOWCNTRL_M2M;
			sourceIncrement = 1 << DMAC0Control0_SOURCEINCREMENT;
			destinationIncrement = 1 << DMAC0Control0_DESTINATIONINCREMENT;
		}
	}

	if(!continueList) {
		uint32_t src = GET_REG(regSrcAddress);
		uint32_t dest = GET_REG(regDestAddress);
		if(transfers > 0xFFF) {
			SET_REG(regControl0, GET_REG(regControl0) & ~(1 << DMAC0Control0_TERMINALCOUNTINTERRUPTENABLE));

			if(DMALists[*controller - 1][*channel])
				free(DMALists[*controller - 1][*channel]);

			DMALinkedList* item = DMALists[*controller - 1][*channel] = malloc(((transfers + 0xDFF) / 0xE00) * sizeof(DMALinkedList));
			SET_REG(regLLI, (uint32_t)item);
			do {
				transfers -= 0xE00;
				
				if(sourceIncrement != 0) {
					src += 0xE00 << DMAC0Control0_DWIDTH(GET_REG(regControl0));
				}
				if(destinationIncrement != 0) {
					dest += 0xE00 << DMAC0Control0_DWIDTH(GET_REG(regControl0));
				}

				item->source = src;
				item->destination = dest;

				if(transfers <= 0xE00) {
					item->control = destinationIncrement | sourceIncrement | (regControl0Mask & GET_REG(regControl0)) | (transfers & DMAC0Control0_SIZEMASK)
						| (1 << DMAC0Control0_TERMINALCOUNTINTERRUPTENABLE);
					item->next = NULL;
				} else {
					item->control = destinationIncrement | sourceIncrement | (regControl0Mask & GET_REG(regControl0)) | 0xE00;
					item->next = item + 1;
					item = item->next;
				}
			} while(transfers > 0xE00);

			CleanAndInvalidateCPUDataCache();
			transfers = 0xE00;
		} else {
			SET_REG(regLLI, 0);
		}
	} else {
		StaticDMALists[*controller - 1][*channel].control = GET_REG(regControl0);
		SET_REG(regLLI, (uint32_t)&StaticDMALists[*controller - 1][*channel]);
	}

	SET_REG(regControl0, (GET_REG(regControl0) & regControl0Mask) | destinationIncrement | sourceIncrement | (transfers & DMAC0Control0_SIZEMASK));
	SET_REG(regConfiguration, DMAC0Configuration_CHANNELENABLED | DMAC0Configuration_TERMINALCOUNTINTERRUPTMASK
			| (flowControl << DMAC0Configuration_FLOWCNTRLSHIFT)
			| (destPeripheral << DMAC0Configuration_DESTPERIPHERALSHIFT)
			| (sourcePeripheral << DMAC0Configuration_SRCPERIPHERALSHIFT));

	return 0;
}
Пример #7
0
static void receiveControl(void* buffer, int bufferLen) {
	CleanAndInvalidateCPUDataCache();
	receive(USB_CONTROLEP, USBControl, buffer, USB_MAX_PACKETSIZE, bufferLen);
}
Пример #8
0
void arm_disable_caches() {
	CleanAndInvalidateCPUDataCache();
	ClearCPUInstructionCache();
	WriteControlRegisterConfigData(ReadControlRegisterConfigData() & ~ARM11_Control_INSTRUCTIONCACHE);	// Disable instruction cache
	WriteControlRegisterConfigData(ReadControlRegisterConfigData() & ~ARM11_Control_DATACACHE);		// Disable data cache
}