/* FUNCTIONS ******************************************************************/
-VOID
-FrLdrStartup(IN ULONG Magic)
-{
- //
- // Start the OS
- //
-}
-
BOOLEAN
ArmDiskGetDriveGeometry(IN ULONG DriveNumber,
OUT PGEOMETRY Geometry)
//
// Check for Feroceon-base boards
//
- case ARM_FEROCEON:
+ case MACH_TYPE_FEROCEON:
//
// These boards use a UART16550. Set us up for 115200 bps
MachVtbl.ConsGetCh = ArmFeroGetCh;
break;
+ //
+ // Check for ARM Versatile PB boards
+ //
+ case MACH_TYPE_VERSATILE_PB:
+
+ //
+ // These boards use a PrimeCell UART (PL011)
+ //
+ ArmVersaSerialInit(115200);
+ MachVtbl.ConsPutChar = ArmVersaPutChar;
+ MachVtbl.ConsKbHit = ArmVersaKbHit;
+ MachVtbl.ConsGetCh = ArmVersaGetCh;
+ break;
+
default:
ASSERT(FALSE);
}
TuiPrintf("%s for ARM\n", GetFreeLoaderVersionString());
TuiPrintf("Bootargs: %s\n", CommandLine);
}
+
+VOID
+FrLdrStartup(IN ULONG Magic)
+{
+ while (TRUE);
+}
--- /dev/null
+/*
+ * PROJECT: ReactOS Boot Loader
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: boot/freeldr/arch/arm/versuart.c
+ * PURPOSE: Implements code for Versatile boards using the PL011 UART
+ * PROGRAMMERS: ReactOS Portable Systems Group
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include <freeldr.h>
+
+/* GLOBALS ********************************************************************/
+
+//
+// UART Registers
+//
+#define UART_PL01x_DR (ArmBoardBlock->UartRegisterBase + 0x00)
+#define UART_PL01x_RSR (ArmBoardBlock->UartRegisterBase + 0x04)
+#define UART_PL01x_ECR (ArmBoardBlock->UartRegisterBase + 0x04)
+#define UART_PL01x_FR (ArmBoardBlock->UartRegisterBase + 0x18)
+#define UART_PL011_IBRD (ArmBoardBlock->UartRegisterBase + 0x24)
+#define UART_PL011_FBRD (ArmBoardBlock->UartRegisterBase + 0x28)
+#define UART_PL011_LCRH (ArmBoardBlock->UartRegisterBase + 0x2C)
+#define UART_PL011_CR (ArmBoardBlock->UartRegisterBase + 0x30)
+#define UART_PL011_IMSC (ArmBoardBlock->UartRegisterBase + 0x38)
+
+//
+// LCR Values
+//
+#define UART_PL011_LCRH_WLEN_8 0x60
+#define UART_PL011_LCRH_FEN 0x10
+
+//
+// FCR Values
+//
+#define UART_PL011_CR_UARTEN 0x01
+#define UART_PL011_CR_TXE 0x100
+#define UART_PL011_CR_RXE 0x200
+
+//
+// LSR Values
+//
+#define UART_PL01x_FR_RXFE 0x10
+#define UART_PL01x_FR_TXFF 0x20
+
+/* FUNCTIONS ******************************************************************/
+
+VOID
+ArmVersaSerialInit(IN ULONG Baudrate)
+{
+ ULONG Divider, Remainder, Fraction;
+
+ //
+ // Calculate baudrate clock divider and remainder
+ //
+ Divider = ArmBoardBlock->ClockRate / (16 * Baudrate);
+ Remainder = ArmBoardBlock->ClockRate % (16 * Baudrate);
+
+ //
+ // Calculate the fractional part
+ //
+ Fraction = (8 * Remainder / Baudrate) >> 1;
+ Fraction += (8 * Remainder / Baudrate) & 1;
+
+ //
+ // Disable interrupts
+ //
+ WRITE_REGISTER_ULONG(UART_PL011_CR, 0);
+
+ //
+ // Set the baud rate to 115200 bps
+ //
+ WRITE_REGISTER_ULONG(UART_PL011_IBRD, Divider);
+ WRITE_REGISTER_ULONG(UART_PL011_FBRD, Fraction);
+
+ //
+ // Set 8 bits for data, 1 stop bit, no parity, FIFO enabled
+ //
+ WRITE_REGISTER_ULONG(UART_PL011_LCRH,
+ UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN);
+
+ //
+ // Clear and enable FIFO
+ //
+ WRITE_REGISTER_ULONG(UART_PL011_CR,
+ UART_PL011_CR_UARTEN |
+ UART_PL011_CR_TXE |
+ UART_PL011_CR_RXE);
+}
+
+VOID
+ArmVersaPutChar(IN INT Char)
+{
+ //
+ // Properly support new-lines
+ //
+ if (Char == '\n') ArmVersaPutChar('\r');
+
+ //
+ // Wait for ready
+ //
+ while ((READ_REGISTER_ULONG(UART_PL01x_FR) & UART_PL01x_FR_TXFF) != 0);
+
+ //
+ // Send the character
+ //
+ WRITE_REGISTER_ULONG(UART_PL01x_DR, Char);
+}
+
+INT
+ArmVersaGetCh(VOID)
+{
+ //
+ // Wait for ready
+ //
+ while ((READ_REGISTER_ULONG(UART_PL01x_FR) & UART_PL01x_FR_RXFE) != 0);
+
+ //
+ // Read the character
+ //
+ return READ_REGISTER_ULONG(UART_PL01x_DR);
+}
+
+BOOLEAN
+ArmVersaKbHit(VOID)
+{
+ //
+ // Return if something is ready
+ //
+ return ((READ_REGISTER_ULONG(UART_PL01x_FR) & UART_PL01x_FR_RXFE) == 0);
+}
#endif
//
-// The only things we support
+// Marvell Feroceon-based SoC:
+// Buffalo Linkstation, KuroBox Pro, D-Link DS323 and others
//
-typedef enum _ARM_BOARD_TYPE
-{
- //
- // Marvell Feroceon-based SoC:
- // Buffalo Linkstation, KuroBox Pro, D-Link DS323 and others
- //
- ARM_FEROCEON = 1,
-} ARM_BOARD_TYPE;
+#define MACH_TYPE_FEROCEON 526
+
+//
+// ARM Versatile PB:
+// qemu-system-arm -M versatilepb, RealView Development Boards and others
+//
+#define MACH_TYPE_VERSATILE_PB 387
//
// Compatible boot-loaders should return us this information
{
ULONG MajorVersion;
ULONG MinorVersion;
- ARM_BOARD_TYPE BoardType;
+ ULONG BoardType;
ULONG ClockRate;
ULONG TimerRegisterBase;
ULONG UartRegisterBase;
BOOLEAN
ArmFeroKbHit(VOID);
+VOID
+ArmVersaSerialInit(IN ULONG Baudrate);
+
+VOID
+ArmVersaPutChar(IN INT Char);
+
+INT
+ArmVersaGetCh(VOID);
+
+BOOLEAN
+ArmVersaKbHit(VOID);
+
extern PARM_BOARD_CONFIGURATION_BLOCK ArmBoardBlock;
#endif
ULONG MachineType;
} PPC_LOADER_BLOCK, *PPPC_LOADER_BLOCK;
+typedef struct _ARM_LOADER_BLOCK
+{
+#ifdef _ARM_
+ ULONG InterruptStack;
+ ULONG FirstLevelDcacheSize;
+ ULONG FirstLevelDcacheFillSize;
+ ULONG FirstLevelIcacheSize;
+ ULONG FirstLevelIcacheFillSize;
+ ULONG GpBase;
+ ULONG PanicStack;
+ ULONG PcrPage;
+ ULONG PdrPage;
+ ULONG SecondLevelDcacheSize;
+ ULONG SecondLevelDcacheFillSize;
+ ULONG SecondLevelIcacheSize;
+ ULONG SecondLevelIcacheFillSize;
+ ULONG PcrPage2;
+#else
+ ULONG PlaceHolder;
+#endif
+} ARM_LOADER_BLOCK, *PARM_LOADER_BLOCK;
+
//
// Firmware information block (NT6+)
//
I386_LOADER_BLOCK I386;
ALPHA_LOADER_BLOCK Alpha;
IA64_LOADER_BLOCK Ia64;
- PPC_LOADER_BLOCK PowerPC;
+ PPC_LOADER_BLOCK PowerPC;
+ ARM_LOADER_BLOCK Arm;
} u;
FIRMWARE_INFORMATION_LOADER_BLOCK FirmwareInformation;
} LOADER_PARAMETER_BLOCK, *PLOADER_PARAMETER_BLOCK;