blob: 7530dc32b8a53e0587ca26ba8344389fd27c8e6b [file] [log] [blame]
Duncan Laurie72748002013-10-31 08:26:23 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright 2013 Google Inc.
5 *
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.
9 *
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.
Duncan Laurie72748002013-10-31 08:26:23 -070014 */
15
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>
24
Duncan Lauriefd461e32013-11-08 23:00:24 -080025#if CONFIG_ARCH_X86
26#include <cpu/x86/msr.h>
27#endif
28
Werner Zeh9d021532016-02-19 10:02:49 +010029#define HAS_IOSF (IS_ENABLED(CONFIG_SOC_INTEL_BAYTRAIL) || \
30 IS_ENABLED(CONFIG_SOC_INTEL_FSP_BAYTRAIL))
31
32#if HAS_IOSF
Julius Werner18ea2d32014-10-07 16:42:17 -070033#include <soc/iosf.h> /* TODO: wrap in <soc/reg_script.h, remove #ifdef? */
Duncan Laurie72748002013-10-31 08:26:23 -070034#endif
35
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
42
Duncan Laurie72748002013-10-31 08:26:23 -070043static inline void reg_script_set_dev(struct reg_script_context *ctx,
44 device_t dev)
45{
46 ctx->dev = dev;
47 ctx->res = NULL;
48}
49
50static inline void reg_script_set_step(struct reg_script_context *ctx,
51 const struct reg_script *step)
52{
53 ctx->step = step;
54}
55
56static inline const struct reg_script *
57reg_script_get_step(struct reg_script_context *ctx)
58{
59 return ctx->step;
60}
61
62static struct resource *reg_script_get_resource(struct reg_script_context *ctx)
63{
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);
69
70 res = ctx->res;
71
72 if (res != NULL && res->index == step->res_index)
73 return res;
74
75 res = find_resource(ctx->dev, step->res_index);
76 ctx->res = res;
77 return res;
78#endif
79}
80
81static uint32_t reg_script_read_pci(struct reg_script_context *ctx)
82{
83 const struct reg_script *step = reg_script_get_step(ctx);
84
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);
92 }
93 return 0;
94}
95
96static void reg_script_write_pci(struct reg_script_context *ctx)
97{
98 const struct reg_script *step = reg_script_get_step(ctx);
99
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;
110 }
111}
112
113static uint32_t reg_script_read_io(struct reg_script_context *ctx)
114{
115 const struct reg_script *step = reg_script_get_step(ctx);
116
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);
124 }
125 return 0;
126}
127
128static void reg_script_write_io(struct reg_script_context *ctx)
129{
130 const struct reg_script *step = reg_script_get_step(ctx);
131
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;
142 }
143}
144
145static uint32_t reg_script_read_mmio(struct reg_script_context *ctx)
146{
147 const struct reg_script *step = reg_script_get_step(ctx);
148
149 switch (step->size) {
150 case REG_SCRIPT_SIZE_8:
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800151 return read8((u8 *)step->reg);
Duncan Laurie72748002013-10-31 08:26:23 -0700152 case REG_SCRIPT_SIZE_16:
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800153 return read16((u16 *)step->reg);
Duncan Laurie72748002013-10-31 08:26:23 -0700154 case REG_SCRIPT_SIZE_32:
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800155 return read32((u32 *)step->reg);
Duncan Laurie72748002013-10-31 08:26:23 -0700156 }
157 return 0;
158}
159
160static void reg_script_write_mmio(struct reg_script_context *ctx)
161{
162 const struct reg_script *step = reg_script_get_step(ctx);
163
164 switch (step->size) {
165 case REG_SCRIPT_SIZE_8:
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800166 write8((u8 *)step->reg, step->value);
Duncan Laurie72748002013-10-31 08:26:23 -0700167 break;
168 case REG_SCRIPT_SIZE_16:
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800169 write16((u16 *)step->reg, step->value);
Duncan Laurie72748002013-10-31 08:26:23 -0700170 break;
171 case REG_SCRIPT_SIZE_32:
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800172 write32((u32 *)step->reg, step->value);
Duncan Laurie72748002013-10-31 08:26:23 -0700173 break;
174 }
175}
176
177static uint32_t reg_script_read_res(struct reg_script_context *ctx)
178{
179 struct resource *res;
180 uint32_t val = 0;
181 const struct reg_script *step = reg_script_get_step(ctx);
182
183 res = reg_script_get_resource(ctx);
184
185 if (res == NULL)
186 return val;
187
188 if (res->flags & IORESOURCE_IO) {
189 const struct reg_script io_step = {
190 .size = step->size,
191 .reg = res->base + step->reg,
192 };
193 reg_script_set_step(ctx, &io_step);
194 val = reg_script_read_io(ctx);
195 }
196 else if (res->flags & IORESOURCE_MEM) {
197 const struct reg_script mmio_step = {
198 .size = step->size,
199 .reg = res->base + step->reg,
200 };
201 reg_script_set_step(ctx, &mmio_step);
202 val = reg_script_read_mmio(ctx);
203 }
204 reg_script_set_step(ctx, step);
205 return val;
206}
207
208static void reg_script_write_res(struct reg_script_context *ctx)
209{
210 struct resource *res;
211 const struct reg_script *step = reg_script_get_step(ctx);
212
213 res = reg_script_get_resource(ctx);
214
215 if (res == NULL)
216 return;
217
218 if (res->flags & IORESOURCE_IO) {
219 const struct reg_script io_step = {
220 .size = step->size,
221 .reg = res->base + step->reg,
222 .value = step->value,
223 };
224 reg_script_set_step(ctx, &io_step);
225 reg_script_write_io(ctx);
226 }
227 else if (res->flags & IORESOURCE_MEM) {
228 const struct reg_script mmio_step = {
229 .size = step->size,
230 .reg = res->base + step->reg,
231 .value = step->value,
232 };
233 reg_script_set_step(ctx, &mmio_step);
234 reg_script_write_mmio(ctx);
235 }
236 reg_script_set_step(ctx, step);
237}
238
Werner Zeh9d021532016-02-19 10:02:49 +0100239#if HAS_IOSF
Duncan Laurie72748002013-10-31 08:26:23 -0700240static uint32_t reg_script_read_iosf(struct reg_script_context *ctx)
241{
Duncan Laurie72748002013-10-31 08:26:23 -0700242 const struct reg_script *step = reg_script_get_step(ctx);
243
244 switch (step->id) {
Aaron Durbinbc5b5572013-12-11 17:13:10 -0800245 case IOSF_PORT_AUNIT:
246 return iosf_aunit_read(step->reg);
247 case IOSF_PORT_CPU_BUS:
248 return iosf_cpu_bus_read(step->reg);
Duncan Laurie72748002013-10-31 08:26:23 -0700249 case IOSF_PORT_BUNIT:
250 return iosf_bunit_read(step->reg);
251 case IOSF_PORT_DUNIT_CH0:
252 return iosf_dunit_ch0_read(step->reg);
253 case IOSF_PORT_PMC:
254 return iosf_punit_read(step->reg);
255 case IOSF_PORT_USBPHY:
256 return iosf_usbphy_read(step->reg);
Aaron Durbinbc5b5572013-12-11 17:13:10 -0800257 case IOSF_PORT_SEC:
258 return iosf_sec_read(step->reg);
259 case IOSF_PORT_0x45:
260 return iosf_port45_read(step->reg);
261 case IOSF_PORT_0x46:
262 return iosf_port46_read(step->reg);
263 case IOSF_PORT_0x47:
264 return iosf_port47_read(step->reg);
Aaron Durbine8f97d42013-11-12 16:38:54 -0600265 case IOSF_PORT_SCORE:
266 return iosf_score_read(step->reg);
Aaron Durbinbc5b5572013-12-11 17:13:10 -0800267 case IOSF_PORT_0x55:
268 return iosf_port55_read(step->reg);
269 case IOSF_PORT_0x58:
270 return iosf_port58_read(step->reg);
271 case IOSF_PORT_0x59:
272 return iosf_port59_read(step->reg);
273 case IOSF_PORT_0x5a:
274 return iosf_port5a_read(step->reg);
Duncan Laurie72748002013-10-31 08:26:23 -0700275 case IOSF_PORT_USHPHY:
276 return iosf_ushphy_read(step->reg);
Aaron Durbine8f97d42013-11-12 16:38:54 -0600277 case IOSF_PORT_SCC:
278 return iosf_scc_read(step->reg);
Aaron Durbin64b902b2013-11-12 20:20:10 -0600279 case IOSF_PORT_LPSS:
280 return iosf_lpss_read(step->reg);
Aaron Durbinbc5b5572013-12-11 17:13:10 -0800281 case IOSF_PORT_0xa2:
282 return iosf_porta2_read(step->reg);
Aaron Durbine8f97d42013-11-12 16:38:54 -0600283 case IOSF_PORT_CCU:
284 return iosf_ccu_read(step->reg);
Aaron Durbinbc5b5572013-12-11 17:13:10 -0800285 case IOSF_PORT_SSUS:
286 return iosf_ssus_read(step->reg);
287 default:
288 printk(BIOS_DEBUG, "No read support for IOSF port 0x%x.\n",
289 step->id);
290 break;
Duncan Laurie72748002013-10-31 08:26:23 -0700291 }
Duncan Laurie72748002013-10-31 08:26:23 -0700292 return 0;
293}
294
295static void reg_script_write_iosf(struct reg_script_context *ctx)
296{
Duncan Laurie72748002013-10-31 08:26:23 -0700297 const struct reg_script *step = reg_script_get_step(ctx);
298
299 switch (step->id) {
Aaron Durbinbc5b5572013-12-11 17:13:10 -0800300 case IOSF_PORT_AUNIT:
301 iosf_aunit_write(step->reg, step->value);
302 break;
303 case IOSF_PORT_CPU_BUS:
304 iosf_cpu_bus_write(step->reg, step->value);
305 break;
Duncan Laurie72748002013-10-31 08:26:23 -0700306 case IOSF_PORT_BUNIT:
307 iosf_bunit_write(step->reg, step->value);
308 break;
309 case IOSF_PORT_DUNIT_CH0:
310 iosf_dunit_write(step->reg, step->value);
311 break;
312 case IOSF_PORT_PMC:
313 iosf_punit_write(step->reg, step->value);
314 break;
315 case IOSF_PORT_USBPHY:
316 iosf_usbphy_write(step->reg, step->value);
317 break;
Aaron Durbinbc5b5572013-12-11 17:13:10 -0800318 case IOSF_PORT_SEC:
319 iosf_sec_write(step->reg, step->value);
320 break;
321 case IOSF_PORT_0x45:
322 iosf_port45_write(step->reg, step->value);
323 break;
324 case IOSF_PORT_0x46:
325 iosf_port46_write(step->reg, step->value);
326 break;
327 case IOSF_PORT_0x47:
328 iosf_port47_write(step->reg, step->value);
329 break;
Aaron Durbine8f97d42013-11-12 16:38:54 -0600330 case IOSF_PORT_SCORE:
331 iosf_score_write(step->reg, step->value);
332 break;
Aaron Durbinbc5b5572013-12-11 17:13:10 -0800333 case IOSF_PORT_0x55:
334 iosf_port55_write(step->reg, step->value);
335 break;
336 case IOSF_PORT_0x58:
337 iosf_port58_write(step->reg, step->value);
338 break;
339 case IOSF_PORT_0x59:
340 iosf_port59_write(step->reg, step->value);
341 break;
342 case IOSF_PORT_0x5a:
343 iosf_port5a_write(step->reg, step->value);
344 break;
Duncan Laurie72748002013-10-31 08:26:23 -0700345 case IOSF_PORT_USHPHY:
346 iosf_ushphy_write(step->reg, step->value);
347 break;
Aaron Durbine8f97d42013-11-12 16:38:54 -0600348 case IOSF_PORT_SCC:
349 iosf_scc_write(step->reg, step->value);
350 break;
Aaron Durbin64b902b2013-11-12 20:20:10 -0600351 case IOSF_PORT_LPSS:
352 iosf_lpss_write(step->reg, step->value);
353 break;
Aaron Durbinbc5b5572013-12-11 17:13:10 -0800354 case IOSF_PORT_0xa2:
355 iosf_porta2_write(step->reg, step->value);
356 break;
Aaron Durbine8f97d42013-11-12 16:38:54 -0600357 case IOSF_PORT_CCU:
358 iosf_ccu_write(step->reg, step->value);
359 break;
Aaron Durbinbc5b5572013-12-11 17:13:10 -0800360 case IOSF_PORT_SSUS:
361 iosf_ssus_write(step->reg, step->value);
362 break;
363 default:
364 printk(BIOS_DEBUG, "No write support for IOSF port 0x%x.\n",
365 step->id);
366 break;
Duncan Laurie72748002013-10-31 08:26:23 -0700367 }
Duncan Laurie72748002013-10-31 08:26:23 -0700368}
Werner Zeh9d021532016-02-19 10:02:49 +0100369#endif /* HAS_IOSF */
Lee Leahy9f5a5c52014-08-29 13:38:59 -0700370
Duncan Laurie72748002013-10-31 08:26:23 -0700371
Duncan Lauriefd461e32013-11-08 23:00:24 -0800372static uint64_t reg_script_read_msr(struct reg_script_context *ctx)
373{
374#if CONFIG_ARCH_X86
375 const struct reg_script *step = reg_script_get_step(ctx);
376 msr_t msr = rdmsr(step->reg);
377 uint64_t value = msr.hi;
378 value = msr.hi;
379 value <<= 32;
380 value |= msr.lo;
381 return value;
382#endif
383}
384
385static void reg_script_write_msr(struct reg_script_context *ctx)
386{
387#if CONFIG_ARCH_X86
388 const struct reg_script *step = reg_script_get_step(ctx);
389 msr_t msr;
390 msr.hi = step->value >> 32;
391 msr.lo = step->value & 0xffffffff;
392 wrmsr(step->reg, msr);
393#endif
394}
395
Lee Leahy9f5a5c52014-08-29 13:38:59 -0700396#ifndef __PRE_RAM__
397/* Default routine provided for systems without platform specific busses */
398const struct reg_script_bus_entry *__attribute__((weak))
399 platform_bus_table(size_t *table_entries)
400{
401 /* No platform bus type table supplied */
402 *table_entries = 0;
403 return NULL;
404}
405
406/* Locate the structure containing the platform specific bus access routines */
407static const struct reg_script_bus_entry
408 *find_bus(const struct reg_script *step)
409{
410 const struct reg_script_bus_entry *bus;
411 size_t table_entries;
412 size_t i;
413
414 /* Locate the platform specific bus */
415 bus = platform_bus_table(&table_entries);
416 for (i = 0; i < table_entries; i++) {
417 if (bus[i].type == step->type)
418 return &bus[i];
419 }
420
421 /* Bus not found */
422 return NULL;
423}
424#endif
425
Duncan Lauriefd461e32013-11-08 23:00:24 -0800426static uint64_t reg_script_read(struct reg_script_context *ctx)
Duncan Laurie72748002013-10-31 08:26:23 -0700427{
428 const struct reg_script *step = reg_script_get_step(ctx);
429
430 switch (step->type) {
431 case REG_SCRIPT_TYPE_PCI:
432 return reg_script_read_pci(ctx);
433 case REG_SCRIPT_TYPE_IO:
434 return reg_script_read_io(ctx);
435 case REG_SCRIPT_TYPE_MMIO:
436 return reg_script_read_mmio(ctx);
437 case REG_SCRIPT_TYPE_RES:
438 return reg_script_read_res(ctx);
Duncan Lauriefd461e32013-11-08 23:00:24 -0800439 case REG_SCRIPT_TYPE_MSR:
440 return reg_script_read_msr(ctx);
Werner Zeh9d021532016-02-19 10:02:49 +0100441#if HAS_IOSF
Lee Leahy9f5a5c52014-08-29 13:38:59 -0700442 case REG_SCRIPT_TYPE_IOSF:
443 return reg_script_read_iosf(ctx);
Werner Zeh9d021532016-02-19 10:02:49 +0100444#endif /* HAS_IOSF */
Lee Leahy9f5a5c52014-08-29 13:38:59 -0700445 default:
446#ifndef __PRE_RAM__
447 {
448 const struct reg_script_bus_entry *bus;
449
450 /* Read from the platform specific bus */
451 bus = find_bus(step);
452 if (NULL != bus)
453 return bus->reg_script_read(ctx);
454 }
455#endif
456 printk(BIOS_ERR,
457 "Unsupported read type (0x%x) for this device!\n",
458 step->type);
459 break;
Duncan Laurie72748002013-10-31 08:26:23 -0700460 }
461 return 0;
462}
463
464static void reg_script_write(struct reg_script_context *ctx)
465{
466 const struct reg_script *step = reg_script_get_step(ctx);
467
468 switch (step->type) {
469 case REG_SCRIPT_TYPE_PCI:
470 reg_script_write_pci(ctx);
471 break;
472 case REG_SCRIPT_TYPE_IO:
473 reg_script_write_io(ctx);
474 break;
475 case REG_SCRIPT_TYPE_MMIO:
476 reg_script_write_mmio(ctx);
477 break;
478 case REG_SCRIPT_TYPE_RES:
479 reg_script_write_res(ctx);
480 break;
Lee Leahy9f5a5c52014-08-29 13:38:59 -0700481 case REG_SCRIPT_TYPE_MSR:
482 reg_script_write_msr(ctx);
483 break;
Werner Zeh9d021532016-02-19 10:02:49 +0100484#if HAS_IOSF
Duncan Laurie72748002013-10-31 08:26:23 -0700485 case REG_SCRIPT_TYPE_IOSF:
486 reg_script_write_iosf(ctx);
487 break;
Werner Zeh9d021532016-02-19 10:02:49 +0100488#endif /* HAS_IOSF */
Lee Leahy9f5a5c52014-08-29 13:38:59 -0700489 default:
490#ifndef __PRE_RAM__
491 {
492 const struct reg_script_bus_entry *bus;
493
494 /* Write to the platform specific bus */
495 bus = find_bus(step);
496 if (NULL != bus) {
497 bus->reg_script_write(ctx);
498 return;
499 }
500 }
501#endif
502 printk(BIOS_ERR,
503 "Unsupported write type (0x%x) for this device!\n",
504 step->type);
Duncan Lauriefd461e32013-11-08 23:00:24 -0800505 break;
Duncan Laurie72748002013-10-31 08:26:23 -0700506 }
507}
508
509static void reg_script_rmw(struct reg_script_context *ctx)
510{
Duncan Lauriefd461e32013-11-08 23:00:24 -0800511 uint64_t value;
Duncan Laurie72748002013-10-31 08:26:23 -0700512 const struct reg_script *step = reg_script_get_step(ctx);
513 struct reg_script write_step = *step;
514
515 value = reg_script_read(ctx);
516 value &= step->mask;
517 value |= step->value;
518 write_step.value = value;
519 reg_script_set_step(ctx, &write_step);
520 reg_script_write(ctx);
521 reg_script_set_step(ctx, step);
522}
523
Lee Leahy6bcbe572016-04-23 07:58:27 -0700524static void reg_script_rxw(struct reg_script_context *ctx)
525{
526 uint64_t value;
527 const struct reg_script *step = reg_script_get_step(ctx);
528 struct reg_script write_step = *step;
529
530/*
531 * XOR logic table
532 * Input XOR Value
533 * 0 0 0
534 * 0 1 1
535 * 1 0 1
536 * 1 1 0
537 *
538 * Supported operations
539 *
540 * Input Mask Temp XOR Value Operation
541 * 0 0 0 0 0 Clear bit
542 * 1 0 0 0 0
543 * 0 0 0 1 1 Set bit
544 * 1 0 0 1 1
545 * 0 1 0 0 0 Preserve bit
546 * 1 1 1 0 1
547 * 0 1 0 1 1 Toggle bit
548 * 1 1 1 1 0
549 */
550 value = reg_script_read(ctx);
551 value &= step->mask;
552 value ^= step->value;
553 write_step.value = value;
554 reg_script_set_step(ctx, &write_step);
555 reg_script_write(ctx);
556 reg_script_set_step(ctx, step);
557}
558
Duncan Laurie72748002013-10-31 08:26:23 -0700559/* In order to easily chain scripts together handle the REG_SCRIPT_COMMAND_NEXT
560 * as recursive call with a new context that has the same dev and resource
561 * as the previous one. That will run to completion and then move on to the
562 * next step of the previous context. */
563static void reg_script_run_next(struct reg_script_context *ctx,
564 const struct reg_script *step);
565
Duncan Lauriefd461e32013-11-08 23:00:24 -0800566
567static void reg_script_run_step(struct reg_script_context *ctx,
568 const struct reg_script *step)
569{
570 uint64_t value = 0, try;
571
572 switch (step->command) {
573 case REG_SCRIPT_COMMAND_READ:
574 (void)reg_script_read(ctx);
575 break;
576 case REG_SCRIPT_COMMAND_WRITE:
577 reg_script_write(ctx);
578 break;
579 case REG_SCRIPT_COMMAND_RMW:
580 reg_script_rmw(ctx);
581 break;
Lee Leahy6bcbe572016-04-23 07:58:27 -0700582 case REG_SCRIPT_COMMAND_RXW:
583 reg_script_rxw(ctx);
584 break;
Duncan Lauriefd461e32013-11-08 23:00:24 -0800585 case REG_SCRIPT_COMMAND_POLL:
586 for (try = 0; try < step->timeout; try += POLL_DELAY) {
587 value = reg_script_read(ctx) & step->mask;
588 if (value == step->value)
589 break;
590 udelay(POLL_DELAY);
591 }
592 if (try >= step->timeout)
593 printk(BIOS_WARNING, "%s: POLL timeout waiting for "
594 "0x%x to be 0x%lx, got 0x%lx\n", __func__,
595 step->reg, (unsigned long)step->value,
596 (unsigned long)value);
597 break;
598 case REG_SCRIPT_COMMAND_SET_DEV:
599 reg_script_set_dev(ctx, step->dev);
600 break;
601 case REG_SCRIPT_COMMAND_NEXT:
602 reg_script_run_next(ctx, step->next);
603 break;
604 default:
605 printk(BIOS_WARNING, "Invalid command: %08x\n",
606 step->command);
607 break;
608 }
609}
610
Duncan Laurie72748002013-10-31 08:26:23 -0700611static void reg_script_run_with_context(struct reg_script_context *ctx)
612{
Duncan Laurie72748002013-10-31 08:26:23 -0700613 while (1) {
614 const struct reg_script *step = reg_script_get_step(ctx);
615
616 if (step->command == REG_SCRIPT_COMMAND_END)
617 break;
618
Duncan Lauriefd461e32013-11-08 23:00:24 -0800619 reg_script_run_step(ctx, step);
Duncan Laurie72748002013-10-31 08:26:23 -0700620 reg_script_set_step(ctx, step + 1);
621 }
622}
623
624static void reg_script_run_next(struct reg_script_context *prev_ctx,
625 const struct reg_script *step)
626{
627 struct reg_script_context ctx;
628
629 /* Use prev context as a basis but start at a new step. */
630 ctx = *prev_ctx;
631 reg_script_set_step(&ctx, step);
632 reg_script_run_with_context(&ctx);
633}
634
Aaron Durbind86f0b72013-12-10 17:09:40 -0800635void reg_script_run_on_dev(device_t dev, const struct reg_script *step)
Duncan Laurie72748002013-10-31 08:26:23 -0700636{
637 struct reg_script_context ctx;
638
Aaron Durbind86f0b72013-12-10 17:09:40 -0800639 reg_script_set_dev(&ctx, dev);
Duncan Laurie72748002013-10-31 08:26:23 -0700640 reg_script_set_step(&ctx, step);
641 reg_script_run_with_context(&ctx);
642}
Aaron Durbind86f0b72013-12-10 17:09:40 -0800643
644void reg_script_run(const struct reg_script *step)
645{
646 reg_script_run_on_dev(EMPTY_DEV, step);
647}