Path: blob/master/arch/powerpc/platforms/cell/beat_udbg.c
10818 views
/*1* udbg function for Beat2*3* (C) Copyright 2006 TOSHIBA CORPORATION4*5* This program is free software; you can redistribute it and/or modify6* it under the terms of the GNU General Public License as published by7* the Free Software Foundation; either version 2 of the License, or8* (at your option) any later version.9*10* This program is distributed in the hope that it will be useful,11* but WITHOUT ANY WARRANTY; without even the implied warranty of12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13* GNU General Public License for more details.14*15* You should have received a copy of the GNU General Public License along16* with this program; if not, write to the Free Software Foundation, Inc.,17* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.18*/1920#include <linux/kernel.h>21#include <linux/console.h>2223#include <asm/machdep.h>24#include <asm/prom.h>25#include <asm/udbg.h>2627#include "beat.h"2829#define celleb_vtermno 03031static void udbg_putc_beat(char c)32{33unsigned long rc;3435if (c == '\n')36udbg_putc_beat('\r');3738rc = beat_put_term_char(celleb_vtermno, 1, (uint64_t)c << 56, 0);39}4041/* Buffered chars getc */42static u64 inbuflen;43static u64 inbuf[2]; /* must be 2 u64s */4445static int udbg_getc_poll_beat(void)46{47/* The interface is tricky because it may return up to 16 chars.48* We save them statically for future calls to udbg_getc().49*/50char ch, *buf = (char *)inbuf;51int i;52long rc;53if (inbuflen == 0) {54/* get some more chars. */55inbuflen = 0;56rc = beat_get_term_char(celleb_vtermno, &inbuflen,57inbuf+0, inbuf+1);58if (rc != 0)59inbuflen = 0; /* otherwise inbuflen is garbage */60}61if (inbuflen <= 0 || inbuflen > 16) {62/* Catch error case as well as other oddities (corruption) */63inbuflen = 0;64return -1;65}66ch = buf[0];67for (i = 1; i < inbuflen; i++) /* shuffle them down. */68buf[i-1] = buf[i];69inbuflen--;70return ch;71}7273static int udbg_getc_beat(void)74{75int ch;76for (;;) {77ch = udbg_getc_poll_beat();78if (ch == -1) {79/* This shouldn't be needed...but... */80volatile unsigned long delay;81for (delay = 0; delay < 2000000; delay++)82;83} else {84return ch;85}86}87}8889/* call this from early_init() for a working debug console on90* vterm capable LPAR machines91*/92void __init udbg_init_debug_beat(void)93{94udbg_putc = udbg_putc_beat;95udbg_getc = udbg_getc_beat;96udbg_getc_poll = udbg_getc_poll_beat;97}9899100