Software APIs
soc_proxy_external_wakeup.c
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
8 #include "sw/device/lib/runtime/irq.h"
10 #include "sw/device/lib/testing/rv_plic_testutils.h"
12 #include "sw/device/lib/testing/test_framework/status.h"
13 
14 #include "hw/top_darjeeling/sw/autogen/top_darjeeling.h"
15 #include "sw/device/lib/testing/autogen/isr_testutils.h"
16 
17 OTTF_DEFINE_TEST_CONFIG();
18 
19 static dif_pwrmgr_t pwrmgr;
20 static dif_rv_plic_t plic;
21 
22 static plic_isr_ctx_t plic_ctx = {.rv_plic = &plic,
23  .hart_id = kTopDarjeelingPlicTargetIbex0};
24 
25 static pwrmgr_isr_ctx_t pwrmgr_isr_ctx = {
26  .pwrmgr = &pwrmgr,
27  .plic_pwrmgr_start_irq_id = kTopDarjeelingPlicIrqIdPwrmgrAonWakeup,
28  .expected_irq = kDifPwrmgrIrqWakeup,
29  .is_only_irq = true};
30 
31 bool test_main(void) {
32  CHECK_DIF_OK(dif_pwrmgr_init(
33  mmio_region_from_addr(TOP_DARJEELING_PWRMGR_AON_BASE_ADDR), &pwrmgr));
34  CHECK_DIF_OK(dif_rv_plic_init(
35  mmio_region_from_addr(TOP_DARJEELING_RV_PLIC_BASE_ADDR), &plic));
36 
37  // Enable global and external IRQ in Ibex.
38  irq_global_ctrl(true);
39  irq_external_ctrl(true);
40 
41  // Enable wakeup interrupt output from Power Manager.
42  rv_plic_testutils_irq_range_enable(&plic, kTopDarjeelingPlicTargetIbex0,
43  kTopDarjeelingPlicIrqIdPwrmgrAonWakeup,
44  kTopDarjeelingPlicIrqIdPwrmgrAonWakeup);
45  CHECK_DIF_OK(dif_pwrmgr_irq_set_enabled(&pwrmgr, 0, kDifToggleEnabled));
46 
47  // Get currently enabled sources for wakeup requests in Power Manager.
48  dif_pwrmgr_request_sources_t wakeup_req_srcs;
50  &wakeup_req_srcs));
51 
52  // Enable external wakeup request in Power Manager.
53  const dif_pwrmgr_request_sources_t ext_wkup_req =
54  (1u << kTopDarjeelingPowerManagerWakeUpsSocProxyWkupExternalReq);
55  wakeup_req_srcs |= ext_wkup_req;
56  CHECK_DIF_OK(dif_pwrmgr_set_request_sources(
57  &pwrmgr, kDifPwrmgrReqTypeWakeup, wakeup_req_srcs, kDifToggleEnabled));
58  LOG_INFO("Power Manager configured.");
59  CHECK_DIF_OK(
61  /*sync_state=*/kDifToggleEnabled));
62  test_status_set(kTestStatusInWfi);
64  test_status_set(kTestStatusInTest);
65 
66  // Wait for wakeup request to show up in Power Manager.
67  while (true) {
68  dif_pwrmgr_request_sources_t cur_wakeup_srcs;
70  &pwrmgr, kDifPwrmgrReqTypeWakeup, &cur_wakeup_srcs));
71  if (cur_wakeup_srcs & ext_wkup_req) {
72  LOG_INFO("External wakeup request detected.");
73  break;
74  }
76  }
77 
78  return true;
79 }
80 
81 // Interrupt service routine
82 void ottf_external_isr(void) {
83  dif_pwrmgr_irq_t irq_id;
84  top_darjeeling_plic_peripheral_t peripheral;
85 
86  isr_testutils_pwrmgr_isr(plic_ctx, pwrmgr_isr_ctx, &peripheral, &irq_id);
87 
88  // Check that peripheral and IRQ ID are correct.
89  CHECK(peripheral == kTopDarjeelingPlicPeripheralPwrmgrAon,
90  "IRQ peripheral %d is incorrect!", peripheral);
91  CHECK(irq_id == kDifPwrmgrIrqWakeup, "IRQ ID %d is incorrect!", irq_id);
92 }