diff --git a/reactos/boot/freeldr/freeldr/arch/arm/macharm.c b/reactos/boot/freeldr/freeldr/arch/arm/macharm.c index 160a300a15b..f214a292ec2 100644 --- a/reactos/boot/freeldr/freeldr/arch/arm/macharm.c +++ b/reactos/boot/freeldr/freeldr/arch/arm/macharm.c @@ -34,7 +34,8 @@ ArmInit(IN PARM_BOARD_CONFIGURATION_BLOCK BootContext) // // This should probably go away once we support more boards // - ASSERT(ArmBoardBlock->BoardType == ARM_FEROCEON); + ASSERT((ArmBoardBlock->BoardType == MACH_TYPE_FEROCEON) || + (ArmBoardBlock->BoardType == MACH_TYPE_VERSATILE_PB)); // // Call FreeLDR's portable entrypoint with our command-line diff --git a/reactos/boot/freeldr/freeldr/arch/arm/stubs.c b/reactos/boot/freeldr/freeldr/arch/arm/stubs.c index e8375d033fd..42ced45b823 100644 --- a/reactos/boot/freeldr/freeldr/arch/arm/stubs.c +++ b/reactos/boot/freeldr/freeldr/arch/arm/stubs.c @@ -16,14 +16,6 @@ ULONG PageDirectoryStart, PageDirectoryEnd; /* FUNCTIONS ******************************************************************/ -VOID -FrLdrStartup(IN ULONG Magic) -{ - // - // Start the OS - // -} - BOOLEAN ArmDiskGetDriveGeometry(IN ULONG DriveNumber, OUT PGEOMETRY Geometry) @@ -110,7 +102,7 @@ MachInit(IN PCCH CommandLine) // // Check for Feroceon-base boards // - case ARM_FEROCEON: + case MACH_TYPE_FEROCEON: // // These boards use a UART16550. Set us up for 115200 bps @@ -121,6 +113,20 @@ MachInit(IN PCCH CommandLine) 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); } @@ -157,3 +163,9 @@ MachInit(IN PCCH CommandLine) TuiPrintf("%s for ARM\n", GetFreeLoaderVersionString()); TuiPrintf("Bootargs: %s\n", CommandLine); } + +VOID +FrLdrStartup(IN ULONG Magic) +{ + while (TRUE); +} diff --git a/reactos/boot/freeldr/freeldr/arch/arm/versuart.c b/reactos/boot/freeldr/freeldr/arch/arm/versuart.c new file mode 100644 index 00000000000..3119bc717d5 --- /dev/null +++ b/reactos/boot/freeldr/freeldr/arch/arm/versuart.c @@ -0,0 +1,132 @@ +/* + * 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 + +/* 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); +} diff --git a/reactos/boot/freeldr/freeldr/freeldr_arch.rbuild b/reactos/boot/freeldr/freeldr/freeldr_arch.rbuild index 411dc600dda..58355d532d8 100644 --- a/reactos/boot/freeldr/freeldr/freeldr_arch.rbuild +++ b/reactos/boot/freeldr/freeldr/freeldr_arch.rbuild @@ -102,6 +102,7 @@ boot.s ferouart.c + versuart.c macharm.c stubs.c diff --git a/reactos/boot/freeldr/freeldr/include/arch/arm/hardware.h b/reactos/boot/freeldr/freeldr/include/arch/arm/hardware.h index 0118c122d4b..76681e9b78c 100644 --- a/reactos/boot/freeldr/freeldr/include/arch/arm/hardware.h +++ b/reactos/boot/freeldr/freeldr/include/arch/arm/hardware.h @@ -14,16 +14,16 @@ #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 @@ -34,7 +34,7 @@ typedef struct _ARM_BOARD_CONFIGURATION_BLOCK { ULONG MajorVersion; ULONG MinorVersion; - ARM_BOARD_TYPE BoardType; + ULONG BoardType; ULONG ClockRate; ULONG TimerRegisterBase; ULONG UartRegisterBase; @@ -105,6 +105,18 @@ ArmFeroGetCh(VOID); 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 diff --git a/reactos/include/reactos/arc/arc.h b/reactos/include/reactos/arc/arc.h index 41431d4f0f2..f1401bf76ec 100644 --- a/reactos/include/reactos/arc/arc.h +++ b/reactos/include/reactos/arc/arc.h @@ -351,6 +351,28 @@ typedef struct _PPC_LOADER_BLOCK 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+) // @@ -426,7 +448,8 @@ typedef struct _LOADER_PARAMETER_BLOCK 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;