arch/sparc/kernel/btext.c

Source file repositories/reference/linux-study-clean/arch/sparc/kernel/btext.c

File Facts

System
Linux kernel
Corpus path
arch/sparc/kernel/btext.c
Extension
.c
Size
7331 bytes
Lines
327
Domain
Architecture Layer
Bucket
arch/sparc
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0
/*
 * Procedures for drawing on the screen early on in the boot process.
 *
 * Benjamin Herrenschmidt <benh@kernel.crashing.org>
 */
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/console.h>
#include <linux/font.h>

#include <asm/btext.h>
#include <asm/oplib.h>
#include <asm/io.h>

#define NO_SCROLL

#ifndef NO_SCROLL
static void scrollscreen(void);
#endif

static void draw_byte(unsigned char c, long locX, long locY);
static void draw_byte_32(const unsigned char *bits, unsigned int *base, int rb);
static void draw_byte_16(const unsigned char *bits, unsigned int *base, int rb);
static void draw_byte_8(const unsigned char *bits, unsigned int *base, int rb);

#define __force_data __section(".data")

static int g_loc_X __force_data;
static int g_loc_Y __force_data;
static int g_max_loc_X __force_data;
static int g_max_loc_Y __force_data;

static int dispDeviceRowBytes __force_data;
static int dispDeviceDepth  __force_data;
static int dispDeviceRect[4] __force_data;
static unsigned char *dispDeviceBase __force_data;

static int __init btext_initialize(phandle node)
{
	unsigned int width, height, depth, pitch;
	unsigned long address = 0;
	u32 prop;

	if (prom_getproperty(node, "width", (char *)&width, 4) < 0)
		return -EINVAL;
	if (prom_getproperty(node, "height", (char *)&height, 4) < 0)
		return -EINVAL;
	if (prom_getproperty(node, "depth", (char *)&depth, 4) < 0)
		return -EINVAL;
	pitch = width * ((depth + 7) / 8);

	if (prom_getproperty(node, "linebytes", (char *)&prop, 4) >= 0 &&
	    prop != 0xffffffffu)
		pitch = prop;

	if (pitch == 1)
		pitch = 0x1000;

	if (prom_getproperty(node, "address", (char *)&prop, 4) >= 0)
		address = prop;

	/* FIXME: Add support for PCI reg properties. Right now, only
	 * reliable on macs
	 */
	if (address == 0)
		return -EINVAL;

	g_loc_X = 0;
	g_loc_Y = 0;
	g_max_loc_X = width / 8;
	g_max_loc_Y = height / 16;
	dispDeviceBase = (unsigned char *)address;
	dispDeviceRowBytes = pitch;
	dispDeviceDepth = depth == 15 ? 16 : depth;
	dispDeviceRect[0] = dispDeviceRect[1] = 0;
	dispDeviceRect[2] = width;
	dispDeviceRect[3] = height;

	return 0;
}

/* Calc the base address of a given point (x,y) */
static unsigned char * calc_base(int x, int y)
{
	unsigned char *base = dispDeviceBase;

	base += (x + dispDeviceRect[0]) * (dispDeviceDepth >> 3);
	base += (y + dispDeviceRect[1]) * dispDeviceRowBytes;

Annotation

Implementation Notes