We now support the ARM Versatile/PB platform, which means qemu-system-arm -M versatil...
authorReactOS Portable Systems Group <ros-arm-bringup@svn.reactos.org>
Mon, 11 Feb 2008 20:15:16 +0000 (20:15 +0000)
committerReactOS Portable Systems Group <ros-arm-bringup@svn.reactos.org>
Mon, 11 Feb 2008 20:15:16 +0000 (20:15 +0000)
We now support the PL011 UART, required for console output on the Versatile.
We now define the ARM_LOADER_BLOCK structure, to be used later when FreeLDR passes control to the kernel.

svn path=/trunk/; revision=32305

reactos/boot/freeldr/freeldr/arch/arm/macharm.c
reactos/boot/freeldr/freeldr/arch/arm/stubs.c
reactos/boot/freeldr/freeldr/arch/arm/versuart.c [new file with mode: 0644]
reactos/boot/freeldr/freeldr/freeldr_arch.rbuild
reactos/boot/freeldr/freeldr/include/arch/arm/hardware.h
reactos/include/reactos/arc/arc.h

index 160a300..f214a29 100644 (file)
@@ -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
index e8375d0..42ced45 100644 (file)
@@ -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 (file)
index 0000000..3119bc7
--- /dev/null
@@ -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 <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);
+}
index 411dc60..58355d5 100644 (file)
                                <define name="_NTHAL_" />
                                <file>boot.s</file>
                                <file>ferouart.c</file>
+                               <file>versuart.c</file>
                                <file>macharm.c</file>
                                <file>stubs.c</file>
                        </module>
index 0118c12..76681e9 100644 (file)
 #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
index 41431d4..f1401bf 100644 (file)
@@ -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;