root/arch/powerpc/boot/opal.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. opal_con_open
  2. opal_con_putc
  3. opal_con_close
  4. opal_init
  5. opal_console_init

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Copyright (c) 2016 IBM Corporation.
   4  */
   5 
   6 #include "ops.h"
   7 #include "stdio.h"
   8 #include "io.h"
   9 #include <libfdt.h>
  10 #include "../include/asm/opal-api.h"
  11 
  12 /* Global OPAL struct used by opal-call.S */
  13 struct opal {
  14         u64 base;
  15         u64 entry;
  16 } opal;
  17 
  18 static u32 opal_con_id;
  19 
  20 /* see opal-wrappers.S */
  21 int64_t opal_console_write(int64_t term_number, u64 *length, const u8 *buffer);
  22 int64_t opal_console_read(int64_t term_number, uint64_t *length, u8 *buffer);
  23 int64_t opal_console_write_buffer_space(uint64_t term_number, uint64_t *length);
  24 int64_t opal_console_flush(uint64_t term_number);
  25 int64_t opal_poll_events(uint64_t *outstanding_event_mask);
  26 
  27 void opal_kentry(unsigned long fdt_addr, void *vmlinux_addr);
  28 
  29 static int opal_con_open(void)
  30 {
  31         /*
  32          * When OPAL loads the boot kernel it stashes the OPAL base and entry
  33          * address in r8 and r9 so the kernel can use the OPAL console
  34          * before unflattening the devicetree. While executing the wrapper will
  35          * probably trash r8 and r9 so this kentry hook restores them before
  36          * entering the decompressed kernel.
  37          */
  38         platform_ops.kentry = opal_kentry;
  39         return 0;
  40 }
  41 
  42 static void opal_con_putc(unsigned char c)
  43 {
  44         int64_t rc;
  45         uint64_t olen, len;
  46 
  47         do {
  48                 rc = opal_console_write_buffer_space(opal_con_id, &olen);
  49                 len = be64_to_cpu(olen);
  50                 if (rc)
  51                         return;
  52                 opal_poll_events(NULL);
  53         } while (len < 1);
  54 
  55 
  56         olen = cpu_to_be64(1);
  57         opal_console_write(opal_con_id, &olen, &c);
  58 }
  59 
  60 static void opal_con_close(void)
  61 {
  62         opal_console_flush(opal_con_id);
  63 }
  64 
  65 static void opal_init(void)
  66 {
  67         void *opal_node;
  68 
  69         opal_node = finddevice("/ibm,opal");
  70         if (!opal_node)
  71                 return;
  72         if (getprop(opal_node, "opal-base-address", &opal.base, sizeof(u64)) < 0)
  73                 return;
  74         opal.base = be64_to_cpu(opal.base);
  75         if (getprop(opal_node, "opal-entry-address", &opal.entry, sizeof(u64)) < 0)
  76                 return;
  77         opal.entry = be64_to_cpu(opal.entry);
  78 }
  79 
  80 int opal_console_init(void *devp, struct serial_console_data *scdp)
  81 {
  82         opal_init();
  83 
  84         if (devp) {
  85                 int n = getprop(devp, "reg", &opal_con_id, sizeof(u32));
  86                 if (n != sizeof(u32))
  87                         return -1;
  88                 opal_con_id = be32_to_cpu(opal_con_id);
  89         } else
  90                 opal_con_id = 0;
  91 
  92         scdp->open = opal_con_open;
  93         scdp->putc = opal_con_putc;
  94         scdp->close = opal_con_close;
  95 
  96         return 0;
  97 }

/* [<][>][^][v][top][bottom][index][help] */