mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-24 22:36:05 +00:00
acpi: Add more support for generating processor tables
This adds tables relating to P-States and C-States. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
7764a8481c
commit
350c7f52b9
3 changed files with 623 additions and 0 deletions
|
@ -10,8 +10,10 @@
|
||||||
#ifndef __ACPI_ACPIGEN_H
|
#ifndef __ACPI_ACPIGEN_H
|
||||||
#define __ACPI_ACPIGEN_H
|
#define __ACPI_ACPIGEN_H
|
||||||
|
|
||||||
|
#include <acpi/acpi_table.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
struct acpi_cstate;
|
||||||
struct acpi_ctx;
|
struct acpi_ctx;
|
||||||
struct acpi_gen_regaddr;
|
struct acpi_gen_regaddr;
|
||||||
struct acpi_gpio;
|
struct acpi_gpio;
|
||||||
|
@ -87,6 +89,53 @@ enum psd_coord {
|
||||||
HW_ALL = 0xfe
|
HW_ALL = 0xfe
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum csd_coord - Coordination types for C-states
|
||||||
|
*
|
||||||
|
* The type of coordination that exists (hardware) or is required (software) as
|
||||||
|
* a result of the underlying hardware dependency
|
||||||
|
*/
|
||||||
|
enum csd_coord {
|
||||||
|
CSD_HW_ALL = 0xfe,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct acpi_cstate - Information about a C-State
|
||||||
|
*
|
||||||
|
* @ctype: C State type (1=C1, 2=C2, 3=C3)
|
||||||
|
* @latency: Worst-case latency to enter and exit the C State (in uS)
|
||||||
|
* @power: Average power consumption of the processor when in this C-State (mW)
|
||||||
|
* @resource: Register to read to place the processor in this state
|
||||||
|
*/
|
||||||
|
struct acpi_cstate {
|
||||||
|
uint ctype;
|
||||||
|
uint latency;
|
||||||
|
uint power;
|
||||||
|
struct acpi_gen_regaddr resource;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct acpi_tstate - Information about a Throttling Supported State
|
||||||
|
*
|
||||||
|
* See ACPI v6.3 section 8.4.5.2: _TSS (Throttling Supported States)
|
||||||
|
*
|
||||||
|
* @percent: Percent of the core CPU operating frequency that will be
|
||||||
|
* available when this throttling state is invoked
|
||||||
|
* @power: Throttling state’s maximum power dissipation (mw)
|
||||||
|
* @latency: Worst-case latency (uS) that the CPU is unavailable during a
|
||||||
|
* transition from any throttling state to this throttling state
|
||||||
|
* @control: Value to be written to the Processor Control Register
|
||||||
|
* (THROTTLE_CTRL) to initiate a transition to this throttling state
|
||||||
|
* @status: Value in THROTTLE_STATUS when in this state
|
||||||
|
*/
|
||||||
|
struct acpi_tstate {
|
||||||
|
uint percent;
|
||||||
|
uint power;
|
||||||
|
uint latency;
|
||||||
|
uint control;
|
||||||
|
uint status;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* acpigen_get_current() - Get the current ACPI code output pointer
|
* acpigen_get_current() - Get the current ACPI code output pointer
|
||||||
*
|
*
|
||||||
|
@ -816,4 +865,117 @@ void acpigen_write_processor_package(struct acpi_ctx *ctx, const char *name,
|
||||||
*/
|
*/
|
||||||
void acpigen_write_processor_cnot(struct acpi_ctx *ctx, const uint num_cores);
|
void acpigen_write_processor_cnot(struct acpi_ctx *ctx, const uint num_cores);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* acpigen_write_ppc() - generates a function returning max P-states
|
||||||
|
*
|
||||||
|
* @ctx: ACPI context pointer
|
||||||
|
* @num_pstates: Number of pstates to return
|
||||||
|
*/
|
||||||
|
void acpigen_write_ppc(struct acpi_ctx *ctx, uint num_pstates);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* acpigen_write_ppc() - generates a function returning PPCM
|
||||||
|
*
|
||||||
|
* This returns the maximum number of supported P-states, as saved in the
|
||||||
|
* variable PPCM
|
||||||
|
*
|
||||||
|
* @ctx: ACPI context pointer
|
||||||
|
*/
|
||||||
|
void acpigen_write_ppc_nvs(struct acpi_ctx *ctx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* acpigen_write_tpc() - Write a _TPC method that returns the TPC limit
|
||||||
|
*
|
||||||
|
* @ctx: ACPI context pointer
|
||||||
|
* @gnvs_tpc_limit: Variable that holds the TPC limit
|
||||||
|
*/
|
||||||
|
void acpigen_write_tpc(struct acpi_ctx *ctx, const char *gnvs_tpc_limit);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* acpigen_write_pss_package() - Write a PSS package
|
||||||
|
*
|
||||||
|
* See ACPI v6.3 section 8.4.6: Processor Performance Control
|
||||||
|
*
|
||||||
|
* @ctx: ACPI context pointer
|
||||||
|
* @corefreq: CPU core frequency in MHz
|
||||||
|
* @translat: worst-case latency in uS that the CPU is unavailable during a
|
||||||
|
* transition from any performance state to this performance state
|
||||||
|
* @busmlat: worst-case latency in microseconds that Bus Masters are prevented
|
||||||
|
* from accessing memory during a transition from any performance state to
|
||||||
|
* this performance state
|
||||||
|
* @control: Value to write to PERF_CTRL to move to this performance state
|
||||||
|
* @status: Expected PERF_STATUS value when in this state
|
||||||
|
*/
|
||||||
|
void acpigen_write_pss_package(struct acpi_ctx *ctx, uint corefreq, uint power,
|
||||||
|
uint translat, uint busmlat, uint control,
|
||||||
|
uint status);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* acpigen_write_psd_package() - Write a PSD package
|
||||||
|
*
|
||||||
|
* Writes a P-State dependency package
|
||||||
|
*
|
||||||
|
* See ACPI v6.3 section 8.4.6.5: _PSD (P-State Dependency)
|
||||||
|
*
|
||||||
|
* @ctx: ACPI context pointer
|
||||||
|
* @domain: Dependency domain number to which this P state entry belongs
|
||||||
|
* @numprocs: Number of processors belonging to the domain for this logical
|
||||||
|
* processor’s P-states
|
||||||
|
* @coordtype: Coordination type
|
||||||
|
*/
|
||||||
|
void acpigen_write_psd_package(struct acpi_ctx *ctx, uint domain, uint numprocs,
|
||||||
|
enum psd_coord coordtype);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* acpigen_write_cst_package() - Write a _CST package
|
||||||
|
*
|
||||||
|
* See ACPI v6.3 section 8.4.2.1: _CST (C States)
|
||||||
|
*
|
||||||
|
* @ctx: ACPI context pointer
|
||||||
|
* @entry: Array of entries
|
||||||
|
* @nentries; Number of entries
|
||||||
|
*/
|
||||||
|
void acpigen_write_cst_package(struct acpi_ctx *ctx,
|
||||||
|
const struct acpi_cstate *entry, int nentries);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* acpigen_write_csd_package() - Write a _CSD Package
|
||||||
|
*
|
||||||
|
* See ACPI v6.3 section 8.4.2.2: _CSD (C-State Dependency)
|
||||||
|
*
|
||||||
|
* @ctx: ACPI context pointer
|
||||||
|
* @domain: dependency domain number to which this C state entry belongs
|
||||||
|
* @numprocs: number of processors belonging to the domain for the particular
|
||||||
|
* C-state
|
||||||
|
* @coordtype: Co-ordination type
|
||||||
|
* @index: Index of the C-State entry in the _CST object for which the
|
||||||
|
* dependency applies
|
||||||
|
*/
|
||||||
|
void acpigen_write_csd_package(struct acpi_ctx *ctx, uint domain, uint numprocs,
|
||||||
|
enum csd_coord coordtype, uint index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* acpigen_write_tss_package() - Write a _TSS package
|
||||||
|
*
|
||||||
|
* @ctx: ACPI context pointer
|
||||||
|
* @entry: Entries to write
|
||||||
|
* @nentries: Number of entries to write
|
||||||
|
*/
|
||||||
|
void acpigen_write_tss_package(struct acpi_ctx *ctx,
|
||||||
|
struct acpi_tstate *entry, int nentries);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* acpigen_write_tsd_package() - Write a _TSD package
|
||||||
|
*
|
||||||
|
* See ACPI v6.3 section 8.4.5.4: _TSD (T-State Dependency)
|
||||||
|
*
|
||||||
|
* @ctx: ACPI context pointer
|
||||||
|
* @domain: dependency domain number to which this T state entry belongs
|
||||||
|
* @numprocs: Number of processors belonging to the domain for this logical
|
||||||
|
* processor’s T-states
|
||||||
|
* @coordtype: Coordination type
|
||||||
|
*/
|
||||||
|
void acpigen_write_tsd_package(struct acpi_ctx *ctx, uint domain, uint numprocs,
|
||||||
|
enum psd_coord coordtype);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -481,6 +481,53 @@ void acpigen_write_register_resource(struct acpi_ctx *ctx,
|
||||||
acpigen_write_resourcetemplate_footer(ctx);
|
acpigen_write_resourcetemplate_footer(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void acpigen_write_ppc(struct acpi_ctx *ctx, uint num_pstates)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Method (_PPC, 0, NotSerialized)
|
||||||
|
* {
|
||||||
|
* Return (num_pstates)
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
acpigen_write_method(ctx, "_PPC", 0);
|
||||||
|
acpigen_emit_byte(ctx, RETURN_OP);
|
||||||
|
acpigen_write_byte(ctx, num_pstates);
|
||||||
|
acpigen_pop_len(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generates a func with max supported P-states saved
|
||||||
|
* in the variable PPCM.
|
||||||
|
*/
|
||||||
|
void acpigen_write_ppc_nvs(struct acpi_ctx *ctx)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Method (_PPC, 0, NotSerialized)
|
||||||
|
* {
|
||||||
|
* Return (PPCM)
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
acpigen_write_method(ctx, "_PPC", 0);
|
||||||
|
acpigen_emit_byte(ctx, RETURN_OP);
|
||||||
|
acpigen_emit_namestring(ctx, "PPCM");
|
||||||
|
acpigen_pop_len(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void acpigen_write_tpc(struct acpi_ctx *ctx, const char *gnvs_tpc_limit)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* // Sample _TPC method
|
||||||
|
* Method (_TPC, 0, NotSerialized)
|
||||||
|
* {
|
||||||
|
* Return (\TLVL)
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
acpigen_write_method(ctx, "_TPC", 0);
|
||||||
|
acpigen_emit_byte(ctx, RETURN_OP);
|
||||||
|
acpigen_emit_namestring(ctx, gnvs_tpc_limit);
|
||||||
|
acpigen_pop_len(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
void acpigen_write_prw(struct acpi_ctx *ctx, uint wake, uint level)
|
void acpigen_write_prw(struct acpi_ctx *ctx, uint wake, uint level)
|
||||||
{
|
{
|
||||||
/* Name (_PRW, Package () { wake, level } */
|
/* Name (_PRW, Package () { wake, level } */
|
||||||
|
@ -491,6 +538,126 @@ void acpigen_write_prw(struct acpi_ctx *ctx, uint wake, uint level)
|
||||||
acpigen_pop_len(ctx);
|
acpigen_pop_len(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void acpigen_write_pss_package(struct acpi_ctx *ctx, u32 core_freq, u32 power,
|
||||||
|
u32 trans_lat, u32 busm_lat, u32 control,
|
||||||
|
u32 status)
|
||||||
|
{
|
||||||
|
acpigen_write_package(ctx, 6);
|
||||||
|
acpigen_write_dword(ctx, core_freq);
|
||||||
|
acpigen_write_dword(ctx, power);
|
||||||
|
acpigen_write_dword(ctx, trans_lat);
|
||||||
|
acpigen_write_dword(ctx, busm_lat);
|
||||||
|
acpigen_write_dword(ctx, control);
|
||||||
|
acpigen_write_dword(ctx, status);
|
||||||
|
acpigen_pop_len(ctx);
|
||||||
|
|
||||||
|
log_debug("PSS: %uMHz power %u control 0x%x status 0x%x\n",
|
||||||
|
core_freq, power, control, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
void acpigen_write_psd_package(struct acpi_ctx *ctx, uint domain, uint numprocs,
|
||||||
|
enum psd_coord coordtype)
|
||||||
|
{
|
||||||
|
acpigen_write_name(ctx, "_PSD");
|
||||||
|
acpigen_write_package(ctx, 1);
|
||||||
|
acpigen_write_package(ctx, 5);
|
||||||
|
acpigen_write_byte(ctx, 5); // 5 values
|
||||||
|
acpigen_write_byte(ctx, 0); // revision 0
|
||||||
|
acpigen_write_dword(ctx, domain);
|
||||||
|
acpigen_write_dword(ctx, coordtype);
|
||||||
|
acpigen_write_dword(ctx, numprocs);
|
||||||
|
acpigen_pop_len(ctx);
|
||||||
|
acpigen_pop_len(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void acpigen_write_cst_package_entry(struct acpi_ctx *ctx,
|
||||||
|
const struct acpi_cstate *cstate)
|
||||||
|
{
|
||||||
|
acpigen_write_package(ctx, 4);
|
||||||
|
acpigen_write_register_resource(ctx, &cstate->resource);
|
||||||
|
acpigen_write_dword(ctx, cstate->ctype);
|
||||||
|
acpigen_write_dword(ctx, cstate->latency);
|
||||||
|
acpigen_write_dword(ctx, cstate->power);
|
||||||
|
acpigen_pop_len(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void acpigen_write_cst_package(struct acpi_ctx *ctx,
|
||||||
|
const struct acpi_cstate *cstate, int nentries)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
acpigen_write_name(ctx, "_CST");
|
||||||
|
acpigen_write_package(ctx, nentries + 1);
|
||||||
|
acpigen_write_dword(ctx, nentries);
|
||||||
|
|
||||||
|
for (i = 0; i < nentries; i++)
|
||||||
|
acpigen_write_cst_package_entry(ctx, cstate + i);
|
||||||
|
|
||||||
|
acpigen_pop_len(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void acpigen_write_csd_package(struct acpi_ctx *ctx, uint domain, uint numprocs,
|
||||||
|
enum csd_coord coordtype, uint index)
|
||||||
|
{
|
||||||
|
acpigen_write_name(ctx, "_CSD");
|
||||||
|
acpigen_write_package(ctx, 1);
|
||||||
|
acpigen_write_package(ctx, 6);
|
||||||
|
acpigen_write_byte(ctx, 6); // 6 values
|
||||||
|
acpigen_write_byte(ctx, 0); // revision 0
|
||||||
|
acpigen_write_dword(ctx, domain);
|
||||||
|
acpigen_write_dword(ctx, coordtype);
|
||||||
|
acpigen_write_dword(ctx, numprocs);
|
||||||
|
acpigen_write_dword(ctx, index);
|
||||||
|
acpigen_pop_len(ctx);
|
||||||
|
acpigen_pop_len(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void acpigen_write_tss_package(struct acpi_ctx *ctx,
|
||||||
|
struct acpi_tstate *entry, int nentries)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Sample _TSS package with 100% and 50% duty cycles
|
||||||
|
* Name (_TSS, Package (0x02)
|
||||||
|
* {
|
||||||
|
* Package(){100, 1000, 0, 0x00, 0)
|
||||||
|
* Package(){50, 520, 0, 0x18, 0)
|
||||||
|
* })
|
||||||
|
*/
|
||||||
|
struct acpi_tstate *tstate = entry;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
acpigen_write_name(ctx, "_TSS");
|
||||||
|
acpigen_write_package(ctx, nentries);
|
||||||
|
|
||||||
|
for (i = 0; i < nentries; i++) {
|
||||||
|
acpigen_write_package(ctx, 5);
|
||||||
|
acpigen_write_dword(ctx, tstate->percent);
|
||||||
|
acpigen_write_dword(ctx, tstate->power);
|
||||||
|
acpigen_write_dword(ctx, tstate->latency);
|
||||||
|
acpigen_write_dword(ctx, tstate->control);
|
||||||
|
acpigen_write_dword(ctx, tstate->status);
|
||||||
|
acpigen_pop_len(ctx);
|
||||||
|
tstate++;
|
||||||
|
}
|
||||||
|
|
||||||
|
acpigen_pop_len(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void acpigen_write_tsd_package(struct acpi_ctx *ctx, u32 domain, u32 numprocs,
|
||||||
|
enum psd_coord coordtype)
|
||||||
|
{
|
||||||
|
acpigen_write_name(ctx, "_TSD");
|
||||||
|
acpigen_write_package(ctx, 1);
|
||||||
|
acpigen_write_package(ctx, 5);
|
||||||
|
acpigen_write_byte(ctx, 5); // 5 values
|
||||||
|
acpigen_write_byte(ctx, 0); // revision 0
|
||||||
|
acpigen_write_dword(ctx, domain);
|
||||||
|
acpigen_write_dword(ctx, coordtype);
|
||||||
|
acpigen_write_dword(ctx, numprocs);
|
||||||
|
acpigen_pop_len(ctx);
|
||||||
|
acpigen_pop_len(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ToUUID(uuid)
|
* ToUUID(uuid)
|
||||||
*
|
*
|
||||||
|
|
|
@ -1450,3 +1450,297 @@ static int dm_test_acpi_write_processor_cnot(struct unit_test_state *uts)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
DM_TEST(dm_test_acpi_write_processor_cnot, 0);
|
DM_TEST(dm_test_acpi_write_processor_cnot, 0);
|
||||||
|
|
||||||
|
/* Test acpigen_write_tpc */
|
||||||
|
static int dm_test_acpi_write_tpc(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
struct acpi_ctx *ctx;
|
||||||
|
u8 *ptr;
|
||||||
|
|
||||||
|
ut_assertok(alloc_context(&ctx));
|
||||||
|
|
||||||
|
ptr = acpigen_get_current(ctx);
|
||||||
|
acpigen_write_tpc(ctx, "\\TLVL");
|
||||||
|
|
||||||
|
ut_asserteq(METHOD_OP, *ptr++);
|
||||||
|
ptr += 3; /* skip length */
|
||||||
|
ut_asserteq_strn("_TPC", (char *)ptr);
|
||||||
|
ptr += 4;
|
||||||
|
ut_asserteq(0, *ptr++);
|
||||||
|
ut_asserteq(RETURN_OP, *ptr++);
|
||||||
|
ut_asserteq_strn("\\TLVL", (char *)ptr);
|
||||||
|
ptr += 5;
|
||||||
|
|
||||||
|
ut_asserteq_ptr(ptr, ctx->current);
|
||||||
|
|
||||||
|
free_context(&ctx);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
DM_TEST(dm_test_acpi_write_tpc, 0);
|
||||||
|
|
||||||
|
/* Test acpigen_write_pss_package(), etc. */
|
||||||
|
static int dm_test_acpi_write_pss_psd(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
struct acpi_ctx *ctx;
|
||||||
|
u8 *ptr;
|
||||||
|
|
||||||
|
ut_assertok(alloc_context(&ctx));
|
||||||
|
|
||||||
|
ptr = acpigen_get_current(ctx);
|
||||||
|
acpigen_write_pss_package(ctx, 1, 2, 3, 4, 5, 6);
|
||||||
|
ut_asserteq(PACKAGE_OP, *ptr++);
|
||||||
|
ptr += 3; /* skip length */
|
||||||
|
ut_asserteq(6, *ptr++);
|
||||||
|
|
||||||
|
ut_asserteq(DWORD_PREFIX, *ptr++);
|
||||||
|
ut_asserteq(1, get_unaligned((u32 *)ptr));
|
||||||
|
ptr += 5;
|
||||||
|
|
||||||
|
ut_asserteq(2, get_unaligned((u32 *)ptr));
|
||||||
|
ptr += 5;
|
||||||
|
|
||||||
|
ut_asserteq(3, get_unaligned((u32 *)ptr));
|
||||||
|
ptr += 5;
|
||||||
|
|
||||||
|
ut_asserteq(4, get_unaligned((u32 *)ptr));
|
||||||
|
ptr += 5;
|
||||||
|
|
||||||
|
ut_asserteq(5, get_unaligned((u32 *)ptr));
|
||||||
|
ptr += 5;
|
||||||
|
|
||||||
|
ut_asserteq(6, get_unaligned((u32 *)ptr));
|
||||||
|
ptr += 4;
|
||||||
|
|
||||||
|
acpigen_write_psd_package(ctx, 6, 7, HW_ALL);
|
||||||
|
ut_asserteq(NAME_OP, *ptr++);
|
||||||
|
ut_asserteq_strn("_PSD", (char *)ptr);
|
||||||
|
ptr += 4;
|
||||||
|
ut_asserteq(PACKAGE_OP, *ptr++);
|
||||||
|
ptr += 3; /* skip length */
|
||||||
|
ut_asserteq(1, *ptr++);
|
||||||
|
ut_asserteq(PACKAGE_OP, *ptr++);
|
||||||
|
ptr += 3; /* skip length */
|
||||||
|
ut_asserteq(5, *ptr++);
|
||||||
|
|
||||||
|
ut_asserteq(BYTE_PREFIX, *ptr++);
|
||||||
|
ut_asserteq(5, *ptr++);
|
||||||
|
ut_asserteq(BYTE_PREFIX, *ptr++);
|
||||||
|
ut_asserteq(0, *ptr++);
|
||||||
|
|
||||||
|
ut_asserteq(DWORD_PREFIX, *ptr++);
|
||||||
|
ut_asserteq(6, get_unaligned((u32 *)ptr));
|
||||||
|
ptr += 5;
|
||||||
|
|
||||||
|
ut_asserteq(HW_ALL, get_unaligned((u32 *)ptr));
|
||||||
|
ptr += 5;
|
||||||
|
|
||||||
|
ut_asserteq(7, get_unaligned((u32 *)ptr));
|
||||||
|
ptr += 4;
|
||||||
|
|
||||||
|
ut_asserteq_ptr(ptr, ctx->current);
|
||||||
|
|
||||||
|
free_context(&ctx);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
DM_TEST(dm_test_acpi_write_pss_psd, 0);
|
||||||
|
|
||||||
|
/* Test acpi_write_cst_package() */
|
||||||
|
static int dm_test_acpi_write_cst(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
static struct acpi_cstate cstate_map[] = {
|
||||||
|
{
|
||||||
|
/* C1 */
|
||||||
|
.ctype = 1, /* ACPI C1 */
|
||||||
|
.latency = 1,
|
||||||
|
.power = 1000,
|
||||||
|
.resource = {
|
||||||
|
.space_id = ACPI_ADDRESS_SPACE_FIXED,
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
.ctype = 2, /* ACPI C2 */
|
||||||
|
.latency = 50,
|
||||||
|
.power = 10,
|
||||||
|
.resource = {
|
||||||
|
.space_id = ACPI_ADDRESS_SPACE_IO,
|
||||||
|
.bit_width = 8,
|
||||||
|
.addrl = 0x415,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
int nentries = ARRAY_SIZE(cstate_map);
|
||||||
|
struct acpi_ctx *ctx;
|
||||||
|
u8 *ptr;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ut_assertok(alloc_context(&ctx));
|
||||||
|
|
||||||
|
ptr = acpigen_get_current(ctx);
|
||||||
|
acpigen_write_cst_package(ctx, cstate_map, nentries);
|
||||||
|
|
||||||
|
ut_asserteq(NAME_OP, *ptr++);
|
||||||
|
ut_asserteq_strn("_CST", (char *)ptr);
|
||||||
|
ptr += 4;
|
||||||
|
ut_asserteq(PACKAGE_OP, *ptr++);
|
||||||
|
ptr += 3; /* skip length */
|
||||||
|
ut_asserteq(nentries + 1, *ptr++);
|
||||||
|
ut_asserteq(DWORD_PREFIX, *ptr++);
|
||||||
|
ut_asserteq(nentries, get_unaligned((u32 *)ptr));
|
||||||
|
ptr += 4;
|
||||||
|
|
||||||
|
for (i = 0; i < nentries; i++) {
|
||||||
|
ut_asserteq(PACKAGE_OP, *ptr++);
|
||||||
|
ptr += 3; /* skip length */
|
||||||
|
ut_asserteq(4, *ptr++);
|
||||||
|
ut_asserteq(BUFFER_OP, *ptr++);
|
||||||
|
ptr += 0x17;
|
||||||
|
ut_asserteq(DWORD_PREFIX, *ptr++);
|
||||||
|
ut_asserteq(cstate_map[i].ctype, get_unaligned((u32 *)ptr));
|
||||||
|
ptr += 5;
|
||||||
|
ut_asserteq(cstate_map[i].latency, get_unaligned((u32 *)ptr));
|
||||||
|
ptr += 5;
|
||||||
|
ut_asserteq(cstate_map[i].power, get_unaligned((u32 *)ptr));
|
||||||
|
ptr += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
ut_asserteq_ptr(ptr, ctx->current);
|
||||||
|
|
||||||
|
free_context(&ctx);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
DM_TEST(dm_test_acpi_write_cst, 0);
|
||||||
|
|
||||||
|
/* Test acpi_write_cst_package() */
|
||||||
|
static int dm_test_acpi_write_csd(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
struct acpi_ctx *ctx;
|
||||||
|
u8 *ptr;
|
||||||
|
|
||||||
|
ut_assertok(alloc_context(&ctx));
|
||||||
|
|
||||||
|
ptr = acpigen_get_current(ctx);
|
||||||
|
acpigen_write_csd_package(ctx, 12, 34, CSD_HW_ALL, 56);
|
||||||
|
|
||||||
|
ut_asserteq(NAME_OP, *ptr++);
|
||||||
|
ut_asserteq_strn("_CSD", (char *)ptr);
|
||||||
|
ptr += 4;
|
||||||
|
ut_asserteq(PACKAGE_OP, *ptr++);
|
||||||
|
ptr += 3; /* skip length */
|
||||||
|
ut_asserteq(1, *ptr++);
|
||||||
|
ut_asserteq(PACKAGE_OP, *ptr++);
|
||||||
|
ptr += 3; /* skip length */
|
||||||
|
ut_asserteq(6, *ptr++);
|
||||||
|
|
||||||
|
ut_asserteq(BYTE_PREFIX, *ptr++);
|
||||||
|
ut_asserteq(6, *ptr++);
|
||||||
|
ut_asserteq(BYTE_PREFIX, *ptr++);
|
||||||
|
ut_asserteq(0, *ptr++);
|
||||||
|
ut_asserteq(DWORD_PREFIX, *ptr++);
|
||||||
|
ut_asserteq(12, get_unaligned((u32 *)ptr));
|
||||||
|
ptr += 5;
|
||||||
|
ut_asserteq(CSD_HW_ALL, get_unaligned((u32 *)ptr));
|
||||||
|
ptr += 5;
|
||||||
|
ut_asserteq(34, get_unaligned((u32 *)ptr));
|
||||||
|
ptr += 5;
|
||||||
|
ut_asserteq(56, get_unaligned((u32 *)ptr));
|
||||||
|
ptr += 4;
|
||||||
|
|
||||||
|
ut_asserteq_ptr(ptr, ctx->current);
|
||||||
|
|
||||||
|
free_context(&ctx);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
DM_TEST(dm_test_acpi_write_csd, 0);
|
||||||
|
|
||||||
|
/* Test acpigen_write_tss_package() */
|
||||||
|
static int dm_test_acpi_write_tss(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
static struct acpi_tstate tstate_list[] = {
|
||||||
|
{ 1, 2, 3, 4, 5, },
|
||||||
|
{ 6, 7, 8, 9, 10, },
|
||||||
|
};
|
||||||
|
int nentries = ARRAY_SIZE(tstate_list);
|
||||||
|
struct acpi_ctx *ctx;
|
||||||
|
u8 *ptr;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ut_assertok(alloc_context(&ctx));
|
||||||
|
|
||||||
|
ptr = acpigen_get_current(ctx);
|
||||||
|
acpigen_write_tss_package(ctx, tstate_list, nentries);
|
||||||
|
|
||||||
|
ut_asserteq(NAME_OP, *ptr++);
|
||||||
|
ut_asserteq_strn("_TSS", (char *)ptr);
|
||||||
|
ptr += 4;
|
||||||
|
ut_asserteq(PACKAGE_OP, *ptr++);
|
||||||
|
ptr += 3; /* skip length */
|
||||||
|
ut_asserteq(nentries, *ptr++);
|
||||||
|
|
||||||
|
for (i = 0; i < nentries; i++) {
|
||||||
|
ut_asserteq(PACKAGE_OP, *ptr++);
|
||||||
|
ptr += 3; /* skip length */
|
||||||
|
ut_asserteq(5, *ptr++);
|
||||||
|
ut_asserteq(DWORD_PREFIX, *ptr++);
|
||||||
|
ut_asserteq(tstate_list[i].percent, get_unaligned((u32 *)ptr));
|
||||||
|
ptr += 5;
|
||||||
|
ut_asserteq(tstate_list[i].power, get_unaligned((u32 *)ptr));
|
||||||
|
ptr += 5;
|
||||||
|
ut_asserteq(tstate_list[i].latency, get_unaligned((u32 *)ptr));
|
||||||
|
ptr += 5;
|
||||||
|
ut_asserteq(tstate_list[i].control, get_unaligned((u32 *)ptr));
|
||||||
|
ptr += 5;
|
||||||
|
ut_asserteq(tstate_list[i].status, get_unaligned((u32 *)ptr));
|
||||||
|
ptr += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
ut_asserteq_ptr(ptr, ctx->current);
|
||||||
|
|
||||||
|
free_context(&ctx);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
DM_TEST(dm_test_acpi_write_tss, 0);
|
||||||
|
|
||||||
|
/* Test acpigen_write_tsd_package() */
|
||||||
|
static int dm_test_acpi_write_tsd_package(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
struct acpi_ctx *ctx;
|
||||||
|
u8 *ptr;
|
||||||
|
|
||||||
|
ut_assertok(alloc_context(&ctx));
|
||||||
|
|
||||||
|
ptr = acpigen_get_current(ctx);
|
||||||
|
acpigen_write_tsd_package(ctx, 12, 34, HW_ALL);
|
||||||
|
|
||||||
|
ut_asserteq(NAME_OP, *ptr++);
|
||||||
|
ut_asserteq_strn("_TSD", (char *)ptr);
|
||||||
|
ptr += 4;
|
||||||
|
ut_asserteq(PACKAGE_OP, *ptr++);
|
||||||
|
ptr += 3; /* skip length */
|
||||||
|
ut_asserteq(1, *ptr++);
|
||||||
|
ut_asserteq(PACKAGE_OP, *ptr++);
|
||||||
|
ptr += 3; /* skip length */
|
||||||
|
ut_asserteq(5, *ptr++);
|
||||||
|
|
||||||
|
ut_asserteq(BYTE_PREFIX, *ptr++);
|
||||||
|
ut_asserteq(5, *ptr++);
|
||||||
|
ut_asserteq(BYTE_PREFIX, *ptr++);
|
||||||
|
ut_asserteq(0, *ptr++);
|
||||||
|
ut_asserteq(DWORD_PREFIX, *ptr++);
|
||||||
|
ut_asserteq(12, get_unaligned((u32 *)ptr));
|
||||||
|
ptr += 5;
|
||||||
|
ut_asserteq(CSD_HW_ALL, get_unaligned((u32 *)ptr));
|
||||||
|
ptr += 5;
|
||||||
|
ut_asserteq(34, get_unaligned((u32 *)ptr));
|
||||||
|
ptr += 4;
|
||||||
|
|
||||||
|
ut_asserteq_ptr(ptr, ctx->current);
|
||||||
|
|
||||||
|
free_context(&ctx);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
DM_TEST(dm_test_acpi_write_tsd_package, 0);
|
||||||
|
|
Loading…
Add table
Reference in a new issue