Exemplo n.º 1
0
void dc_dbg_init()
{
#ifdef DBG_COM
	u32 divisor;
	u8  lcr;
	/* set baud rate and data format (8N1) */
	/*  turn on DTR and RTS  */
    WRITE_PORT_UCHAR(pv(SER_MCR(COM_BASE)), SR_MCR_DTR | SR_MCR_RTS);

	/* set DLAB */
    lcr = READ_PORT_UCHAR(pv(SER_LCR(COM_BASE))) | SR_LCR_DLAB;
    WRITE_PORT_UCHAR(pv(SER_LCR(COM_BASE)), lcr);

	/* set baud rate */
    divisor = 115200 / DEFAULT_BAUD_RATE;
    WRITE_PORT_UCHAR(pv(SER_DLL(COM_BASE)), divisor & 0xff);
    WRITE_PORT_UCHAR(pv(SER_DLM(COM_BASE)), (divisor >> 8) & 0xff);

	/* reset DLAB and set 8N1 format */
    WRITE_PORT_UCHAR(pv(SER_LCR(COM_BASE)), 
		SR_LCR_CS8 | SR_LCR_ST1 | SR_LCR_PNO);

	/* read junk out of the RBR */
	READ_PORT_UCHAR(pv(SER_RBR(COM_BASE)));
#endif /* DBG_COM */

#ifdef DBG_HAL_DISPLAY
	InbvAcquireDisplayOwnership();
	InbvEnableDisplayString(TRUE);
#endif /* DBG_HAL_DISPLAY */
}
Exemplo n.º 2
0
NTSTATUS NTAPI
SerialSetBaudRate(
	IN PSERIAL_DEVICE_EXTENSION DeviceExtension,
	IN ULONG NewBaudRate)
{
	ULONG BaudRate;
	USHORT divisor;
	PUCHAR ComPortBase = ULongToPtr(DeviceExtension->BaseAddress);
	NTSTATUS Status = STATUS_SUCCESS;

	if (NewBaudRate == 0)
		return STATUS_INVALID_PARAMETER;

	divisor = (USHORT)(BAUD_CLOCK / (CLOCKS_PER_BIT * NewBaudRate));
	BaudRate = BAUD_CLOCK / (CLOCKS_PER_BIT * divisor);

	Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, ULongToPtr(DeviceExtension->ComPort));
	if (NT_SUCCESS(Status))
	{
		UCHAR Lcr;
		TRACE_(SERIAL, "SerialSetBaudRate(COM%lu, %lu Bauds)\n", DeviceExtension->ComPort, BaudRate);
		/* Set Bit 7 of LCR to expose baud registers */
		Lcr = READ_PORT_UCHAR(SER_LCR(ComPortBase));
		WRITE_PORT_UCHAR(SER_LCR(ComPortBase), Lcr | SR_LCR_DLAB);
		/* Write the baud rate */
		WRITE_PORT_UCHAR(SER_DLL(ComPortBase), divisor & 0xff);
		WRITE_PORT_UCHAR(SER_DLM(ComPortBase), divisor >> 8);
		/* Switch back to normal registers */
		WRITE_PORT_UCHAR(SER_LCR(ComPortBase), Lcr);

		IoReleaseRemoveLock(&DeviceExtension->RemoveLock, ULongToPtr(DeviceExtension->ComPort));
	}

	if (NT_SUCCESS(Status))
		DeviceExtension->BaudRate = BaudRate;
	return Status;
}
Exemplo n.º 3
0
NTSTATUS NTAPI
SerialSetLineControl(
	IN PSERIAL_DEVICE_EXTENSION DeviceExtension,
	IN PSERIAL_LINE_CONTROL NewSettings)
{
	PUCHAR ComPortBase;
	UCHAR Lcr = 0;
	NTSTATUS Status;

	ASSERT(DeviceExtension);
	ASSERT(NewSettings);

	TRACE_(SERIAL, "SerialSetLineControl(COM%lu, Settings { %lu %lu %lu })\n",
		DeviceExtension->ComPort, NewSettings->StopBits, NewSettings->Parity, NewSettings->WordLength);

	/* Verify parameters */
	switch (NewSettings->WordLength)
	{
		case 5: Lcr |= SR_LCR_CS5; break;
		case 6: Lcr |= SR_LCR_CS6; break;
		case 7: Lcr |= SR_LCR_CS7; break;
		case 8: Lcr |= SR_LCR_CS8; break;
		default: return STATUS_INVALID_PARAMETER;
	}

	if (NewSettings->WordLength < 5 || NewSettings->WordLength > 8)
		return STATUS_INVALID_PARAMETER;

	switch (NewSettings->Parity)
	{
		case NO_PARITY:    Lcr |= SR_LCR_PNO; break;
		case ODD_PARITY:   Lcr |= SR_LCR_POD; break;
		case EVEN_PARITY:  Lcr |= SR_LCR_PEV; break;
		case MARK_PARITY:  Lcr |= SR_LCR_PMK; break;
		case SPACE_PARITY: Lcr |= SR_LCR_PSP; break;
		default: return STATUS_INVALID_PARAMETER;
	}

	switch (NewSettings->StopBits)
	{
		case STOP_BIT_1:
			Lcr |= SR_LCR_ST1;
			break;
		case STOP_BITS_1_5:
			if (NewSettings->WordLength != 5)
				return STATUS_INVALID_PARAMETER;
			Lcr |= SR_LCR_ST2;
			break;
		case STOP_BITS_2:
			if (NewSettings->WordLength < 6 || NewSettings->WordLength > 8)
				return STATUS_INVALID_PARAMETER;
			Lcr |= SR_LCR_ST2;
			break;
		default:
			return STATUS_INVALID_PARAMETER;
	}

	/* Update current parameters */
	ComPortBase = ULongToPtr(DeviceExtension->BaseAddress);
	Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, ULongToPtr(DeviceExtension->ComPort));
	if (!NT_SUCCESS(Status))
		return Status;
	WRITE_PORT_UCHAR(SER_LCR(ComPortBase), Lcr);

	/* Read junk out of RBR */
	READ_PORT_UCHAR(SER_RBR(ComPortBase));
	IoReleaseRemoveLock(&DeviceExtension->RemoveLock, ULongToPtr(DeviceExtension->ComPort));

	if (NT_SUCCESS(Status))
		DeviceExtension->SerialLineControl = *NewSettings;

	return Status;
}
Exemplo n.º 4
0
UART_TYPE
SerialDetectUartType(
	IN PUCHAR BaseAddress)
{
	UCHAR Lcr, TestLcr;
	UCHAR OldScr, Scr5A, ScrA5;
	BOOLEAN FifoEnabled;
	UCHAR NewFifoStatus;

	Lcr = READ_PORT_UCHAR(SER_LCR(BaseAddress));
	WRITE_PORT_UCHAR(SER_LCR(BaseAddress), Lcr ^ 0xFF);
	TestLcr = READ_PORT_UCHAR(SER_LCR(BaseAddress)) ^ 0xFF;
	WRITE_PORT_UCHAR(SER_LCR(BaseAddress), Lcr);

	/* Accessing the LCR must work for a usable serial port */
	if (TestLcr != Lcr)
		return UartUnknown;

	/* Ensure that all following accesses are done as required */
	READ_PORT_UCHAR(SER_RBR(BaseAddress));
	READ_PORT_UCHAR(SER_IER(BaseAddress));
	READ_PORT_UCHAR(SER_IIR(BaseAddress));
	READ_PORT_UCHAR(SER_LCR(BaseAddress));
	READ_PORT_UCHAR(SER_MCR(BaseAddress));
	READ_PORT_UCHAR(SER_LSR(BaseAddress));
	READ_PORT_UCHAR(SER_MSR(BaseAddress));
	READ_PORT_UCHAR(SER_SCR(BaseAddress));

	/* Test scratch pad */
	OldScr = READ_PORT_UCHAR(SER_SCR(BaseAddress));
	WRITE_PORT_UCHAR(SER_SCR(BaseAddress), 0x5A);
	Scr5A = READ_PORT_UCHAR(SER_SCR(BaseAddress));
	WRITE_PORT_UCHAR(SER_SCR(BaseAddress), 0xA5);
	ScrA5 = READ_PORT_UCHAR(SER_SCR(BaseAddress));
	WRITE_PORT_UCHAR(SER_SCR(BaseAddress), OldScr);

	/* When non-functional, we have a 8250 */
	if (Scr5A != 0x5A || ScrA5 != 0xA5)
		return Uart8250;

	/* Test FIFO type */
	FifoEnabled = (READ_PORT_UCHAR(SER_IIR(BaseAddress)) & 0x80) != 0;
	WRITE_PORT_UCHAR(SER_FCR(BaseAddress), SR_FCR_ENABLE_FIFO);
	NewFifoStatus = READ_PORT_UCHAR(SER_IIR(BaseAddress)) & 0xC0;
	if (!FifoEnabled)
		WRITE_PORT_UCHAR(SER_FCR(BaseAddress), 0);
	switch (NewFifoStatus)
	{
		case 0x00:
			return Uart16450;
		case 0x40:
		case 0x80:
			/* Not sure about this but the documentation says that 0x40
			 * indicates an unusable FIFO but my tests only worked
			 * with 0x80 */
			return Uart16550;
	}

	/* FIFO is only functional for 16550A+ */
	return Uart16550A;
}