2 * This file is part of the coreboot project.
4 * Copyright 2013 Google Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
17 #include <console/console.h>
19 #include <device/device.h>
20 #include <device/resource.h>
21 #include <device/pci.h>
23 #include <reg_script.h>
25 #if IS_ENABLED(CONFIG_ARCH_X86)
26 #include <cpu/x86/msr.h>
29 #define HAS_IOSF (IS_ENABLED(CONFIG_SOC_INTEL_BAYTRAIL) || \
30 IS_ENABLED(CONFIG_SOC_INTEL_FSP_BAYTRAIL))
33 #include <soc/iosf.h> /* TODO: wrap in <soc/reg_script.h, remove #ifdef? */
36 #define POLL_DELAY 100 /* 100us */
37 #if defined(__PRE_RAM__)
40 #define EMPTY_DEV NULL
43 static inline void reg_script_set_dev(struct reg_script_context
*ctx
,
50 static inline void reg_script_set_step(struct reg_script_context
*ctx
,
51 const struct reg_script
*step
)
56 static inline const struct reg_script
*
57 reg_script_get_step(struct reg_script_context
*ctx
)
62 static struct resource
*reg_script_get_resource(struct reg_script_context
*ctx
)
64 #if defined(__PRE_RAM__)
68 const struct reg_script
*step
= reg_script_get_step(ctx
);
72 if (res
!= NULL
&& res
->index
== step
->res_index
)
75 res
= find_resource(ctx
->dev
, step
->res_index
);
81 static uint32_t reg_script_read_pci(struct reg_script_context
*ctx
)
83 const struct reg_script
*step
= reg_script_get_step(ctx
);
86 case REG_SCRIPT_SIZE_8
:
87 return pci_read_config8(ctx
->dev
, step
->reg
);
88 case REG_SCRIPT_SIZE_16
:
89 return pci_read_config16(ctx
->dev
, step
->reg
);
90 case REG_SCRIPT_SIZE_32
:
91 return pci_read_config32(ctx
->dev
, step
->reg
);
96 static void reg_script_write_pci(struct reg_script_context
*ctx
)
98 const struct reg_script
*step
= reg_script_get_step(ctx
);
100 switch (step
->size
) {
101 case REG_SCRIPT_SIZE_8
:
102 pci_write_config8(ctx
->dev
, step
->reg
, step
->value
);
104 case REG_SCRIPT_SIZE_16
:
105 pci_write_config16(ctx
->dev
, step
->reg
, step
->value
);
107 case REG_SCRIPT_SIZE_32
:
108 pci_write_config32(ctx
->dev
, step
->reg
, step
->value
);
113 static uint32_t reg_script_read_io(struct reg_script_context
*ctx
)
115 const struct reg_script
*step
= reg_script_get_step(ctx
);
117 switch (step
->size
) {
118 case REG_SCRIPT_SIZE_8
:
119 return inb(step
->reg
);
120 case REG_SCRIPT_SIZE_16
:
121 return inw(step
->reg
);
122 case REG_SCRIPT_SIZE_32
:
123 return inl(step
->reg
);
128 static void reg_script_write_io(struct reg_script_context
*ctx
)
130 const struct reg_script
*step
= reg_script_get_step(ctx
);
132 switch (step
->size
) {
133 case REG_SCRIPT_SIZE_8
:
134 outb(step
->value
, step
->reg
);
136 case REG_SCRIPT_SIZE_16
:
137 outw(step
->value
, step
->reg
);
139 case REG_SCRIPT_SIZE_32
:
140 outl(step
->value
, step
->reg
);
145 static uint32_t reg_script_read_mmio(struct reg_script_context
*ctx
)
147 const struct reg_script
*step
= reg_script_get_step(ctx
);
149 switch (step
->size
) {
150 case REG_SCRIPT_SIZE_8
:
151 return read8((u8
*)step
->reg
);
152 case REG_SCRIPT_SIZE_16
:
153 return read16((u16
*)step
->reg
);
154 case REG_SCRIPT_SIZE_32
:
155 return read32((u32
*)step
->reg
);
160 static void reg_script_write_mmio(struct reg_script_context
*ctx
)
162 const struct reg_script
*step
= reg_script_get_step(ctx
);
164 switch (step
->size
) {
165 case REG_SCRIPT_SIZE_8
:
166 write8((u8
*)step
->reg
, step
->value
);
168 case REG_SCRIPT_SIZE_16
:
169 write16((u16
*)step
->reg
, step
->value
);
171 case REG_SCRIPT_SIZE_32
:
172 write32((u32
*)step
->reg
, step
->value
);
177 static uint32_t reg_script_read_res(struct reg_script_context
*ctx
)
179 struct resource
*res
;
181 const struct reg_script
*step
= reg_script_get_step(ctx
);
183 res
= reg_script_get_resource(ctx
);
188 if (res
->flags
& IORESOURCE_IO
) {
189 const struct reg_script io_step
= {
191 .reg
= res
->base
+ step
->reg
,
193 reg_script_set_step(ctx
, &io_step
);
194 val
= reg_script_read_io(ctx
);
195 } else if (res
->flags
& IORESOURCE_MEM
) {
196 const struct reg_script mmio_step
= {
198 .reg
= res
->base
+ step
->reg
,
200 reg_script_set_step(ctx
, &mmio_step
);
201 val
= reg_script_read_mmio(ctx
);
203 reg_script_set_step(ctx
, step
);
207 static void reg_script_write_res(struct reg_script_context
*ctx
)
209 struct resource
*res
;
210 const struct reg_script
*step
= reg_script_get_step(ctx
);
212 res
= reg_script_get_resource(ctx
);
217 if (res
->flags
& IORESOURCE_IO
) {
218 const struct reg_script io_step
= {
220 .reg
= res
->base
+ step
->reg
,
221 .value
= step
->value
,
223 reg_script_set_step(ctx
, &io_step
);
224 reg_script_write_io(ctx
);
225 } else if (res
->flags
& IORESOURCE_MEM
) {
226 const struct reg_script mmio_step
= {
228 .reg
= res
->base
+ step
->reg
,
229 .value
= step
->value
,
231 reg_script_set_step(ctx
, &mmio_step
);
232 reg_script_write_mmio(ctx
);
234 reg_script_set_step(ctx
, step
);
238 static uint32_t reg_script_read_iosf(struct reg_script_context
*ctx
)
240 const struct reg_script
*step
= reg_script_get_step(ctx
);
243 case IOSF_PORT_AUNIT
:
244 return iosf_aunit_read(step
->reg
);
245 case IOSF_PORT_CPU_BUS
:
246 return iosf_cpu_bus_read(step
->reg
);
247 case IOSF_PORT_BUNIT
:
248 return iosf_bunit_read(step
->reg
);
249 case IOSF_PORT_DUNIT_CH0
:
250 return iosf_dunit_ch0_read(step
->reg
);
252 return iosf_punit_read(step
->reg
);
253 case IOSF_PORT_USBPHY
:
254 return iosf_usbphy_read(step
->reg
);
256 return iosf_sec_read(step
->reg
);
258 return iosf_port45_read(step
->reg
);
260 return iosf_port46_read(step
->reg
);
262 return iosf_port47_read(step
->reg
);
263 case IOSF_PORT_SCORE
:
264 return iosf_score_read(step
->reg
);
266 return iosf_port55_read(step
->reg
);
268 return iosf_port58_read(step
->reg
);
270 return iosf_port59_read(step
->reg
);
272 return iosf_port5a_read(step
->reg
);
273 case IOSF_PORT_USHPHY
:
274 return iosf_ushphy_read(step
->reg
);
276 return iosf_scc_read(step
->reg
);
278 return iosf_lpss_read(step
->reg
);
280 return iosf_porta2_read(step
->reg
);
282 return iosf_ccu_read(step
->reg
);
284 return iosf_ssus_read(step
->reg
);
286 printk(BIOS_DEBUG
, "No read support for IOSF port 0x%x.\n",
293 static void reg_script_write_iosf(struct reg_script_context
*ctx
)
295 const struct reg_script
*step
= reg_script_get_step(ctx
);
298 case IOSF_PORT_AUNIT
:
299 iosf_aunit_write(step
->reg
, step
->value
);
301 case IOSF_PORT_CPU_BUS
:
302 iosf_cpu_bus_write(step
->reg
, step
->value
);
304 case IOSF_PORT_BUNIT
:
305 iosf_bunit_write(step
->reg
, step
->value
);
307 case IOSF_PORT_DUNIT_CH0
:
308 iosf_dunit_write(step
->reg
, step
->value
);
311 iosf_punit_write(step
->reg
, step
->value
);
313 case IOSF_PORT_USBPHY
:
314 iosf_usbphy_write(step
->reg
, step
->value
);
317 iosf_sec_write(step
->reg
, step
->value
);
320 iosf_port45_write(step
->reg
, step
->value
);
323 iosf_port46_write(step
->reg
, step
->value
);
326 iosf_port47_write(step
->reg
, step
->value
);
328 case IOSF_PORT_SCORE
:
329 iosf_score_write(step
->reg
, step
->value
);
332 iosf_port55_write(step
->reg
, step
->value
);
335 iosf_port58_write(step
->reg
, step
->value
);
338 iosf_port59_write(step
->reg
, step
->value
);
341 iosf_port5a_write(step
->reg
, step
->value
);
343 case IOSF_PORT_USHPHY
:
344 iosf_ushphy_write(step
->reg
, step
->value
);
347 iosf_scc_write(step
->reg
, step
->value
);
350 iosf_lpss_write(step
->reg
, step
->value
);
353 iosf_porta2_write(step
->reg
, step
->value
);
356 iosf_ccu_write(step
->reg
, step
->value
);
359 iosf_ssus_write(step
->reg
, step
->value
);
362 printk(BIOS_DEBUG
, "No write support for IOSF port 0x%x.\n",
367 #endif /* HAS_IOSF */
370 static uint64_t reg_script_read_msr(struct reg_script_context
*ctx
)
372 #if IS_ENABLED(CONFIG_ARCH_X86)
373 const struct reg_script
*step
= reg_script_get_step(ctx
);
374 msr_t msr
= rdmsr(step
->reg
);
375 uint64_t value
= msr
.hi
;
383 static void reg_script_write_msr(struct reg_script_context
*ctx
)
385 #if IS_ENABLED(CONFIG_ARCH_X86)
386 const struct reg_script
*step
= reg_script_get_step(ctx
);
388 msr
.hi
= step
->value
>> 32;
389 msr
.lo
= step
->value
& 0xffffffff;
390 wrmsr(step
->reg
, msr
);
394 /* Locate the structure containing the platform specific bus access routines */
395 static const struct reg_script_bus_entry
396 *find_bus(const struct reg_script
*step
)
398 extern const struct reg_script_bus_entry
*_rsbe_init_begin
[];
399 extern const struct reg_script_bus_entry
*_ersbe_init_begin
[];
400 const struct reg_script_bus_entry
* const *bus
;
401 size_t table_entries
;
404 /* Locate the platform specific bus */
405 bus
= _rsbe_init_begin
;
406 table_entries
= &_ersbe_init_begin
[0] - &_rsbe_init_begin
[0];
407 for (i
= 0; i
< table_entries
; i
++) {
408 if (bus
[i
]->type
== step
->type
)
416 static void reg_script_display(struct reg_script_context
*ctx
,
417 const struct reg_script
*step
, const char *arrow
, uint64_t value
)
419 /* Display the register address and data */
420 if (ctx
->display_prefix
!= NULL
)
421 printk(BIOS_INFO
, "%s: ", ctx
->display_prefix
);
422 if (ctx
->display_features
& REG_SCRIPT_DISPLAY_REGISTER
)
423 printk(BIOS_INFO
, "0x%08x %s ", step
->reg
, arrow
);
424 if (ctx
->display_features
& REG_SCRIPT_DISPLAY_VALUE
)
425 switch (step
->size
) {
426 case REG_SCRIPT_SIZE_8
:
427 printk(BIOS_INFO
, "0x%02x\n", (uint8_t)value
);
429 case REG_SCRIPT_SIZE_16
:
430 printk(BIOS_INFO
, "0x%04x\n", (int16_t)value
);
432 case REG_SCRIPT_SIZE_32
:
433 printk(BIOS_INFO
, "0x%08x\n", (uint32_t)value
);
436 printk(BIOS_INFO
, "0x%016llx\n", value
);
441 static uint64_t reg_script_read(struct reg_script_context
*ctx
)
443 const struct reg_script
*step
= reg_script_get_step(ctx
);
446 switch (step
->type
) {
447 case REG_SCRIPT_TYPE_PCI
:
448 ctx
->display_prefix
= "PCI";
449 value
= reg_script_read_pci(ctx
);
451 case REG_SCRIPT_TYPE_IO
:
452 ctx
->display_prefix
= "IO";
453 value
= reg_script_read_io(ctx
);
455 case REG_SCRIPT_TYPE_MMIO
:
456 ctx
->display_prefix
= "MMIO";
457 value
= reg_script_read_mmio(ctx
);
459 case REG_SCRIPT_TYPE_RES
:
460 ctx
->display_prefix
= "RES";
461 value
= reg_script_read_res(ctx
);
463 case REG_SCRIPT_TYPE_MSR
:
464 ctx
->display_prefix
= "MSR";
465 value
= reg_script_read_msr(ctx
);
468 case REG_SCRIPT_TYPE_IOSF
:
469 ctx
->display_prefix
= "IOSF";
470 value
= reg_script_read_iosf(ctx
);
472 #endif /* HAS_IOSF */
475 const struct reg_script_bus_entry
*bus
;
477 /* Read from the platform specific bus */
478 bus
= find_bus(step
);
480 value
= bus
->reg_script_read(ctx
);
485 "Unsupported read type (0x%x) for this device!\n",
490 /* Display the register address and data */
491 if (ctx
->display_features
)
492 reg_script_display(ctx
, step
, "-->", value
);
496 static void reg_script_write(struct reg_script_context
*ctx
)
498 const struct reg_script
*step
= reg_script_get_step(ctx
);
500 switch (step
->type
) {
501 case REG_SCRIPT_TYPE_PCI
:
502 ctx
->display_prefix
= "PCI";
503 reg_script_write_pci(ctx
);
505 case REG_SCRIPT_TYPE_IO
:
506 ctx
->display_prefix
= "IO";
507 reg_script_write_io(ctx
);
509 case REG_SCRIPT_TYPE_MMIO
:
510 ctx
->display_prefix
= "MMIO";
511 reg_script_write_mmio(ctx
);
513 case REG_SCRIPT_TYPE_RES
:
514 ctx
->display_prefix
= "RES";
515 reg_script_write_res(ctx
);
517 case REG_SCRIPT_TYPE_MSR
:
518 ctx
->display_prefix
= "MSR";
519 reg_script_write_msr(ctx
);
522 case REG_SCRIPT_TYPE_IOSF
:
523 ctx
->display_prefix
= "IOSF";
524 reg_script_write_iosf(ctx
);
526 #endif /* HAS_IOSF */
529 const struct reg_script_bus_entry
*bus
;
531 /* Write to the platform specific bus */
532 bus
= find_bus(step
);
534 bus
->reg_script_write(ctx
);
539 "Unsupported write type (0x%x) for this device!\n",
544 /* Display the register address and data */
545 if (ctx
->display_features
)
546 reg_script_display(ctx
, step
, "<--", step
->value
);
549 static void reg_script_rmw(struct reg_script_context
*ctx
)
552 const struct reg_script
*step
= reg_script_get_step(ctx
);
553 struct reg_script write_step
= *step
;
555 value
= reg_script_read(ctx
);
557 value
|= step
->value
;
558 write_step
.value
= value
;
559 reg_script_set_step(ctx
, &write_step
);
560 reg_script_write(ctx
);
561 reg_script_set_step(ctx
, step
);
564 static void reg_script_rxw(struct reg_script_context
*ctx
)
567 const struct reg_script
*step
= reg_script_get_step(ctx
);
568 struct reg_script write_step
= *step
;
578 * Supported operations
580 * Input Mask Temp XOR Value Operation
581 * 0 0 0 0 0 Clear bit
585 * 0 1 0 0 0 Preserve bit
587 * 0 1 0 1 1 Toggle bit
590 value
= reg_script_read(ctx
);
592 value
^= step
->value
;
593 write_step
.value
= value
;
594 reg_script_set_step(ctx
, &write_step
);
595 reg_script_write(ctx
);
596 reg_script_set_step(ctx
, step
);
599 /* In order to easily chain scripts together handle the REG_SCRIPT_COMMAND_NEXT
600 * as recursive call with a new context that has the same dev and resource
601 * as the previous one. That will run to completion and then move on to the
602 * next step of the previous context. */
603 static void reg_script_run_next(struct reg_script_context
*ctx
,
604 const struct reg_script
*step
);
607 static void reg_script_run_step(struct reg_script_context
*ctx
,
608 const struct reg_script
*step
)
610 uint64_t value
= 0, try;
612 ctx
->display_features
= ctx
->display_state
;
613 ctx
->display_prefix
= NULL
;
614 switch (step
->command
) {
615 case REG_SCRIPT_COMMAND_READ
:
616 (void)reg_script_read(ctx
);
618 case REG_SCRIPT_COMMAND_WRITE
:
619 reg_script_write(ctx
);
621 case REG_SCRIPT_COMMAND_RMW
:
624 case REG_SCRIPT_COMMAND_RXW
:
627 case REG_SCRIPT_COMMAND_POLL
:
628 for (try = 0; try < step
->timeout
; try += POLL_DELAY
) {
629 value
= reg_script_read(ctx
) & step
->mask
;
630 if (value
== step
->value
)
634 if (try >= step
->timeout
)
635 printk(BIOS_WARNING
, "%s: POLL timeout waiting for "
636 "0x%x to be 0x%lx, got 0x%lx\n", __func__
,
637 step
->reg
, (unsigned long)step
->value
,
638 (unsigned long)value
);
640 case REG_SCRIPT_COMMAND_SET_DEV
:
641 reg_script_set_dev(ctx
, step
->dev
);
643 case REG_SCRIPT_COMMAND_NEXT
:
644 reg_script_run_next(ctx
, step
->next
);
646 case REG_SCRIPT_COMMAND_DISPLAY
:
647 ctx
->display_state
= step
->value
;
651 printk(BIOS_WARNING
, "Invalid command: %08x\n",
657 static void reg_script_run_with_context(struct reg_script_context
*ctx
)
660 const struct reg_script
*step
= reg_script_get_step(ctx
);
662 if (step
->command
== REG_SCRIPT_COMMAND_END
)
665 reg_script_run_step(ctx
, step
);
666 reg_script_set_step(ctx
, step
+ 1);
670 static void reg_script_run_next(struct reg_script_context
*prev_ctx
,
671 const struct reg_script
*step
)
673 struct reg_script_context ctx
;
675 /* Use prev context as a basis but start at a new step. */
677 reg_script_set_step(&ctx
, step
);
678 reg_script_run_with_context(&ctx
);
681 void reg_script_run_on_dev(device_t dev
, const struct reg_script
*step
)
683 struct reg_script_context ctx
;
685 ctx
.display_state
= REG_SCRIPT_DISPLAY_NOTHING
;
686 reg_script_set_dev(&ctx
, dev
);
687 reg_script_set_step(&ctx
, step
);
688 reg_script_run_with_context(&ctx
);
691 void reg_script_run(const struct reg_script
*step
)
693 reg_script_run_on_dev(EMPTY_DEV
, step
);