Return to db_mp.c CVS log | Up to [local] / sys / arch / i386 / i386 |
File: [local] / sys / arch / i386 / i386 / db_mp.c (download)
Revision 1.1.1.1 (vendor branch), Tue Mar 4 16:06:21 2008 UTC (16 years, 3 months ago) by nbrk
Import of OpenBSD 4.2 release kernel tree with initial code to support Jornada 720/728, StrongARM 1110-based handheld PC. At this point kernel roots on NFS and boots into vfs_mountroot() and traps. What is supported: - glass console, Jornada framebuffer (jfb) works in 16bpp direct color mode (needs some palette tweaks for non black/white/blue colors, i think) - saic, SA11x0 interrupt controller (needs cleanup) - sacom, SA11x0 UART (supported only as boot console for now) - SA11x0 GPIO controller fully supported (but can't handle multiple interrupt handlers on one gpio pin) - sassp, SSP port on SA11x0 that attaches spibus - Jornada microcontroller (jmcu) to control kbd, battery, etc throught the SPI bus (wskbd attaches on jmcu, but not tested) - tod functions seem work - initial code for SA-1111 (chip companion) : this is TODO Next important steps, i think: - gpio and intc on sa1111 - pcmcia support for sa11x0 (and sa1111 help logic) - REAL root on nfs when we have PCMCIA support (we may use any of supported pccard NICs) - root on wd0! (using already supported PCMCIA-ATA) |
/* $OpenBSD: db_mp.c,v 1.4 2004/07/20 20:18:53 art Exp $ */ /* * Copyright (c) 2003, 2004 Andreas Gunnarsson <andreas@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include <sys/types.h> #include <sys/simplelock.h> #include <machine/db_machdep.h> #include <sys/mutex.h> #include <ddb/db_output.h> struct mutex ddb_mp_mutex = MUTEX_INITIALIZER(IPL_HIGH); volatile int ddb_state = DDB_STATE_NOT_RUNNING; /* protected by ddb_mp_mutex */ volatile cpuid_t ddb_active_cpu; /* protected by ddb_mp_mutex */ extern volatile boolean_t db_switch_cpu; extern volatile long db_switch_to_cpu; /* * All processors wait in db_enter_ddb() (unless explicitly started from * ddb) but only one owns ddb. If the current processor should own ddb, * db_enter_ddb() returns 1. If the current processor should keep * executing as usual (if ddb is exited or the processor is explicitly * started), db_enter_ddb returns 0. * If this is the first CPU entering ddb, db_enter_ddb() will stop all * other CPUs by sending IPIs. */ int db_enter_ddb() { int i; mtx_enter(&ddb_mp_mutex); /* If we are first in, grab ddb and stop all other CPUs */ if (ddb_state == DDB_STATE_NOT_RUNNING) { ddb_active_cpu = cpu_number(); ddb_state = DDB_STATE_RUNNING; curcpu()->ci_ddb_paused = CI_DDB_INDDB; mtx_leave(&ddb_mp_mutex); for (i = 0; i < I386_MAXPROCS; i++) { if (cpu_info[i] != NULL && i != cpu_number() && cpu_info[i]->ci_ddb_paused != CI_DDB_STOPPED) { cpu_info[i]->ci_ddb_paused = CI_DDB_SHOULDSTOP; i386_send_ipi(cpu_info[i], I386_IPI_DDB); } } return (1); } /* Leaving ddb completely. Start all other CPUs and return 0 */ if (ddb_active_cpu == cpu_number() && ddb_state == DDB_STATE_EXITING) { for (i = 0; i < I386_MAXPROCS; i++) { if (cpu_info[i] != NULL) { cpu_info[i]->ci_ddb_paused = CI_DDB_RUNNING; } } mtx_leave(&ddb_mp_mutex); return (0); } /* We're switching to another CPU. db_ddbproc_cmd() has made sure * it is waiting for ddb, we just have to set ddb_active_cpu. */ if (ddb_active_cpu == cpu_number() && db_switch_cpu) { curcpu()->ci_ddb_paused = CI_DDB_SHOULDSTOP; db_switch_cpu = 0; ddb_active_cpu = db_switch_to_cpu; cpu_info[db_switch_to_cpu]->ci_ddb_paused = CI_DDB_ENTERDDB; } /* Wait until we should enter ddb or resume */ while (ddb_active_cpu != cpu_number() && curcpu()->ci_ddb_paused != CI_DDB_RUNNING) { if (curcpu()->ci_ddb_paused == CI_DDB_SHOULDSTOP) curcpu()->ci_ddb_paused = CI_DDB_STOPPED; mtx_leave(&ddb_mp_mutex); /* Busy wait without locking, we'll confirm with lock later */ while (ddb_active_cpu != cpu_number() && curcpu()->ci_ddb_paused != CI_DDB_RUNNING) ; /* Do nothing */ mtx_enter(&ddb_mp_mutex); } /* Either enter ddb or exit */ if (ddb_active_cpu == cpu_number() && ddb_state == DDB_STATE_RUNNING) { curcpu()->ci_ddb_paused = CI_DDB_INDDB; mtx_leave(&ddb_mp_mutex); return (1); } else { mtx_leave(&ddb_mp_mutex); return (0); } } void db_startcpu(int cpu) { if (cpu != cpu_number() && cpu_info[cpu] != NULL) { mtx_enter(&ddb_mp_mutex); cpu_info[cpu]->ci_ddb_paused = CI_DDB_RUNNING; mtx_leave(&ddb_mp_mutex); } } void db_stopcpu(int cpu) { mtx_enter(&ddb_mp_mutex); if (cpu != cpu_number() && cpu_info[cpu] != NULL && cpu_info[cpu]->ci_ddb_paused != CI_DDB_STOPPED) { cpu_info[cpu]->ci_ddb_paused = CI_DDB_SHOULDSTOP; mtx_leave(&ddb_mp_mutex); i386_send_ipi(cpu_info[cpu], I386_IPI_DDB); } else { mtx_leave(&ddb_mp_mutex); } } void i386_ipi_db(struct cpu_info *ci) { Debugger(); }