• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2 *
3 *  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
4 *  Copyright (c) 2015, Linaro Limited. All rights reserved.
5 *
6 *  This program and the accompanying materials
7 *  are licensed and made available under the terms and conditions of the BSD License
8 *  which accompanies this distribution.  The full text of the license may be found at
9 *  http://opensource.org/licenses/bsd-license.php
10 *
11 *  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 *  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 *
14 **/
15 
16 
17 #include <PiDxe.h>
18 #include <Library/DebugLib.h>
19 #include <Library/UefiBootServicesTableLib.h>
20 #include <Library/BaseLib.h>
21 #include <Library/UefiRuntimeLib.h>
22 #include <Library/DxeServicesTableLib.h>
23 #include <Guid/EventGroup.h>
24 
25 #include <Library/PlatformSysCtrlLib.h>
26 #include "I2CLibInternal.h"
27 
28 STATIC EFI_EVENT              mI2cLibVirtualAddrChangeEvent;
29 
30 STATIC UINTN gI2cBase[MAX_SOCKET][I2C_PORT_MAX];
31 
GetI2cBase(UINT32 Socket,UINT8 Port)32 UINTN GetI2cBase (UINT32 Socket, UINT8 Port)
33 {
34   if (gI2cBase[Socket][Port] == 0) {
35     gI2cBase[Socket][Port] = PlatformGetI2cBase(Socket, Port);
36   }
37 
38   return gI2cBase[Socket][Port];
39 }
40 
41 VOID
42 EFIAPI
I2cLibVirtualNotifyEvent(IN EFI_EVENT Event,IN VOID * Context)43 I2cLibVirtualNotifyEvent (
44   IN EFI_EVENT        Event,
45   IN VOID             *Context
46   )
47 {
48   UINT32 Socket;
49   UINT8  Port;
50 
51   // We assume that all I2C ports used in one runtime driver need to be
52   // converted into virtual address.
53   for (Socket = 0; Socket < MAX_SOCKET; Socket++) {
54     for (Port = 0; Port < I2C_PORT_MAX; Port++) {
55       if (gI2cBase[Socket][Port] != 0) {
56         EfiConvertPointer (0x0, (VOID **)&gI2cBase[Socket][Port]);
57       }
58     }
59   }
60 
61   return;
62 }
63 
64 EFI_STATUS
I2cLibRuntimeSetup(UINT32 Socket,UINT8 Port)65 I2cLibRuntimeSetup (UINT32 Socket, UINT8 Port)
66 {
67   EFI_STATUS Status;
68 
69   UINTN Base = GetI2cBase (Socket, Port);
70 
71   // Declare the controller as EFI_MEMORY_RUNTIME
72   Status = gDS->AddMemorySpace (
73       EfiGcdMemoryTypeMemoryMappedIo,
74       Base, SIZE_64KB,
75       EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
76       );
77   if (EFI_ERROR (Status)) {
78     DEBUG ((EFI_D_WARN, "[%a:%d] AddMemorySpace failed: %r\n", __FUNCTION__, __LINE__, Status));
79   }
80 
81   Status = gDS->SetMemorySpaceAttributes (Base, SIZE_64KB, EFI_MEMORY_UC | EFI_MEMORY_RUNTIME);
82   if (EFI_ERROR (Status)) {
83     DEBUG ((EFI_D_ERROR, "[%a:%d] SetMemorySpaceAttributes failed: %r\n", __FUNCTION__, __LINE__, Status));
84     return Status;
85   }
86 
87   //
88   // Register for the virtual address change event
89   //
90   // Only create event once
91   if (mI2cLibVirtualAddrChangeEvent == NULL) {
92     Status = gBS->CreateEventEx (
93         EVT_NOTIFY_SIGNAL,
94         TPL_NOTIFY,
95         I2cLibVirtualNotifyEvent,
96         NULL,
97         &gEfiEventVirtualAddressChangeGuid,
98         &mI2cLibVirtualAddrChangeEvent
99     );
100     if (EFI_ERROR (Status)) {
101       DEBUG ((EFI_D_ERROR, "[%a:%d] Create event failed: %r\n", __FUNCTION__, __LINE__, Status));
102       return Status;
103     }
104   }
105 
106   return EFI_SUCCESS;
107 }
108 
109 
110