[lib][uefi] Default implementation of BootService.SetWatchdogTimer()
The platform_watchdog_ methods are optional features that the target platform can choose to implement. If they are implemented, then BootService.SetWatchdogTimer() would call them to setup the hardware watchdog. If they are not implemented (for example presubmit targets), then BootService.SetWatchdogTimer() would test the WEAK symbol against a NULL pointer and error out. To use BootService.SetWatchdogTimer(), platforms can choose to either implement platform_watchdog_init and platform_watchdog_set_enabled, or override the entire BootService.SetWatchdogTimer() method.
This commit is contained in:
committed by
Kelvin Zhang
parent
7b26b7cf3a
commit
e38bf65034
@@ -393,4 +393,5 @@ void setup_boot_service_table(EfiBootService *service) {
|
|||||||
service->stall = stall;
|
service->stall = stall;
|
||||||
service->raise_tpl = raise_tpl;
|
service->raise_tpl = raise_tpl;
|
||||||
service->restore_tpl = restore_tpl;
|
service->restore_tpl = restore_tpl;
|
||||||
|
service->set_watchdog_timer = set_watchdog_timer;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,14 @@ LOCAL_DIR := $(GET_LOCAL_DIR)
|
|||||||
|
|
||||||
MODULE := $(LOCAL_DIR)
|
MODULE := $(LOCAL_DIR)
|
||||||
|
|
||||||
MODULE_INCLUDES += $(LOCAL_DIR)/local/include
|
|
||||||
|
|
||||||
MODULE_DEFINES=MSPACES=1
|
MODULE_DEFINES=MSPACES=1
|
||||||
|
|
||||||
|
MODULE_INCLUDES += \
|
||||||
|
lib/watchdog/include \
|
||||||
|
|
||||||
|
MODULE_DEPS += \
|
||||||
|
lib/libcpp \
|
||||||
|
|
||||||
MODULE_SRCS += \
|
MODULE_SRCS += \
|
||||||
$(LOCAL_DIR)/uefi.cpp \
|
$(LOCAL_DIR)/uefi.cpp \
|
||||||
$(LOCAL_DIR)/relocation.cpp \
|
$(LOCAL_DIR)/relocation.cpp \
|
||||||
|
|||||||
@@ -18,7 +18,10 @@
|
|||||||
#include "uefi_platform.h"
|
#include "uefi_platform.h"
|
||||||
|
|
||||||
#include <arch/arm64.h>
|
#include <arch/arm64.h>
|
||||||
|
#include <lib/watchdog.h>
|
||||||
#include <libfdt.h>
|
#include <libfdt.h>
|
||||||
|
#include <lk/err.h>
|
||||||
|
#include <lk/trace.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <uefi/protocols/gbl_efi_image_loading_protocol.h>
|
#include <uefi/protocols/gbl_efi_image_loading_protocol.h>
|
||||||
@@ -27,6 +30,8 @@
|
|||||||
|
|
||||||
#include "defer.h"
|
#include "defer.h"
|
||||||
|
|
||||||
|
#define LOCAL_TRACE 0
|
||||||
|
|
||||||
__WEAK EFI_STATUS efi_dt_fixup(struct EfiDtFixupProtocol *self, void *fdt,
|
__WEAK EFI_STATUS efi_dt_fixup(struct EfiDtFixupProtocol *self, void *fdt,
|
||||||
size_t *buffer_size, uint32_t flags) {
|
size_t *buffer_size, uint32_t flags) {
|
||||||
auto offset = fdt_subnode_offset(fdt, 0, "chosen");
|
auto offset = fdt_subnode_offset(fdt, 0, "chosen");
|
||||||
@@ -111,6 +116,46 @@ __WEAK EfiStatus get_timestamp_properties(EfiTimestampProperties *properties) {
|
|||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__BEGIN_CDECLS
|
||||||
|
|
||||||
|
// Redeclaring these as WEAK has two effects:
|
||||||
|
// 1. Since we are also including lib/watchdog.h, the compiler would ensure
|
||||||
|
// that the declarations had matching prototypes.
|
||||||
|
// 2. If the platform did not provide these methods, then these symbols would
|
||||||
|
// resolve to NULL, and can be checked at runtime.
|
||||||
|
extern __WEAK status_t platform_watchdog_init(
|
||||||
|
lk_time_t target_timeout, lk_time_t* recommended_pet_period);
|
||||||
|
extern __WEAK void platform_watchdog_set_enabled(bool enabled);
|
||||||
|
|
||||||
|
__END_CDECLS
|
||||||
|
|
||||||
|
__WEAK EfiStatus set_watchdog_timer(size_t timeout, uint64_t watchdog_code,
|
||||||
|
size_t data_size, char16_t* watchdog_data) {
|
||||||
|
if (platform_watchdog_init == nullptr || platform_watchdog_set_enabled == nullptr) {
|
||||||
|
TRACEF(
|
||||||
|
"unimplemented: platform_watchdog_init = %p "
|
||||||
|
"platform_watchdog_set_enabled = %p\n",
|
||||||
|
platform_watchdog_init, platform_watchdog_set_enabled);
|
||||||
|
return UNSUPPORTED;
|
||||||
|
}
|
||||||
|
if (timeout != 0) {
|
||||||
|
lk_time_t ignored = 0;
|
||||||
|
status_t ret = platform_watchdog_init(timeout * 1000, &ignored);
|
||||||
|
LTRACEF("platform_watchdog_init() ret=%d\n", ret);
|
||||||
|
if (ret == ERR_INVALID_ARGS) {
|
||||||
|
return INVALID_PARAMETER;
|
||||||
|
} else if (ret != NO_ERROR) {
|
||||||
|
return UNSUPPORTED;
|
||||||
|
}
|
||||||
|
platform_watchdog_set_enabled(true);
|
||||||
|
LTRACEF("enabled hw watchdog\n");
|
||||||
|
} else {
|
||||||
|
platform_watchdog_set_enabled(false);
|
||||||
|
LTRACEF("disabled hw watchdog\n");
|
||||||
|
}
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
const char *GetImageType(const char16_t *ImageType) {
|
const char *GetImageType(const char16_t *ImageType) {
|
||||||
|
|||||||
@@ -47,6 +47,10 @@ uint64_t get_timestamp();
|
|||||||
|
|
||||||
EfiStatus get_timestamp_properties(EfiTimestampProperties *properties);
|
EfiStatus get_timestamp_properties(EfiTimestampProperties *properties);
|
||||||
|
|
||||||
|
// timeout unit is in seconds.
|
||||||
|
EfiStatus set_watchdog_timer(size_t timeout, uint64_t watchdog_code,
|
||||||
|
size_t data_size, char16_t* watchdog_data);
|
||||||
|
|
||||||
// alloc_page/free_pages is implemented in memory_protocols.cpp
|
// alloc_page/free_pages is implemented in memory_protocols.cpp
|
||||||
void *alloc_page(void *addr, size_t size, size_t align_log2 = PAGE_SIZE_SHIFT);
|
void *alloc_page(void *addr, size_t size, size_t align_log2 = PAGE_SIZE_SHIFT);
|
||||||
|
|
||||||
@@ -71,4 +75,4 @@ void setup_heap();
|
|||||||
// Caled by LK once after executing UEFI application to tear down the heap
|
// Caled by LK once after executing UEFI application to tear down the heap
|
||||||
void reset_heap();
|
void reset_heap();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <lk/compiler.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <kernel/thread.h>
|
#include <kernel/thread.h>
|
||||||
@@ -14,6 +15,8 @@
|
|||||||
|
|
||||||
#define WATCHDOG_MAGIC 'wdog'
|
#define WATCHDOG_MAGIC 'wdog'
|
||||||
|
|
||||||
|
__BEGIN_CDECLS
|
||||||
|
|
||||||
typedef struct watchdog {
|
typedef struct watchdog {
|
||||||
uint32_t magic;
|
uint32_t magic;
|
||||||
const char *name;
|
const char *name;
|
||||||
@@ -64,3 +67,5 @@ extern void platform_watchdog_pet(void);
|
|||||||
|
|
||||||
status_t watchdog_hw_init(lk_time_t timeout);
|
status_t watchdog_hw_init(lk_time_t timeout);
|
||||||
void watchdog_hw_set_enabled(bool enabled);
|
void watchdog_hw_set_enabled(bool enabled);
|
||||||
|
|
||||||
|
__END_CDECLS
|
||||||
|
|||||||
Reference in New Issue
Block a user