arch/powerpc/platforms/ps3/gelic_udbg.c

Source file repositories/reference/linux-study-clean/arch/powerpc/platforms/ps3/gelic_udbg.c

File Facts

System
Linux kernel
Corpus path
arch/powerpc/platforms/ps3/gelic_udbg.c
Extension
.c
Size
5744 bytes
Lines
246
Domain
Architecture Layer
Bucket
arch/powerpc
Inferred role
Architecture Layer: exported/initcall integration point
Status
integration 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

struct gelic_descr {
	/* as defined by the hardware */
	__be32 buf_addr;
	__be32 buf_size;
	__be32 next_descr_addr;
	__be32 dmac_cmd_status;
	__be32 result_size;
	__be32 valid_size;	/* all zeroes for tx */
	__be32 data_status;
	__be32 data_error;	/* all zeroes for tx */
} __attribute__((aligned(32)));

struct debug_block {
	struct gelic_descr descr;
	u8 pkt[1520];
} __packed;

static __iomem struct ethhdr *h_eth;
static __iomem struct vlan_hdr *h_vlan;
static __iomem struct iphdr *h_ip;
static __iomem struct udphdr *h_udp;

static __iomem char *pmsg;
static __iomem char *pmsgc;

static __iomem struct debug_block dbg __attribute__((aligned(32)));

static int header_size;

static void map_dma_mem(int bus_id, int dev_id, void *start, size_t len,
			u64 *real_bus_addr)
{
	s64 result;
	u64 real_addr = ((u64)start) & 0x0fffffffffffffffUL;
	u64 real_end = real_addr + len;
	u64 map_start = real_addr & ~0xfff;
	u64 map_end = (real_end + 0xfff) & ~0xfff;
	u64 bus_addr = 0;

	u64 flags = 0xf800000000000000UL;

	result = lv1_allocate_device_dma_region(bus_id, dev_id,
						map_end - map_start, 12, 0,
						&bus_addr);
	if (result)
		lv1_panic(0);

	result = lv1_map_device_dma_region(bus_id, dev_id, map_start,
					   bus_addr, map_end - map_start,
					   flags);
	if (result)
		lv1_panic(0);

	*real_bus_addr = bus_addr + real_addr - map_start;
}

static int unmap_dma_mem(int bus_id, int dev_id, u64 bus_addr, size_t len)
{
	s64 result;
	u64 real_bus_addr;

	real_bus_addr = bus_addr & ~0xfff;
	len += bus_addr - real_bus_addr;
	len = (len + 0xfff) & ~0xfff;

	result = lv1_unmap_device_dma_region(bus_id, dev_id, real_bus_addr,
					     len);
	if (result)
		return result;

	return lv1_free_device_dma_region(bus_id, dev_id, real_bus_addr);
}

static void __init gelic_debug_init(void)
{
	s64 result;
	u64 v2;
	u64 mac;
	u64 vlan_id;

	result = lv1_open_device(GELIC_BUS_ID, GELIC_DEVICE_ID, 0);
	if (result)
		lv1_panic(0);

	map_dma_mem(GELIC_BUS_ID, GELIC_DEVICE_ID, &dbg, sizeof(dbg),
		    &bus_addr);

	memset(&dbg, 0, sizeof(dbg));

	dbg.descr.buf_addr = bus_addr + offsetof(struct debug_block, pkt);

Annotation

Implementation Notes