Rename __attribute__((packed)) --> __packed
[coreboot.git] / src / lib / reg_script.c
blob56285f1ce18c3ccc356f38d5f45b9ddab2a83bbb
1 /*
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.
16 #include <arch/io.h>
17 #include <console/console.h>
18 #include <delay.h>
19 #include <device/device.h>
20 #include <device/resource.h>
21 #include <device/pci.h>
22 #include <stdint.h>
23 #include <reg_script.h>
25 #if IS_ENABLED(CONFIG_ARCH_X86)
26 #include <cpu/x86/msr.h>
27 #endif
29 #define HAS_IOSF (IS_ENABLED(CONFIG_SOC_INTEL_BAYTRAIL) || \
30 IS_ENABLED(CONFIG_SOC_INTEL_FSP_BAYTRAIL))
32 #if HAS_IOSF
33 #include <soc/iosf.h> /* TODO: wrap in <soc/reg_script.h, remove #ifdef? */
34 #endif
36 #define POLL_DELAY 100 /* 100us */
37 #if defined(__PRE_RAM__)
38 #define EMPTY_DEV 0
39 #else
40 #define EMPTY_DEV NULL
41 #endif
43 static inline void reg_script_set_dev(struct reg_script_context *ctx,
44 device_t dev)
46 ctx->dev = dev;
47 ctx->res = NULL;
50 static inline void reg_script_set_step(struct reg_script_context *ctx,
51 const struct reg_script *step)
53 ctx->step = step;
56 static inline const struct reg_script *
57 reg_script_get_step(struct reg_script_context *ctx)
59 return ctx->step;
62 static struct resource *reg_script_get_resource(struct reg_script_context *ctx)
64 #if defined(__PRE_RAM__)
65 return NULL;
66 #else
67 struct resource *res;
68 const struct reg_script *step = reg_script_get_step(ctx);
70 res = ctx->res;
72 if (res != NULL && res->index == step->res_index)
73 return res;
75 res = find_resource(ctx->dev, step->res_index);
76 ctx->res = res;
77 return res;
78 #endif
81 static uint32_t reg_script_read_pci(struct reg_script_context *ctx)
83 const struct reg_script *step = reg_script_get_step(ctx);
85 switch (step->size) {
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);
93 return 0;
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);
103 break;
104 case REG_SCRIPT_SIZE_16:
105 pci_write_config16(ctx->dev, step->reg, step->value);
106 break;
107 case REG_SCRIPT_SIZE_32:
108 pci_write_config32(ctx->dev, step->reg, step->value);
109 break;
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);
125 return 0;
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);
135 break;
136 case REG_SCRIPT_SIZE_16:
137 outw(step->value, step->reg);
138 break;
139 case REG_SCRIPT_SIZE_32:
140 outl(step->value, step->reg);
141 break;
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);
157 return 0;
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);
167 break;
168 case REG_SCRIPT_SIZE_16:
169 write16((u16 *)step->reg, step->value);
170 break;
171 case REG_SCRIPT_SIZE_32:
172 write32((u32 *)step->reg, step->value);
173 break;
177 static uint32_t reg_script_read_res(struct reg_script_context *ctx)
179 struct resource *res;
180 uint32_t val = 0;
181 const struct reg_script *step = reg_script_get_step(ctx);
183 res = reg_script_get_resource(ctx);
185 if (res == NULL)
186 return val;
188 if (res->flags & IORESOURCE_IO) {
189 const struct reg_script io_step = {
190 .size = step->size,
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 = {
197 .size = step->size,
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);
204 return val;
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);
214 if (res == NULL)
215 return;
217 if (res->flags & IORESOURCE_IO) {
218 const struct reg_script io_step = {
219 .size = step->size,
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 = {
227 .size = step->size,
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);
237 #if HAS_IOSF
238 static uint32_t reg_script_read_iosf(struct reg_script_context *ctx)
240 const struct reg_script *step = reg_script_get_step(ctx);
242 switch (step->id) {
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);
251 case IOSF_PORT_PMC:
252 return iosf_punit_read(step->reg);
253 case IOSF_PORT_USBPHY:
254 return iosf_usbphy_read(step->reg);
255 case IOSF_PORT_SEC:
256 return iosf_sec_read(step->reg);
257 case IOSF_PORT_0x45:
258 return iosf_port45_read(step->reg);
259 case IOSF_PORT_0x46:
260 return iosf_port46_read(step->reg);
261 case IOSF_PORT_0x47:
262 return iosf_port47_read(step->reg);
263 case IOSF_PORT_SCORE:
264 return iosf_score_read(step->reg);
265 case IOSF_PORT_0x55:
266 return iosf_port55_read(step->reg);
267 case IOSF_PORT_0x58:
268 return iosf_port58_read(step->reg);
269 case IOSF_PORT_0x59:
270 return iosf_port59_read(step->reg);
271 case IOSF_PORT_0x5a:
272 return iosf_port5a_read(step->reg);
273 case IOSF_PORT_USHPHY:
274 return iosf_ushphy_read(step->reg);
275 case IOSF_PORT_SCC:
276 return iosf_scc_read(step->reg);
277 case IOSF_PORT_LPSS:
278 return iosf_lpss_read(step->reg);
279 case IOSF_PORT_0xa2:
280 return iosf_porta2_read(step->reg);
281 case IOSF_PORT_CCU:
282 return iosf_ccu_read(step->reg);
283 case IOSF_PORT_SSUS:
284 return iosf_ssus_read(step->reg);
285 default:
286 printk(BIOS_DEBUG, "No read support for IOSF port 0x%x.\n",
287 step->id);
288 break;
290 return 0;
293 static void reg_script_write_iosf(struct reg_script_context *ctx)
295 const struct reg_script *step = reg_script_get_step(ctx);
297 switch (step->id) {
298 case IOSF_PORT_AUNIT:
299 iosf_aunit_write(step->reg, step->value);
300 break;
301 case IOSF_PORT_CPU_BUS:
302 iosf_cpu_bus_write(step->reg, step->value);
303 break;
304 case IOSF_PORT_BUNIT:
305 iosf_bunit_write(step->reg, step->value);
306 break;
307 case IOSF_PORT_DUNIT_CH0:
308 iosf_dunit_write(step->reg, step->value);
309 break;
310 case IOSF_PORT_PMC:
311 iosf_punit_write(step->reg, step->value);
312 break;
313 case IOSF_PORT_USBPHY:
314 iosf_usbphy_write(step->reg, step->value);
315 break;
316 case IOSF_PORT_SEC:
317 iosf_sec_write(step->reg, step->value);
318 break;
319 case IOSF_PORT_0x45:
320 iosf_port45_write(step->reg, step->value);
321 break;
322 case IOSF_PORT_0x46:
323 iosf_port46_write(step->reg, step->value);
324 break;
325 case IOSF_PORT_0x47:
326 iosf_port47_write(step->reg, step->value);
327 break;
328 case IOSF_PORT_SCORE:
329 iosf_score_write(step->reg, step->value);
330 break;
331 case IOSF_PORT_0x55:
332 iosf_port55_write(step->reg, step->value);
333 break;
334 case IOSF_PORT_0x58:
335 iosf_port58_write(step->reg, step->value);
336 break;
337 case IOSF_PORT_0x59:
338 iosf_port59_write(step->reg, step->value);
339 break;
340 case IOSF_PORT_0x5a:
341 iosf_port5a_write(step->reg, step->value);
342 break;
343 case IOSF_PORT_USHPHY:
344 iosf_ushphy_write(step->reg, step->value);
345 break;
346 case IOSF_PORT_SCC:
347 iosf_scc_write(step->reg, step->value);
348 break;
349 case IOSF_PORT_LPSS:
350 iosf_lpss_write(step->reg, step->value);
351 break;
352 case IOSF_PORT_0xa2:
353 iosf_porta2_write(step->reg, step->value);
354 break;
355 case IOSF_PORT_CCU:
356 iosf_ccu_write(step->reg, step->value);
357 break;
358 case IOSF_PORT_SSUS:
359 iosf_ssus_write(step->reg, step->value);
360 break;
361 default:
362 printk(BIOS_DEBUG, "No write support for IOSF port 0x%x.\n",
363 step->id);
364 break;
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;
376 value = msr.hi;
377 value <<= 32;
378 value |= msr.lo;
379 return value;
380 #endif
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);
387 msr_t msr;
388 msr.hi = step->value >> 32;
389 msr.lo = step->value & 0xffffffff;
390 wrmsr(step->reg, msr);
391 #endif
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;
402 size_t i;
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)
409 return bus[i];
412 /* Bus not found */
413 return NULL;
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);
428 break;
429 case REG_SCRIPT_SIZE_16:
430 printk(BIOS_INFO, "0x%04x\n", (int16_t)value);
431 break;
432 case REG_SCRIPT_SIZE_32:
433 printk(BIOS_INFO, "0x%08x\n", (uint32_t)value);
434 break;
435 default:
436 printk(BIOS_INFO, "0x%016llx\n", value);
437 break;
441 static uint64_t reg_script_read(struct reg_script_context *ctx)
443 const struct reg_script *step = reg_script_get_step(ctx);
444 uint64_t value = 0;
446 switch (step->type) {
447 case REG_SCRIPT_TYPE_PCI:
448 ctx->display_prefix = "PCI";
449 value = reg_script_read_pci(ctx);
450 break;
451 case REG_SCRIPT_TYPE_IO:
452 ctx->display_prefix = "IO";
453 value = reg_script_read_io(ctx);
454 break;
455 case REG_SCRIPT_TYPE_MMIO:
456 ctx->display_prefix = "MMIO";
457 value = reg_script_read_mmio(ctx);
458 break;
459 case REG_SCRIPT_TYPE_RES:
460 ctx->display_prefix = "RES";
461 value = reg_script_read_res(ctx);
462 break;
463 case REG_SCRIPT_TYPE_MSR:
464 ctx->display_prefix = "MSR";
465 value = reg_script_read_msr(ctx);
466 break;
467 #if HAS_IOSF
468 case REG_SCRIPT_TYPE_IOSF:
469 ctx->display_prefix = "IOSF";
470 value = reg_script_read_iosf(ctx);
471 break;
472 #endif /* HAS_IOSF */
473 default:
475 const struct reg_script_bus_entry *bus;
477 /* Read from the platform specific bus */
478 bus = find_bus(step);
479 if (bus != NULL) {
480 value = bus->reg_script_read(ctx);
481 break;
484 printk(BIOS_ERR,
485 "Unsupported read type (0x%x) for this device!\n",
486 step->type);
487 return 0;
490 /* Display the register address and data */
491 if (ctx->display_features)
492 reg_script_display(ctx, step, "-->", value);
493 return 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);
504 break;
505 case REG_SCRIPT_TYPE_IO:
506 ctx->display_prefix = "IO";
507 reg_script_write_io(ctx);
508 break;
509 case REG_SCRIPT_TYPE_MMIO:
510 ctx->display_prefix = "MMIO";
511 reg_script_write_mmio(ctx);
512 break;
513 case REG_SCRIPT_TYPE_RES:
514 ctx->display_prefix = "RES";
515 reg_script_write_res(ctx);
516 break;
517 case REG_SCRIPT_TYPE_MSR:
518 ctx->display_prefix = "MSR";
519 reg_script_write_msr(ctx);
520 break;
521 #if HAS_IOSF
522 case REG_SCRIPT_TYPE_IOSF:
523 ctx->display_prefix = "IOSF";
524 reg_script_write_iosf(ctx);
525 break;
526 #endif /* HAS_IOSF */
527 default:
529 const struct reg_script_bus_entry *bus;
531 /* Write to the platform specific bus */
532 bus = find_bus(step);
533 if (bus != NULL) {
534 bus->reg_script_write(ctx);
535 break;
538 printk(BIOS_ERR,
539 "Unsupported write type (0x%x) for this device!\n",
540 step->type);
541 return;
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)
551 uint64_t value;
552 const struct reg_script *step = reg_script_get_step(ctx);
553 struct reg_script write_step = *step;
555 value = reg_script_read(ctx);
556 value &= step->mask;
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)
566 uint64_t value;
567 const struct reg_script *step = reg_script_get_step(ctx);
568 struct reg_script write_step = *step;
571 * XOR logic table
572 * Input XOR Value
573 * 0 0 0
574 * 0 1 1
575 * 1 0 1
576 * 1 1 0
578 * Supported operations
580 * Input Mask Temp XOR Value Operation
581 * 0 0 0 0 0 Clear bit
582 * 1 0 0 0 0
583 * 0 0 0 1 1 Set bit
584 * 1 0 0 1 1
585 * 0 1 0 0 0 Preserve bit
586 * 1 1 1 0 1
587 * 0 1 0 1 1 Toggle bit
588 * 1 1 1 1 0
590 value = reg_script_read(ctx);
591 value &= step->mask;
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);
617 break;
618 case REG_SCRIPT_COMMAND_WRITE:
619 reg_script_write(ctx);
620 break;
621 case REG_SCRIPT_COMMAND_RMW:
622 reg_script_rmw(ctx);
623 break;
624 case REG_SCRIPT_COMMAND_RXW:
625 reg_script_rxw(ctx);
626 break;
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)
631 break;
632 udelay(POLL_DELAY);
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);
639 break;
640 case REG_SCRIPT_COMMAND_SET_DEV:
641 reg_script_set_dev(ctx, step->dev);
642 break;
643 case REG_SCRIPT_COMMAND_NEXT:
644 reg_script_run_next(ctx, step->next);
645 break;
646 case REG_SCRIPT_COMMAND_DISPLAY:
647 ctx->display_state = step->value;
648 break;
650 default:
651 printk(BIOS_WARNING, "Invalid command: %08x\n",
652 step->command);
653 break;
657 static void reg_script_run_with_context(struct reg_script_context *ctx)
659 while (1) {
660 const struct reg_script *step = reg_script_get_step(ctx);
662 if (step->command == REG_SCRIPT_COMMAND_END)
663 break;
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. */
676 ctx = *prev_ctx;
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);